Rusty Russell [ARCHIVE] on Nostr: 📅 Original date posted:2020-10-20 📝 Original message: Christian Decker ...
📅 Original date posted:2020-10-20
📝 Original message:
Christian Decker <decker.christian at gmail.com> 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.
📝 Original message:
Christian Decker <decker.christian at gmail.com> 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.