From rusty at rustcorp.com.au Tue Apr 20 21:19:24 2021 From: rusty at rustcorp.com.au (Rusty Russell) Date: Wed, 21 Apr 2021 06:49:24 +0930 Subject: [Lightning-dev] [RFC] Simplified (but less optimal) HTLC Negotiation In-Reply-To: <87pn559mtn.fsf@gmail.com> References: <87r1q3kod8.fsf@rustcorp.com.au> <87v9fez69y.fsf@gmail.com> <87o8l4fgmb.fsf@rustcorp.com.au> <87k0vrn7lc.fsf@gmail.com> <87blgwzcsf.fsf@rustcorp.com.au> <87pn559mtn.fsf@gmail.com> Message-ID: <87r1j4hcwz.fsf@rustcorp.com.au> Christian Decker writes: > Rusty Russell writes: >>> 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? > > So this would pretty much be a batch-ack, sent after a whole series of > changes were proposed to the leader, and referenced by their `htlc_id`, > correct? This is one optimization step further than what I was thinking, > but it can work. My proposal would have been to either reflect the whole > message (nodes need to remember proposals they've sent anyway in case of > disconnects, so matching incoming changes with the pending ones should > not be too hard), or send back individual acks, containing the hash of > the message if we want to safe on bytes transferred. Alternatively we > could also use reference the change by its htlc_id. [ Following up on an old thread ] After consideration, I prefer alternation. It fits better with the existing implementations, and it is more optimal than reflection for optimized implementations. In particular, you have a rule that says you can send updates and commitment_signed when it's not your turn, and the leader either responds with a "giving way" message, or ignores your changes and sends its own. A simple implementation *never* sends a commitment_signed until it receives "giving way" so it doesn't have to deal with orphaned commitments. A more complex implementation sends opportunistically and then has to remember that it's committed if it loses the race. Such an implementation is only slower than the current system if that race happens. I've been revisiting this because it makes things like splicing easier: the current draft requires stopping changes while splicing is being negotiated, which is not entirely trivial. With the simplified method, you don't have to wait at all. Cheers, Rusty.