ILPv4 makes some trade-offs compared to ILPv1. However, mixed in with these trade-offs are some - imho - pure improvements. This document describes what it would look like if I had to redesign ILPv1 given what we know now, but weren't willing to make some of the more controversial trade-offs. This work also revealed the surprising conclusion that ILPv1 transactional semantics (non-chunked or "universal mode quasi-atomic") are possible to achieve using ILPv4.
There are two main differences that are relevant for this discussion:
- ILPv4 assumes that all parties in the chain of an ILP transaction understand ILP. ILPv1 is designed around "ledgers" which are systems that act like an ILP connector, but do not understand ILP.
- ILPv4 assumes that all payments are small. ILPv1 is designed to support larger payments as well, which requires support for additional features, such as liquidity curves to deal with different rates for differently sized payments.
As noted in the original ILPv4 ticket, it is possible to model an ILPv1 ledger as a connector whereby the sending party pre-funds with the connector and the connector post-funds with the receiving party. That way, both sides trust the connector.
We also have the concept of simulating a connector in the plugin for example in ilp-plugin-mini-accounts. Putting these ideas together, we can actually use an escrowing ledger like five-bells-ledger in ILPv4.
To use this ilp-plugin-bells-escrow
, you would configure the hosting connector to settle with every payment. Then you would add the following behavior in the plugin. On the sending side, you would prepare on ILPv4-prepare, ignore sendMoney, return successfully on ledger fulfill and throw on ledger reject/cancel. On the receiving side you would emit data
on ledger prepare and emit money
on ledger fulfill.
Other escrowing ledgers such as blockchains could be used the same way.
ILPv4 generally assumes that larger payments will be split into smaller chunks. However, this is only necessary when the maximum packet size is small. In order to get ILPv1 behavior, we simply need to configure connectors with a large packet size.
ILPv1 has various functionality related to handling different exchange rates for differently sized payments. This includes liquidity curves in the routing protocol and the quoting protocol ILQP. This functionality serves two important goals:
- Performance improvements / quote caching
- Quoting by destination amount
When we originally designed ILPv1, we anticipated that quoting would add significant overhead to the payment process. However, in practice, we found that even when doing a one hop payment over the fastest real-money ledger (XRP Ledger), the latency added due to quoting was negligible. As a result, I would say today that all of the caching functionality in the quoting and routing protocols was horribly overengineered and it is better to just quote ahead of every payment. The payment will take one or more orders of magnitude longer anyway and this removes a tremendous amount of complexity.
Quoting by destination amount is difficult without ILQP. It would be possible to create increasingly large prepared payments in an iterative process similar to chunked payments in ILPv4. However, we have to assume that preparing payments is slow and expensive in this context, so this would probably not work for a ILPv1 style network. (It is still an interesting option for doing non-chunked payments quoted by destination amount in ILPv4.)
Based on the considerations above, I would remove the quote-liquidity functionality from ILQP since it presents an unnecessary optimization and keep only the quote-by-source and quote-by-destination messages.
If implemented this way, I believe the resulting solution would be better than canonical ILPv1, but worse than canonical ILPv4. It retains many of ILPv4's architectural and protocol simplifications and contains the workarounds for legacy ledgers to the respective ledger plugins.
Writing this document lead to some interesting realizations for doing non-chunked payments in ILPv4. Iteratively preparing a payment in chunks (which all contain the same condition) is a novel idea which effectively provides a way for receivers to atomically receive a payment, yet allows the sender to "quote by destination amount" without needing ILQP.
It seems worthwhile further exploring the space between and around ILPv1 and ILPv4. That said, my strong recommendation is to focus our efforts on ILPv4 because it is overall the most promising approach and provides the greatest benefit to users: extremely fast and cheap payments, even when payment size is very small - i.e. the Internet of Value.
Thanks for writing this up! I don't know all the iterations the definition of ILPv1 went through before I joined, but if we define it as what our reference stack implemented before the switch to ILPv4, I would say:
You're right that a connector can act like a ledger, but to fully support the "trustless connectors, and rollback to the safety of the ledger" which at least that last version of ILPv1 provided, you would have to build this connector-that-acts-as-a-ledger on top of what I called ILPv4.1, otherwise the sender can't instruct the "ledger" which (next) "connector" they want to use.
Another system ILPv4 misses is push distribution of exchange rate information. It was introduced in ilp-kit 3.0 and then removed again in ILPv2.
And one more difference that also affects the game theoretical network dynamics, since ILPv4 uses forwarded payments, it requires test payments and/or more trust between nodes