- From: Andrew Bransford Brown <andrewbb@gmail.com>
- Date: Fri, 18 Aug 2017 16:13:55 -0400
- 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>
- Message-ID: <CAPS+YFLZyQfNayB7yAneO+DKuRJ-eQvfjZ7RBxb9s4xkjRw+1w@mail.gmail.com>
A standard up for review as part of NIST's Cybersecurity Framework: Only 3 commands are allowed to databases: Load, Store, and Delete. Proof of concept: http://systemdotpersistence.blogspot.com. Questions/comments welcome. On Fri, Aug 18, 2017 at 4:10 PM, Andrew Bransford Brown <andrewbb@gmail.com> wrote: > 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:14:21 UTC