From rusty at rustcorp.com.au Tue Oct 20 23:40:48 2020 From: rusty at rustcorp.com.au (Rusty Russell) Date: Wed, 21 Oct 2020 10:10:48 +1030 Subject: [Lightning-dev] [RFC] Simplified (but less optimal) HTLC Negotiation In-Reply-To: <87k0vrn7lc.fsf@gmail.com> References: <87r1q3kod8.fsf@rustcorp.com.au> <87v9fez69y.fsf@gmail.com> <87o8l4fgmb.fsf@rustcorp.com.au> <87k0vrn7lc.fsf@gmail.com> Message-ID: <87blgwzcsf.fsf@rustcorp.com.au> Christian Decker writes: >> And you don't get the benefit of the turn-taking approach, which is that >> you can have a known state for fee changes. Even if you change it to >> have opener always the leader, it still has to handle the case where >> incoming changes are not allowed under the new fee regime (and similar >> issues for other dynamic updates). > > Good point, I hadn't considered that a change from one side might become > invalid due to a change from the other side. I think however this can only > affect changes that result in other changes no longer being applicable, > e.g., changing the number of HTLCs you'll allow on a channel making the > HTLC we just added and whose update_add is still in flight invalid. To make dynamic changes in the current system, you need to make them the same way we make feechanges: first remote, then local (once they ack). This means you have to handle the cases where this causes the the commit tx to not meet the new restrictions. It's all possible, it's just messy. > I don't think fee changes are impacted here, since the non-leader only > applies the change to its commitment once it gets back its own change. > The leader will have inserted your update_add into its stream after the > fee update, and so you'll first apply the fee update, and then use the > correct fee to add the HTLC to your commitment, resulting in the same > state. Sure, but we still have the (existing) problem where you propose a fee change you can no longer afford, because the other side is also adding things. They can just refuse to reflect the fee in that case, though. > The remaining edgecases where changes can become invalid if they are in > flight, can be addressed by bouncing the change through the non-leader, > telling him that "hey, I'd like to propose this change, if you're good > with it send it back to me and I'll add it to my stream". This can be > seen as draining the queue of in-flight changes, however the non-leader > may pipeline its own changes after it and take the updated parameters > into consideration. Think of it as a two-phase commit, alerting the peer > with a proposal, before committing it by adding it to the stream. It > adds latency (about 1/2RTT over the token-passing approach since we can > emulate it with the token-passing approach) but these synchronization > points are rare and not on the critical path when forwarding payments. You can create a protocol to reject changes, but now we're more complex than the simply-alternate-leader approach. > With the leader-based approach, we add 1RTT latency to the updates from > one side, but the other never has to wait for the token, resulting in > 1/2RTT per direction as well, since messages are well-balanced. Good point. >> Yes, but it alternates because that's optimal for a non-busy channel >> (since it's usually "Alice adds htlc, Bob completes the htlc"). > > What's bothering me more about the turn-based approach is that while the > token is in flight, neither endpoint can make any progress, since the > one reliquishing the token promised not to say anything and the other > one hasn't gotten the token yet. This might result in rather a lot of > dead-air if both sides have a constant stream of changes to add. So we'd > likely have to add a timeout to defer giving up the token, to counter > dead-air, further adding delay to the changes from the other end, and > adding yet another parameter. I originally allowed optimistically sending commitment_signed. But it means there can be more than one commitment tx for any given height (you have to assume they received the sig and might broadcast it), which seemed to complicate things. OTOH this is only true if you choose to do this. > This is in stark contrast to the leader-based approach, where both > parties can just keep queuing updates without silent times to > transferring the token from one end to the other. You've swayed me, but it needs new wire msgs to indicate "these are your proposals I'm reflecting to you". OTOH they don't need to carry data, so we can probably just have: update_htlcs_ack: * [`channel_id`:`channel_id`] * [`u16`:`num_added`] * [`num_added*u64`:`added`] * [`u16`:`num_removed`] * [`num_removed*u64`:`removed`] update_fee can stay the same. Thoughts? Rusty.