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 ILPv4 RFC #387

Merged
merged 8 commits into from
Feb 24, 2018
Merged

Add ILPv4 RFC #387

merged 8 commits into from
Feb 24, 2018

Conversation

emschwartz
Copy link
Member

@emschwartz emschwartz commented Feb 9, 2018

Replaces the previous ILP spec (IL-RFC 3). See #359.

Open questions:

  • Do we need diagrams or any more explanation of the protocol flow or motivations?
  • Should we add any more error codes?
  • Anything else that should go in this spec?

Copy link
Collaborator

@mDuo13 mDuo13 left a comment

Choose a reason for hiding this comment

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

This is a nicely concise description of a much-simplified and elegant protocol. I left a few questions and comments on things that were not clear to me.

I'll be interested to see what the higher-level protocol landscape looks like.


Before the protocol starts, the sender and receiver use a higher-level protocol to agree on the destination account and packet condition.

1. Sender constructs an ILP Prepare packet with the receiver's destination account, the agreed-upon condition, and an amount and expiry of their choice. The sender may include additional data, the formatting of which is determined by the higher-level protocol.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the expiry a duration or a deadline? The phrasing in point 5 ("shorten the expiry time") makes me wonder.

Copy link
Member Author

Choose a reason for hiding this comment

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

What is the difference? The expiry / deadline by which each bilateral transfer must be made or rolled back decreases with each successive hop so that the connectors have a window of time to deliver the fulfillment back even if the next transfer executes at the last possible moment.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's a question about whether it's represented as a point in time ("February 9th, at 17:24 UTC") or a duration of time ("3600 seconds from now").

You can't "shorten" a point, so ultimately this may just be a nitpick with that wording.

If it's a duration, then that raises other questions. (Whose "now" are we using? Which end do I shorten it from? etc.)

Copy link
Member Author

Choose a reason for hiding this comment

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

It's a timestamp, so I'll adjust the wording about it

Copy link
Collaborator

Choose a reason for hiding this comment

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

I second others opinion, that it is much more elegant and simplified protocol. also the naming conventions are very well placed for comparison with tradition ipv4 & hence the understanding of layers/packets. I have two minor points that I found was not clear to me.

1.) using PaymentChannels instead of hashlocks - I understand they do not need to include the processing time of slower ledgers, hence connector risks & somewhat even underlying ledger (architectural) issues are mitigated.

However How can this produce the same or better settlement of Bilateral payment obligations ?

2.) For proof of settlement - the document says ".. sender's signed payment channel update (or other proof of settlement) .. "
But could not find what other proofs of settlement are accepted and is this something that a user/entity can change ( ex: add/select ones own accepted proofs among a bunch of proofs that are "verified for use"? )

As i mentioned, really find this a much more simplified & way more elegant . I think its a great move to have such close design co-relation with the ip stack. Thanks for all the great work kindly.


1. Sender constructs an ILP Prepare packet with the receiver's destination account, the agreed-upon condition, and an amount and expiry of their choice. The sender may include additional data, the formatting of which is determined by the higher-level protocol.
2. Sender sends the ILP Prepare packet to a connector over some communication channel, such as a Websocket.
3. Connector checks whether the sender has sufficient bandwidth (balance or credit) to send the amount specified in the packet. If so, the connector reduces the sender's bandwidth by the value of the packet. If not, the connector returns an ILP Reject packet.
Copy link
Collaborator

Choose a reason for hiding this comment

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

In later hops, is the "sender" the originator or the previous connector?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Somewhere in this document, we should discuss what the difference is between "bandwidth" and "balance". I'm fuzzy about what "reducing the sender's bandwidth" actually looks like in practice. Does the connector need pull permissions to the shared payment channel? Does doing this give the connector money they can theoretically spend elsewhere? Is this just a hold?

In particular, I'm unclear if there's a difference between this operation and the one in step 9 where "connector credits the receiver's account".


- **Designed for Smaller, More Homogenous Packet Amounts** - ILPv4 applies a number of simplifications based on the change from supporting all packet amounts to focusing the Interledger layer on lower-value packets. Larger amounts can be sent using chunked payments, but the core network is optimized for sending large volumes of small packets. This renders unnecessary some of the more complex features of previous versions like Liquidity Curves for expressing how exchange rates may vary depending on the packet amount. Lower-value packets also help to minimize [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
- **Payment Channels, Not On-Ledger Escrow** - Since ILPv4 is optimized for smaller packets, speed and cost are of greater importantance than in previous versions. ILPv4 uses ledgers or payment channels for settling bilateral payment obligations but ILPv4 packets are sent just between connectors, rather than through the underlying ledgers themselves. This enables packet timeouts to be short, because they do not need to include the processing time of slower ledgers, which further reduces [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
- **Forwarding, Not Delivery** - In contrast to the first version of ILP, ILPv4 does not have the destination amount in the packet and connectors must only apply their local rate to forward packets. Senders may use higher-level protocols to indicate to the receiver the minimum amount they should accept for each packet, but this is no longer built into the core protocol. Connectors have only one simple behavior and do not need to maintain up-to-date price information on all possible destintations.
Copy link
Collaborator

Choose a reason for hiding this comment

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

If it's possible to deliver an exact amount—no more than a desired amount—maybe it's worth noting that here too.

If it's not possible, that's definitely worth note.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not possible to ask connectors to deliver an exact amount but you can have the receiver reject the packet if it's less than you want it to be

6. Connector forwards the packet to the next hop, which may be another connector. All subsequent connectors go through steps 3-6 until the packet reaches the receiver.
7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender).
8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step until the Fulfill (or Reject) packet reaches the sender.
Copy link
Collaborator

Choose a reason for hiding this comment

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

In this step, "credit's the receiver's account" seems to refer to the receiver of an individual hop, not the overall beneficiary. If so, that should be explicit.

Copy link
Member Author

Choose a reason for hiding this comment

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

Each hop does credit the next one if the connector or receiver after them delivers the fulfillment in time

9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step until the Fulfill (or Reject) packet reaches the sender.
10. Sender checks that the preimage in the ILP Fulfill packet matches the condition in their Prepare packet and may read any data returned by the receiver.
11. Sender signs an update to their payment channel with the first connector to cover the value of the ILP Prepare (or they may settle less frequently using slower on-ledger transfers or physical deliveries of cash or other goods) and communicates it to the connector.
12. Connector validates the sender's signed payment channel update (or other proof of settlement) and increases the sender's bandwidth by the amount they paid. If the sender does not pay for the ILP Prepare, the connector may refuse to process further ILP packets until they do or the connector may block that user entirely.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This definitely sounds like a bigger risk on connectors than in ILPv1, even if the amounts are smaller. In v1, connectors only had to choose ledgers they trust to enforce cryptographic escrow. Now it sounds like senders can shop around for sucker connectors. Given that this protocol does not define any way to identify senders, blocking them permanently could be quite a challenge.

I suspect that this is supposed to be solved in a higher-level protocol or in the setup of the payment channels, but the phrasing of this point doesn't really make that clear.

Mostly unrelated, this is another place "bandwidth" is used in a somewhat mysterious way.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's certainly a different type of risk but I'm not sure it's a bigger one. In ILPv1, connectors ran the risk that some sender would tie up their liquidity for a long period of time and then either reject the payment or accept it only if the exchange rate had moved in their favor (the free option problem). A big issue with that was that anyone could cause that to happen, even someone that was indirectly connected.

Now, the model is that each bilateral connection requires some level of trust. Either the sender needs to trust the connector (if the account is pre-funded) or the connector needs to trust the sender (if their account is post-funded, as in this example). Like in ILPv1, you need to trust whoever you're directly connected to, but now you're directly connected to other connectors (or senders or receivers), rather than ledgers.

| **F03** | **Invalid Amount** | The amount is invalid, for example it contains more digits of precision than are available on the destination ledger or the amount is greater than the total amount of the given asset in existence. | (empty) |
| **F04** | **Insufficient Destination Amount** | The receiver deemed the amount insufficient, for example you tried to pay a $100 invoice with $10. | (empty) |
| **F05** | **Wrong Condition** | The receiver generated a different condition and cannot fulfill the payment. | (empty) |
| **F06** | **Unexpected Payment** | The receiver was not expecting a payment like this (the memo and destination address don't make sense in that combination, for example if the receiver does not understand the transport protocol used) | (empty) |
Copy link
Collaborator

Choose a reason for hiding this comment

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

The description refers to a "memo" which is (I think) not defined elsewhere in the protocol.

| **F04** | **Insufficient Destination Amount** | The receiver deemed the amount insufficient, for example you tried to pay a $100 invoice with $10. | (empty) |
| **F05** | **Wrong Condition** | The receiver generated a different condition and cannot fulfill the payment. | (empty) |
| **F06** | **Unexpected Payment** | The receiver was not expecting a payment like this (the memo and destination address don't make sense in that combination, for example if the receiver does not understand the transport protocol used) | (empty) |
| **F07** | **Cannot Receive** | The receiver is unable to accept this payment due to a constraint. For example, the payment would put the receiver above its maximum account balance. | (empty) |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does "receiver" here only refer to the beneficiary, or could it also be a connector?

|---|---|---|---|
| **T00** | **Internal Error** | A generic unexpected exception. This usually indicates a bug or unhandled error case. | (empty) |
| **T01** | **Ledger Unreachable** | The connector has a route or partial route to the destination but was unable to reach the next ledger. Try again later. | (empty) |
| **T02** | **Ledger Busy** | The ledger is rejecting requests due to overloading. Try again later. | (empty) |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should the "Ledger" errors (T01 and T02) be re-specified or removed now that the ledgers are not synchronously part of this protocol?

Copy link
Member Author

Choose a reason for hiding this comment

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

We could deprecate those or change the meaning to talk about connectors now. Both of them could apply if a previous connector knows the route but can't contact their peer at that moment. I don't think these are actually used right now

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, maybe redefine them to relate to connectors and rename them "Peer Busy" and "Peer Unreachable".

So you'd have:

  • T01 Peer Unreachable - "I can't pass this forward because the connector I want to pass it to didn't respond."
  • T02 Peer Busy - "I can't pass this forward because the connector I want to pass it to is lagging or giving me a busy signal."
  • T03 Connector Busy - "I'm busy."

Although, given that, I don't know when T02 would be used over T03 or vice versa. So maybe we should just remove one of those.

| **T01** | **Ledger Unreachable** | The connector has a route or partial route to the destination but was unable to reach the next ledger. Try again later. | (empty) |
| **T02** | **Ledger Busy** | The ledger is rejecting requests due to overloading. Try again later. | (empty) |
| **T03** | **Connector Busy** | The connector is rejecting requests due to overloading. Try again later. | (empty) |
| **T04** | **Insufficient Liquidity** | The connector would like to fulfill your request, but it doesn't currently have enough money. Try again later. | (empty) |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is "liquidity" or "money" here the same as the "bandwidth" described in the Flow section?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. I think the main difference between the bandwidth and balance concepts is that bandwidth captures the fact that it may refill quickly if you have a fast settlement method like a payment channel

| Code | Name | Description | Data Fields |
|---|---|---|---|
| **R00** | **Transfer Timed Out** | The transfer timed out, meaning the next party in the chain did not respond. This could be because you set your timeout too low or because something look longer than it should. The sender MAY try again with a higher expiry, but they SHOULD NOT do this indefinitely or a malicious connector could cause them to tie up their money for an unreasonably long time. | (empty) |
| **R01** | **Insufficient Source Amount** | Either the sender did not send enough money or the exchange rate changed before the payment was prepared. The sender MAY try again with a higher amount, but they SHOULD NOT do this indefinitely or a malicious connector could steal money from them. | (empty) |
Copy link
Collaborator

Choose a reason for hiding this comment

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

before the payment was prepared

I think this one needs to be rephrased for v4. It probably means that after subtracting fees, the Amount went below 0 or a minimum specified by a higher-level protocol.

| `amount` | UInt64 | Local amount, denominated in the minimum divisible unit of the asset of the bilateral relationship. This field is modified by each connector, who applies their exchange rate before forwarding the packet |
| `expiresAt` | Fixed-Length [Interledger Timestamp](../asn1/InterledgerTypes.asn) | Date and time when the packet expires. This field is modified by each connector, who subtracts some amount of time from the expiry before forwarding the packet |
| `executionCondition` | UInt256 | Sha256 hash digest of the `fulfillment` that will execute the transfer of value represented by this packet |
| `destination` | [ILP Address](../0015-ilp-addresses/0015-ilp-addresses.md) | ILP Address of the receiver |
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would argue that connectors need one more piece of data that's not in the ILP packet: the sender from the previous hop.

The connector can figure this out from the communication channel by which they received an ILP packet, but I suspect it would simplify implementations and make them far more flexible in terms of underlying communication layers if the packet contained a from field identifying the previous connector (or the originator in the first hop), probably also by ILP address.

With that information, a connector would know whose "bandwidth" to debit from just the ILP Packet itself. Although I guess you'd have to worry about spoofing other senders to tie up their "bandwidth"...

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, connectors should figure this out based on which communication channel they got the packet from. If there were a from field, it would just be one more thing the connector would need to verify because it would be easy to lie about it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That makes sense. You should find a place to state it explicitly in the standard.

- **Neutrality** - Interledger is not tied to any company, currency, or network.
- **Interoperability** - ILP should be usable across any type of ledger, even those that were not built for interoperability.
- **Security** - Senders, connectors, and receivers should be protected from one another and especially isolated from risks posed by parties that they are indirectly connected to.
- **Simplicity** - The core ILP should be as simple as possible. There is room for significant variability at lower and higher layers of the [Interledger stack](../0001-interledger-architecture/0001-interledger-architecture.md#interledger-protocol-suite), but the Interledger layer is the one part where widespread agreement is needed for interoperability.
Copy link
Contributor

Choose a reason for hiding this comment

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

explain what "the core ILP" is. Is it the three OER-encoded packet formats? Do we (or should we) have an RFC that describes "the core ILP"? Does "Interledger Protocol v4" contain more than "the core ILP", or are they synonymous?

Copy link
Contributor

Choose a reason for hiding this comment

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

Is "the Interledger layer" synonymous with "the core ILP"?

Copy link
Member Author

Choose a reason for hiding this comment

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

Previously the Interledger layer was made up of ILP and ILQP. Now it's just ILP

- **Interoperability** - ILP should be usable across any type of ledger, even those that were not built for interoperability.
- **Security** - Senders, connectors, and receivers should be protected from one another and especially isolated from risks posed by parties that they are indirectly connected to.
- **Simplicity** - The core ILP should be as simple as possible. There is room for significant variability at lower and higher layers of the [Interledger stack](../0001-interledger-architecture/0001-interledger-architecture.md#interledger-protocol-suite), but the Interledger layer is the one part where widespread agreement is needed for interoperability.
- **End-to-End Principle** - Inspired by the Internet, any features that do not need to be implemented by the core protocol and network should be built into the edges of the network (the sender and receiver).
Copy link
Contributor

Choose a reason for hiding this comment

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

I think by "core" you mean "the parts of the protocol, and the nodes in the network, that are only concerned with forwarding payments for others, and neither with receiving nor sending such payments"


### Relation to Other Protocols

ILPv4 packets may be sent over any communication channel between peers. Payment obligations created by ILP packets may be settled using any available means, ranging from ledger transfers triggered by an API, to signed updates to payment channels, or the physical delivery of cash or other goods.
Copy link
Contributor

Choose a reason for hiding this comment

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

first mention of the existence of packets, other than the figurative "packets of money" in the opening sentence. maybe in the first paragraph, state that there are three packet types, corresponding to request / success / error, and that they are OER-encoded. Then here, you can explain that it's those OER strings that are being sent between peers.


ILPv4 packets may be sent over any communication channel between peers. Payment obligations created by ILP packets may be settled using any available means, ranging from ledger transfers triggered by an API, to signed updates to payment channels, or the physical delivery of cash or other goods.

ILPv4 will probably be used with a Transport Layer protocol such as the Pre-Shared Key V2 (PSKv2) protocol, which handles the generation of ILP conditions and fulfillments.
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should explain why PSKv2 and not PSKv1. so one of the design goals should be speed, right? and that will lead to small max payment size and that will lead to PSKv2 being a better fit than PSKv1.

Copy link
Contributor

Choose a reason for hiding this comment

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

ah, i see that's mentioned in the next paragraph. still, i think we should also list it as a design goal now.

### Differences from Previous Versions of ILP

- **Designed for Smaller, More Homogenous Packet Amounts** - ILPv4 applies a number of simplifications based on the change from supporting all packet amounts to focusing the Interledger layer on lower-value packets. Larger amounts can be sent using chunked payments, but the core network is optimized for sending large volumes of small packets. This renders unnecessary some of the more complex features of previous versions like Liquidity Curves for expressing how exchange rates may vary depending on the packet amount. Lower-value packets also help to minimize [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
- **Payment Channels, Not On-Ledger Escrow** - Since ILPv4 is optimized for smaller packets, speed and cost are of greater importantance than in previous versions. ILPv4 uses ledgers or payment channels for settling bilateral payment obligations but ILPv4 packets are sent just between connectors, rather than through the underlying ledgers themselves. This enables packet timeouts to be short, because they do not need to include the processing time of slower ledgers, which further reduces [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
Copy link
Contributor

Choose a reason for hiding this comment

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

in which sense is ILPv4 optimized for smaller packets? is the choice for unconditional payment channels a part of the ILPv4 design, or could someone do conditional payment channels and large packets, and still call it ILPv4?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's an interesting question. I think a lot of the things we've now built into or on top of ILPv4 assume the packets are relatively small, but you might still be able to do larger packets or conditional transfers.

Some of the assumptions are:

  • Sending packets is free or of negligible cost, so we can use them liberally for things like quoting
  • Ledger protocols are now mostly request/response, meaning the response isn't retried if it doesn't go through the first time
  • Connectors don't store prepared packets in a db, because the assumption is that if your system dies you just lose all the packets that are in-flight
  • Connectors have relatively low maximum hold times by default and as a connector you should be prepared to forward packets that have less than 30 seconds before they expire (you won't fare very well if you need to build in a long expiry window because your ledger is slower than that)
  • As someone sending packets through the open Interledger, you won't be able to rely on the assumption that your payment can go through in one chunk and you might be told it's too big

@mDuo13
Copy link
Collaborator

mDuo13 commented Feb 9, 2018

Thinking on this spec overnight, I had a couple more points:

  • We probably want to add some definitions of key terms, like a one-paragraph description of payment channels, and an explanation of how "bandwidth" is different from "balance" (if we're going to use the term bandwidth at all).
  • Similarly, maybe add a brief list of required or recommended background reading?

6. Connector forwards the packet to the next hop, which may be another connector. All subsequent connectors go through steps 3-6 until the packet reaches the receiver.
7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender).
8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step until the Fulfill (or Reject) packet reaches the sender.
Copy link
Contributor

@wilsonianb wilsonianb Feb 9, 2018

Choose a reason for hiding this comment

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

If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector.

Why can't the previous connector just determine that the Prepare expired when they don't get a Fulfill packet before their own expiration?

### Differences from Previous Versions of ILP

- **Designed for Smaller, More Homogenous Packet Amounts** - ILPv4 applies a number of simplifications based on the change from supporting all packet amounts to focusing the Interledger layer on lower-value packets. Larger amounts can be sent using chunked payments, but the core network is optimized for sending large volumes of small packets. This renders unnecessary some of the more complex features of previous versions like Liquidity Curves for expressing how exchange rates may vary depending on the packet amount. Lower-value packets also help to minimize [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
- **Payment Channels, Not On-Ledger Escrow** - Since ILPv4 is optimized for smaller packets, speed and cost are of greater importantance than in previous versions. ILPv4 uses ledgers or payment channels for settling bilateral payment obligations but ILPv4 packets are sent just between connectors, rather than through the underlying ledgers themselves. This enables packet timeouts to be short, because they do not need to include the processing time of slower ledgers, which further reduces [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: "importantance"


- **Designed for Smaller, More Homogenous Packet Amounts** - ILPv4 applies a number of simplifications based on the change from supporting all packet amounts to focusing the Interledger layer on lower-value packets. Larger amounts can be sent using chunked payments, but the core network is optimized for sending large volumes of small packets. This renders unnecessary some of the more complex features of previous versions like Liquidity Curves for expressing how exchange rates may vary depending on the packet amount. Lower-value packets also help to minimize [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
- **Payment Channels, Not On-Ledger Escrow** - Since ILPv4 is optimized for smaller packets, speed and cost are of greater importantance than in previous versions. ILPv4 uses ledgers or payment channels for settling bilateral payment obligations but ILPv4 packets are sent just between connectors, rather than through the underlying ledgers themselves. This enables packet timeouts to be short, because they do not need to include the processing time of slower ledgers, which further reduces [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
- **Forwarding, Not Delivery** - In contrast to the first version of ILP, ILPv4 does not have the destination amount in the packet and connectors must only apply their local rate to forward packets. Senders may use higher-level protocols to indicate to the receiver the minimum amount they should accept for each packet, but this is no longer built into the core protocol. Connectors have only one simple behavior and do not need to maintain up-to-date price information on all possible destintations.
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: "destintations"


# Interledger Protocol V4

Interledger is a protocol for sending packets of money across different payment networks or ledgers. ILPv4 is a simplification of previous versions of the protocol designed primarily for "penny switching", or routing large volumes of smaller-value packets. ILPv4 can be integrated with any type of ledger, including those not built for interoperability, and it can be used with a variety of higher-level protocols that implement features ranging from quoting to sending larger amounts of value with chunked payments.

Choose a reason for hiding this comment

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

Maybe say using "penny switching" to limit risk instead of expensive atomic swaps

Copy link
Member Author

Choose a reason for hiding this comment

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

There are a bunch of reasons we opted for penny switching, risk being one of them. To me, that phrasing seems to bring up more questions than it answers (for example, what makes atomic swaps expensive?) and I'm not sure this document is the place to speak to all of those points

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is actually incorrect. The size of the packets will be emergent and has nothing to do with the protocol. The protocol limits amounts per packet to UInt64.MAX and given that this can be scaled it's effectively unlimited.

I think you could replace "designed primarily for "penny switching", or routing large volumes of smaller-value packets. ILPv4" with "which"

Copy link
Member Author

Choose a reason for hiding this comment

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

It is emergent but we have made a number of assumptions that are based on relatively small packet amounts:

  • Connectors can severely limit their customers' bandwidths to limit their risk, without making their customers' payments fail (because the customers will work around that)
  • Sending packets is free or of negligible cost, so we can use them liberally for things like quoting
  • We don't need a way to express how exchange rates vary based on the payment amount and/or hold time
  • As someone sending packets through the open Interledger, you won't be able to rely on the assumption that your payment can go through in one chunk and you might be told it's too big

And some of the implementation assumptions:

  • Ledger protocols are now mostly request/response, meaning the response (fulfillment) isn't retried if it doesn't go through the first time
  • Connectors don't store prepared packets in a db, because the assumption is that if your system dies you just lose all the packets that are in-flight and the timeout is too short for you to bring the system up and submit the fulfillments anyway
  • Connectors have relatively low maximum hold times by default and as a connector you should be prepared to forward packets that have less than 30 seconds before they expire (you won't fare very well if you need to build in a long expiry window because your ledger is slower than that)


- **Neutrality** - Interledger is not tied to any company, currency, or network.
- **Interoperability** - ILP should be usable across any type of ledger, even those that were not built for interoperability.
- **Security** - Senders, connectors, and receivers should be protected from one another and especially isolated from risks posed by parties that they are indirectly connected to. Connectors should not be able to steal money from senders, and senders should not be able to tie up too much of connectors' funds or otherwise interfere with their operation.

Choose a reason for hiding this comment

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

tie up too much of connectors' funds -> tie up connectors' funds

Copy link
Member Author

Choose a reason for hiding this comment

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

Why? You tie up connectors' funds every time you prepare a payment. The problem is if you take up too much bandwidth

- **Neutrality** - Interledger is not tied to any company, currency, or network.
- **Interoperability** - ILP should be usable across any type of ledger, even those that were not built for interoperability.
- **Security** - Senders, connectors, and receivers should be protected from one another and especially isolated from risks posed by parties that they are indirectly connected to. Connectors should not be able to steal money from senders, and senders should not be able to tie up too much of connectors' funds or otherwise interfere with their operation.
- **Simplicity** - The core ILP should be as simple as possible. There is room for significant variability at lower and higher layers of the [Interledger stack](../0001-interledger-architecture/0001-interledger-architecture.md#interledger-protocol-suite), but the Interledger layer is the one part where widespread agreement is needed for interoperability.

Choose a reason for hiding this comment

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

"Interledger stack" should be updated for ILPv4 as well, otherwise reading it will contradict this document

Copy link
Member Author

Choose a reason for hiding this comment

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


### Terminology

- **Balance** - Connectors may track the credit each customer or peer holds with them. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low.

Choose a reason for hiding this comment

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

How about: "Because this balance represents un-settled debt between direct neighbors, either party can default on it. If an account is pre-funded, the customer/peer trusts the connector not to zero their balance. If an account is post-funded, the connector trusts the customer/peer to later settle this debt. Either party may stop transacting if the balance exceeds their trust in the other party. The amount of trust required to practically transact is related inversely to the speed of the ledger used for settlement."

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would recommend using the term Account and not balance as this aligns well with financial terminology people will be familiar with.

I also think defining the term Node makes a lot of explanations simpler.

  • Node - A participant in an Interledger payment (node on the Interledger network), that has accounts with one or more other nodes. There are three specializations of a node:
    • Senders - originate payments
    • Receivers - are the final recipients of payments, and
    • Connectors - are the intermediaries between a sender and a receiver that forward ILP packets. They may generate revenue from spreads on currency conversion, through subscription fees, or other means.

(Moved connector definition up here)

  • Peer - A node with which another node holds an account. In some cases the relationship between two nodes will be a parent/child relationship whereby the parent provides additional services to the child beyond simply forwarding ILP packets.

  • Account - Two peers establish an account with one another where they track the current obligations they hold with one another; i.e. the balance on the account. The account is denominated in a single asset. The peers agree on the precision and scale they will use for the amounts of that asset when they express amounts in messages between one another. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low.

@sharafian said:

The amount of trust required to practically transact is related inversely to the speed of the ledger used for settlement.

This is a useful point to make somewhere in this document but not here in the definitions.

### Terminology

- **Balance** - Connectors may track the credit each customer or peer holds with them. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low.
- **Bandwidth** - Connectors may limit the total value of ILP packets a customer or peer can send or receive within a given time period. This may be limited by the minimum balance on that party's account, which can be refilled by settling outstanding debts through a ledger or payment channel. Connectors may also limit each account's bandwidth to prevent one customer or peer from using or tying up all of the connector's liquidity.

Choose a reason for hiding this comment

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

all of the connector's liquidity -> all of the connector's bandwidth with their peers.

Copy link
Collaborator

Choose a reason for hiding this comment

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

within a given time period.

This sounds like a hard limit as opposed to a limit on the total in-flight. Is that intentional?

6. Connector forwards the packet to the next hop, which may be another connector. All subsequent connectors go through steps 3-6 (treating the previous connector as the sender) until the packet reaches the receiver.
7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender).
8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step (treating the next connector as the receiver whom they will credit) until the Fulfill (or Reject) packet reaches the sender.

Choose a reason for hiding this comment

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

The connector also has to verify that the fulfillment matches the condition.

Also treating the next connector as the receiver whom they will credit might be confusing, because "next" could be interpreted as either direction.

5. Connector modifies the packet amount and expiry to apply their exchange rate and move the expiry timestamp earlier.
6. Connector forwards the packet to the next hop, which may be another connector. All subsequent connectors go through steps 3-6 (treating the previous connector as the sender) until the packet reaches the receiver.
7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender).
8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.

Choose a reason for hiding this comment

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

The receiver should only fulfill so long as it doesn't put the Connector's unsettled balance with them above the maximum amount that the receiver tolerates (just like what the connector does in step 3)

7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender).
8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step (treating the next connector as the receiver whom they will credit) until the Fulfill (or Reject) packet reaches the sender.
10. Sender checks that the preimage in the ILP Fulfill packet matches the condition in their Prepare packet and may read any data returned by the receiver.

Choose a reason for hiding this comment

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

Additionally, the sender has to do some accounting to acknowledge that their packet was fulfilled, so they can determine how much to settle. Otherwise the trust model is different because the connector could tell them to settle more. Sometimes it might be acceptable (I trust my bank to not put fake charges on my account), but in the payment channel case especially the sender tracks their balance.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@sharafian said:

so they can determine how much to settle

How can this be different from the amount they specified in the prepare packet?

Copy link
Member Author

Choose a reason for hiding this comment

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

He means that you want to keep track of how much you owe (based on the sum of the amounts in the prepare packets) so that the connector doesn't just make up an amount they want you to pay them.

8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step (treating the next connector as the receiver whom they will credit) until the Fulfill (or Reject) packet reaches the sender.
10. Sender checks that the preimage in the ILP Fulfill packet matches the condition in their Prepare packet and may read any data returned by the receiver.
11. Sender signs an update to their payment channel with the first connector to cover the value of the ILP Prepare (or they may settle less frequently using slower on-ledger transfers or physical deliveries of cash or other goods) and communicates it to the connector.

Choose a reason for hiding this comment

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

Not sure if 11 and 12 should actually go in here, because technically they're not a part of the packet flow. Maybe an appendix of some kind to this list? I guess for payment channels it makes sense that you might do it every packet, but that's not mandated by ILP

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's useful to have in there to give some explanation of how the balance is expected to be settled.

I guess for payment channels it makes sense that you might do it every packet, but that's not mandated by ILP

Is that not clear from "(or they may settle less frequently using slower on-ledger transfers or physical deliveries of cash or other goods)"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree with @sharafian here. We should describe it as part of the overall process but not put it in the flow. This may be a pre-paid account in which case this step happens before step 2.

| `destination` | [ILP Address](../0015-ilp-addresses/0015-ilp-addresses.md) | ILP Address of the receiver |
| `data` | Variable-Length Octet String | End-to-end data. Connectors MUST NOT modify this data. Most higher-level protocols will encrypt and authenticate this data, so receivers will reject packets in which the data is modified |

**Note:** There is no `from` or `source` address in the ILP Prepare packet. Each hop MUST determine which of their immediate peers or customers the packet came from (to debit the correct account) based on the communication channel the packet was received through. Also, higher-level protocols MAY communicate the sender's address to the receiver if the use case calls for receivers to send ILP Prepare packets to the sender (they can communicate responses to the sender using the `data` field in ILP Fulfill and Reject packets).

Choose a reason for hiding this comment

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

Based on communication channel and authentication information (e.g. in the case of an HTTP endpoint)

Copy link
Collaborator

Choose a reason for hiding this comment

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

@sharafian depending on your definition of "communication channel" that is implied.

http://www.enterpriseintegrationpatterns.com/patterns/messaging/PointToPointChannel.html


# Interledger Protocol V4

Interledger is a protocol for sending packets of money across different payment networks or ledgers. ILPv4 is a simplification of previous versions of the protocol designed primarily for "penny switching", or routing large volumes of smaller-value packets. ILPv4 can be integrated with any type of ledger, including those not built for interoperability, and it can be used with a variety of higher-level protocols that implement features ranging from quoting to sending larger amounts of value with chunked payments.
Copy link
Contributor

Choose a reason for hiding this comment

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

The second sentence in the intro has an ambiguous modifier after the phrase, "previous versions of the protocol" (it's unclear if the penny-switching phrase referes to ILPv4, or to previous versions).

Consider something like the following:

Interledger (ILP) is a protocol for sending packets of money across different payment networks or ledgers. The latest version, ILPv4, is a simplification of the protocol designed primarily for "penny switching", or routing large volumes of smaller-value packets, to limit risk instead of trying to accommodate expensive atomic swaps

Copy link
Contributor

Choose a reason for hiding this comment

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

Or just this if you don't like the change proposed by Ben...

Interledger (ILP) is a protocol for sending packets of money across different payment networks or ledgers. The latest version, ILPv4, is a simplification of the protocol designed primarily for "penny switching", or routing large volumes of smaller-value packets.

Copy link
Collaborator

@adrianhopebailie adrianhopebailie left a comment

Choose a reason for hiding this comment

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

Great document. Some suggested changes but excited about getting this published.

| Field | Type | Description |
|---|---|---|
| `type` | UInt8 | ID of the ILP Packet type |
| `data` | Variable-Length Octet String | Packet contents, prefixed with their length |
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no length prefix here. The type tells you what the sequence of remaining fields is.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think the comment in the ASN.1 might contradict the definition (see here) but the implementation definitely uses a length-prefixed field

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm. I believe that is an implementation error. The ASN.1 definition resolves to:

InterledgerPreparePacket ::= SEQUENCE {
  type UInt8,
  data InterledgerPrepare -- If type == 12 then data is of type InterledgerPrepare
}

InterledgerPrepare ::= SEQUENCE {
  amount UInt64,
  expiresAt Timestamp,
  executionCondition UInt256,
  destination Address,
  data OCTET STRING (SIZE (0..32767))
}

In other words it is a SEQUENCE as a field within a SEQUENCE. There is no length indicator on the field.

Copy link
Member Author

Choose a reason for hiding this comment

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

🤷‍♂️ that might be the kind of implementation error that sticks because changing it would break everything (like HTTP "Referer")

Copy link
Collaborator

@adrianhopebailie adrianhopebailie Feb 12, 2018

Choose a reason for hiding this comment

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

I think we can change the ASN.1 to reflect the implementation but it will be ugly. We'd lose the binding (in ASN.1) between the type and the format.

Something like:

InterledgerPacket ::= SEQUENCE {
  type UInt8,
  data OCTET STRING
}

Then implementors need to know that if type == 12 then data must be parsed as an InterledgerPrepare. It's not pretty.

Choose a reason for hiding this comment

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

The intended meaning is definitely that there should be a length prefix (otherwise extensibility is broken). I couldn't find a document that describes how CLASS is encoded in OER, so I don't know whether the ASN.1 is technically correct. Given that @justmoon tested this in an ASN.1 tool, I assume that CLASS does encode with a length prefix.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The intended meaning is definitely that there should be a length prefix (otherwise extensibility is broken).

No, that's why we previously had extensibility in each packet type. An ASN.1 SEQUENCE has no overall length indicator because the sequence of fields is known and their length can be determined independently.

As we've discussed before, this is why you can't send an ILP packet over a transport that doesn't support framing because if you get a bad packet you don't know when the the next good packet starts.

I couldn't find a document that describes how CLASS is encoded in OER, so I don't know whether the ASN.1 is technically correct.

CLASS is not explicitly encoded. It is a way of defining Information Objects which are arrangements of other ASN.1 types. See http://www.oss.com/asn1/resources/asn1-made-simple/advanced-topics.html

In our definition of PACKET we specify that a packet must be defined by a UInt8 type and then the packet data.

We then define PacketSet which is the acceptable list of types.

This is not valid ASN.1 but basically we define an InterledgerPreparePacket as:

InterledgerPreparePacket ::= SEQUENCE {
  type ::= UInt8 12,
  data ::= SEQUENCE {
    amount UInt64,
    expiresAt Timestamp,
    executionCondition UInt256,
    destination Address,
    data OCTET STRING (SIZE (0..32767))
  }
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

I used the tool at http://asn1-playground.oss.com/ and it produces the same output as the implementation so either they are both wrong (unlikely) or there is some aspect of OER encoding that I need to understand better (more likely).

Encoding to the file 'data.oer' using OER encoding rule...
InterledgerPacket SEQUENCE
  type UInt8 INTEGER [length = 1]
    12
  data InterledgerPrepare SEQUENCE
    amount UInt64 INTEGER [length = 8]
      1000
    expiresAt Timestamp PrintableString [length = 17]
      "20170212201100000"
    executionCondition UInt256 OCTET STRING [length = 32]
      0x0000000000000000000000000000000000 ...
    destination Address IA5String [length = 6]
      "g.test"
    data OCTET STRING [length = 0]
      <no content>
Total encoded length = 67
Encoded successfully in 67 bytes:
0C410000 00000000 03E83230 31373032 31323230 31313030 30303000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000006 672E7465
737400

0C = 12
41 = 65 (length of data)
000000 00000003 E8 = 1000 (amount)
323031 37303231 32323031 31303030 3030 = "20170212201100000" (expiresAt)
0000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 0000 = 0 (condition as UInt256)
06 + 67 2E746573 74 = 6 (length of address) + "g.test" (address)
00 = 0 (length of data)

Copy link
Member

Choose a reason for hiding this comment

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

The InterledgerPacket's data field is what's called an open type. The OER spec says:

30 Encoding of open type values

NOTE – An open type is an ASN.1 type that can take any abstract value of any ASN.1 type. Each value of an open type consists of:
a) a contained type; and
b) a value of the contained type.

The encoding of an open type value shall consist of a length determinant (see 8.6) followed by a series of octets, which are the encoding of the value of the contained type.

(emphasis added)

So both OSS' and our implementations are both correct in adding a length determinant.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I realized when implementing this, the reason for having the length and it's important for implementors to be aware of this if they wish to be forward-compatible (although this is less of an issue in ILPv4 because there is not case when you would forward a packet with a type you don't know.)

Since this is an Open Type, a decoder may encounter a type value they don't recognize (e.g. 15) and therefor don't know how to decode the associated data. There may be situations where this is not a critical error and so the decoder can simply consume the correct number of bytes and continue decoding the rest of the message (and possibly forward these un-parsable bytes to the next entity).


# Interledger Protocol V4

Interledger is a protocol for sending packets of money across different payment networks or ledgers. ILPv4 is a simplification of previous versions of the protocol designed primarily for "penny switching", or routing large volumes of smaller-value packets. ILPv4 can be integrated with any type of ledger, including those not built for interoperability, and it can be used with a variety of higher-level protocols that implement features ranging from quoting to sending larger amounts of value with chunked payments.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is actually incorrect. The size of the packets will be emergent and has nothing to do with the protocol. The protocol limits amounts per packet to UInt64.MAX and given that this can be scaled it's effectively unlimited.

I think you could replace "designed primarily for "penny switching", or routing large volumes of smaller-value packets. ILPv4" with "which"


### Terminology

- **Balance** - Connectors may track the credit each customer or peer holds with them. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would recommend using the term Account and not balance as this aligns well with financial terminology people will be familiar with.

I also think defining the term Node makes a lot of explanations simpler.

  • Node - A participant in an Interledger payment (node on the Interledger network), that has accounts with one or more other nodes. There are three specializations of a node:
    • Senders - originate payments
    • Receivers - are the final recipients of payments, and
    • Connectors - are the intermediaries between a sender and a receiver that forward ILP packets. They may generate revenue from spreads on currency conversion, through subscription fees, or other means.

(Moved connector definition up here)

  • Peer - A node with which another node holds an account. In some cases the relationship between two nodes will be a parent/child relationship whereby the parent provides additional services to the child beyond simply forwarding ILP packets.

  • Account - Two peers establish an account with one another where they track the current obligations they hold with one another; i.e. the balance on the account. The account is denominated in a single asset. The peers agree on the precision and scale they will use for the amounts of that asset when they express amounts in messages between one another. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low.

@sharafian said:

The amount of trust required to practically transact is related inversely to the speed of the ledger used for settlement.

This is a useful point to make somewhere in this document but not here in the definitions.

### Terminology

- **Balance** - Connectors may track the credit each customer or peer holds with them. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low.
- **Bandwidth** - Connectors may limit the total value of ILP packets a customer or peer can send or receive within a given time period. This may be limited by the minimum balance on that party's account, which can be refilled by settling outstanding debts through a ledger or payment channel. Connectors may also limit each account's bandwidth to prevent one customer or peer from using or tying up all of the connector's liquidity.
Copy link
Collaborator

Choose a reason for hiding this comment

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

within a given time period.

This sounds like a hard limit as opposed to a limit on the total in-flight. Is that intentional?


- **Balance** - Connectors may track the credit each customer or peer holds with them. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low.
- **Bandwidth** - Connectors may limit the total value of ILP packets a customer or peer can send or receive within a given time period. This may be limited by the minimum balance on that party's account, which can be refilled by settling outstanding debts through a ledger or payment channel. Connectors may also limit each account's bandwidth to prevent one customer or peer from using or tying up all of the connector's liquidity.
- **Condition and Fulfillment** - ILP packets are secured with conditions so that they cannot be lost or stolen by intermediary connectors. ILP Prepare packets are sent with a condition or SHA-256 hash in them. When the receiver receives the packet, they present the fulfillment, or valid preimage of the hash, to execute the transfer.
Copy link
Collaborator

Choose a reason for hiding this comment

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

@sharafian suggested:

These do not correspond to on-ledger escrow, but allow parties to verify that their balances are correct.

I would go further and say that these are key to the reconciliation of balances between peers. Two peers should only consider an ILP payment complete (and therefor have an impact on the account between them) iff:

  • the fulfillment is valid (the SHA-256 hash of it is exactly equal to the condition)
  • the fulfillment was delivered before the expiry

7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender).
8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step (treating the next connector as the receiver whom they will credit) until the Fulfill (or Reject) packet reaches the sender.
10. Sender checks that the preimage in the ILP Fulfill packet matches the condition in their Prepare packet and may read any data returned by the receiver.
Copy link
Collaborator

Choose a reason for hiding this comment

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

@sharafian said:

so they can determine how much to settle

How can this be different from the amount they specified in the prepare packet?

8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step (treating the next connector as the receiver whom they will credit) until the Fulfill (or Reject) packet reaches the sender.
10. Sender checks that the preimage in the ILP Fulfill packet matches the condition in their Prepare packet and may read any data returned by the receiver.
11. Sender signs an update to their payment channel with the first connector to cover the value of the ILP Prepare (or they may settle less frequently using slower on-ledger transfers or physical deliveries of cash or other goods) and communicates it to the connector.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree with @sharafian here. We should describe it as part of the overall process but not put it in the flow. This may be a pre-paid account in which case this step happens before step 2.


| Field | Type | Description |
|---|---|---|
| `amount` | UInt64 | Local amount, denominated in the minimum divisible unit of the asset of the bilateral relationship. This field is modified by each connector, who applies their exchange rate before forwarding the packet |
Copy link
Collaborator

Choose a reason for hiding this comment

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

"applies their exchange rate" and adjusts the amount to the appropriate scale and precision of the account on the outgoing channel.

2. Sender sends the ILP Prepare packet to a connector over some communication channel, such as a Websocket.
3. Connector gets the packet and determines who the sender was based on the communication channel it was received through. The connector checks whether the sender has sufficient balance or credit to send the amount specified in the packet. If so, the connector reduces the sender's available balance by the value of the packet. If not, the connector returns an ILP Reject packet.
4. Connector uses the destination ILP address from the packet and its local routing tables to determine which next hop to forward the packet to.
5. Connector modifies the packet amount and expiry to apply their exchange rate and move the expiry timestamp earlier.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Some explanation as to what "earlier" means and how they would calculate this (or is that described somewhere else?)

| `destination` | [ILP Address](../0015-ilp-addresses/0015-ilp-addresses.md) | ILP Address of the receiver |
| `data` | Variable-Length Octet String | End-to-end data. Connectors MUST NOT modify this data. Most higher-level protocols will encrypt and authenticate this data, so receivers will reject packets in which the data is modified |

**Note:** There is no `from` or `source` address in the ILP Prepare packet. Each hop MUST determine which of their immediate peers or customers the packet came from (to debit the correct account) based on the communication channel the packet was received through. Also, higher-level protocols MAY communicate the sender's address to the receiver if the use case calls for receivers to send ILP Prepare packets to the sender (they can communicate responses to the sender using the `data` field in ILP Fulfill and Reject packets).
Copy link
Collaborator

Choose a reason for hiding this comment

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

@sharafian depending on your definition of "communication channel" that is implied.

http://www.enterpriseintegrationpatterns.com/patterns/messaging/PointToPointChannel.html

6. Connector forwards the packet to the next hop, which may be another connector. All subsequent connectors go through steps 3-6 (treating the previous connector as the sender) until the packet reaches the receiver.
7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender).
8. Receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol.
9. Connector checks that the receiver has returned the fulfillment before the expiry in the ILP Prepare packet. If so, the connector returns the same ILP Fulfill packet to the previous connector and credits the receiver's account with the amount in the ILP Prepare packet. If the Prepare has expired, the connector returns an ILP Reject packet to the previous connector. Each connector repeats this step (treating the next connector as the receiver whom they will credit) until the Fulfill (or Reject) packet reaches the sender.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still unclear on if the ILP Reject packet is necessary since the previous connector will just time out before receiving the Fulfill packet. Is the reject simply a courtesy?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll add a bit more of a description about that.

In short, the answer is that connectors must relay reject packets that they get. In addition, connectors can set timers for outgoing prepared and send back reject packets when they expire. I haven't thought about this too much but that's probably in the category of recommended behavior rather than mandatory functionality.

Choose a reason for hiding this comment

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

I think right now a lot of things won't work without the ILP reject, but nobody will lose money so you could argue it's technically not necessary

Copy link
Collaborator

@mDuo13 mDuo13 left a comment

Choose a reason for hiding this comment

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

Looking much, much better.

I strongly disagree with the term "node" (sorry I didn't jump on to weigh in on that sooner) and suggest "participant" instead.

Otherwise, I caught a couple typos and some ambiguous wordings but nothing big. Excited to see this finalized.

- **Connector** - Intermediary that maintains settlement accounts on one or more ledgers or payment systems. Connectors forward ILP packets. They may generate revenue from spreads on currency conversion, through subscription fees, or other means.
- **Account** - Two peers establish an account with one another where they track the current obligations they hold with one another; i.e. the balance on the account. The account is denominated in a single asset. The peers agree on the precision and scale they will use for the amounts of that asset when they express amounts in messages between one another. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low. Note that the mentions of "accounts" in this document refers to those that Interledger nodes _hold with one another_, rather than the "accounts" they may hold on underlying ledgers because the latter are not directly part of the ILPv4 packet flow.
- **Bandwidth** - Connectors may limit the total value of ILP packets an account can have in-flight (prepared but not yet fulfilled or rejected) at the same time. The limit may either be based on how much the connector trusts the account-holder, represented by the minimum balance limit on the account, or it may be used to prevent one account from tying up all of the connector's bandwidth with its peers.
- **Condition and Fulfillment** - ILP packets are secured with conditions so that they cannot be lost or stolen by intermediary connectors. ILP Prepare packets are sent with a condition or SHA-256 hash in them. When the receiver receives the packet, they present the fulfillment, or valid preimage of the hash, to execute the transfer. Unlike in earlier versions of ILP, the conditions and fulfillments are NOT assumed to be enforced by the underlying ledger but they help peers reconcile their account balances. Two peers should only consider an ILP packet executed (and therefore affect their account balances) if
Copy link
Collaborator

Choose a reason for hiding this comment

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

ILP Prepare packets are sent with a condition or SHA-256 hash in them. When the receiver receives the packet, they present the fulfillment, or valid preimage of the hash, to execute the transfer.

Is this intended to leave open the possibility that a condition might not be a SHA-256 hash? That's the implication I read from this phrasing. If that's not intended, I recommend the following rephrase:

ILP Prepare packets contain a condition in the form of a SHA-256 hash. When the receiver receives the packet, they present the fulfillment, in the form of a valid preimage of the condition hash, to execute the transfer.

* **Sender** - The party that originates payment
* **Receiver** - The final recipient of a payment
* **Connector** - The intermediaries between a sender and a receiver that forward ILP Packets. They may generate revenue from spreads on currency conversion, through subscription fees, or other means.
- **Payment** - In the context of this specification, a payment is understood to mean the transfer of value from the sender (payer) to the receiver (payee). This may be affected by sending multiple ILP Packets that together result in the total transfer of value required to complete the payment.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This may be affected by sending multiple ILP Packets that together result in the total transfer of value required to complete the payment.

In this context, "affected" is the wrong verb. @adrianhopebailie's original "effected" was correct, if confusing. A less tricky rephrase might be as follows:

Higher-level protocols may execute a "payment" by sending a series of ILP Packets whose sum is equal to the desired payment value.

- **Ledger** - A system that tracks and transfers value between accounts. In earlier versions of Interledger, ILP packets were transmitted through transfers on ledgers. In ILPv4, ledgers are used primarily to settle obligations between connectors, their peers, and their customers.
- **Payment Channel** - A method of using signed claims against funds held on a ledger, rather than on-ledger transfers that may be too slow or expensive, to settle obligations. The channels used in ILPv4 may be unidirectional or bidirectional but generally they will be [simple](../0022-hashed-timelock-agreements/0022-hashed-timelock-agreements.md#simple-payment-channels) rather than [conditional](../0022-hashed-timelock-agreements/0022-hashed-timelock-agreements.md#conditional-payment-channels-with-htlcs) channels.
- **Ledger** - A generic term for any system that tracks transfer of value between, and balances on, accounts. In earlier versions of Interledger, ILP packets were transmitted through transfers on ledgers. In ILPv4, ledgers are used primarily to adjust balances between nodes, to rebalance their accounts, following the exchange of one or more ILP Packets between the nodes.
- **Node** - A participant in an Interledger payment (node on the Interledger network), that has accounts with one or more other nodes. There are three specializations of a node:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Apologies for being contrary here, but I have strong feelings against using the term "node" for this meaning, because the term "node" is so overloaded. In the XRP Ledger, people constantly misunderstand what constitutes a "node" and what level it exists on. Is a "node" the software server? A data structure? An identity? And so on.

I suggest using the term "Participant" here instead, and maybe even clarifying that a participant is probably a person or business entity—something that can own assets, generally.

* **Receiver** - The final recipient of a payment
* **Connector** - The intermediaries between a sender and a receiver that forward ILP Packets. They may generate revenue from spreads on currency conversion, through subscription fees, or other means.
- **Payment** - In the context of this specification, a payment is understood to mean the transfer of value from the sender (payer) to the receiver (payee). This may be affected by sending multiple ILP Packets that together result in the total transfer of value required to complete the payment.
- **Payment Channel** - A method of using signed claims against funds held on a ledger, rather than on-ledger transfers that may be too slow or expensive, to rebalance accountsl. See [Payment Channels in ILPv4](#payment-channels-in-ilpv4) for more details.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo: accountsl

* **Connector** - The intermediaries between a sender and a receiver that forward ILP Packets. They may generate revenue from spreads on currency conversion, through subscription fees, or other means.
- **Payment** - In the context of this specification, a payment is understood to mean the transfer of value from the sender (payer) to the receiver (payee). This may be affected by sending multiple ILP Packets that together result in the total transfer of value required to complete the payment.
- **Payment Channel** - A method of using signed claims against funds held on a ledger, rather than on-ledger transfers that may be too slow or expensive, to rebalance accountsl. See [Payment Channels in ILPv4](#payment-channels-in-ilpv4) for more details.
- **Peer** - A node with which another node holds an account. In some cases the relationship between two nodes will be a parent/child relationship whereby the parent provides additional services to the child beyond simply forwarding ILP packets.
Copy link
Collaborator

Choose a reason for hiding this comment

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

In some cases the relationship between two nodes will be a parent/child relationship whereby the parent provides additional services to the child beyond simply forwarding ILP packets.

Suggest simplifying this:

In some cases, one participant may provide additional services to the peer beyond simply forwarding ILP Packets.

Alternatively, I think it might be OK to remove the sentence entirely.

- **Forwarding, Not Delivery** - ILPv4 connectors forward packets based on their local exchange rates, in constrast with the first version of ILP in which connectors would attempt to deliver a fixed destination amount. Now, instead of fixed destination amount delivery being built into the core protocol, senders may use higher-level protocols to indicate the minimum amount the receiver should accept for a given packet and receivers can reject packets with less than that. This significantly simplifies the connector behavior, because the do not need to maintain up-to-date price information on the entire rest of the network and can simply apply their local rate instead. If receivers want to receive no more than a certain amount, they can reject packets that go too far over the amount and senders can retry the packet with lower amounts.
- **Quoting is an Application Concern** - Connectors are only responsible for forwarding ILP packets and do not need to implement a [separate protocol for quoting](../0008-interledger-quoting-protocol/0008-interledger-quoting-protocol.md). Applications can use test packets to determine the exchange rate of a particular path.

### Why Unconditional Payment Channels

The only requirement for ledgers to be integrated with ILPv4 is that they must be able to make simple transfers so that Interledger nodes can rebalance their accounts. If ledger transfers are fast and inexpensive, nodes can settle their account balances more frequently and set lower trust limits (minimum account balances) with one another.
Copy link
Collaborator

Choose a reason for hiding this comment

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

minimum account balances

Maybe "minimum or maximum"?

10. Sender checks that the preimage in the ILP Fulfill packet matches the condition in their Prepare packet and may read any data returned by the receiver. The sender may keep a local record of the total value of packets fulfilled to determine how much they owe their connector.
11. Sender repeats the process, starting from step 1, as many times as is necessary to transfer the desired total amount of value.

After each packet is fulfilled, each noce may sign an update to their payment channel with their peer to cover the value of the packet, or they may rebalance their accounts less frequently using slower on-ledger transfers or physical deliveries of cash or other goods. Each node may limit their peers' maximum outstanding balances, and they may automatically credit accounts when payment channel updates or external transfers are received.
Copy link
Collaborator

Choose a reason for hiding this comment

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

typo: noce

I think this is meant to read "node" but I suggest "participant" instead (categorically) as in my earlier comments.

Copy link
Collaborator

Choose a reason for hiding this comment

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

...they may automatically credit accounts when payment channel updates or external transfers are received.

Suggest rephrasing to active voice:

..they may automatically credit accounts when they receive payment channel updates or external transfers.

Copy link
Member

@dora-gt dora-gt left a comment

Choose a reason for hiding this comment

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

I left some comments.
I'm sorry if I'm missing something and asking some strange questions.


# Interledger Protocol V4

Interledger is a protocol for sending packets of money across different payment networks or ledgers. ILPv4 is a simplification of previous versions of the protocol that is optimized for routing large volumes of smaller-value packets, also known as "penny switching". ILPv4 can be integrated with any type of ledger, including those not built for interoperability, and it is designed be used with a variety of higher-level protocols that implement features ranging from quoting to sending larger amounts of value with chunked payments.
Copy link
Member

Choose a reason for hiding this comment

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

It may be better that clarifying the words: "smaller-value packets", "penny-switching" and "chunked payments". I can understand the words because I know it already, but those who read this document for the first time may not be able to.

e.g.

ILPv4 sends large amount of money splitting it into "smaller-value packets", sending it repeatedly. As single packet transfers very small amount of value, we call it "penny-switching". It is also called "chunked-payments".

- **Neutrality** - Interledger is not tied to any company, currency, or network.
- **Interoperability** - ILP should be usable across any type of ledger, even those that were not built for interoperability.
- **Security** - Senders, connectors, and receivers should be protected from one another and especially isolated from risks posed by parties that they are indirectly connected to. Connectors should not be able to steal money from senders, and senders should not be able to tie up too much of connectors' funds or otherwise interfere with their operation.
- **Simplicity** - The core ILP should be as simple as possible. There is room for significant variability at lower and higher layers of the [Interledger stack](../0001-interledger-architecture/0001-interledger-architecture.md#interledger-protocol-suite), but the Interledger layer is the one part where widespread agreement is needed for interoperability.
Copy link
Member

Choose a reason for hiding this comment

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

I may change like this,
but the Interledger layer is the one part where widespread agreement is needed for interoperability.
to
but the Interledger layer is the one part where widespread agreement is needed for interoperability and simplicity enables it.


### Terminology

- **Account** - Two peers establish an account with one another where they track the current obligations they hold with one another; i.e. the balance on the account. The account is denominated in a single asset. The peers agree on the precision and scale they will use for the amounts of that asset when they express amounts in messages between one another. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low. Note that the mentions of "accounts" in this document refers to those that Interledger participants _hold with one another_, rather than the "accounts" they may hold on underlying ledgers because the latter are not directly part of the ILPv4 packet flow.
Copy link
Member

@dora-gt dora-gt Feb 13, 2018

Choose a reason for hiding this comment

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

Does this mean Payment Channel? or just an account on a ledger?

Copy link
Member Author

@emschwartz emschwartz Feb 14, 2018

Choose a reason for hiding this comment

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

Neither actually, it's a kind of virtual account that tracks the value of settlements or payment channel claims minus the total value of fulfilled ILP packets.

If I've sent 100 units of packets through you and only sent you payment channel updates totaling 80 units, my account balance with you would be -20 units.

On the other hand, if I've prepaid and sent you 250 units upfront and then sent 100 units worth of packets through you, my account balance with you would be 150 units.


- **Account** - Two peers establish an account with one another where they track the current obligations they hold with one another; i.e. the balance on the account. The account is denominated in a single asset. The peers agree on the precision and scale they will use for the amounts of that asset when they express amounts in messages between one another. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low. Note that the mentions of "accounts" in this document refers to those that Interledger participants _hold with one another_, rather than the "accounts" they may hold on underlying ledgers because the latter are not directly part of the ILPv4 packet flow.
- **Bandwidth** - Connectors may limit the total value of ILP packets an account can have in-flight (prepared but not yet fulfilled or rejected) at the same time. The limit may either be based on how much the connector trusts the account-holder, represented by the minimum balance limit on the account, or it may be used to prevent one account from tying up all of the connector's bandwidth with its peers.
- **Condition and Fulfillment** - ILP packets are secured with conditions so that they cannot be lost or stolen by intermediary connectors. ILP Prepare packets contain a condition in the form of a SHA-256 hash. When the receiver receives the packet, they present the fulfillment, in the form of a valid preimage of the condition hash, to execute the transfer. Unlike in earlier versions of ILP, the conditions and fulfillments are NOT assumed to be enforced by the underlying ledger but they help peers reconcile their account balances. Two peers should only consider an ILP packet executed (and therefore affect their account balances) if the fulfillment is a valid preimage of the condition and the fulfillment is received before the Prepare's expiry.
Copy link
Member

Choose a reason for hiding this comment

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

Link to 0016-pre-shared-key/0016-pre-shared-key.md helps a lot.
It was very hard for me to understand the relationship between condition and fulfillment.
Now I can understand thanks to the pseudo code in the bottom of the page.


- **Designed for Smaller, More Homogenous Packet Amounts** - ILPv4 applies a number of simplifications by only supporting low-value packets. Larger amounts can be sent through higher-level protocols that implement chunked payments, but the core network is optimized for sending large volumes of small packets. This renders unnecessary some of the more complex features of previous versions like Liquidity Curves for expressing how exchange rates may vary depending on the packet amount. Lower-value packets also help to minimize [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md).
- **Payment Channels, Not On-Ledger Escrow** - Since ILPv4 is optimized for smaller packets, speed and cost are of greater importance than in previous versions. ILPv4 uses ledgers or payment channels for settling bilateral payment obligations but ILPv4 packets are sent just between connectors, rather than through the underlying ledgers themselves. This enables packet timeouts to be short, because they do not need to include the processing time of slower ledgers, which further reduces [connector risks](../0018-connector-risk-mitigations/0018-connector-risk-mitigations.md). See [Why Unconditional Payment Channels](#why-unconditional-payment-channels) for more details.
- **Forwarding, Not Delivery** - ILPv4 connectors forward packets based on their local exchange rates, in constrast with the first version of ILP in which connectors would attempt to deliver a fixed destination amount. Now, instead of fixed destination amount delivery being built into the core protocol, senders may use higher-level protocols to indicate the minimum amount the receiver should accept for a given packet and receivers can reject packets with less than that. This significantly simplifies the connector behavior, because the do not need to maintain up-to-date price information on the entire rest of the network and can simply apply their local rate instead. If receivers want to receive no more than a certain amount, they can reject packets that go too far over the amount and senders can retry the packet with lower amounts.
Copy link
Member

Choose a reason for hiding this comment

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

constrast -> contrast?

Before the protocol starts, the sender and receiver use a higher-level protocol to agree on the destination account and packet condition.

1. Sender constructs an ILP Prepare packet with the receiver's destination account, the agreed-upon condition, and an amount and expiry of their choice. The sender may include additional data, the formatting of which is determined by the higher-level protocol.
2. Sender sends the ILP Prepare packet to a connector over some communication channel, such as a Websocket.
Copy link
Member

Choose a reason for hiding this comment

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

Websocket -> WebSocket maybe?


1. Sender constructs an ILP Prepare packet with the receiver's destination account, the agreed-upon condition, and an amount and expiry of their choice. The sender may include additional data, the formatting of which is determined by the higher-level protocol.
2. Sender sends the ILP Prepare packet to a connector over some communication channel, such as a Websocket.
3. Connector gets the packet and determines who the sender was based on the communication channel it was received through. The connector checks whether the sender has sufficient balance or credit to send the amount specified in the packet. If so, the connector reduces the sender's available balance by the value of the packet. If not, the connector returns an ILP Reject packet.
Copy link
Member

Choose a reason for hiding this comment

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

How to determine who the sender is? I could not imagine because ILP packet does not contain the sender address.

5. Connector modifies the packet amount and expiry to apply their exchange rate and move the expiry timestamp earlier (for example, each connector may subtract one second from the expiry to give themselves a minimum of one second to pass the Fulfill on in step 9).
6. Connector forwards the packet to the next hop, which may be another connector. All subsequent connectors go through steps 3-6 (treating the previous connector as the sender) until the packet reaches the receiver.
7. Receiver checks the ILP Prepare packet, according to whatever is stipulated by the higher-level protocol (such as checking whether the amount received is above some minimum specified by the sender). Receiver also checks that the Prepare would not put the connector's unsettled balance above the maximum the receiver tolerates (this is the same as the minimum balance limit of the connector _with the receiver_).
8. To accept the packet, the receiver returns an ILP Fulfill packet, containing the preimage of the condition in the ILP Prepare packet. The receiver may include additional data, the formatting of which is determined by the higher-level protocol. If the receiver does not want the ILP Prepare packet or it does not pass one of the checks, the receiver returns an ILP Reject packet.
Copy link
Member

Choose a reason for hiding this comment

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

On the same connection that the connector received the ILP Prepare packet on?
If the connection is lost, the connector may not be able to return the fulfillment packet because they can't identify who the sender was (ILP packet doesn't contain sender address).
Am I missing something?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The connection has to be authenticated in such a way that the connector can identify the sender and recognize which pre-established account¹ is theirs.

¹ In this case, the "account" is probably a payment channel but it could also be some other means of tracking a balance between the connector and the sender.

Copy link
Member

Choose a reason for hiding this comment

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

@mDuo13 is there protocol for it?

@mDuo13
Copy link
Collaborator

mDuo13 commented Feb 13, 2018

After reading @dora-gt 's comments, I think some things would be clearer if this RFC included a section defining the prerequisites—the necessary setup—for a sender and a connector to do ILPv4 transfers with one another. That would probably help clarify the account, connection authentication, and payment channel distinctions. Part of why they're confusing now is that you have to infer what the necessary setup is from the description of the repeatable process.

- **End-to-End Principle** - Inspired by the Internet, any features that do not need to be implemented by the core Interledger Protocol and network of connectors should be built into the edges of the network (the sender and receiver).

### Terminology

- **Account** - Two peers establish an account with one another where they track the current obligations they hold with one another; i.e. the balance on the account. The account is denominated in a single asset. The peers agree on the precision and scale they will use for the amounts of that asset when they express amounts in messages between one another. Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low. Note that the mentions of "accounts" in this document refers to those that Interledger participants _hold with one another_, rather than the "accounts" they may hold on underlying ledgers because the latter are not directly part of the ILPv4 packet flow.
- **Account** - Two peers establish an account with one another to track the current obligations they hold with one another. The account balance represents the difference between the value of ILP packets sent and received and the amount of value that has been transferred through an underlying ledger or payment channel (for example, if peer A has signed payment channel updates for 100 units to peer B, peer A sent ILP packets worth 150 units through B, A received ILP packets worth 30 units from B, then peer A owes 20 units to peer B). Each account is denominated in a single asset and peers agree on the precision and scale they will use for the amounts of that asset when they express amounts in messages between one another (for example, a scale of 9 means that an amount of 1000000000 in an ILP packet sent between those peers represents 1 unit of that asset). Accounts may be pre-funded (in which case the customer or peer trusts the connector for the value of the account balance) or post-funded (in which case the connector trusts the customer or peer for the amount the account is allowed to go negative). Connectors may refuse to process further ILP packets if an account balance goes too low. Note that the mentions of "accounts" in this document refers to those that Interledger participants _hold with one another_, rather than the "accounts" they may hold on underlying ledgers because the latter are not directly part of the ILPv4 packet flow.
Copy link
Member

Choose a reason for hiding this comment

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

I think it's still unclear that WHO has the responsibility to maintain the account, and WHERE to store it.

Copy link
Collaborator

@mDuo13 mDuo13 left a comment

Choose a reason for hiding this comment

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

New prerequisites section helps a lot


### Terminology

- **Account** - Two peers establish an account with one another to track the current obligations they hold with one another.
Copy link

Choose a reason for hiding this comment

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

This account definition reminds me of loro/nostro accounts, but surely is not. Could it be renamed totally to Link or Stream or something else? For fun: that could lead to uplink/downlink metaphor, which reflects connector and client distinction quite right. @emschwartz

Copy link
Member Author

@emschwartz emschwartz Feb 22, 2018

Choose a reason for hiding this comment

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

There are probably some similarities, but I'm not a real expert on nostro/vostro accounts.

Link is an interesting idea, and kind of funny because the layer below the internetworking layer in the old OSI model is called the Data Link layer. You establish a "Money Link" with your peer...

It would help clear up the confusion between "accounts" on the underlying ledgers and the balance you hold with your Interledger peer

Copy link
Collaborator

@adrianhopebailie adrianhopebailie left a comment

Choose a reason for hiding this comment

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

Suggest this is merged and further discussion is raised as issues.

Looks like this is IL RFC 0027!

Copy link

@rhuairahrighairidh rhuairahrighairidh left a comment

Choose a reason for hiding this comment

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

I like document. Clears up a lot of confusions.
Although I feel it would be hard to understand without an understanding of the general interledger architecture.
In the future, adding a link back to an improved version of rfc001 would be nice.

Copy link
Member

@justmoon justmoon left a comment

Choose a reason for hiding this comment

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

LGTM

@emschwartz emschwartz force-pushed the es-ilp4-spec branch 2 times, most recently from 0aa766d to 7274e78 Compare February 24, 2018 17:36
@emschwartz emschwartz merged commit e09b65a into master Feb 24, 2018
@emschwartz emschwartz deleted the es-ilp4-spec branch February 24, 2018 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.