W3C home > Mailing lists > Public > public-interledger@w3.org > August 2017

Re: [Ledger] An attempt to clean up the protocol architecture

From: Andrew Bransford Brown <andrewbb@gmail.com>
Date: Fri, 18 Aug 2017 16:10:43 -0400
Message-ID: <CAPS+YFK0iVK=srHeKf+d9YFqF6JXfbFpA58NuJVWHY8nZ-qFJQ@mail.gmail.com>
To: Adrian Hope-Bailie <adrian@hopebailie.com>
Cc: Ben Sharafian <sharafian@ripple.com>, Evan Schwartz <evan@ripple.com>, Interledger Community Group <public-interledger@w3.org>, Interledger Mailing List - IETF <ledger@ietf.org>
If the human species survives, they'll say humans nearly went extinct,
because some liked to keep secrets (top secret, secret, classified).

On Thu, Aug 17, 2017 at 1:32 PM, Adrian Hope-Bailie <adrian@hopebailie.com>
wrote:

>
>
> On 16 August 2017 at 10:22, Ben Sharafian <sharafian@ripple.com> wrote:
>
>> OK, I think in that case we're mostly disagreeing over where the
>> condition/fulfillment/expiry actually go in the data.
>>
>
> That's one way to look at it but that's ultimately what the architecting
> the layering is. Deciding at which layer (and therefor encapsulated in what
> packet) certain data should be.
>
>
>> The reason I don't agree with your position is based on which parties I
>> think should be aware of ILP.
>>
>
> I don't think that's the right way to look at it. The connector needs to
> be able to understand at least the ILP layer data AND the lower layer data.
> Normally the way the processing stack is implemented is that there is a
> module for each layer that processes the data from that layer and then
> passes the payload and any other important information up to the next layer.
>
>
>> In order to track the balance between each other accurately, the two
>> connectors have to keep track of conditions, fulfillments, and expiries on
>> each of the transfers.
>>
>
> This is where I disagree with you. Two connectors exchanging a transfer
> only care about the data that is relevant to them for that transfer. It's
> quite possible for two connectors to perform a transfer that has no
> conditions or fulfillments or a transfer that has a different condition and
> fulfillment (such as an atomic mode transfer where the condition is a
> compound one that has multiple sub-conditions).
>
>
>> That means the connectors' accounting logic that handles the conditions,
>> fulfillments, and expiries is going to be using some information inside the
>> ILP packet and some information outside of it in order to perform these
>> transfers.
>>
>
> It will only use info inside the packet if it uses conditional transfers
> that use that same condition. This is the most likely scenario but that is
> not a protocol requirement.
>
>
>>
>> I think it's cleaner to say everything required to make these local
>> transfers should go in one protocol, so the accounting logic of these
>> connectors doesn't have to deal with ILP directly.
>>
>
> I strongly disagree with that. That's entirely the wrong reason to put
> data into a specific layer. The data in the ILP layer is there because it's
> "end-to-end" data.
>
> If a protocol at a lower layer wants to use that data then it must
> replicate it. That seems inefficient but it's the correct way to do it.
>
> One could define a lower layer protocol that doesn't replicate the data
> but the rules of the protocol are "Get the condition from the ILP packet".
> In that case, that specific lower level protocol is forcing implementations
> to understand the ILP packet format, that's an implementation detail.
>
> Another lower layer protocol might take the condition from the ILP packet
> and re-encode it in a different form (like a base64ulr string or NI: uri)
>
>
>> Then the connectors' ILP-packet-related behavior can all be routing
>> related.
>>
>
> Routing requires looking at the condition, expiry and amount. A
> connector's routing logic shouldn't forward a packet if the expiry is too
> low or if the condition is obviously corrupted.
>
> If the protocols were designed correctly as I am proposing then another
> routing decision would be, is the condition that was used in the incoming
> transfer the same as the one used in the ILP packet?
>
>
>
>> This would add a few benefits; two connectors could perform non-ILP
>> conditional transfers between one another (which would be useful for
>> reconciliation and settlement), and could also allow two connectors to use
>> more complex condition types (i.e. signatures for atomic mode) without
>> forcing us to support that in the ILP packet.
>>
>
> You seem to have this backwards. Both of these things are supported if the
> condition and expiry ARE in the ILP packet. Atomic mode is not supported in
> the ILP protocol it is supported in the lower layer transfer protocol. The
> ILP packet just contains the end-to-end condition (always a SHA-256 hash)
> and then the local transfer can have a different condition that is derived
> from the condition in the ILP packet.
>
>
>> It also keeps the integrity of the ILP packet as something lower levels
>> don't modify; the connector has to modify the expiry in order to pass along
>> an ILP payment (they may not modify the expiry if they're using something
>> like atomic mode, but then we have the issue with advanced condition types
>> not being supported in the ILP packet).
>>
>
> I think the expiry should always be the expiry set by the sender. It won't
> be changed.
>
>>
>> In the case where the ledger _does_ care about the condition and
>> fulfillment, the argument in favor of separating
>> condition/fulfillment/expiry from the rest of the packet is similar.
>> Because we don't control the features of all ledgers, we'll need our
>> plugins or ledger adapters to be aware of ILP. This makes it hard to
>> interact with any events that don't involve ILP packets, and impossible to
>> handle features that extend beyond what we support in the ILP packet. We
>> could pass details about non-ILP ledger features (like a crypto condition)
>> in the side data, but in the event of any redundancy we have to check the
>> ledger-supplied info, not the info in the ILP packet.
>>
>
> Comparing the condition in the local transfer and the one in the ILP
> packet should be part of the routing logic.
>
>
>>
>> Basically, condition/fulfillment/expiry are used for accounting local
>> transfers (even if they aren't being "ledger" enforced) in addition to
>> their role as every-hop information. By putting them in the ILP packet, we
>> limit the special features that ledgers can support and make our software
>> abstractions harder to separate cleanly. By putting them in the local
>> transfer alongside the ILP packet but not inside it, we do separate the
>> data a little more, but we have more freedom in what the underlying
>> accounting and ledger logic can do, and our software modules will have more
>> clearly separated domains.
>>
>
> They should be in both the local transfer AND the ILP packet if they are
> needed by the local transfer protocol. This allows the flexibility you
> desire because the local transfer protocol can do ANYTHING including using
> the condition from the ILP packet as-is, not at all or enhanced for
> something like atomic mode.
>
>
>
>>
>> On Tue, Aug 15, 2017 at 10:24 AM, Adrian Hope-Bailie <
>> adrian@hopebailie.com> wrote:
>>
>>> Exactly 👍
>>>
>>> On Tue, Aug 15, 2017 at 6:52 PM Ben Sharafian <sharafian@ripple.com>
>>> wrote:
>>>
>>>> Ok, I think I have a better idea of what you're saying.
>>>>
>>>> It sounds like you're saying the ILP layer contains all information
>>>> that is common between every hop (destination, destination amount, opaque
>>>> data, condition, fulfillment, expiry). The lower level would then be used
>>>> for all the transfer-local details (source amount, next connector account,
>>>> custom/local data).
>>>>
>>>> If the lower level wanted to do anything related to the every-hop
>>>> payment, i.e. escrow funds until the receipt has been produced, it would
>>>> look into the ILP layer for that information. If the lower level didn't do
>>>> any escrow or expiries that require every-hop details, it would simply
>>>> function as a communication method.
>>>>
>>>> Is that right?
>>>>
>>>> On Tue, Aug 15, 2017 at 6:35 PM, Adrian Hope-Bailie <
>>>> adrian@hopebailie.com> wrote:
>>>>
>>>>>
>>>>>
>>>>> On 15 August 2017 at 16:00, Ben Sharafian <sharafian@ripple.com>
>>>>> wrote:
>>>>>
>>>>>> In that case, the plugin or whatever is doing the accounting is the
>>>>>>>>> ledger. Digital value is always tracked in ledgers, so I think it does make
>>>>>>>>> sense to think of this as the base layer. The reason to abstract the
>>>>>>>>> functionality you expect from the ledger layer is precisely so you can
>>>>>>>>> handle it in different ways, depending on what the underlying systems
>>>>>>>>> provide.
>>>>>>>>
>>>>>>>> I see 3 ways to think of the layer(s) underpinning ILP:
>>>>>>>>
>>>>>>>>    1. The "Ledger Layer" provides both messaging capabilities and
>>>>>>>>    some type of HTLA
>>>>>>>>    <https://github.com/interledger/rfcs/blob/master/0022-hashed-timelock-agreements/0022-hashed-timelock-agreements.md>
>>>>>>>>
>>>>>>>>
>>>>>>>>    1. There are separate plugins for messaging and for transfers
>>>>>>>>    and when you peer with someone you have to agree on a plugin for each
>>>>>>>>
>>>>>>>>
>>>>>>>>    1. We standardize the messaging part and say that all goes over
>>>>>>>>    IP and then just have more minimal plugins for the on-ledger settlements
>>>>>>>>
>>>>>>>> Number 1 is what we have and I think that still makes the most
>>>>>>>> sense.
>>>>>>>
>>>>>>>
>>>>>> I think you're confusing implementation details and defining of
>>>>>>> interfaces with definition of a protocol stack. The only differences
>>>>>>> between the tree examples you have above is in implementation.
>>>>>>
>>>>>>
>>>>>> I had to scroll up after reading this to make sure it was @adrian
>>>>>> talking, because that seems like the opposite of what you were arguing for.
>>>>>>
>>>>>
>>>>> I don't think so. But I think that is part of the problem. We are not
>>>>> all focused on the same thing. I am actually not very interested in CLP at
>>>>> all. It is one of potentially many protocols that may exist below the ILP
>>>>> layer. All we're doing by defining CLP is bootstrapping the network by
>>>>> defining a protocol for everyone to use to get started.
>>>>>
>>>>> In designing the ILP layer properly we should try and forget
>>>>> everything we know about the lower layers other than what features we
>>>>> require of them.
>>>>>
>>>>> There is a misconception that ILP requires the lower layers to support
>>>>> conditional transfers, that is not true.
>>>>>
>>>>> All we actually need from a lower layer protocol is to transfer data
>>>>> back and forth and provide a way to reliably map requests to responses.
>>>>>
>>>>> What ILP provides lower layers is a way to reward your peer for
>>>>> passing on the packet. The Internetworking layer defines a condition, a
>>>>> reward that must be paid to the receiver for the fulfillment and the time
>>>>> allowed to claim this reward.
>>>>>
>>>>> Because of this, within lower-layer protocols that offer the basic
>>>>> request/response features we need, we could add conditional payment
>>>>> semantics that use the condition, expiry and fulfillment provided by ILP.
>>>>> This would allow a node to offer a reward to  their next peer to for
>>>>> delivering the packet they send them and to make the local financial
>>>>> transaction contingent on the end-to-end transaction.
>>>>>
>>>>> But crucially, adding that semantic to the lower layer protocol
>>>>> provides nothing extra to the ILP layer. The value is purely derived from
>>>>> the two peers who use that protocol and can now use conditional payments to
>>>>> protect themselves from their peers.
>>>>>
>>>>>
>>>>>> The proposal that you're arguing for is basically asserting that
>>>>>> we're going to be using CLP, because it makes the assumption that the
>>>>>> connectors (who understand ILP) are managing the HTLA logic.
>>>>>>
>>>>>
>>>>> Not at all. I am asserting that it doesn't matter what protocol you
>>>>> use below the ILP layer because it shouldn't matter. All of this talk about
>>>>> ILP being different because money is more important than data is nonsense.
>>>>>
>>>>> The difference between ILP and IP that makes ILP suitable for value
>>>>> transfer and IP not is at the internetworking layer. ILP requires that all
>>>>> packets are either a request or response and that the responses follow the
>>>>> same path as the requests. Further ILP defines a signature scheme that
>>>>> gives the sender a way to be certain the request was received by the
>>>>> receiver.
>>>>>
>>>>> *This could be done entirely without money* but then there would be
>>>>> little incentive to sign the receipt or deliver the signature back to the
>>>>> original sender.
>>>>>
>>>>> So, if you add money then you add economic incentives to the mix. At
>>>>> each hop the sender promises the next upstream peer a payment if they can
>>>>> return the receipt. The net effect is that this can be used to transfer
>>>>> money from the sender to the receiver by simply defining up front the
>>>>> amount that the receiver must get to produce the signature.
>>>>>
>>>>>
>>>>>>
>>>>>> In the current model, the CLP/trustline model and the direct ledger
>>>>>> model both work without having to treat anything on the ILP layer
>>>>>> differently. We're favoring on-ledger messaging because of our
>>>>>> implementation, yes, but we've been able to switch most all of our plugins
>>>>>> from on-ledger messaging to RPC-based messaging without changing the ILP
>>>>>> layer at all.
>>>>>>
>>>>>> With the ledger-level abstraction, we were able to switch from our
>>>>>> ledger-based mode of thinking to the CLP/trustline based way without
>>>>>> changing anything other than the plugin. Your argument comes from an
>>>>>> assumption of a CLP-style ledger protocol with some underlying ledger,
>>>>>> which we can't assume is always the case.
>>>>>>
>>>>>
>>>>> I'm not sure what any of that proves tbh. These are all implementation
>>>>> concerns. They don't change the fact that the condition, expiry and
>>>>> fulfillment are part of ILP not the lower layer protocols.
>>>>>
>>>>>>
>>>>>>
>>>>>> From the perspective of the Interledger Protocol the implementation
>>>>>>> of the lower layers is not important, that's the whole point of layering.
>>>>>>> By forcing important aspects of ILP like the condition, fulfillment and
>>>>>>> expiry down into those layers you muddy the waters and we now have to
>>>>>>> standardize those protocols too. Instead we should just be defining the
>>>>>>> functions they must provide and then leave it up to implementations to
>>>>>>> provide those functions.
>>>>>>
>>>>>>
>>>>>> I don't agree with this point; the condition and fulfillment have
>>>>>> actual meaning to the ledger layer.
>>>>>>
>>>>>
>>>>> NO THEY DON'T! They have meaning to SOME ledgers that implement SOME
>>>>> lower layer protocols, IF they choose to use them.
>>>>>
>>>>> Excuse the shouting but this is the crux of the issue. We need to all
>>>>> agree that it is entirely possible for a transfer to be done that doesn't
>>>>> use the condition and fulfillment and that if this was in the middle of a
>>>>> 10-hop ILP payment it would have no effect on the sender and receiver.
>>>>>
>>>>>>
>>>>>> You've said that the ledger often doesn't care about fulfillment and
>>>>>> condition, but the ledger _layer_'s (where transfers are done) role is to
>>>>>> take in condition and fulfillment and make a transfer which satisfies its
>>>>>> HTLA.
>>>>>>
>>>>>
>>>>> No, the ledger's role is to keep a tab of net financial positions
>>>>> between two peers. It MAY use conditions and fulfillments that it pulls
>>>>> from the ILP layer to help it do that in a way both peers agree on.
>>>>>
>>>>> Note that a "layer" doesn't have a role. I think there is some
>>>>> confusion about the difference between layering the protocol and
>>>>> abstracting functionality into different components.
>>>>>
>>>>>
>>>>>> If the ledger layer has to look into the ILP packet to do so, that is
>>>>>> a blatant breaking of layering.
>>>>>>
>>>>>
>>>>> Not at all! The module acting at the layers *below* the
>>>>> internetworking layer shouldn't modify anything inside the packets of the
>>>>> higher layers but they can definitely inspect them and adjust their
>>>>> behavior based on what they to find.
>>>>>
>>>>> In fact the prevalence of this is the subject of a lot of debate at
>>>>> the IETF currently because endpoints are often encrypting their payloads
>>>>> and in some cases this makes it difficult for middle-boxes to be effective
>>>>> at their jobs.
>>>>>
>>>>> By putting the condition, fulfillment, and expiry on the ledger layer,
>>>>>> we leave it open for any ledger type to work, rather than forcing all
>>>>>> ledger-layer software to understand ILP.
>>>>>>
>>>>>
>>>>> Actually you do the opposite. You make it a requirement of every
>>>>> protocol below the ILP layer to define a way to carry these data elements
>>>>> and encode and decode them, even if they don't use them
>>>>>
>>>>> Ledger layer components don't have to understand ILP unless they
>>>>> choose to re-use the condition for their own local transfer. Ledgers
>>>>> themselves *never* have to understand ILP.
>>>>>
>>>>> Remember a ledger layer protocol could use a completely different
>>>>> conditional payments scheme, like atomic mode ILP, where it takes the
>>>>> end-to-end condition and creates a new compound condition that depends on
>>>>> the fulfillment and some notary signature.
>>>>>
>>>>> There will be a component in a connector's stack that must pass the
>>>>> ILP packet to the next peer. If it does this using a transfer protocol that
>>>>> uses conditional transfers and wants to use the same condition as the ILP
>>>>> packet then it must decode the packet.
>>>>>
>>>>> But, it will likely do something with that condition before sending
>>>>> the transfer to the ledger like encoding it differently or rehashing it
>>>>> (lightning?) so that it's in the form expected by the ledger.
>>>>>
>>>>> That's an implementation decision of the lower layer protocol used
>>>>> between those two peers.
>>>>>
>>>>>
>>>>>>
>>>>>> I agree that Interledger defines how conditions, fulfillments, and
>>>>>> expiries should be chained together, but it makes no assertions about their
>>>>>> data format.
>>>>>>
>>>>>
>>>>> ILP doesn't define how anything is chained together. From the
>>>>> perspective of ILP the condition and fulfillment are end-to-end data. They
>>>>> are agreed by the two endpoints who don't care how they get from Alice to
>>>>> Bob and back.
>>>>>
>>>>> The design of ILP is such that it facilitates the design of lower
>>>>> level protocols that can be used to carry the ILP packets across multiple
>>>>> hops (networks) using economic incentives such that the sender pays enough
>>>>> for the first hop to ensure that all nodes in between can extract the fee
>>>>> they want and the receiver will still get the amount they expected..
>>>>>
>>>>>
>>>>>
>>>>>> ILP says you should send your outgoing transfer with the same
>>>>>> condition as the incoming one, and a lower expiry.
>>>>>>
>>>>>
>>>>> No it doesn't. An internetworking protocol can't prescribe that kind
>>>>> of thing to lower level protocols. An incoming and outgoing transfer could
>>>>> be sent using completely different protocols and the financial agreement
>>>>> with the peers on those two routes could be vastly different too.
>>>>>
>>>>> The only service ILP requires of lower level protocols is that they
>>>>> can map a response to an original request. This requirement is okay because
>>>>> it is isolated to a single route/link at a time not a requirement that
>>>>> crosses the inter-network boundary that ILP crosses.
>>>>>
>>>>>
>>>>>> But because ILP allows for many different types of ledgers, it
>>>>>> doesn't make sense to assert how these are encoded.
>>>>>>
>>>>>
>>>>> By putting them in the ILP packet you do the opposite. You make no
>>>>> assertions about how they are encoded if they are used at lower layers, or
>>>>> how they may be combined with other conditions or even used to derive new
>>>>> conditions.
>>>>>
>>>>>>
>>>>>> IP doesn't tell you how to encode an ethernet packet. It doesn't even
>>>>>> know whether it's going over a computer or a hand-written letter carried by
>>>>>> a pigeon. IP takes for granted that you can send data over one connection
>>>>>> by putting it in a lower level.
>>>>>>
>>>>>
>>>>> Correct, but if a link layer protocol wanted to look into the IP
>>>>> packet headers of a packet it wants to transfer and use some data from
>>>>> there in its internal logic (or even reuse data in it's own frame) that
>>>>> would be totally fine.
>>>>>
>>>>>
>>>>>> Even though IP tells you how to chain these connections together, it
>>>>>> doesn't have to put the things it's chaining on the internetworking level.
>>>>>>
>>>>>
>>>>> IP doesn't tell you how to chain things together. IP simply defines
>>>>> the end-to end data envelope and address space. Because of this nodes that
>>>>> implement the multiple lower layer protocols are able to push IP packets
>>>>> down a link and expect the node on the other side to understand the headers
>>>>> and route it onward on another link.
>>>>>
>>>>> Everything needed by the IP module to decide what to do with the
>>>>> packet is in the IP packet headers. i.e. Has it exceeded a TTL? Is there a
>>>>> route for this destination? Is it corrupted (checksum fails)? But also,
>>>>> everything that is needed by the endpoint (like the source address) is also
>>>>> in there.
>>>>>
>>>>> There is no dependency on nodes to be good citizens and always pass
>>>>> certain other data from the lower layers into the next link. That would be
>>>>> breaking the layering.
>>>>>
>>>>>
>>>>>> IP also assumes that if you get some incoming data on a connection
>>>>>> you can copy it and send it out on the next connection. Because you can
>>>>>> already send data over a connection, all IP adds is the missing piece: a
>>>>>> packet that tells you where to go.
>>>>>>
>>>>>> With ILP, we assume that there is a way to prepare a conditional
>>>>>> transfer, expire a conditional transfer, and fulfill a conditional
>>>>>> transfer.
>>>>>>
>>>>>
>>>>> No we don't! We assume that if we deliver the packet as intended we'll
>>>>> get back a response packet with a signature that matches the condition in
>>>>> the packet. So, if we have an agreement with someone that they will pay us
>>>>> when we present that signature then we are prepared to enter a similar
>>>>> agreement with the next peer because we expect that signature to come all
>>>>> the way back along the interledger layer route..
>>>>>
>>>>>
>>>>>> We also assume that if you get an incoming transfer you can create an
>>>>>> outgoing transfer with the same condition. The abstraction we made means
>>>>>> that conditions and fulfillments are already carried in the lower levels.
>>>>>>
>>>>>
>>>>> That is a bad assumption that comes from the broken layering. What if
>>>>> my outgoing link doesn't support conditional transfers? So now where do I
>>>>> put the condition?
>>>>>
>>>>>>
>>>>>>
>>>>>> We could have assumed that no ledgers ever support conditional
>>>>>> transfers, and said the only thing ILP gets from lower levels is the
>>>>>> ability to send a transfer. But if we want to support the case where any of
>>>>>> them do, we have to keep the conditions and fulfillments in the layer where
>>>>>> they're actually used.
>>>>>>
>>>>>
>>>>> I don't follow that logic at all. If we want to support the case where
>>>>> any of them do then we must ensure the condition and expiry are always
>>>>> carried in a consistent place at the internetworking layer so that if they
>>>>> do want to use them they know where to find them.
>>>>>
>>>>>
>>>>>>
>>>>>> On Tue, Aug 15, 2017 at 12:04 PM, Adrian Hope-Bailie <
>>>>>> adrian@hopebailie.com> wrote:
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 14 August 2017 at 22:03, Evan Schwartz <evan@ripple.com> wrote:
>>>>>>>
>>>>>>>> I think this thread is going to get extremely unwieldy but here
>>>>>>>> goes:
>>>>>>>>
>>>>>>>> > - All interledger layer messages should be ILP packets
>>>>>>>> (including fulfillments) and be capable of carrying higher layer protocol
>>>>>>>> payloads.
>>>>>>>>
>>>>>>>> Interledger has higher requirements than ILP for the lowest layer,
>>>>>>>> specifically because we are carrying money and not just data. One of the
>>>>>>>> requirements is being able to transmit a 32-byte fulfillment back along the
>>>>>>>> same path that carried the payment originally. If we expect this of the
>>>>>>>> lower layer, I don't see a point in putting the fulfillment into an ILP
>>>>>>>> packet and transmitting it as Interledger data along the same path. All
>>>>>>>> ledger-layer protocols will need to interpret the fulfillment passed in
>>>>>>>> their protocol, not the one passed through the Interledger layer.
>>>>>>>>
>>>>>>>
>>>>>>> This is not correct. There is no requirement on ledger layer
>>>>>>> protocols to transmit or understand the fulfillment. You are looking at
>>>>>>> this through the lens of existing implementations from the bottom up
>>>>>>> instead of starting at the interledger layer.
>>>>>>>
>>>>>>> The primary function of the condition and fulfillment is as a signed
>>>>>>> end-to-end receipt. If the sender agrees a condition with a receiver and
>>>>>>> then gets back the valid fulfillment they don't care what happened in the
>>>>>>> middle. The receiver has signed a receipt saying they have their money.
>>>>>>>
>>>>>>> The value of using a standard for the receipt and signature is that
>>>>>>> each transfer along the way CAN re-use it. One the one hand you can have a
>>>>>>> transfer between two peers that have zero trust and the ledger they use
>>>>>>> supports conditional payments completely. On the other extreme you can have
>>>>>>> two peers that have a full trust and ignore the condition and fulfillment
>>>>>>> completely.
>>>>>>>
>>>>>>> The ledger layer protocols carry ILP packets. Payment requests and
>>>>>>> either fulfillment or error responses. If a ledger layer protocol wants to
>>>>>>> use the condition and fulfillment for their own operations they can extract
>>>>>>> these from the ILP packets and use them.
>>>>>>>
>>>>>>>
>>>>>>>> > - While it may make sense to split the interledger payment and
>>>>>>>> interledger quoting protocols into new higher level protocols that seems
>>>>>>>> like an unnecessary abstraction. Instead the packet definitions should just
>>>>>>>> have some consistency and probably a common base/header.
>>>>>>>>
>>>>>>>> The current protocols effectively have this header but it isn't
>>>>>>>> separated out. There are two fields in the request header: type and
>>>>>>>> destination address. There is one field in the response header: type. I
>>>>>>>> don't think it makes that much of a big difference to separate these fields
>>>>>>>> if all of the fields in that packet need to be interpreted together (for
>>>>>>>> example, you can't understand a quote request if you strip off the
>>>>>>>> destination address).
>>>>>>>>
>>>>>>>
>>>>>>> I agree that we don't HAVE to explicitly separate them out but I
>>>>>>> think ti would make it clearer how the stack is architected if there was a
>>>>>>> header that was consistent across all packets. Currently the only thing
>>>>>>> that is consitent across all ILP packets is that they are defined int he
>>>>>>> same file.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> > - We should define two base ILP packet types: request and
>>>>>>>> response.
>>>>>>>>
>>>>>>>> Unless this adds some substantive benefit or new fields I don't
>>>>>>>> think it's worth breaking all of the formats we have just to rearrange
>>>>>>>> things.
>>>>>>>>
>>>>>>>
>>>>>>> The goal of this exercise is to tease out the best design and ignore
>>>>>>> the cost of change until we can compare the results with the current design.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> > - ILP is not about ledgers, it is about trustlines between
>>>>>>>> nodes/hosts.
>>>>>>>>
>>>>>>>> A ledger is any system that tracks accounts and balances. When you
>>>>>>>> use a trustline all of your messages still need to go through an accounting
>>>>>>>> system (such as the plugin in the JS implementation) and then on to the
>>>>>>>> other program logic.
>>>>>>>>
>>>>>>>
>>>>>>> As above, this is incorrect. There is no requirement for "all
>>>>>>> messages to go through an accounting system".
>>>>>>>
>>>>>>> Since designing the first implementation of 5-bells ledger we have
>>>>>>> assumed that passing the ILP packet MUST be done by the ledger because that
>>>>>>> is how we implemented it. But that is not true. It is perfectly valid for
>>>>>>> the passing of an ILP packet from one peer to another to be simply an
>>>>>>> exchange of data.
>>>>>>>
>>>>>>> The receiving peer makes a decision about whether or not to forward
>>>>>>> the packet based on the current financial position they have with the
>>>>>>> sending peer.
>>>>>>>
>>>>>>> It is convenient if the ledger that records the net positions of the
>>>>>>> peers also forwards the messaging and even better if it natively supports
>>>>>>> conditional payments and can use the condition and the fulfillment from the
>>>>>>> ILP packet for those but that's all it is, convenient.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> In that case, the plugin or whatever is doing the accounting is the
>>>>>>>> ledger. Digital value is always tracked in ledgers, so I think it does make
>>>>>>>> sense to think of this as the base layer. The reason to abstract the
>>>>>>>> functionality you expect from the ledger layer is precisely so you can
>>>>>>>> handle it in different ways, depending on what the underlying systems
>>>>>>>> provide.
>>>>>>>>
>>>>>>>> I see 3 ways to think of the layer(s) underpinning ILP:
>>>>>>>>
>>>>>>>>    1. The "Ledger Layer" provides both messaging capabilities and
>>>>>>>>    some type of HTLA
>>>>>>>>    <https://github.com/interledger/rfcs/blob/master/0022-hashed-timelock-agreements/0022-hashed-timelock-agreements.md>
>>>>>>>>    2. There are separate plugins for messaging and for transfers
>>>>>>>>    and when you peer with someone you have to agree on a plugin for each
>>>>>>>>    3. We standardize the messaging part and say that all goes over
>>>>>>>>    IP and then just have more minimal plugins for the on-ledger settlements
>>>>>>>>
>>>>>>>> Number 1 is what we have and I think that still makes the most
>>>>>>>> sense.
>>>>>>>>
>>>>>>>
>>>>>>> I think you're confusing implementation details and defining of
>>>>>>> interfaces with definition of a protocol stack. The only differences
>>>>>>> between the tree examples you have above is in implementation.
>>>>>>>
>>>>>>> From the perspective of the Interledger Protocol the implementation
>>>>>>> of the lower layers is not important, that's the whole point of layering.
>>>>>>> By forcing important aspects of ILP like the condition, fulfillment and
>>>>>>> expiry down into those layers you muddy the waters and we now have to
>>>>>>> standardize those protocols too. Instead we should just be defining the
>>>>>>> functions they must provide and then leave it up to implementations to
>>>>>>> provide those functions.
>>>>>>>
>>>>>>> I know we want to define a standard to bootstrap the system (CLP)
>>>>>>> but that's misleading us into thinking it's an essential part of the stack.
>>>>>>> It's perfectly valid for two peers to not use CLP and still be part of the
>>>>>>> Interledger.
>>>>>>>
>>>>>>> That said, you raise an interesting consideration about the layers
>>>>>>> below ILP and actually I think it makes sense to split these.
>>>>>>>
>>>>>>> We keep trying to force messaging through the ledger layer and
>>>>>>> actually that's the wrong place to put it if we can split the ledger layer
>>>>>>> into a messaging layer and a ledger layer. That way we can stop trying to
>>>>>>> think of all HLTAs as ledgers.
>>>>>>>
>>>>>>> A thought, why not use sub-layers as is common in other stacks:
>>>>>>>
>>>>>>> 1. Link layer: Layer upon which two peers that have a direct link,
>>>>>>> or participate in the same payment network, communicate
>>>>>>> 2. Transfer/ ledger: Layer on which financial positions between two
>>>>>>> peers are recorded
>>>>>>>
>>>>>>> This reflects the already emerging HTLA model and many of our
>>>>>>> existing plugins and ledger integrations.
>>>>>>> Link Layer: XRP Paychan, Lightning
>>>>>>> Ledger Layer: XRP Ledger, Bitcoin
>>>>>>>
>>>>>>> This doesn't prevent us from defining a standard binary protocol
>>>>>>> that defines all of the operations for both layers (like CLP) but I see
>>>>>>> value in distinguishing between these two.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> > - The protocol should differentiate between the operation of
>>>>>>>> preparing a transfer on a ledger and the operation of passing an ILP packet
>>>>>>>> from one peer to another.
>>>>>>>>
>>>>>>>> The protocol assumes your conditional transfer is underpinned by
>>>>>>>> some HTLA
>>>>>>>> <https://github.com/interledger/rfcs/blob/master/0022-hashed-timelock-agreements/0022-hashed-timelock-agreements.md>.
>>>>>>>> It doesn't care whether that's on-ledger or not.
>>>>>>>>
>>>>>>>
>>>>>>> What do you mean when you say "the protocol"? In my statement I am
>>>>>>> referring to ILP.
>>>>>>> My point above being that ILP expects ILP packets to be passed from
>>>>>>> peer to peer but has no expectations about transfers.
>>>>>>>
>>>>>>> It's perfectly legal (from an ILP perspective) for two peers to
>>>>>>> exchange ILP packets with no transfers. Clearly if a node routes a packet
>>>>>>> on and has no incoming transfer it's going to lose money but that's a
>>>>>>> consideration for that node. It doesn't affect anyone else in the chain.
>>>>>>>
>>>>>>> ILP doesn't assume anything about transfers at all, let alone
>>>>>>> conditional transfers. It provides useful semantics for conditional
>>>>>>> transfers to be used by two peers to transact as part of a larger ILP
>>>>>>> payment.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> > - The condition and timeout should be included in the ILP
>>>>>>>> payment packet.
>>>>>>>>
>>>>>>>> I strongly disagree with this. We had this debate a year ago and I
>>>>>>>> was on your side but was convinced that this is not a good idea.
>>>>>>>>
>>>>>>>
>>>>>>> Yes, I recall this and I'm sorry I didn't push harder on this point.
>>>>>>> Unfortunately I think the decision to pull it out of the packet is mostly
>>>>>>> driven by how our prototypes were implemented rather than good architecture.
>>>>>>>
>>>>>>>>
>>>>>>>> The layer below ILP must be capable of doing conditional transfers
>>>>>>>> based on sha256 hashlocks with 32-byte preimages.
>>>>>>>>
>>>>>>>
>>>>>>> This is not true and I think it would be useful for us to agree on
>>>>>>> this as this seems to be the argument I am coming up against most often.
>>>>>>> The peers participating in a transfer that is part of an ILP payment may
>>>>>>> wish to use conditional transfers as a way to enforce their agreement but
>>>>>>> this is not a requirement of the protocol.
>>>>>>>
>>>>>>> The agreement between any two peers is: "I will pay you X if you can
>>>>>>> provide a receipt that Y was paid Z before T".
>>>>>>> ILP provides a standard for expressing this agreement so that these
>>>>>>> can be chained together BUT it is not a requirement that every agreement in
>>>>>>> the chain uses the condition, and fulfillment provided at the ILP layer.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> As a result, the original condition and the corresponding preimage
>>>>>>>> MUST be expressed in that layer.
>>>>>>>>
>>>>>>>
>>>>>>> As I have shown above, this is not true.
>>>>>>>
>>>>>>>
>>>>>>>> Then the question is whether we should also include it in the
>>>>>>>> packet that is forwarded. What ultimately convinced me is the following:
>>>>>>>> All connectors MUST ignore the condition if it is in the packet, because
>>>>>>>> they are only guaranteed their money back if they use the same condition
>>>>>>>> from the incoming transfer they got.
>>>>>>>>
>>>>>>>
>>>>>>> Here is where the layering is being corrupted.
>>>>>>>
>>>>>>> All connectors MUST inspect the condition in the ILP packet as part
>>>>>>> of their decision to route the packet or not.
>>>>>>> When the local transfer module of the connectors stack passes the
>>>>>>> ILP packet up to the ILP module it should indicate the properties of the
>>>>>>> incoming transfer that carried the packet.
>>>>>>> This is essential firstly so that the routing logic in the ILP
>>>>>>> module can record the incoming transfer identifier so it is able to use the
>>>>>>> correct response id when it passes back the fulfillment or error.
>>>>>>> The other properties that the ILP module should look at are the
>>>>>>> condition and expiry on the incoming transfer.
>>>>>>>
>>>>>>> If the incoming route uses conditional transfers and these are
>>>>>>> supposed to match the condition and expiry in the ILP packet then the ILP
>>>>>>> module should compare them and reject the packet if:
>>>>>>> a) the conditions don't match OR
>>>>>>> b) the expiry is too short
>>>>>>>
>>>>>>> We should still discuss if the expiry should be set by the sender
>>>>>>> and left unchanged or used like a TTL and decremented by each node.
>>>>>>>
>>>>>>>
>>>>>>>> Also, the receiver will need to take out the condition in order to
>>>>>>>> hash the packet for PSK or IPR.
>>>>>>>>
>>>>>>>
>>>>>>> This is completely normal. Zeroing a checksum field in a header
>>>>>>> before calculating the checksum is VERY common precisely because it's long
>>>>>>> been accepted that the right place to put that data is in the headers and
>>>>>>> the work of zero'ing it out to calculate the checksum (or signature in our
>>>>>>> case) is not material.
>>>>>>>
>>>>>>>
>>>>>>>> So basically, no one wants the condition in there. It feels like it
>>>>>>>> ought to be in there, but literally none of the parties want the extra 32
>>>>>>>> bytes in there.
>>>>>>>>
>>>>>>>
>>>>>>> "Nobody wants it there" is a terrible reason to abandon the correct
>>>>>>> design. The whole purpose of a good architecture is you accept that there
>>>>>>> may be cases in future that haven't been considered now so designing just
>>>>>>> for the known cases is a bad idea.
>>>>>>>
>>>>>>> Good architecture is not the same as optimization. Taking stuff out
>>>>>>> (even when it feels wrong) to save a few bytes is a good sign that it's a
>>>>>>> bad idea.
>>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> The reason the timeout should not be in there is that there isn't a
>>>>>>>> single timeout for the payment. There are multiple separate timeouts for
>>>>>>>> each of the bilateral transfers. Those must go in the individual transfers
>>>>>>>> and there is no sensible value to put in the Interledger packet.
>>>>>>>>
>>>>>>>
>>>>>>> As above, this is somewhat equivalent to the TTL in an IP packet.
>>>>>>> I'm open to discussing if it should be a fixed value set by the sender
>>>>>>> where each node uses their own value but has the sender-defined value as a
>>>>>>> reference or it is actually decremented at each hop.
>>>>>>>
>>>>>>> Either way, this is part of ILP not the ledger layer just like the
>>>>>>> condition and fulfillment. It may be used by the ledger layer but that's
>>>>>>> implementation specific. It belongs in the ILP packet.
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>> --
>>> Sent from a mobile device, please excuse any typos
>>>
>>
>>
>
Received on Friday, 18 August 2017 20:11:09 UTC

This archive was generated by hypermail 2.3.1 : Friday, 18 August 2017 20:11:10 UTC