Anthony Towns [ARCHIVE] on Nostr: π Original date posted:2021-10-19 π Original message: On Wed, Oct 13, 2021 at ...
π
Original date posted:2021-10-19
π Original message:
On Wed, Oct 13, 2021 at 03:15:14PM +1100, Lloyd Fournier wrote:
> If you're willing to accept that "worst case" happening more often, I
> think you could then retain the low latency forwarding, by having the
> transaction structure be:
So the idea here is that we have two channel parameters:
PD - the payment delay or payment timeout delta, say 40 blocks
RD - the channel recovery delay, say 2016 blocks
and the idea is that if you publish an old state, I have the longer delay
(RD) to correct that; *but* if the currently active state includes a
payment that I've forwarded to you, I may only have the shorter delay
(PD) in order to forward the payment claim details back in order to
avoid being out of pocket.
The goal is to keep that working while also allowing me to tell you about
a payment to you in such a way that you can safely forward it on *without*
an additional round-trip back to me (to acknowledge that you've received
it and that I've received your acknowledgement).
It's not really a super-important goal; it could shave off 50% of
the time to accept a ln tx when everything goes right, and there's no
bottlenecks elsewhere in the implementation, but it can't do anything
more than that, and doesn't help the really slow cases when things go
wrong. Mostly, I just find it interesting.
Suppose that a payment is forwarded from Alice to Bob, Carol and finally
reaches Dave. Alice/Bob and Carol/Dave are both colocated in a data centre
and have high bandwidth and have 1ms (rtt) latency, but Bob/Carol are
on different continents (but not via tor) and have 100ms (rtt) latency.
With 1.5 round-trips before forwarding, we'd get:
t=0 Alice tells Bob
t=1.5 Bob tells Carol
t=151.5 Carol tells Dave
t=153 Dave reveals the secret to Carol
t=153.5 Carol reveals the secret to Bob
t=203.5 Bob reveals the secret to Alice
t=204 Alice knows the secret!
That's how things work now, with "X tells Y" being:
X->Y: update_add_htlc, commitment_signed
Y->X: commitment_signed, revoke_and_ack
X->Y: revoke_and_ack
and "X reveals the secret to Y" being:
X->Y: update_fulfill_htlc
However, if we could do it optimally we would have:
t=0 Alice tells Bob about the payment
t=0.5 Bob tells Carol about the payment
t=50.5 Carol tells Dave about the payment
t=51 Dave accepts the payment and tells Carol the secret
t=51.5 Carol accepts the payment and tells Bob the secret
t=101.5 Bob accepts the payment and tells Alice the secret
t=102 Alice knows the secret!
Looking just at Bob/Carol we might also have the underlying commitment
state updates:
t=50.5 Carol acks the payment to Bob (commitment_signed,
revoke_and_ack)
t=100.5 Bob acks Carol's ack, revoking old state (revoke_and_ack)
t=150.5 Carol's safe with the new state including the payment
t=51.5 Carol reveals the secret and signs a new updated state
(update_fulfill_htlc, commitmnt_signed)
t=101.5 Bob acks receipt of the secret (commitment_signed,
revoke_and_ack)
t=151.5 Carol's safe with the new state with an increased balance
(revoke_and_ack)
t=201.5 Bob's state is up to date
Note that the first of those doesn't complete until well after Alice
would know the secret in an optimal construction; and that as described
the second upate overlaps the first, which might not be particularly
desirable.
> In my mind your "update the base channel state" idea seems to fix everything by
> itself.
Yeah -- if you're willing to do 1.5 round-trips (and thanks to musig2 this
doesn't blow out to 2.5 (?) round-trips) that does solve everything. The
challenge is to do it in 0.5 round-trips. :)
> So at T - to_self_delay (or a bit before) you say to your counterparty
> "can we lift this HTLC out of your in-flight tx into the 'balance tx' (which
> will go back to naming a 'commitment tx' since it doesn't just have balance
> outputs anymore) so I can use it too? -- otherwise I'll have to close the
> channel on chain now to force you to reveal it to me on time?". If they agree,
> after the revocation and new commit tx everything is back to (tx symmetric)
> Poon-Dryja so no need for extra CSVs.
Maybe? So the idea is that:
1) Bob gets a "low-latency" tx that spends Alice's balance and has a
bunch of outputs for really recent payments
2) In normal conditions, in 5 or 10 or 30 seconds, Alice/Bob renegotiate
the base commitment to move those payments out of the "low-latency"
tx
3) In abnormal conditions, with an active forwarded "low-latency" tx and
communications failure of length up to "PD", Alice closes the channel
on chain.
4) Bob then has "PD" period to post the "low-latency" tx, if he
doesn't, Alice can do a layered claim of her balance preventing Bob
from oing so.
5) If Bob does post his "low-latency" tx, then he'll also need to reveal
secrets prior to the payment timeout.
So taking the payment timeout as T, then he'll have to post the
low-latency tx (4) and reveal the secret (5) no later than T, which
means he'll be upset if Alice drops to the chain later than T-PD, and
Alice won't do that unless comms failure begins at T-2*PD.
That means that:
* Alice should not propose and Bob should not accept a low-latency
payment if T < now+2*PD
* Alice should drop the commitment tx on-chain no later than T-PD,
Bob should drop the commitment and low-latency txs on chain prior
to T (Alice to ensure she can timeout any payments, Bob to ensure
he can claim any payments prior to Alice timing them out)
* Alice should reserve her balance asap (at time T) if Bob does not
post the low-latency transaction
* ... and not much else?
> I realise this kills some of the elegance of your original protocol and adds
> quite a bit of complexity but I think it retains the important properties.
I think the only complexity it actually adds is that Alice needs to
be able to prevent Bob from posting the "low-latency" tx if he doesn't
react within "PD" -- which is just a signature from Bob allowing her to
spend the output with nSequence set to "PD"?
Since it's putting payments back into the commitment tx, it also makes
it more separable -- you could stick it behind a feature bit so nodes
can just not implement low-latency payments, particularly if they're
not usually forwarding payments, or are only connected to nearby nodes
anyway...
(I don't think that approach works for "offline" peers, though, because
they'd need to be able to post the low-latency tx within the "PD" delay,
and can't do that because they're offline)
Cheers,
aj
π Original message:
On Wed, Oct 13, 2021 at 03:15:14PM +1100, Lloyd Fournier wrote:
> If you're willing to accept that "worst case" happening more often, I
> think you could then retain the low latency forwarding, by having the
> transaction structure be:
So the idea here is that we have two channel parameters:
PD - the payment delay or payment timeout delta, say 40 blocks
RD - the channel recovery delay, say 2016 blocks
and the idea is that if you publish an old state, I have the longer delay
(RD) to correct that; *but* if the currently active state includes a
payment that I've forwarded to you, I may only have the shorter delay
(PD) in order to forward the payment claim details back in order to
avoid being out of pocket.
The goal is to keep that working while also allowing me to tell you about
a payment to you in such a way that you can safely forward it on *without*
an additional round-trip back to me (to acknowledge that you've received
it and that I've received your acknowledgement).
It's not really a super-important goal; it could shave off 50% of
the time to accept a ln tx when everything goes right, and there's no
bottlenecks elsewhere in the implementation, but it can't do anything
more than that, and doesn't help the really slow cases when things go
wrong. Mostly, I just find it interesting.
Suppose that a payment is forwarded from Alice to Bob, Carol and finally
reaches Dave. Alice/Bob and Carol/Dave are both colocated in a data centre
and have high bandwidth and have 1ms (rtt) latency, but Bob/Carol are
on different continents (but not via tor) and have 100ms (rtt) latency.
With 1.5 round-trips before forwarding, we'd get:
t=0 Alice tells Bob
t=1.5 Bob tells Carol
t=151.5 Carol tells Dave
t=153 Dave reveals the secret to Carol
t=153.5 Carol reveals the secret to Bob
t=203.5 Bob reveals the secret to Alice
t=204 Alice knows the secret!
That's how things work now, with "X tells Y" being:
X->Y: update_add_htlc, commitment_signed
Y->X: commitment_signed, revoke_and_ack
X->Y: revoke_and_ack
and "X reveals the secret to Y" being:
X->Y: update_fulfill_htlc
However, if we could do it optimally we would have:
t=0 Alice tells Bob about the payment
t=0.5 Bob tells Carol about the payment
t=50.5 Carol tells Dave about the payment
t=51 Dave accepts the payment and tells Carol the secret
t=51.5 Carol accepts the payment and tells Bob the secret
t=101.5 Bob accepts the payment and tells Alice the secret
t=102 Alice knows the secret!
Looking just at Bob/Carol we might also have the underlying commitment
state updates:
t=50.5 Carol acks the payment to Bob (commitment_signed,
revoke_and_ack)
t=100.5 Bob acks Carol's ack, revoking old state (revoke_and_ack)
t=150.5 Carol's safe with the new state including the payment
t=51.5 Carol reveals the secret and signs a new updated state
(update_fulfill_htlc, commitmnt_signed)
t=101.5 Bob acks receipt of the secret (commitment_signed,
revoke_and_ack)
t=151.5 Carol's safe with the new state with an increased balance
(revoke_and_ack)
t=201.5 Bob's state is up to date
Note that the first of those doesn't complete until well after Alice
would know the secret in an optimal construction; and that as described
the second upate overlaps the first, which might not be particularly
desirable.
> In my mind your "update the base channel state" idea seems to fix everything by
> itself.
Yeah -- if you're willing to do 1.5 round-trips (and thanks to musig2 this
doesn't blow out to 2.5 (?) round-trips) that does solve everything. The
challenge is to do it in 0.5 round-trips. :)
> So at T - to_self_delay (or a bit before) you say to your counterparty
> "can we lift this HTLC out of your in-flight tx into the 'balance tx' (which
> will go back to naming a 'commitment tx' since it doesn't just have balance
> outputs anymore) so I can use it too? -- otherwise I'll have to close the
> channel on chain now to force you to reveal it to me on time?". If they agree,
> after the revocation and new commit tx everything is back to (tx symmetric)
> Poon-Dryja so no need for extra CSVs.
Maybe? So the idea is that:
1) Bob gets a "low-latency" tx that spends Alice's balance and has a
bunch of outputs for really recent payments
2) In normal conditions, in 5 or 10 or 30 seconds, Alice/Bob renegotiate
the base commitment to move those payments out of the "low-latency"
tx
3) In abnormal conditions, with an active forwarded "low-latency" tx and
communications failure of length up to "PD", Alice closes the channel
on chain.
4) Bob then has "PD" period to post the "low-latency" tx, if he
doesn't, Alice can do a layered claim of her balance preventing Bob
from oing so.
5) If Bob does post his "low-latency" tx, then he'll also need to reveal
secrets prior to the payment timeout.
So taking the payment timeout as T, then he'll have to post the
low-latency tx (4) and reveal the secret (5) no later than T, which
means he'll be upset if Alice drops to the chain later than T-PD, and
Alice won't do that unless comms failure begins at T-2*PD.
That means that:
* Alice should not propose and Bob should not accept a low-latency
payment if T < now+2*PD
* Alice should drop the commitment tx on-chain no later than T-PD,
Bob should drop the commitment and low-latency txs on chain prior
to T (Alice to ensure she can timeout any payments, Bob to ensure
he can claim any payments prior to Alice timing them out)
* Alice should reserve her balance asap (at time T) if Bob does not
post the low-latency transaction
* ... and not much else?
> I realise this kills some of the elegance of your original protocol and adds
> quite a bit of complexity but I think it retains the important properties.
I think the only complexity it actually adds is that Alice needs to
be able to prevent Bob from posting the "low-latency" tx if he doesn't
react within "PD" -- which is just a signature from Bob allowing her to
spend the output with nSequence set to "PD"?
Since it's putting payments back into the commitment tx, it also makes
it more separable -- you could stick it behind a feature bit so nodes
can just not implement low-latency payments, particularly if they're
not usually forwarding payments, or are only connected to nearby nodes
anyway...
(I don't think that approach works for "offline" peers, though, because
they'd need to be able to post the low-latency tx within the "PD" delay,
and can't do that because they're offline)
Cheers,
aj