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

Proposal: Connector forwarding/delivery distinction #77

Closed
justmoon opened this issue Aug 18, 2016 · 4 comments
Closed

Proposal: Connector forwarding/delivery distinction #77

justmoon opened this issue Aug 18, 2016 · 4 comments
Labels

Comments

@justmoon
Copy link
Member

justmoon commented Aug 18, 2016

The current ILP connector implementation make a distinction between forwarding payments and delivering payments.

  • Forwarding occurs when the best matching (longest prefix) routing table entry names another connector. In other words, the connector has no direct access to the destination ledger.
  • Delivery occurs when the best matching routing table entry is a local ledger.

This mirrors closely a typical IP routing table:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.15.20.1      0.0.0.0         UG    600    0        0 wlan0
10.15.1.1       10.15.20.1      255.255.255.255 UGH   600    0        0 wlan0
10.15.20.0      0.0.0.0         255.255.254.0   U     600    0        0 wlan0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 docker0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

(Note the G flag. If set, it means to forward the packet through another gateway/router. If not set, it means to deliver the packet locally to the right host. The exception is subnetting, which is addressed later in this post.)

ILP Addresses

The ILP address space is divided into ledger prefixes. Here are some ILP addresses:

us.gov.fed.usd.ledger1.alice
cn.gov.pboc.cny.ledger2.bob.411dbf36-6180-4f3f-aa46-83092ebc8e36
btc.bitchannels.v1.1FfmbHfnpaZjKFvyi1okTjJJusN455paPH

The italicized portion is the ledger portion. The rest is the account portion. Every ILP address breaks down in this way.

This compares to IP addresses, which consist of a network and a host portion, which constitutes a similar breakdown.

Note that the ledger portion typically ends in a period (.) - this isn't mandatory, but strongly recommended practice, because otherwise the last segment of the ledger portion and the first part of the account portion will merge together with no visual separation at all. It also provides an easy way to distinguish between an ILP address (us.gov.fed.usd.ledger1.alice) and a ledger prefix (us.gov.fed.usd.ledger1.).

Common Prefixes

We believe that eventually, a very large number of ledger may be part of the Interledger. In order to plan for that, ledgers are encouraged to coordinate with each other in such a way that more closely related ledgers have longer common prefixes.

For instance, us.gov.fed.usd.ledger1. and us.gov.fed.usd.ledger2. might be very closely related, while us.gov.fed.usd.ledger1. and cn.gov.pboc.cny.ledger2. are not.

A connector operating in China may only have a generic us. route in its routing table, sending all US-directed payments through a single peer connector. This allows connectors to simplify and optimize their routing tables in order to reduce the amount of memory and bandwidth required for routing.

Note that there is no physical ledger with the address us.gov.fed.usd.. Common prefixes are merely informational.

Tagging

The account portion may include dots in order to indicate a further subdivision of the account space. Each ledger decides how it wants to handle address translation from the account portion of an ILP address to its local account address space. A typical behavior would be to discard all contents of the account portion from the first period onwards and deliver to an account by that identifier.

This gives account holders a large address space to tag their payments. For instance in the example given above, cn.gov.pboc.cny.ledger2.bob.411dbf36-6180-4f3f-aa46-83092ebc8e36, the account owner Bob has added a unique identifier to the address, presumably to associate the payment with some other prenegotiated data later.

Subledgering

Account holders may want to subdivide their funds and allocate them to different departments, devices, apps, etc. For instance, Bob might own a phone which has an app called "ACME App". This app can send and receive funds autonomously. In order to more easily keep track of its expenses, he might give it a unique ILP address like cn.gov.pboc.cny.ledger2.bob.phone.acme.

Bob might also want to restrict the amount of funds available for ACME App to spend. After all, the app could have a bug and Bob doesn't want it to be able to spend his entire life savings. So Bob sets up his own ledger and he operates an ILP connector between his account cn.gov.pboc.cny.ledger2.bob and the ledger he operates with the prefix cn.gov.pboc.cny.ledger2.bob.phone..

We call this a subledger. Bob has taken the account portion bob.phone.acme and subdivided it into a subledger portion bob.phone. and a subaccount portion acme.

The concept of a subledger is similar to subnets in IP.

Note that the connector on the cn.gov.pboc.cny.ledger2. still thinks it is the final hop and therefore delivering the payment. This is correct and expected. Creating a subledger is not the same as creating a new ledger. For instance, since the unit of the amount delivered is determined by the ledger portion of the ILP address, the subledger MUST use the same currency as the parent ledger. Bob also cannot charge himself any fees when relaying a payment to his subledger.

Tail Routing Table (TRT)

In some cases, users may wish to do something akin to subledgering, but without the limitations described in the previous section. In order to do this, we propose a new header type, called the Tail Routing Table (TRT) header.

In the most minimal design, this header would contain only a list of ledger prefixes and amounts:

Prefix Amount
ilpdemo.red. 221
ilpdemo.red.bob. 201
ilpdemo.red.bob.sub. 200
ilpdemo.red.bob.sub.doubledollars. 100

This would allow the last regular connector (the connector delivering on cn.gov.pboc.cny.ledger2.) to look up the amount that it is expected to deliver. Whenever a connector is delivering (as opposed to forwarding) a payment, it would look up the local ledger prefix in the TRT header to see if there is a different amount that has been requested. If not, it would default to the amount given in the ILP header.

The main limitation of this design is that the amount is fixed. We can use this for sending a payment, but it will not help a connector with quoting. (This might be fine, since the connector can ask the next connector for a quote.) If we wanted a slightly more sophisticated design, we could include not amounts, but rates. I.e. each entry in the table would show the exchange rate between a given ledger prefix and the final destination account.

However, this limits us to a fixed rate. To provide even more flexibility, we would have to include a rate curve, similar to the rate curves found in the Connector-to-Connector Protocol (CCP).

Finally, we may also wish to override the next hop from the default (first segment of the account portion) to some arbitrary account on the same ledger.

Here is an example of a more fully featured TRT:

Prefix Next Hop Curve
ilpdemo.red. ilpdemo.red.bobconnector [curve]
ilpdemo.red.bob. n/a [curve]
ilpdemo.red.bob.sub. n/a [curve]
ilpdemo.red.bob.sub.doubledollars. n/a [curve]

Tail Routing Tables can also be used for source routing. In source routing, we know the entire path. As a result, we know what the local prefix will be at each step. So we simply need to include a routing entry for each hop which will take precedence over the connector's default routing table.

@adrianhopebailie
Copy link
Collaborator

it would look up the local ledger prefix in the ARI header to see if there is a different amount that has been requested

Do you mean TRT header?

@adrianhopebailie
Copy link
Collaborator

Also, wanted to re-ask my question from #76 to confirm I am thinking about this correctly:

@emschwartz said:

because the connector doesn't realize it's sending to another connector it will take too much of the money and try to deliver less than the required amount to the connector. Because of this, the payment will be rejected. Would the ignorant connector retry the transfer applying its normal rate (figuring, maybe there is a connector there so it wants the extra money)?

This may still happen (even if we implement this proposal) if the routing table of the sending connector doesn't yet have enough data to distinguish between forwarding and delivering for a specific prefix.

So, I think in this case the receiving connector would reject the transfer because it cannot deliver the full amount to the receiver. The sending connector would get back a "transfer rejected" message indicating insufficient funds and then could update it's routing tables to reflect that there is another connector on the other side of that transfer and then get a quote from that connector before retrying.

If this is correct we should ensure that the process for rejecting a transfer carries enough data back to the sending connector for them to update their routing tables.

@justmoon
Copy link
Member Author

Do you mean TRT header?

Fixed, thanks!

because the connector doesn't realize it's sending to another connector it will take too much of the money and try to deliver less than the required amount to the connector.

The fundamental metaphor behind ILP is recursive subcontracting. A asks B to deliver a payment. But B can't deliver it themselves, so they forward it to C instead. This continues until somebody is able to deliver it. Note that you don't know whether the next person is delivering or forwarding, but you have to know whether you are delivering or forwarding. If you mix forwarding vs delivery you end up reimplementing/reinventing the entirety of ILP to support this "not-really-delivery"-delivery.

Put in a different way: The next participant is always chosen by the previous one. So it should always represent the intent of the party making the request. You should be able to "accidentally send to a connector" any more than you can "accidentally hire a plumber." If there is another connector, it's because the previous connector chose to forward its payment through a connector.

The way that subledgering fits into this picture is that it's not really forwarding. It's a single ledger, which is simply broken down / shared across multiple smaller ledgers. It should still provide typical ledger features (fungibility, out-of-band-fees, etc.). A component that is reconciling a parent ledger with a subledger would not do quoting, charge fees, etc., so we may not even want to call it a connector. Although it does share other properties with connnectors (in that it makes a transfer in response to a transfer.) Maybe you could call it a subledger connector or something.

At the risk of being tedious, I want to emphasize again: If you want to have another connector you have to tell the previous connector somehow that you want it to use that next connector. The preferred way would be by peering with it and choosing a unique prefix for your ledger.

But, I'm sensitive to the idea that we may want to give people a tool to create connectors - even complex ones - without having to be trusted by what could be a bank. The way they can do that is ask the sender to ask its connectors to use a specific path. It doesn't care about the whole path, just about the last little bit. That's what the TRT header does. So even though the bank connector might not have my connector in its routing table, it would see the TRT header and know how to reach me.

sappenin added a commit to fluid-money/fluid-ilp-connector that referenced this issue Nov 18, 2016
* Create various Manager classes for Connector and Ledger
* Introduce Delivered vs Forwarded per interledger/rfcs#77
* Fix test harness.
@emschwartz
Copy link
Member

I think this was addressed by #154. @justmoon can we close this now?

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

No branches or pull requests

3 participants