Closed justmoon closed 7 years ago
What are the thoughts on bob.wf.fed.us
vs. us.fed.wf.bob
? The former is more similar to internet addresses, whereas the latter is more like Java package naming.
Could you explain a bit more the change from us.fed.wf/bob
to us.fed.wf.bob
?
How does the last connector know whether it's supposed to send a local transfer to an account called bob
or whether it's being asked whether it knows about a ledger called bob
?
What are the thoughts on bob.wf.fed.us vs. us.fed.wf.bob? The former is more similar to internet addresses, whereas the latter is more like Java package naming.
Left-to-right is more natural in English. URIs use it (scheme comes first) and paths use it (Windows, Linux and HTTP). DNS was initially used for email primarily, which is right-to-left, so that's presumably why DNS ended up right-to-left. This is one of the strange artifacts of history - you read a URI left-to-right until you get to the domain, which is right-to-left, then you continue reading the path left-to-right.
I assume Java packages, Android apps and other instances of reverse DNS notation are attempts to correct this odd choice.
Note that there is unfortunately no culturally neutral choice, we have to pick one or the other. We are using big-endian (most significant first) encodings for our binary protocols. Arabic numerals are written most significant first. So it makes sense to choose most significant first for our addressing scheme as well. But of course I'm interested to hear counter-arguments if there are any.
How does the last connector know whether it's supposed to send a local transfer to an account called bob or whether it's being asked whether it knows about a ledger called bob?
ilp-core
will check whether a given address is local to any of the ledgers it is directly connected to and if not it will resolve it to an address that is local using its routing table.
One important note is that the connector doesn't need to know whether or not it is the last connector. It only needs to know what the next hop is.
So what would happen in your example is if I'm a connector and I get a payment with a destinationAccount of us.fed.wf.bob
and I have a local ledger plugin with prefix us.fed.wf
, then I would tell that plugin to deliver to bob
. The plugin MAY resolve that name however it wants, in the case of ilp-plugin-bells
it would simply send to the literal account bob
.
If the address was, say, us.fed.wf.bob.clarice
, then ilp-plugin-bells
would still deliver to bob
. The account bob
may belong to a connector which may forward it to someone else or it may belong to a receiver who will handle the payment. Doesn't matter to me, the connector.
And if I don't have a local ledger plugin with prefix us.fed.wf
, then I will forward the payment to whoever is my route for us.fed.wf.bob
, e.g. us.fed.bofa.domestic
.
Hmm. I still don't see how this mixing of accounts and ledgers would work. What if there is an account on the local ledger with the same name as another ledger? How would my local ledger plugin be able to resolve that and know whether to send it to that account or a connector that connects to that ledger?
Also, specifying the accounts you should send to within a path sounds like a kind of source routing. That's not necessarily a bad thing but it seems like accounts and ledgers should be denoted separately.
Left-to-right is more natural in English.
This isn't obvious to me. Physical mailing addresses are ordered most-specific first, just like domain names.
I assume Java packages, Android apps and other instances of reverse DNS notation are attempts to correct this odd choice.
The linked articles says "A characteristic of reverse-DNS strings is that they are based on registered domain names, and are only reversed for sorting purposes."
I also was wondering the same things as Evan about how to tell if an address component refers to a ledger or an account. Why not just use email address syntax?
Also before we were using actual DNS addresses for ledgers, but here it looks like something else. Are we no longer using DNS addresses for ledgers, and if so why?
The linked articles says "A characteristic of reverse-DNS strings is that they are based on registered domain names, and are only reversed for sorting purposes."
(Emphasis added.) Actually, that just made me realize a very strong technical reason why we would write addresses this way. We are routing first in the general direction of the destination and then get more and more specific. If we write addresses left-to-right, that means that we will be looking up prefixes in the routing table. If we write addresses right-to-left, we would be looking up suffixes.
Since most implementations of key/value stores allow you to look up keys by prefix, not suffix, we would have to reverse addresses all the time if we go with domain name (little endian) ordering.
What if there is an account on the local ledger with the same name as another ledger?
Then presumably that account is the omnibus account for that subledger. Avoiding name collisions is up to the ledger or ledger plugin.
How would my local ledger plugin be able to resolve that?
- Check if the address is me. If so, I'm done.
- Check if the address is a local ledger prefix. If so, send using the corresponding ledger plugin.
- Check if the address is a prefix in my routing table. If so, change the address to the next hop address and go to step 2.
- Else chop off the last segment of the address and go to step 2. If there is nothing more to chop off, stop and emit an error
no route to account
.
In other words longer prefixes trump shorter prefixes. When prefixes are the same length, local ledger prefixes trump routing table prefixes.
Suppose we have an address like us.wf.bob.mary
.
We start in China. The connector in China has ledger plugins with the local prefixes cn.alipay
and cn.unionpay
and a routing table containing us => cn.alipay.yuhao
. The longest known prefix in us.wf.bob.mary
is us
which points to a connector with the address cn.alipay.yuhao
. So it sends the payment onwards to cn.alipay.yuhao
.
The connector cn.alipay.yuhao
also has an account in the US called us.bofa.yuhao
. It recognizes local prefixes cn.alipay
and us.bofa
and has a routing entry us.wf => us.bofa.connie
. The longest prefix it recognizes in us.wf.bob.mary
is us.wf
which according to its routing table should be forwarded to us.bofa.connie
. So it sends the payment onward to us.bofa.connie
.
The connector us.bofa.connie
also has an account at WF called us.wf.connie
. It recognizes local prefixes us.bofa
and us.wf
. The longest prefix it recognizes in us.wf.bob.mary
is us.wf
which is a local ledger prefix. So it sends the payment locally to us.wf.bob.mary
. However, note that the ledger plugin only uses the first non-prefix element as the local account identifier, so it actually sends the payment to us.wf.bob
.
The connector us.wf.bob
is the gateway for a subledger by the same name. It recognizes local prefixes us.wf
and us.wf.bob
. The longest prefix it recognizes in us.wf.bob.mary
is us.wf.bob
which is the prefix of its local subledger. So it sends the payment to us.wf.bob.mary
.
This does introduce a limitation - it assumes that subledgers have one gateway connector (as opposed to multiple.) I think this is a defensible assumption. It doesn't prohibit lateral routes - if there is a route in my routing table for the prefix us.wf.bob
I will prefer that over the local prefix us.wf
, because it is longer. You can also have multiple gateway connectors corresponding to different ledgers because those would be different addresses i.e. us.wf.bob
vs us.acme.bob
. And you can have multiple upstream gateways in general, because the routing is only used going to a ledger, not from it.
Also before we were using actual DNS addresses for ledgers, but here it looks like something else. Are we no longer using DNS addresses for ledgers, and if so why?
We were previously using opaque strings as ledger names, e.g. https://red.ilpdemo.org/ledger
. This means that all ledgers must be in all routing tables, which doesn't scale to more than a few thousand ledgers. If we want to be able to support billions of ledgers in the Internet of Value we need to be able to route to prefixes. That way we can know how to route towards us.*
without knowing every single ledger in the US. We could use something like fed.gov;acme.com;bob.example
but it's simpler and more readable to just introduce new identifiers specifically designed for ILP routing, like us.acme.bob
.
So if I understand correctly, the dotted addresses are basically "partial path hints": they are "partial" in the sense that the path only goes to a well-known connector, not all the way to the sender, and they are "hints" in the sense that there may be a shorter/better path.
It may be possible to get these hints dynamically if ledgers and connectors provide sorted lists of next-hop ledgers and connectors in order of size/liquidity. So using the original DNS-based address format, you could query the ledger for it's connectors, and the first connector in the array would be the recommended gateway (for ledgers that don't support this query I assume the address would point to a connector with a virtual ledger plugin?). The sender could then query that connector for it's "biggest" ledger and proceed recursively until a known connector is found. If a cycle is detected, it can switch to the second biggest and continue searching the whole graph. In this way, the information that was statically-encoded in the dotted address could be obtained dynamically, which would be more robust (it can route around connectors and ledgers that are down if there is an alternative path).
Also, in any case, I'd like to suggest avoiding using countries as top-level names as it would be better to not support artificial boundaries in any way.
It may be possible to get these hints dynamically if ledgers and connectors provide sorted lists of next-hop ledgers and connectors in order of size/liquidity.
Good observation! This would fall under auto-configuration (think DHCP) which we decided to keep out of the initial PR, but it is definitely planned for the future. For now, people running a connector just have to define their ILP addresses manually.
Also, in any case, I'd like to suggest avoiding using countries as top-level names as it would be better to not support artificial boundaries in any way.
Good point. ILP itself won't specify what it should be and it'll likely be different for different types of ledgers. (For a cryptocurrency for instance, a country doesn't really make sense, so it may start with the name of the crypto-currency instead.)
@justmoon can this issue be closed now?
Yes. Let's make a mental note that every time we formally specify a ledger protocol/integration (e.g. Common Ledger API), one of the things to be addressed is how ILP addresses map to local ones.
So far we haven't explained how ILP addresses would actually map to local ledger addresses. We need a scheme similar to the Address Resolution Protocol (ARP) in the IP stack.
Flow
Examples
We are
us.fed.wf.alice
.Note: The
send()
API is simplified in this example.Address Format Change
Before:
After:
Previously, we thought that being able to differentiate an account address from a ledger address was a useful feature. But as we investigated the details of the address resolution process, we discovered that this distinction makes it impossible for
us.fed.wf/bob
to be a ledger with subaccounts.We were able to find the scheme outlined in this issue which properly allows for local address resolution without distinguishing between ledger addresses and account addresses.
Ledger Plugin API Changes
We want to add a new method to the ledger plugin:
getPrefix
returns the ledger plugin's ILP addressprefix
(which may be configured, automatically detected, hard-coded, etc.)If an ILP address begins with a ledger plugin's prefix, the address is considered local with respect to that plugin.
The call
getAddress
returns the ILP address. (Instead of the local account identifier.)Ledger plugin configuration is custom per plugin (custom settings are no longer wrapped in an
auth
property.)The
account
property in thesend()
call contains a ILP address (not a local address).Some properties (such as
_store
) MAY be injected by the application hosting the plugin, however these are guaranteed to start with an underscore. (_
)Configuration Examples
with @bensharaf and @pedrorechez