jlspc [ARCHIVE] on Nostr: 📅 Original date posted:2023-04-28 📝 Original message: Replies inline: > > > One ...
📅 Original date posted:2023-04-28
📝 Original message:
Replies inline:
> > > One thing that confuses me about the paper is how to think about routing
> > > to a "channel" rather than a node -- ie the payment from "E->FG->A" where
> > > "FG" isn't "F" or "G", but "both of them".
> > Yes, I found it very difficult to think about, and I kept getting confused between concepts like "user", "node", "channel", and "factory".
> > The thing that works best for me is to create a clear definition of each of these terms, along with the term "party".
> Okay, that makes sense. I think it might work better to treat "node" as
> synonymous with "user" rather than "party" though -- that way you can say
> "you create a lightning node by running lightning node software such as
> lnd/cln/eclair/etc". That means not all vertices in the payment routing
> network are nodes; but all vertices in the *gossip* network are nodes,
> so that seems okay.
Yes, it's probably best to refer to a user who runs lightning node software as being a "node".
On the other hand, it sounds really awkward to talk about routing in a directed graph without using the word "node" in some form. Maybe "routing node" for entities in the routing network?
> (I'm not sure "channel factories" is really the most evocative way of
> describing them -- at least when I think of a factory, I think the product
> should be accessible to everyone; but for channel factories you have to
> be involved in the factory's original mutlisig to be able to use one of
> its channels. Maybe better to call them "channel coops", where you're
> creating a little commune of friends/allies to work together with each
> other. Could be pronounced like "workers' co-op" or like "chicken coop",
> either way :)
Good point regarding "factories". I like "channel co-op" as an alternative.
> > * Logical Channel: a layer 2 construct that consists of all of the physical channels owned by a specific pair of parties
> > - the size (capacity) of a logical channel is the sum of the sizes of their physical channels
> > - (Footnote: It's possible, with a significant amount of software development work that I in no way discount, to route a payment through a logical channel where the payment traverses multiple physical channels at the same time. This is done by using separate HTLCs, all sharing the same secret, in each of the physical channels that the payment traverses. I can write more about this if that would be helpful.)
> I think it might already be interesting to write a BOLT/BLIP for that?
> Having a single channel backed by multiple on-chain utxos is probably
> interesting for splicing (adding or spending a utxo while keeping the
> channel open on the other utxos might be able to be done more simply than
> splicing in general), and having multiple utxos might let you increase
> some of your channel limits, eg `max_accepted_htlcs` might be able to
> be increased to 483*U where U is the number of UTXOs backing the channel.
Sounds good. I'm glad to write something up, but I'm afraid it may take me a few months.
> > > It feels like there's a whole
> > > mass of complications hidden in there from a routing perspective; like how
> > > do you link "FG" back with "F" and "G", how do you decide fees, how do
> > > you communicate fees/max_htlc/etc.
> > Regarding the specific issues you raised:
> > Q: How do you link "FG" back with "F" and "G"?
> > A: In terms of gossiping and the channel graph, you don't
> Yeah, I think that simplifies things substantially.
> I think the main thing that misled me here was the "CD->E->FG" payment
> chain -- it doesn't make sense to me why E would want to devote funds
> that can only be used for rebalancing channels, but not normal payments.
Actually, E's funds in the channels ((C,D),E) and (E,(F,G)) can be used for normal payments. It might not seem attractive to do so, but there may be reasons for doing just that (see below).
> Having that be CD->DE->FG seems like it would make much more sense in that
> model. (Though, obviously, no one except D and E could necessarily tell
> the difference between those two scenarios in practice, and just because
> something doesn't make sense, doesn't mean nobody will actually do it)
I included going from a single-user party to a multi-user party and back to a single-user party, as in E->FG->HI->A in Figure 4 in the paper, just to show the poassibility. I didn't think it would be common, given the extra signatures and fees required. However, I'm now thinking that routing through multi-user parties could be important in practice, even when making normal LN payments between single users. There's a lot more on that idea below.
> The other thing was that going from N nodes to C*N channels, then
> re-considering each of the C*N channels (A->B, etc) as also potentially
> being nodes and adding an additional K*C*N channels (AB->CD, etc) seemed
> like it might be quadratic to me. But it's probably not -- C (channels per
> node) and K (utxos per channel) are probably constant or logarithmic in
> N, so it's probably okay?
Yep, I'd assume C and K are largely independent of N (and constant or nearly so as the network grows), so that shouldn't be a problem.
> On the other hand, I could see the rebalancing channels not actually
> being very useful for routing payments (they require 3+ signatures,
> and may not even be publicly connected to any of the level-1 nodes),
> so it could make sense to just treat them as two different networks,
> where regular people doing payments only see the base channels, but
> high-availability nodes also find out about the rebalancing channels.
> If so, then the extra nodes/channels in the rebalancing graph only affect
> people who can afford to dedicate the resources to storing it anyway,
> so it's probably fine.
It would be possible to have a separate rebalancing network consisting of multi-user parties only and a base network consisting of single-user parties only. However, that both complicates and limits the rebalancing functionality.
Let's say A and B want to decrease the size of their channel (A,B) using the separate rebalancing network.
They make a payment on the rebalancing network:
AB->CD->EF->GH->IJ
However, there are two problems with this approach:
1) A and B have to find another channel (I,J) that wants to increase its capacity by exactly the same amount (minus fees) to offset the decrease in (A,B). In general, the rebalancing network can move capacity from one base channel (a.k.a., two-user channel or channel with single-user parties) to another one, but it can't increase or decrease the overall capacity of the channels in the base network.
2) The payment AB->CD->EF->IJ not only rebalances channels, it also sends bitcoin from the payer in (A,B) to the payee in (I,J). This would have to be offset by making a corresponding payment (using the base network) from the payee in (I,J) (e.g., I) to the payer in (A,B) (e.g., A) and that offsetting payment would have to be atomic with the rebalancing payment. It's possible to make this work by using the same secret for the payments in the base network and the rebalancing network, but it certainly adds complexity.
In addition, there are reasons for wanting to include multi-user parties when making regular LN payments (again, see below).
Connecting the level-2 routing nodes with the level-1 routing nodes requires at least some channels that consist of a multi-user party and a single-user party, such as the channel ((C,D),E). Once that's done, the above problems go away and it's possible to increase or decrease the overall capacity of the two-user channels without going on-chain.
> > Finally, I realize that creating a world without factories doesn't sound like a good solution for scaling Bitcoin. However, I believe hierarchical channels largely solve the problem of resizing channels off-chain.
> I think this is probably a lot harder in practice than in theory? If
> you have an {A,B} channel holding 3 BTC across two hierarchial channels,
> {X:1 BTC, AB:1 BTC} and {Y:1 BTC, AB:2 BTC}, and someone wants to route
> 0.5 BTC through X->AB->Y, then that will look something like:
> {X:1, AB:1} {AB:2, Y:1}
> {X:0.5, XAB:0.5, AB:1} {AB:2, Y:1}
> {X:0.5, XAB:0.5, AB:1} {AB:1.5, ABY:0.5 Y:1}
> and either:
> {X:1, AB:1} {AB:2, Y:1} (on failure)
> or
> {X:0.5, AB:1.5} {AB:1.5, Y:1.5} (on success)
> But what if you're in the middle of routing 2 BTC over the A,B channel
> in the meantime? In that case you need some of the AB payments to be
> conditional on the success path of XAB and the failure path of ABY.
> I *think* that's fine, and doesn't involve a combinatorical blowup in
> the event that you're routing rebalances across multiple off-chain utxos
> -- you just end up splitting your channel across {X+2*Y} utxos where X
> is the number of "physical" channels and "Y" is the number of pending
> rebalances. But it seems like there's a fair chunk of complexity and
> maybe some extra round trips (eg, moving a pending HTLC from being
> purely in the AB:2 output to being split across the {XAB:0.5/success and
> ABY:0.5/timeout} atomically seems tricky?).
Wow, that's a cool idea!
I hadn't considered having an active HTLC (sending 2 BTC from A to B) that's (partially) funded by a pair of active HTLCs (sending 0.5 BTC from X to Y via the path X->AB->Y). I figured that would be too complex, but I hadn't thought through the details.
In contrast, I had considered having an active HTLC that's funded by a resolved (either successful or failed) HTLC. This seems important, as the resolved HTLC requires 3+ signatures in order to merge it into a new Commitment transaction, so it might not be possible to get all the signatures right away. For example, dedicated users A and B want to be able to use their newly-gained capacity in the channel (C,(A,B)) after making a payment from casual user C without having to wait for C to update the state of (C,(A,B)).
The hierarchical channels paper requires that all the funds in an HTLC be provided by a single user, denoted as the "payer". As a result, the capital in a hierarchical channel can only be used for a single active HTLC at a single level at a time. This requires multiplexing the capital between level-1 channel HTLCs and level-2 channel HTLCs, but I figured that was OK as the level-2 channels would mainly be used for rebalancing, which should be far less frequent than level-1 payments (and the rebalancing could wait until a path was available). Thus, one doesn't have to allow an active HTLC to be funded by a pair of active HTLCs in order to have flexible off-chain rebalancing of channels.
However, as you point out, it should be possible to have an active HTLC be funded by a pair of active HTLCs. The thing that's amazing about this is that the *same capital* is used for routing at two different levels in the hierarchy simultaneously! In other words, in addition to routing normal LN payments through single-user parties, it's possible to simultaneously route independent normal LN payments through multi-user parties by re-using the *same capital*.
Sure, the payments through multi-user parties require more signatures, so that could slow them down or complicate them, but the potential to maybe double the routing fees that can be generated from a given unit of capital (in addition to enabling off-chain rebalancing) sounds pretty compelling if the cost of capital is high.
As you noted, making this work atomically is tricky. Let's consider your example again, using slightly modified notation.
Initially, there's an {A,B} channel holding 3 BTC across two hierarchical channels:
State 0:
{X:1 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{A:2 BTC, B:0 BTC}, Y:1 BTC}
First, A initiates a payment of 2 BTC with secret s1 via B in the hierarchical channel with Y:
State 1:
{X:1 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:2 BTC}, Y:1 BTC}
Then, while this payment is pending, X sends 0.5 BTC with secret s2 to Y via the following states:
State 2:
{X:0.5 BTC, X_or_s2_{A_or_s1_B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:2 BTC}, Y:1 BTC}
State 3:
{X:0.5 BTC, X_or_s2_{A_or_s1_B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:1.5 BTC}, {A_or_s1_B:0.5 BTC}_or_s2_Y:0.5 BTC, Y:1 BTC}
>From this point, there are 8 possibilities in terms of whether the HTLCs succeed or fail, and in which order they do so.
For example, if s1 is revealed and then the payment with secret s2 times out, we get:
State 4:
{X:0.5 BTC, X_or_s2_{B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{B:1.5 BTC}, {B:0.5 BTC}_or_s2_Y:0.5 BTC, Y:1 BTC}
State 5:
{X:0.5 BTC, X:0.5 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{B:1.5 BTC}, {B:0.5 BTC}, Y:1 BTC}
State 6:
{X:1.0 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{A:0 BTC, B:2.0 BTC}, Y:1 BTC}
Alternatively, if s2 is revealed and then s1 is revealed, we get:
State 4':
{X:0.5 BTC, {A_or_s1_B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:1.5 BTC}, Y:0.5 BTC, Y:1 BTC}
State 5':
{X:0.5 BTC, {B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{B:1.5 BTC}, Y:0.5 BTC, Y:1 BTC}
State 6':
{X:0.5 BTC, {A:0.5 BTC, B:1 BTC}}
and
{{A:0 BTC, B:1.5 BTC}, Y:1.5 BTC}
The trickiest step is defining State 2. When A and B get the HTCL offered by X with secret s2, A and B figure out what they're going to give up in the hierarchical channel with Y in case the payment from X succeeds. Given that all of A's and B's capital in {{A_or_s1_B:2 BTC}, Y:1 BTC} is in the HTLC with secret s1, they take 0.5 BTC of that HTLC and add it as the payout from secret s2 in the channel with X to obtain State 2. Then, they update the channel with Y to obtain State 3.
This seems to address the atomicity issue. However, there are a couple other details to address in the hierarchical channel protocol.
First, in the adaptation of the FFO protocol to hierarchical channels, the "payee" for an HTLC is the user that must provide the HTLC's secret with an HTLC-kickoff transaction (see Figure 14 in the paper). However, when the HTLC pays to a lower-level HTLC, there is no single "payee" that can be determined. This could be addressed by enabling both users that could be payees to reveal the HTLC's secret with an HTLC-kickoff transaction followed by an HTLC-success transaction (note that this doubles the number of HTLC-payment transactions that are required).
Second, in going from HTLCs to PTLCs, the payee has to create a secret that's subtracted from the secret that's revealed at the payment's next hop. The challenge is how to define a secret that depends on multiple potential payees' secrets. I think it may be possible to solve this by having all potential payees at hop i create their own secret, define the overall secret at hop i as being the sum of the potential payees' secrets (after protecting against key/secret cancellation), and sharing partial signatures between potential payees at hop i such that each potential payee just needs to get hop (i+1)'s secret in order to produce hop (i)'s overall secret, but I haven't worked through the details.
To be clear, the idea of having an active HTLC that's funded by a pair of active HTLCs is your idea, and it's very interesting. We don't need to support this in order to resize channels off-chain, but it does allow a given unit of capital to facilitate two independent payments simultaneously, which is amazing!
> (I figure implementing something eltoo-like via 2-user tunable penalty
> channels and/or ln-symmetry (let alone splicing, taproot funding
> addresses, and ptlcs) is a sufficient sink for all the available
> engineering effort any time soon, but talking about hierarchial/factory
> things well in advance of when they could reasonably be implemented is
> fun too)
That makes sense.
I'm also hoping that a good understanding of what's possible without changing Bitcoin, plus what's enabled with changes like CTV and/or APO, will help inform any future changes to Bitcoin's consensus rules.
Regards,
John
📝 Original message:
Replies inline:
> > > One thing that confuses me about the paper is how to think about routing
> > > to a "channel" rather than a node -- ie the payment from "E->FG->A" where
> > > "FG" isn't "F" or "G", but "both of them".
> > Yes, I found it very difficult to think about, and I kept getting confused between concepts like "user", "node", "channel", and "factory".
> > The thing that works best for me is to create a clear definition of each of these terms, along with the term "party".
> Okay, that makes sense. I think it might work better to treat "node" as
> synonymous with "user" rather than "party" though -- that way you can say
> "you create a lightning node by running lightning node software such as
> lnd/cln/eclair/etc". That means not all vertices in the payment routing
> network are nodes; but all vertices in the *gossip* network are nodes,
> so that seems okay.
Yes, it's probably best to refer to a user who runs lightning node software as being a "node".
On the other hand, it sounds really awkward to talk about routing in a directed graph without using the word "node" in some form. Maybe "routing node" for entities in the routing network?
> (I'm not sure "channel factories" is really the most evocative way of
> describing them -- at least when I think of a factory, I think the product
> should be accessible to everyone; but for channel factories you have to
> be involved in the factory's original mutlisig to be able to use one of
> its channels. Maybe better to call them "channel coops", where you're
> creating a little commune of friends/allies to work together with each
> other. Could be pronounced like "workers' co-op" or like "chicken coop",
> either way :)
Good point regarding "factories". I like "channel co-op" as an alternative.
> > * Logical Channel: a layer 2 construct that consists of all of the physical channels owned by a specific pair of parties
> > - the size (capacity) of a logical channel is the sum of the sizes of their physical channels
> > - (Footnote: It's possible, with a significant amount of software development work that I in no way discount, to route a payment through a logical channel where the payment traverses multiple physical channels at the same time. This is done by using separate HTLCs, all sharing the same secret, in each of the physical channels that the payment traverses. I can write more about this if that would be helpful.)
> I think it might already be interesting to write a BOLT/BLIP for that?
> Having a single channel backed by multiple on-chain utxos is probably
> interesting for splicing (adding or spending a utxo while keeping the
> channel open on the other utxos might be able to be done more simply than
> splicing in general), and having multiple utxos might let you increase
> some of your channel limits, eg `max_accepted_htlcs` might be able to
> be increased to 483*U where U is the number of UTXOs backing the channel.
Sounds good. I'm glad to write something up, but I'm afraid it may take me a few months.
> > > It feels like there's a whole
> > > mass of complications hidden in there from a routing perspective; like how
> > > do you link "FG" back with "F" and "G", how do you decide fees, how do
> > > you communicate fees/max_htlc/etc.
> > Regarding the specific issues you raised:
> > Q: How do you link "FG" back with "F" and "G"?
> > A: In terms of gossiping and the channel graph, you don't
> Yeah, I think that simplifies things substantially.
> I think the main thing that misled me here was the "CD->E->FG" payment
> chain -- it doesn't make sense to me why E would want to devote funds
> that can only be used for rebalancing channels, but not normal payments.
Actually, E's funds in the channels ((C,D),E) and (E,(F,G)) can be used for normal payments. It might not seem attractive to do so, but there may be reasons for doing just that (see below).
> Having that be CD->DE->FG seems like it would make much more sense in that
> model. (Though, obviously, no one except D and E could necessarily tell
> the difference between those two scenarios in practice, and just because
> something doesn't make sense, doesn't mean nobody will actually do it)
I included going from a single-user party to a multi-user party and back to a single-user party, as in E->FG->HI->A in Figure 4 in the paper, just to show the poassibility. I didn't think it would be common, given the extra signatures and fees required. However, I'm now thinking that routing through multi-user parties could be important in practice, even when making normal LN payments between single users. There's a lot more on that idea below.
> The other thing was that going from N nodes to C*N channels, then
> re-considering each of the C*N channels (A->B, etc) as also potentially
> being nodes and adding an additional K*C*N channels (AB->CD, etc) seemed
> like it might be quadratic to me. But it's probably not -- C (channels per
> node) and K (utxos per channel) are probably constant or logarithmic in
> N, so it's probably okay?
Yep, I'd assume C and K are largely independent of N (and constant or nearly so as the network grows), so that shouldn't be a problem.
> On the other hand, I could see the rebalancing channels not actually
> being very useful for routing payments (they require 3+ signatures,
> and may not even be publicly connected to any of the level-1 nodes),
> so it could make sense to just treat them as two different networks,
> where regular people doing payments only see the base channels, but
> high-availability nodes also find out about the rebalancing channels.
> If so, then the extra nodes/channels in the rebalancing graph only affect
> people who can afford to dedicate the resources to storing it anyway,
> so it's probably fine.
It would be possible to have a separate rebalancing network consisting of multi-user parties only and a base network consisting of single-user parties only. However, that both complicates and limits the rebalancing functionality.
Let's say A and B want to decrease the size of their channel (A,B) using the separate rebalancing network.
They make a payment on the rebalancing network:
AB->CD->EF->GH->IJ
However, there are two problems with this approach:
1) A and B have to find another channel (I,J) that wants to increase its capacity by exactly the same amount (minus fees) to offset the decrease in (A,B). In general, the rebalancing network can move capacity from one base channel (a.k.a., two-user channel or channel with single-user parties) to another one, but it can't increase or decrease the overall capacity of the channels in the base network.
2) The payment AB->CD->EF->IJ not only rebalances channels, it also sends bitcoin from the payer in (A,B) to the payee in (I,J). This would have to be offset by making a corresponding payment (using the base network) from the payee in (I,J) (e.g., I) to the payer in (A,B) (e.g., A) and that offsetting payment would have to be atomic with the rebalancing payment. It's possible to make this work by using the same secret for the payments in the base network and the rebalancing network, but it certainly adds complexity.
In addition, there are reasons for wanting to include multi-user parties when making regular LN payments (again, see below).
Connecting the level-2 routing nodes with the level-1 routing nodes requires at least some channels that consist of a multi-user party and a single-user party, such as the channel ((C,D),E). Once that's done, the above problems go away and it's possible to increase or decrease the overall capacity of the two-user channels without going on-chain.
> > Finally, I realize that creating a world without factories doesn't sound like a good solution for scaling Bitcoin. However, I believe hierarchical channels largely solve the problem of resizing channels off-chain.
> I think this is probably a lot harder in practice than in theory? If
> you have an {A,B} channel holding 3 BTC across two hierarchial channels,
> {X:1 BTC, AB:1 BTC} and {Y:1 BTC, AB:2 BTC}, and someone wants to route
> 0.5 BTC through X->AB->Y, then that will look something like:
> {X:1, AB:1} {AB:2, Y:1}
> {X:0.5, XAB:0.5, AB:1} {AB:2, Y:1}
> {X:0.5, XAB:0.5, AB:1} {AB:1.5, ABY:0.5 Y:1}
> and either:
> {X:1, AB:1} {AB:2, Y:1} (on failure)
> or
> {X:0.5, AB:1.5} {AB:1.5, Y:1.5} (on success)
> But what if you're in the middle of routing 2 BTC over the A,B channel
> in the meantime? In that case you need some of the AB payments to be
> conditional on the success path of XAB and the failure path of ABY.
> I *think* that's fine, and doesn't involve a combinatorical blowup in
> the event that you're routing rebalances across multiple off-chain utxos
> -- you just end up splitting your channel across {X+2*Y} utxos where X
> is the number of "physical" channels and "Y" is the number of pending
> rebalances. But it seems like there's a fair chunk of complexity and
> maybe some extra round trips (eg, moving a pending HTLC from being
> purely in the AB:2 output to being split across the {XAB:0.5/success and
> ABY:0.5/timeout} atomically seems tricky?).
Wow, that's a cool idea!
I hadn't considered having an active HTLC (sending 2 BTC from A to B) that's (partially) funded by a pair of active HTLCs (sending 0.5 BTC from X to Y via the path X->AB->Y). I figured that would be too complex, but I hadn't thought through the details.
In contrast, I had considered having an active HTLC that's funded by a resolved (either successful or failed) HTLC. This seems important, as the resolved HTLC requires 3+ signatures in order to merge it into a new Commitment transaction, so it might not be possible to get all the signatures right away. For example, dedicated users A and B want to be able to use their newly-gained capacity in the channel (C,(A,B)) after making a payment from casual user C without having to wait for C to update the state of (C,(A,B)).
The hierarchical channels paper requires that all the funds in an HTLC be provided by a single user, denoted as the "payer". As a result, the capital in a hierarchical channel can only be used for a single active HTLC at a single level at a time. This requires multiplexing the capital between level-1 channel HTLCs and level-2 channel HTLCs, but I figured that was OK as the level-2 channels would mainly be used for rebalancing, which should be far less frequent than level-1 payments (and the rebalancing could wait until a path was available). Thus, one doesn't have to allow an active HTLC to be funded by a pair of active HTLCs in order to have flexible off-chain rebalancing of channels.
However, as you point out, it should be possible to have an active HTLC be funded by a pair of active HTLCs. The thing that's amazing about this is that the *same capital* is used for routing at two different levels in the hierarchy simultaneously! In other words, in addition to routing normal LN payments through single-user parties, it's possible to simultaneously route independent normal LN payments through multi-user parties by re-using the *same capital*.
Sure, the payments through multi-user parties require more signatures, so that could slow them down or complicate them, but the potential to maybe double the routing fees that can be generated from a given unit of capital (in addition to enabling off-chain rebalancing) sounds pretty compelling if the cost of capital is high.
As you noted, making this work atomically is tricky. Let's consider your example again, using slightly modified notation.
Initially, there's an {A,B} channel holding 3 BTC across two hierarchical channels:
State 0:
{X:1 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{A:2 BTC, B:0 BTC}, Y:1 BTC}
First, A initiates a payment of 2 BTC with secret s1 via B in the hierarchical channel with Y:
State 1:
{X:1 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:2 BTC}, Y:1 BTC}
Then, while this payment is pending, X sends 0.5 BTC with secret s2 to Y via the following states:
State 2:
{X:0.5 BTC, X_or_s2_{A_or_s1_B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:2 BTC}, Y:1 BTC}
State 3:
{X:0.5 BTC, X_or_s2_{A_or_s1_B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:1.5 BTC}, {A_or_s1_B:0.5 BTC}_or_s2_Y:0.5 BTC, Y:1 BTC}
>From this point, there are 8 possibilities in terms of whether the HTLCs succeed or fail, and in which order they do so.
For example, if s1 is revealed and then the payment with secret s2 times out, we get:
State 4:
{X:0.5 BTC, X_or_s2_{B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{B:1.5 BTC}, {B:0.5 BTC}_or_s2_Y:0.5 BTC, Y:1 BTC}
State 5:
{X:0.5 BTC, X:0.5 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{B:1.5 BTC}, {B:0.5 BTC}, Y:1 BTC}
State 6:
{X:1.0 BTC, {A:0.5 BTC, B:0.5 BTC}}
and
{{A:0 BTC, B:2.0 BTC}, Y:1 BTC}
Alternatively, if s2 is revealed and then s1 is revealed, we get:
State 4':
{X:0.5 BTC, {A_or_s1_B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{A_or_s1_B:1.5 BTC}, Y:0.5 BTC, Y:1 BTC}
State 5':
{X:0.5 BTC, {B:0.5 BTC}, {A:0.5 BTC, B:0.5 BTC}}
and
{{B:1.5 BTC}, Y:0.5 BTC, Y:1 BTC}
State 6':
{X:0.5 BTC, {A:0.5 BTC, B:1 BTC}}
and
{{A:0 BTC, B:1.5 BTC}, Y:1.5 BTC}
The trickiest step is defining State 2. When A and B get the HTCL offered by X with secret s2, A and B figure out what they're going to give up in the hierarchical channel with Y in case the payment from X succeeds. Given that all of A's and B's capital in {{A_or_s1_B:2 BTC}, Y:1 BTC} is in the HTLC with secret s1, they take 0.5 BTC of that HTLC and add it as the payout from secret s2 in the channel with X to obtain State 2. Then, they update the channel with Y to obtain State 3.
This seems to address the atomicity issue. However, there are a couple other details to address in the hierarchical channel protocol.
First, in the adaptation of the FFO protocol to hierarchical channels, the "payee" for an HTLC is the user that must provide the HTLC's secret with an HTLC-kickoff transaction (see Figure 14 in the paper). However, when the HTLC pays to a lower-level HTLC, there is no single "payee" that can be determined. This could be addressed by enabling both users that could be payees to reveal the HTLC's secret with an HTLC-kickoff transaction followed by an HTLC-success transaction (note that this doubles the number of HTLC-payment transactions that are required).
Second, in going from HTLCs to PTLCs, the payee has to create a secret that's subtracted from the secret that's revealed at the payment's next hop. The challenge is how to define a secret that depends on multiple potential payees' secrets. I think it may be possible to solve this by having all potential payees at hop i create their own secret, define the overall secret at hop i as being the sum of the potential payees' secrets (after protecting against key/secret cancellation), and sharing partial signatures between potential payees at hop i such that each potential payee just needs to get hop (i+1)'s secret in order to produce hop (i)'s overall secret, but I haven't worked through the details.
To be clear, the idea of having an active HTLC that's funded by a pair of active HTLCs is your idea, and it's very interesting. We don't need to support this in order to resize channels off-chain, but it does allow a given unit of capital to facilitate two independent payments simultaneously, which is amazing!
> (I figure implementing something eltoo-like via 2-user tunable penalty
> channels and/or ln-symmetry (let alone splicing, taproot funding
> addresses, and ptlcs) is a sufficient sink for all the available
> engineering effort any time soon, but talking about hierarchial/factory
> things well in advance of when they could reasonably be implemented is
> fun too)
That makes sense.
I'm also hoping that a good understanding of what's possible without changing Bitcoin, plus what's enabled with changes like CTV and/or APO, will help inform any future changes to Bitcoin's consensus rules.
Regards,
John