From cjp at ultimatestunts.nl Thu Apr 7 20:21:53 2016 From: cjp at ultimatestunts.nl (CJP) Date: Thu, 07 Apr 2016 22:21:53 +0200 Subject: [Lightning-dev] Laundry list of inter-peer wire protocol changes In-Reply-To: <1454435768.2011.28.camel@ultimatestunts.nl> References: <87d1snvhyf.fsf@rustcorp.com.au> <1453923255.11915.36.camel@ultimatestunts.nl> <87mvrpru3e.fsf@rustcorp.com.au> <1454435768.2011.28.camel@ultimatestunts.nl> Message-ID: <1460060513.3590.39.camel@ultimatestunts.nl> CJP schreef op di 02-02-2016 om 18:56 [+0100]: > > > > * Reserving before locking: this is an optimization, to reduce the risk > > > of locking funds in payment channels on a part of the route, and then > > > having to undo the locking when it turns out that the remaining part of > > > the route doesn't exist (anymore). Reserving is an informal(*), > > > temporary locking of funds for use in the transaction, and can be done > > > and undone very fast, without any channel operations. It is done > > > together with route searching + establishment. > > > > I think that trades one DoS for another, though. It saves cryptographic > > constructs, but latency is the real cost, and this increases it. > > > > Of course, we'll have to revisit that if the network in practice proves > > subject to these problems... > > For one category of channel designs, reserving is absolutely essential: > channels where bi-directional payments are made possible with a > decrementing lock time. There, you want to make sure that failed routing > attempts don't cause lock time decrements, since that would reduce the > channel lifetime more than necessary. I'd have to check whether there is > still any use case for this channel design, and whether the reserving > step is important for some other reason. After actually implementing some of these things, I'd like to revisit this discussion. The "reserving" stage used to be important for channel types where the bi-directional nature of the channel is realized with decreasing lock times (see above). Now that a large part of the community has put its hope on Lightning, it's more likely that the extensions required for better channel types will be included in Bitcoin, so this issue has become less important. Another reason why the "reserving" stage is important, is that it it necessary for bi-directional routing. In order to make both payer and payee anonymous, we need to provide this feature, where both route to a meeting point. For the part between meeting point and payee, routing goes from payee to meeting point(*), but locking goes from meeting point to payee, so they can't be done in the same stage. Finally, the "reserving" stage allows you to set a tighter value on the HTLC time-outs. If you do routing together with locking, then routing has to go in the payer->payee direction; the time-out has to be reduced on every hop. Assuming(**) the payer doesn't know the number of hops in advance, the time-out has to be set to a very high value by the payer, to maximize chances of a successful transaction. If you do routing in the reverse direction (payee->payer), you can start with a very low time-out, and increment it on every hop. This will generally result in lower time-out values, which is desirable. That's about it, for the advantages offered by the separate reserving stage in Amiko Pay. Let me finish with an attempt to make an ASCII-art sequence diagram of reserving, bi-directional routing and locking in Amiko Pay: H(R) = the transaction hash (also included in other messages) MR() = MakeRoute message without time info MR(t) = MakeRoute message with time info HR() = HaveRoute message without time info HR(t) = HaveRoute message L(t) = Lock message (adds HTLC to channel) A = Alice (payer) B = Bob (meeting point) C = Carol (intermediate node). There can be many intermediate nodes between A and B, and between B and D. D = Dave (payee) A B C D |<------------------ H(R) --------------------| |------MR()---->| |<-MR(T0+dt)--| |<-MR(T0+2*dt)--| |<-HR(T0+3*dt)--|--HR(T0+2*dt)->| |--HR(T0+dt)->| |<------------------ HR() --------------------| |--L(T0+3*dt)-->|--L(T0+2*dt)-->|--L(T0+dt)-->| (...and then the sequence continues with removing the HTLCs and releasing funds towards payee-side of each channel.) CJP (*) It can't go in the other direction, since the meeting point should not know the identity (or network address) of the payee. (**) This is the case for non-source routing. One advantage of non-source routing is that nodes don't need a map of the entire network; this improves privacy, and could help to keep the network open to new participants, even against the will of many powerful existing participants. In the end, I imagine a system where a mix of source-routing and non-source routing can be used, to get the best of both worlds.