Hey all,

I'd like to detail a bit more my statement from the last email.

> I personally think it has to be the first option, because the second
> one exposes the seller to griefing

That is my current conclusion *if we want to provide some kind of lease
enforcement via CLTV*, and we want to ensure it protects both the buyer
and the seller equally.

But we can look at it from a different angle: if what people want to
buy is option 2, then we should find a way to make option 2 work. In
my opinion, option 2 would be best without any CLTV enforcement of the
lease, and relying only on incentives (and thus letting the buyer take
the risk that the seller splices out or force-closes).

But maybe then it doesn't even make sense to have lease durations? Maybe
we only need to provide a feature to buy X amount of inbound liquidity
now, and let the seller decide whether they want to keep that liquidity
available for a long time or move it elsewhere.

Cheers,
Bastien

Le ven. 8 déc. 2023 à 09:00, Bastien TEINTURIER <bast...@acinq.fr> a écrit :

> Hey Matt,
>
> > The question then is really: do operators want to buy/sell X sats of
> > inbound flow or Y days of an open channel with an initial inbound
> > balance of X sats?
>
> Agreed, this is what we need to decide. I personally think it has to be
> the first option, because the second one exposes the seller to griefing
> by the attack described in my first email, which makes it impossible for
> the seller to find the right price for that channel because they don't
> know how much liquidity will actually end up being locked.
>
> But that's definitely up for debate if people feel otherwise!
>
> Thanks,
> Bastien
>
> Le jeu. 7 déc. 2023 à 22:18, Matt Morehouse <mattmoreho...@gmail.com> a
> écrit :
>
>> On Mon, Dec 4, 2023 at 9:48 AM Bastien TEINTURIER <bast...@acinq.fr>
>> wrote:
>> >
>> > But I've thought about it more, and the following strategy may work:
>> >
>> > - store three counters for the seller's funds:
>> >   - `to_local`: seller's funds that are not leased
>> >   - `to_local_leased`: seller's funds that are leased
>> >   - `to_local_leased_owed`: similar to `to_local_leased`, without taking
>> >     into account pending HTLCs sent by the seller
>> > - when the seller sends HTLCs:
>> >   - deduce the HTLC amounts from `to_local_leased` first
>> >   - when `to_local_leased` reaches `0 sat`, deduce from `to_local`
>> >   - keep `to_local_leased_owed` unchanged
>> > - when HTLCs sent by the seller are fulfilled:
>> >   - deduce the HTLC amounts from `to_local_leased_owed`
>> > - when HTLCs sent by the seller are failed:
>> >   - add the corresponding amount to `to_local_leased` first
>> >   - once `to_local_leased = to_local_leased_owed`, add the remaining
>> >     amount to `to_local`
>> > - when creating commitment transactions:
>> >   - if `to_local_leased` is greater than dust, create a corresponding
>> >     output with a CLTV matching the lease
>> >   - if `to_local` is greater than dust, create a corresponding output
>> >     without any CLTV lease
>>
>> Neat idea.  This changes the meaning of liquidity ads slightly -- the
>> liquidity is only leased for the one-way trip, and any channel balance
>> that comes back to the seller is not encumbered.  In other words,
>> instead of the channel itself being leased, only the initial inbound
>> liquidity is.  Once the cumulative flow to the buyer meets the leased
>> amount, the seller can reclaim any balance on their side without
>> penalty.  Of course if there's enough bidirectional flow happening,
>> the seller may choose to keep the channel open to earn more fees.
>>
>> The question then is really: do operators want to buy/sell X sats of
>> inbound flow or Y days of an open channel with an initial inbound
>> balance of X sats?
>>
>> >
>> > This computation must occur when sending/receiving `commit_sig`. The
>> > order in which we evaluate those updates matters: we must start with
>> > the `update_fulfill_htlc` updates before the `update_fail_htlc` ones,
>> > because we need to start by updating `to_local_leased_owed`. I believe
>> > that works, but it needs more analysis. Please try to break it, and let
>> > me know what you find!
>>
>> On first look, I think this works.  I'll study it closer if we decide
>> this is the direction we want to go.
>>
>> >
>> > We also need to handle concurrent leases. We want to support the
>> > following scenario:
>> >
>> > - Alice buys 10k sats from Bob for one month
>> > - 1 week later, the on-chain fees are very low: Alice buys 50k sats
>> >   from Bob for 6 months
>> > - 1 more week later, she buys 10k sats from Bob for one week
>> >
>> > We thus have three concurrent leases, with overlapping lease durations.
>> > That's costly for the channel initiator, because we must add three new
>> > outputs to the commitment transactions. But that part should be ok, the
>> > seller should price that in its decision to fund the lease or not.
>> >
>> > I think we would need to have three `to_local_leased_owed` buckets, one
>> > per lease. How do we order them, to decide from which bucket we take
>> > funds first? I think the option that makes the most sense is to order
>> > them by lease expiry (not by lease start or lease amount, which could
>> > be unfair to the buyer).
>> >
>> > Would that create scenarios where one side can cheat? Are there issues
>> > with channel reserve because of the increased commit tx weight?
>> >
>> > Cheers,
>> > Bastien
>> >
>> > Le sam. 2 déc. 2023 à 03:23, ZmnSCPxj <zmnsc...@protonmail.com> a
>> écrit :
>> >>
>> >> Halfway through, I thought "is it not possible to have two Bob-owned
>> outputs that sum up to the total Bob-owned amount, with a CLTV on up to the
>> amount that was purchased and the rest (if above dust limit) without a
>> CLTV?"
>> >>
>> >> so e.g. if the purchased amount is 2 units but the total channel
>> capacity is 12 units:
>> >>
>> >> * Bob owns 0 units: no Bob outputs
>> >> * Bob owns 1 unit: Bob has a CLTV-encumbered output of 1 unit
>> >> * Bob owns 2 units: Bob has a CLTV-encumbered output of 2 units
>> >> * Bob owns 3 units (assuming 1 unit is above dust limit):  Bob has:
>> >>   * A CLTV-encumbered output of 2 units
>> >>   * An ordinary output of 1 unit
>> >> * etc.
>> >>
>> >> This locks up only the agreed-upon amount but lets Bob keep any amount
>> above the rest.
>> >>
>> >> Alternately, only allow CLTV-locking if the buyer is not providing its
>> own funds (i.e. pure inbound purchase).
>> >> This is still effectively my original idea as then any funds Alice
>> wants to add would be in a separate, unencumbered channel.
>> >>
>> >> Regards,
>> >> ZmnSCPxj
>> >>
>> >>
>> >> Sent with Proton Mail secure email.
>> >>
>> >> On Friday, December 1st, 2023 at 5:45 PM, Bastien TEINTURIER <
>> bast...@acinq.fr> wrote:
>> >>
>> >>
>> >> > Good morning list,
>> >> >
>> >> > I've been thinking a lot about liquidity ads recently, and I want to
>> >> > highlight some subtleties that should be taken into account in the
>> >> > protocol design. This is a rather long post, but I believe this is
>> >> > important to make sure we get it right and strike the right balance
>> >> > between protocol complexity and incentives design. Strap in, grab a
>> >> > coffee, and enjoy the ride.
>> >> >
>> >> > First of all, it's important to understand exactly what you are
>> buying
>> >> > when paying for a liquidity ad. There are two dimensions here: an
>> amount
>> >> > and a duration. If Alice buys 100 000 sats of inbound liquidity from
>> Bob
>> >> > for one month, what exactly does that mean? Obviously, it means that
>> Bob
>> >> > will immediately add 100 000 sats (or more) to his side of the
>> channel,
>> >> > and Alice will pay a fee proportional to that amount *and* that
>> duration
>> >> > (because locking funds for one month should cost more than locking
>> funds
>> >> > for one day). But is that really the only thing that Alice is buying?
>> >> >
>> >> > The current spec proposal adds a CLTV of one month to the seller's
>> >> > output in the commitment transactions. Without that CLTV, the seller
>> >> > could accept the trade, and immediately close the channel to reuse
>> the
>> >> > funds elsewhere. This CLTV protects the buyer from malicious sellers.
>> >> > But it is actually doing a lot more: what Alice has bought is
>> actually
>> >> > *any* liquidity that ends up on Bob's side, for a whole month. And
>> the
>> >> > issue is that this is impossible for Bob to price correctly, and can
>> be
>> >> > used for liquidity griefing attacks against him.
>> >> >
>> >> > Imagine that Alice opens a 1 BTC channel with Bob and asks him to add
>> >> > 10 000 sats of inbound liquidity for a month. This sounds interesting
>> >> > for Bob, because Alice is bringing a lot of funds in, so he can
>> expect
>> >> > payments to flow towards him which will bring him routing fees. And
>> she
>> >> > isn't asking for a lot of liquidity, so Bob can definitely spare
>> that.
>> >> > But then Alice sends all the channels funds through Bob to Carol.
>> This
>> >> > means that Bob now has 1 BTC locked for the whole month, while Alice
>> >> > only paid for 10 000 sats! He earned some routing fees, but that
>> isn't
>> >> > enough to make up for the long duration of the lock. If payments keep
>> >> > flowing in both directions with enough velocity, this is great for
>> both
>> >> > Bob and Alice. But if the channel is then unused, or Alice just goes
>> >> > offline, this was a very bad investment for Bob. With splicing, Bob
>> >> > cannot even know beforehand how much liquidity is potentially at
>> risk,
>> >> > because Alice may splice funds in after paying for the liquidity ad.
>> >> >
>> >> > If Alice pays for a 10 000 sats lease, we only want those 10 000 sats
>> >> > to be encumbered with a CLTV. But this is actually not enforceable.
>> We
>> >> > could create a separate output in the commitment transaction with the
>> >> > leased funds and a CLTV, while keeping the rest of the seller's
>> funds in
>> >> > a normal output that doesn't have a CLTV. But then what happens when
>> >> > HTLCs are relayed and then failed? To which output should we add the
>> >> > funds back? Any strategy we use here can be exploited either by the
>> >> > seller to drain the leased funds back to its non-CLTV-locked output,
>> >> > or by the buyer to keep funds in the CLTV-locked output forever.
>> >> >
>> >> > Adding a CLTV thus protects the buyer at the expense of the seller.
>> In
>> >> > some cases this is ok: if you are a new seller who wants to attract
>> >> > buyers, you may be willing to take that risk. But in most cases, the
>> >> > seller is going to be more reputable than the buyer, and has more
>> >> > incentives to behave correctly than the buyer. When buying liquidity,
>> >> > you will likely look at the network's topology, and buy from nodes
>> that
>> >> > are well-connected, or known to be reliable. Or if you are a mobile
>> >> > wallet user, you'll be buying from your LSPs, who have incentives to
>> >> > behave honestly to earn fees and attract new users. In those
>> scenarios,
>> >> > the buyers will very often be new nodes, without any public channels,
>> >> > which means that the seller has no way of knowing what their
>> incentives
>> >> > are beforehand. It thus makes more sense to protect the seller than
>> to
>> >> > protect the buyer. For those use-cases, the simplest solution is to
>> not
>> >> > add a CLTV at all: the buyer is taking the risk that the seller
>> removes
>> >> > the liquidity before the end of the lease. But if that happens,
>> they'll
>> >> > just mourn their lost fees, blacklist that node, and move on. There
>> will
>> >> > be a lot more buyers than sellers in that market, so I believe that
>> this
>> >> > model makes sense for most large public nodes.
>> >> >
>> >> > I think that both use-cases should be supported, so I suggest making
>> the
>> >> > CLTV enforcement of the lease optional. It will be up to each seller
>> to
>> >> > decide whether they are willing to take the risk of locking their
>> funds
>> >> > to attract buyers or not. Sellers can (should) price that additional
>> >> > risk in their advertised rates.
>> >> >
>> >> > In the case where the CLTV is enforced, splicing brings in additional
>> >> > subtleties. We should prevent the seller from making any splice-out,
>> >> > otherwise they would effectively be bypassing the lease CLTV. But we
>> >> > should allow the seller to splice-in, and the buyer should still be
>> >> > allowed to splice-in and splice-out. Unfortunately, the seller can
>> >> > prevent the buyer from splicing funds in and out of the channel, by
>> >> > simply adding splice-out outputs in any splice attempt: the buyer has
>> >> > no other choice than aborting that splice.
>> >> >
>> >> > I initially thought that we could actually use splice-out to get the
>> >> > best of both worlds: add a CLTV on the seller's output, but allow
>> them
>> >> > to splice-out whatever funds are "in excess" of the leased amount.
>> But
>> >> > that doesn't work, because the buyer can unilaterally reject the
>> splice
>> >> > attempt, and the seller still ends up with all their funds locked for
>> >> > the lease duration (even though the seller can also play the abort
>> game
>> >> > to prevent the buyer from making any splice, as described above).
>> >> >
>> >> > Thanks for reading this long post, I think this will be useful if you
>> >> > are planning on selling liquidity through liquidity ads, as you
>> should
>> >> > fully understand the drawbacks of the CLTV lock. I do want to
>> highlight
>> >> > that this is a great protocol, and that a liquidity marketplace is an
>> >> > important building block for lightning. We'll be working hard to make
>> >> > sure you can find this in your favorite implementations soon!
>> >> >
>> >> > Cheers,
>> >> > Bastien
>>
>
_______________________________________________
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev

Reply via email to