Settlement Architecture

settlement
#1

The topic on the Plugin Architecture and Ledger Integrations got a bit unwieldy and stale since the summit so I am kicking off something new here to get feedback on some ongoing discussion that has been happening on Slack and in other channels.

Firstly, I’d suggest that anyone new to the concept of “settlement” look at the IL-RFC 32 on Peering, Clearing and Settlement which has some non-technical detail on why you need separate payments, clearing and settlement layers in ILP.

Also, be aware that IL-RFC 32 may need to be updated based on the outcome of the discussion regarding whether to track net balances or separate Payable and Receivable balances.

I considered making a blog post of this but I’m keen to hear back from people with questions or comments so please fire away below.

The goal here is to level-set. Our design will be based on some assumptions so we should all agree on what those are.

Why do we need settlement?

Two reasons:

  1. We need a separate settlement layer because we explicitly want ILP to provide an inter-networking layer over multiple existing networks. This is somewhat unique to ILP and is less about the traditional concept of settlement and finality and more about inter-networking. In the early days of developing ILP we focused primarily on this characteristic of the layers below ILP so we called this the “Ledger Layer” (because Interledger was inter-networking ledgers).

  2. The more traditional reason for having a separate settlement layer is due to the fact that settlement is the process of achieving finality for a payment. Payments are really just messages that establish financial obligations between the participants. Settlement is the process by which these are discharged finally and irrevocably. (Some useful definitions in the BIS Glossary)

Expanding on this second reason it is important to note that almost all payment networks have separate payment and settlement systems.

In the extreme case (usually for high value payments) settlement is done on a Real Time Gross basis. This means that settlement is performed for each payment at the same time as the payment. So it is natural to ask, why not simply use settlement systems for all payments (ignoring the inter-networking rationale for now) and avoid the complexity of having two systems?

The answer is well illustrated when looking at Bitcoin and Lightning. The cost of a settlement transaction is high and often, in order to achieve the safety guarantees expected from a settlement system, they are slow too (e.g. Bitcoin). To support smaller payments it’s necessary to layer a new system (e.g. Lightning) on top of the settlement system that is designed with different characteristics that compromise some of robustness of the settlement system for the sake of performance and cost.

Thesis:

For any system that executes financial transactions atomically and durably between distributed participants; as the value of a transaction decreases, the ratio of the cost to the value increases.

As a result payments systems use aggregation and netting to reduce the number of transactions required to settle a batch of payments. I.e. Lots of payments and fewer settlements means lower costs per payment.

This means that payments systems are generally designed to provide liveness guarantees rather than safety guarantees and will favour eventual consistency between participants (using reconciliation, clearing etc) over atomicity and durability.

Sidebar: What this also means is that a system that is used for payments of a particular value might need a new payment system layered over it in order to viably support smaller payments. i.e. A payments system can be used as the settlement system for another payment system (usually designed for even faster or even smaller payments).

This implies that the differing characteristics of payment and settlement systems are relative, not absolute. For a payment system like ILP, where there is a great variety of settlement systems we need to support, some of which may even be fast and cheap low value payments systems themselves.

Optimizing Settlement

In exchange for layering a payments system on top of a settlement system we must make some compromises and our goal in designing the architecture is to minimise the effect of these.

  1. Locked Up Liquidity: Because we have capital that is moving in the settlement layer at a different rate to the payments being made there is a delay between a recipient of a payment getting paid and having the capital they are owed available to settle another outgoing payment. Therefor the cost of participating in the settlement system is directly related to the amount of capital required and the time that it is locked up.

  2. Settlement Risk: Participants in the payment system are creating financial obligations with one another but these are not guaranteed to be paid until settlement has occurred. Therefor participants face the risk that a peer may not be able to settle them for payments they have made to them.

The cost of locking up liquidity can be offset by providing credit instead of requiring collateral. I.e. Increase risk to reduce costs. Conversely, the risk of not getting settled can be offset by requiring pre-funding. I.e. Increase costs to reduce risk.

So it should be obvious that the goals of a good settlement system are to balance and minimise these risks and costs.

To do this it is important to consider various factors that influence both the costs and the risks:

  • the risk profile of the peer
  • the cost of capital of the underlying asset
  • the speed at which settlements can be completed
  • the cost (both reputational and financial) of running out of liquidity and rejecting payments
  • the cost of performing settlement transactions
  • the revenue generated from processing payments

Our goal is to design a means by which this system can track the payments happenning at the ILP layer and orchestrate payments on the settlement layer so that we minimize the liquidity that is locked up but only to the point that the risk is acceptable to the node owner.

Architecture

The Interledger layer is not complex. The protocol rules are simple. Packets are exchanged between peers and the financial obligations between those peers are adjusted according to the result of that exchange.

The interface to the settlement systems that will be used by ILP nodes is also not complex, it simply needs to support sending settlements and being notified when settlements are received.

The complexity lies in the business logic that exists between the ILP layer and the settlement layer.

The Settlement Business Logic must observe changes in the balances at both the settlement and ILP layers and react to these to balance the risk and cost described previously as best they can.

This could be simple when settlement is fast and cheap (XRP Payment Channels) but gets more complex if the cost of the capital is high (XRP price goes up?), or if the cost of settlement is material, or if settlements take longer than a few seconds.

In the simple case it may be sufficient for that logic to simply track the balances at the ILP layer and trigger settlements based on pre-configured thresholds however it’s likely that in time this will need to be adaptive to a changing environment.

Summary

We build payments systems that are faster and cheaper on top of settlement systems that are slower and more expensive but safer.

We must design an integration between these systems so that we get the fastest, cheapest payments at the lowest risk but can also choose where on the spectrum we wish to operate in terms of those three dimensions.

In the case of ILP we must also design that integration so that we support the widest possible choice of settlement systems.

9 Likes
Auto-Peering, Easy Peering, and Open Signup
Community Call - May 1, 2019
Community Call - May 15, 2019
Auto-Peering, Easy Peering, and Open Signup
#2

Great post! @adrianhopebailie

How exactly would you like to proceed on this?

How can/ should we contribute (non-technical)?

#3

The goal is just to level-set and have a discussion about what we need to consider in designing a settlement architecture and propose some ideas. Mapping the Solution Space as @emschwartz suggested.

The current architecture looks like this:

All of the Settlement Business Logic and the Settlement System Interface are in the plugins AND all ILP packets go through the plugins too. @emschwartz gave a nice breakdown of the pros and cons of this approach in Plugin Architecture and Ledger Integrations. To summarise; the plugin has all the info it needs to implement sophisticated Settlement Business Logic BUT it is all tightly coupled with the interface to the Settlement System, the interface to the other connector and must be implemented in Javascript (or at least wrapped in a Javascript adaptor).

NOTE: Not shown here, but adding significant complexity is the lifecycle management aspects of the current architecture. A plugin can be in numerous lifecycle states (connecting, connected, disconnected, terminated etc) which are not granular enough to indicate the state of the multiple connections the plugin maintains (to the peer, to the settlement system etc).

The Settlement Engine

We’ve talked a lot about a “Settlement Engine” but I don’t believe we all agree on what that is. Below are my understandings of the two proposals on the table and an attempt to come to agreement on some definitions.

I’ve given the “Settlement Engine” a specific definition which I think is consistent with the use of the descriptor “Engine” in other architectures; it is responsible for orchestrating complex business logic.

I’ve also defined what I call the “Ledger Adaptor” as a separate component that simply holds settlement system-specific integration logic. i.e. The Ledger Adaptor knows how to speak to a settlement system but it only performs operations on that system when instructed to do so by the Settlement Engine.

The interface to the Ledger Adaptor is unsurprisingly familiar (sendMoney, receiveMoney, sendData, receiveData) but in contrast to the Javascript Ledger Interface, calling these APIs is not expected to have side-effects.

E.g. Calling sendMoney on the Ledger Adaptor results in a payment being sent over the settlement system. This may succeed or fail and the Settlement Engine decides how to proceed once the result of this operation is known.

The Ledger Adaptor is also able to call sendData on the Settlement Engine which is simply a way of requesting that a message is passed to the corresponding Ledger Adaptor on the peer. (e.g. To exchange a Payment Channel claim)

This SHOULD be in the form of an ILP packet addressed to peer.settle.* hence I have proposed that this would be “injected” by the Settlement Engine into the outgoing middleware pipeline but really this is up to implementors.

Note that the Settlement Engine could also initiate a message to the other Settlement Engine.

In both proposed architectures the Settlement Engine tracks the various balances and balance change events in both the clearing accounts (Peer ILP balances) and settlement accounts (Settlement system balances) and decides when to make a settlement on the settlement system (call sendMoney on the Ledger Adaptor).

The Settlement Engine also receives notifications of incoming settlements from the Ledger Adaptor. Not shown, but required is a mechanism for the Settlement Engine to query the Ledger Adaptor for balances on the settlement system.

The major difference between the two proposals is where the Settlement Engine is implemented.

Proposal 1 - Internal Settlement Engine

In this architecture the Settlement Engine is internal to the connector.

The interface that needs to be defined is between connectors and Ledger Adaptors. It likely includes:

  • sendMoney (perform a settlement)
  • receiveMoney (acknowledge an incoming settlement)
  • sendData (send a message to the Ledger Adaptor on the peer)
  • receiveData (accept a message from the Ledger Adaptor on the other peer)
  • getBalance (get the current balance of the settlement account, i.e. available liquidity for settlements)

Proposal 2 - External Settlement Engine

In this architecture the Settlement Engine is external to the connector.

An interface needs to be defined between the Settlement Engine and the Connector AND between the Ledger Adaptor and the Settlement Engine:

Settlement Engine -> Ledger Adaptor:

  • sendMoney (perform a settlement)
  • receiveMoney (acknowledge an incoming settlement)
  • receiveData (accept a message from the Ledger Adaptor on the other peer)
  • getBalance (get the current balance of the settlement account, i.e. available liquidity for settlements)

Settlement Engine -> Connector

  • getBalance (get the current balance of the clearing account, i.e. ILP balance)
  • setBalance (update the current balance of the clearing account, apply a delta)
  • sendData (send a message to the Settlement Engine on the peer)
  • receiveData (accept a message from the Settlement Engine on the other peer)

Next steps…
If we agree on what is being proposed then I think we can proceed to discussing the pros and cons of the two designs and decide which we should use (or even find a way to support both).

4 Likes
Ledger Adapter API
Ledger Adapter API
Ledger Adapter API
#4

This is an excellent summary. Thanks a lot @adrianhopebailie for writing it up!

A couple of clarifying questions:

  • Are the APIs between the various components you’re describing assumed to be HTTP/RPC APIs (network calls), internal APIs, or is that to be determined?
  • Would a combined settlement engine + ledger adapter be a 3rd option? (It seemed like that was what we were discussing before)

If we agree on having a ledger adapter with an HTTP/RPC API, then we actually don’t need to agree on the internal / external settlement engine design. I think the main question to this point has been how to abstract away different settlement systems in such a way that we don’t need to reimplement the integration in every programming language. If different people start working on external settlement engines that require different APIs from the connector, it may be nice to try to standardize those but it doesn’t seem like we need as broad agreement on that design as for the ledger adapter.

Update: I started a new thread on the Ledger Adapter API to work on designing that component.

2 Likes
#5

Great post @adrianhopebailie!

In my opinion external Settlement Engine + combining the Ledger Adapter is a good solution. Like @emschwartz already mentioned that’s how I also had it mind.

Cheers

#6

Agree. We should focus on the ledger adaptor first. I think we could re-use a lot of the code in existing plugins for these.

For max re-use it would be best if they were network APIs so that we can write the adaptors once and re-use them widely.

That said, and in line with your previous comment, we can probably leave the integration between the connector and settlement engine to evolve as people develop stand-alone engines. It sounds like a lot of connectors plan to do a simple engine in the connector.

I anticipate we’ll externalise this for Rafiki and as a result may have a proposal for this interface soon.

Sure, but this changes the API that we should prioritise standardising (Connector to SE) and I agree with the idea of focusing on the ledger adaptor first.

1 Like
#7

What are the advantages of starting with the Ledger Adapter (LA) over the Settlement Engine (SE)?

The SE seems is easier to standardized than a ledger adapter as the LA is too ledger-specific. Or am I missing something?

How do you plan on dealing with ledger-specific integrations?

#8

Using @adrianhopebailie’s terminology, the Ledger Adapter is purely an abstraction over the ledger’s capability to send and receive money. In contrast, the Settlement Engine implements the logic for when those functions should be called.

The Ledger Adapter is the ledger-specific integration. Each ledger would have its own Ledger Adapter that implements the common functions needed by the Settlement Engine / connector.

1 Like
#9

Nice explanation! I think I broadly agree with the analysis between the two proposals, but I still have some open questions.

I don’t think the diagram in proposal 1 entirely accurately describes it. I see “sendMoney” and “receiveMoney” as a much more direct API between the “ledger adapter” and the “balance service.”

I see the difference between the two proposals as the question of where the “settlement engine” component should exist (but not whether it’s an external service or an internal service). Does it exist between the balance service and the “ledger adapter,” interfacing between the two, or does its logic exist within the “ledger adapter” itself?

Proposal 1 has the flexibility to:

  • Implement a thin “settlement engine” in between the balance service and “ledger adapter,” which likely only uses basic settleTo/settleThreshold logic (so simple that it probably doesn’t need to be a separate service), or,
  • Implement a complex “settlement engine” with ledger-specific orchestration logic that exists within the “ledger adapter” itself.

The sendMoney/receiveMoney primitive can be used in both cases (subject to a minor tradeoff(s), in each, which I can elaborate on).

One thing I’m unclear about: what is the “settlement engine” doing?

If it has very complicated ledger-specific logic around triggering settlement, per what you and Matt were suggesting, then does it have to be reimplemented for different “ledger adapters”?

Also, could you provide specific examples of what logic you see the settlement engine might implement in both simple use cases and more advanced use cases? I think it might help better isolate what problem we’re trying to solve


As an aside, I have some differences on the proposed terminology (and maybe they go beyond nomenclature):

  • I think “settlement” as a descriptor is clearer and more generic than “ledger.” For example, while payment channels are technically their own type of “ledger,” people don’t typically think of them that way, and calling the integration a “ledger adapter” could create confusion as to whether it integrates with the base layer ledger, such as Bitcoin or Ethereum.
    • I see this as an abstraction to integrate with any mechanism to settle outside of the credit relationship on Interledger. What if I implemented a custom settlement integration that, e.g., mailed you cash? Is there a “ledger” in that case?
  • Your description of the intermediary component is that it “orchestrates complex business logic,” which fits the definition of “engine.”
    1. While addressed earlier, with respect to logic triggering settlement, some of this is tied directly to the settlement system, and may need to coexist with it.
    2. What is the best definition of “engine”? This definition seems more consistent with other sources I was able to find online: “An ‘engine’ is a self-contained, but externally-controllable, piece of code that encapsulates powerful logic designed to perform a specific type of work” (which to me aligns much more with the settlement system integration than its orchestration logic!)
  • “Adapter” sounds boring and “settlement engine” sounds pretty awesome :wink:

(i.e. we should call the settlement system integration a “settlement engine” rather than “ledger adapter”)

1 Like
#10

I’m currently working through the RFC’s and codebase to fully understand the existing system and the current design progression to the settlement engine. I have a few questions that may have obvious answers, but I just want to be certain that I’m understanding things correctly:

  • Is a unique settlement engine expected to exist between every pair of connectors that do business with each other? Or is the settlement engine expected to leverage many network participants to contribute to the safety and liveness of a global settlement engine state that many connectors can leverage? And in either case, why is that the current thinking?
  • If it’s the latter, what is the current thought about how this system could achieve Byzantine fault tolerance?
  • Also if it’s the latter, what is the thinking about how this system can avoid the Sybil attack?

Thank you for reading my questions.

#11

Awesome work so far, @adrianhopebailie. I am glad this is getting more attention, because the previous plug-in architecture has been quite frustrating to work with at times.

That’s pretty slick. :sunglasses:

I believe the ledger adapter just exposes generic functionality to the ledger from the settlement engine in this proposal. The role of the ledger adapter is to provide a mapping from settlement logic (e.g. paying or requesting payment for outstanding debt obligations at an arbitrary time) to the specific-ledger functionality (e.g. signing base-layer transactions or handling payment channel claims). In other words, the settlement engine is used for maintaining relationships on the network with generic business logic operations, but the ledger adapter abstracts all of the low-level ledger-specific operations away.

Suppose we form a connection and issue a bunch of trades back and forth. You have effectively credited me 0.01 BTC in the process, which I must pay at settlement time. The terms of our credit relationship say that we must settle any time the credited amount exceeds 0.01 BTC, or approximately every hour – whichever comes first.

If I do not fulfill my debt obligation, then you start sending an appropriate reject message whenever I try to send a payment through the connection we share. The settlement engine allows us to (independently?) define business logic. In this example, I know why you are unwilling to route my packets – we have to settle up. My settlement engine uses the ledger adapter to construct and broadcast a Bitcoin transaction, and then your settlement engine uses the ledger adapter for confirmation.

The settlement engine allows us to implement business logic based on value and time without worrying about ledger-specific functionality, afforded by the adapter.

For a minimal ledger adapter, I do not think so. A minimal implementation would probably only need to include sending money, checking balance, and possibly sending data. If we think of a ledger as a language, the ledger adapter is acting as the Rosetta Stone for business logic within the settlement engine. The business logic within the settlement engine is effectively a domain-specific language that can be extended to include ledger-specific functionality.

The settlement engine is used for handling out-standing debt obligations. It serves as the conditional logic for packet forwarding, based on the credit relationships of incoming and outgoing connections. It is the semantic framework for packet forwarding, whereas the syntactic framework (e.g. packet malformation, fulfillment checks, octet encoding rules) is carried out by the base protocol.

In most cases, I think the ledger adapter simply provides an interface for value and time. Hypothetically, it could be extended to build business logic using ledger-specific events (e.g. EVM or block height), but I believe this is a non-goal for minimal adapter implementations.

Simple:

  • Time-based Settlement (e.g. hourly :timer_clock:)
  • Value-based Settlement (e.g. credit threshold :credit_card:)

Advanced:

  • Stop-Limit Order-based Settlement (e.g. price oracle :crystal_ball:)
  • Event-sourced Settlement (e.g. EVM, block height :robot:)
  • Demand-based Settlement (e.g. discounted settlement triggered by insufficient liquidity :non-potable_water:)

Please feel free to correct my interpretation. (@adrianhopebailie, @emschwartz)

3 Likes
#12

@seanrowan the “settlement system” or ledger is the possibly global or at least multi-party thing that tracks a lot of different participants’ balances (think XRP, Bitcoin, etc). Each of those works in a completely different way, which makes integrating with many of them difficult.

We need some abstraction for those different settlement systems and the key questions are:

  1. Does the settlement abstraction live in the same process as the connector (plugins), on its own (@adrianhopebailie called this the “ledger adapter”, though @kincaid disagrees with that term), or in the same process with the logic that dictates when to settle based on the ILP credit balance
  2. What is the API for that abstraction?

We would like to be able to reuse the same abstraction component for the different implementations of Interledger, which means we need to agree on how it works and what the interface is.

To be clear though, the “settlement engine” / “ledger adapter” is a component that would be run by a single party and would manage their money on the underlying settlement system. Byzantine fault tolerance may be a feature of the underlying settlement system, but not the engine/adapter/abstraction on top of it.

1 Like
#13

Thanks @adrianhopebailie @emschwartz @kincaid for all of the input and discussion, appreciate you guys moving this forward. I wanted to offer up my perspective given what Strata is seeing in the network today in hopes that giving some main net context could help us choose the best solution.

For the more complex, business level relationships that we are helping coordinate, the “business logic” for settlement is still very simple. The settleThreshold configuration is totally sufficient for the present time, and we anticipate it will not be an issue for a very long time to come. This makes me think that if this is the case for businesses that are handling higher volume between one another, that it is likely also the case for an open source implementation of the connector that we want to make available for others to run.

Given this, I think that designing the settlement engine as an entire stand alone component is an over optimization for the current time. I’m not strongly opinionated about where it should exist (in the connector vs. in the ledger adapter) but I think that designing the settlement engine as a stand alone piece introduces unnecessary complexity.

Happy to discuss further, and thanks again for all of the time you guys have spent developing this crucial part of the ecosystem.

4 Likes
#14

Based on comments from @ekrenzke, @kincaid and @austin_king both here and on the other Ledger Adapter Interface thread, I think we should not try to abstract the Settlement Engine -> Ledger Adaptor interface.

  1. It’s complex and the complexity is probably not warranted at this time
  2. It’s hard to get the abstraction right
  3. Worst case scenario is that some code is re-used between different ledger specific settlement engines and this is extracted into stand-alone libraries

As I said on that thread I’d advocate for standardising on the interface I proposed above as:

This can be optimised (now or when it’s deemed to be required) by supplementing getBalance with a subscribeToBalanceChanges that allows the SE to get a stream of balance updates from the connector instead of polling.

I am confident that concerns about the volume of updates that will be sent can be alleviated using a debounced stream however I think this is a premature optimisation.

1 Like
Ledger Adapter API
#15

Addressing some comments from @emschwartz in another thread:

This applies however you do settlement. In fact it happens today in effect when you do a sendMoney, adjust the ILP balance and then the settlement fails.

Settlement is orchestration of atomic state changes to different systems so there is always a risk that one change happens before the other or that you need to roll-back changes on one to cover that they failed on the other.

The safest way to do this is to put the liquidity on hold at the connector, attempt the settlement and then release it if the settlement fails.

This is not really an argument agains the interface design, it’s an argument against moving the settlement business logic out of the connector because it’s too difficult to get consensus on the interface design.

This is a fair argument and I can see that it may be the pragmatic way forward. We have implemented the settlement logic in a different component to the routing/balance checking logic in Rafiki so that we have the flexibility to scale these independently in time. We imagine running a single settlement engine per settlement system that is designed to be robust, stateful and always up so it can do things like watching settlement ledger for closing channels and incoming payments in contrast to the connector which will be stateless and can scale quickly to serve single or multiple peers.

Right now most Rafiki instances will run the connector and SE in the same process but at least by splitting this out logically now we can split them into their own process in future.

We had envisioned this differently actually. We’ll continue to build out our SE implementation and if anyone wants to use it they can simply stream balance updates to it. Our expectation was that we’d develop an SE for a single settlement system and then re-use non-ledger specific code for others.

We MIGHT try to separate out the SE and Ledger Adaptor as proposed in that thread but probably not for now.

I wouldn’t bet on any of this being a small amount of work unless we just stick with the plugins as they are :smiley:

#16

It’s a game of telephone!

My point to Evan was that in order to do it safely, the external balance service approach (even assuming it uses a debounced stream), requires a lot more messages.

  1. Connector sends balance update to balance service
  2. Balance service notifies settlement engine of update
  3. Settlement engine decides to settle, then sends message to balance service with new balance
  4. Balance service ACKs that update, which is important because the SE can’t safely settle until it gets the ACK

(1.5 roundtrips, excluding connector -> balance service)

Whereas, with the sendMoney/receiveMoney approach:

  1. Connector update balances, decides to settle, then sends sendMoney message to settlement engine. The SE can safely start settling immediately.

(0.5 roundtrips)

Not with the ETH plugin, Lightning plugin, or Kava’s XRP plugin! :wink:

They all persist a “payoutAmount” for failed settlements, and will retry it later.

Which…kinda?

We already migrated our XRP payment channel plugin and added a sendMoney/receiveMoney HTTP API: https://github.com/Kava-Labs/ilp-plugin-xrp-paychan/tree/ko-http-api (refer to tests)

On the Rust connector side, since most of the balance logic is already implemented, I imagine interfacing with this should be relatively straightforward.

(I would emphasize that this branch is something I just threw together for testing, but it should do the thing, allowing two peers to open channels, and send and receive paychan claims, using whatever transport the connector provides).

The larger amount of work, as we see it, is getting these settlement engines (sorry Adrian) to a production-grade state for connector operators. Right now, they’re mostly a blackbox: there’s either no admin management interface, or no management interface that works reliably. That means no way to get your money out, and certainly no good way to understand what’s actually happening. And then ultimately, building out more robust automatic liquidity management.

Switch is more or less a much simplified “admin management” interface for end users. But building the same thing for connector operators will probably be more challenging

#17

So the balance in the connector and the settled amount get out of sync. That’s just a way of reducing the number of messages required to stay in sync by allowing the synchronization to be delayed isn’t it?

#18

Yes, they get temporarily out of sync.

AFAIK, the only real operational disadvantage of that is after a sendMoney call, if the settlement fails or otherwise is not sent immediately, that owed balance cannot be netted against incoming packets. In your approach, it could be refunded to the balance shared with the connector, enabling it to be netted.

I think that’s a reasonable tradeoff for the ease of implementation, lesser “API surface” required to get consensus on, and other benefits, but it’s worth digging into further.

#19

Don’t disagree at all. As I’ve said before we should just be clear when we make a design decision what the trade-offs are. This is really helpful, especially in the future, when we or others want to re-assess the design or understand why we took the path we did.

1 Like
#20

So where does that leave us? Reading through both this thread and the discussion in Ledger Adaptor API, it’s unclear to me where there’s consensus and where there is not.

Here’s how things appear to stand from may vantage point (I’m guessing I’ve missed a few things, or am possibly simply wrong in certain areas, so please chime-in if you disagree):

Consensus

  1. Settlement Adaptor: We want a non-Connector process that can interact with an underlying settlement system (e.g., Bitcoin, XRPL, etc) that does not run in the Connector process. This will allow us to scale Connectors and Settlement systems independently. I’m calling this thing the Settlement Adaptor (shout-out to @kincaid for good rationale around why to drop the word “ledger” here).
  2. Settlement Engine: We all agree that ILP-account balance-tracking (i.e., “when to settle based on the ILP credit balance”) should live in a Settlement Engine, but for now this component will just be an internal service/function of each Connector implementation.
    1. Based upon how implementations get built, it may make sense in the future to extract this into a standalone system and/or shared-libraries, but this is out of scope for now.
  3. Connector/SE <-> SA Transport: To aid adoption and for simplicity, we’re all OK with the Connector/SE communicating with the Settlement Adaptor using an HTTP+JSON API as a first-attempt. We may explore other techniques later if it makes sense.
  4. Settlement Adaptor API Endpoints
    1. sendMoney: When called by an external system (e.g., a Connector), instructs the Settlement Adaptor to send a payment via the underlying settlement system (e.g., XRPL).
    2. getBalance: Returns the current balance of the underlying settlement account (i.e. available liquidity for settlements).
    3. sendData: When called by an external system (e.g., a Connector), allows an ILP packet to be transmitted to the Settlement Adaptor for further processing, such as to exchange a Payment Channel claim.
  5. Connector/SE API Endpoints
    1. sendData: Allows the local Settlement Adaptor to communicate with the other Settlement Adaptor (used by the peer Connector) by transiting the local Connector using ILP link-layer technologies and peer.settle. addresses.
    2. sendMoney: Allows the Settlement Adaptor to indicate that a settlement payment was received on the underlying settlement system. For example, the account 123 received 10 XRP. The Connector will react to this callback and update its balances appropriately.

Open Questions

  1. Are the above API endpoints correct?
  2. If you get into a taxi cab, and ask the driver to drive backwards to your destination, will the cab driver owe you money?
1 Like