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

_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev

Reply via email to