Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-14 Thread Bastien TEINTURIER
> Simple protocols are ideal -- easier implementation, less bugs, less
> attack surface, etc.

I couldn't agree more! Let's keep complexity for the cases where it's
really necessary and brings enough value. I don't think CLTVs in this
case bring enough value to make up for the additional complexity.

> I think Keagan's idea of streaming lease fees makes a lot of sense
> here -- it's an ongoing incentive to keep the channel open.

I agree, and it could be as simple as having the seller publish a bolt
12 offer with recurrence in their liquidity ads. The buyer can then
regularly pay that offer through the standard bolt 12 flow, and the
seller would take that into account in its analysis of whether to keep
the channel open or not, and potentially add more liquidity.

This can even be done in two phases. We can deploy a very simple version
of liquidity ads without any CLTV or recurring payments attached, and in
a second step, once bolt 12 is widely deployed, add an optional bolt 12
offer to liquidity ads rates.

Thanks,
Bastien

Le mer. 13 déc. 2023 à 20:47, Matt Morehouse  a
écrit :

> If timelocks don't give us substantial benefit, let's avoid them.
> Simple protocols are ideal -- easier implementation, less bugs, less
> attack surface, etc.
>
> Notably, the current network works without locking anyone into
> channels.  Alice can open a channel with outbound liquidity to Bob.
> If the channel doesn't generate enough fees for Bob, it costs him
> nothing to close the channel and reallocate any funds on his side.
> There is no mechanism to lock Bob into the channel, and AFAIK no one
> has requested such a mechanism to be implemented.
>
> Can an analogous approach work for inbound liquidity?  Alice wants to
> open a channel with inbound liquidity from Bob.  As above Alice is
> willing to pay all transaction fees, so the only cost to Bob is the
> opportunity cost of his liquidity.  Instead of locking Bob into the
> channel, Alice can incentivize him to keep it open by (1) routing
> payments through the channel and/or (2) paying Bob directly.
>
> I think Keagan's idea of streaming lease fees makes a lot of sense
> here -- it's an ongoing incentive to keep the channel open.  The
> amount and frequency of payments can be agreed to during channel open,
> to provide some predictability for Alice and Bob.  But at any later
> point, either one can back out of the agreement with minimal cost if
> it is no longer mutually beneficial.
>
> I think such an approach would simplify the protocol and still achieve
> good results in practice due to the incentive structure -- everyone
> benefits more from cooperating than from trying to cheat each other.
> This is very similar to how the current network works.
>
>
> On Wed, Dec 13, 2023 at 12:59 PM Bastien TEINTURIER 
> wrote:
> >
> > Hey Keagan,
> >
> > Thanks for your feedback!
> >
> > > The question I have before we even get to the starting line of
> > > implementation is "What is actually being bought?".
> >
> > I fully agree, that is exactly why I created this thread and the
> > question I was asking in the initial post. And it's not obvious
> > what we actually want to buy, because different scenarios seem to
> > need slightly different kinds of inbound liquidity guarantees (in
> > the ideal case).
> >
> > > What timelocks ensure is that *if* liquidity exists within the channel
> > > that it isn't worth it for the seller to close, but it does very
> > > little to actually incentivize that liquidity being there in the first
> > > place.
> >
> > Yes, I fully agree with that (and the rest of your post). I don't think
> > timelocks are the right solution here. If a buyer is generating enough
> > fees for the seller from their lightning usage, the seller will have an
> > incentive to regularly add inbound liquidity towards the buyer, when it
> > makes sense in terms of on-chain fees or other operations. That provides
> > more utility to the buyer than protecting the remaining liquidity with a
> > timelock. We should not force this to happen at defined times, because
> > that would be incompatible with the unpredictability of on-chain fee
> > fluctuations.
> >
> > I think we have to accept that in order for lightning to provide the
> > most utility, we may need to buy excess liquidity when on-chain fees
> > are low, and wait for good mempool conditions to opportunistically
> > re-allocate liquidity (and that liquidity providers will have to
> > allocate in a way that makes the most sense for them as a whole, not
> > to each individual buyer, even though they will strive to satisfy
> > both whenever possible).
> >
> > Curious to see what other people on the list think as well.
> >
> > Thanks,
> > Bastien
> >
> > Le mer. 13 déc. 2023 à 03:24, Keagan McClelland <
> keagan.mcclell...@gmail.com> a écrit :
> >>
> >> Hey y'all,
> >>
> >> When these sorts of debates arise it prompts me to want to take a step
> back and do a more fundamental analysis of what's going on. The question I
> hav

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-14 Thread Matt Morehouse
If timelocks don't give us substantial benefit, let's avoid them.
Simple protocols are ideal -- easier implementation, less bugs, less
attack surface, etc.

Notably, the current network works without locking anyone into
channels.  Alice can open a channel with outbound liquidity to Bob.
If the channel doesn't generate enough fees for Bob, it costs him
nothing to close the channel and reallocate any funds on his side.
There is no mechanism to lock Bob into the channel, and AFAIK no one
has requested such a mechanism to be implemented.

Can an analogous approach work for inbound liquidity?  Alice wants to
open a channel with inbound liquidity from Bob.  As above Alice is
willing to pay all transaction fees, so the only cost to Bob is the
opportunity cost of his liquidity.  Instead of locking Bob into the
channel, Alice can incentivize him to keep it open by (1) routing
payments through the channel and/or (2) paying Bob directly.

I think Keagan's idea of streaming lease fees makes a lot of sense
here -- it's an ongoing incentive to keep the channel open.  The
amount and frequency of payments can be agreed to during channel open,
to provide some predictability for Alice and Bob.  But at any later
point, either one can back out of the agreement with minimal cost if
it is no longer mutually beneficial.

I think such an approach would simplify the protocol and still achieve
good results in practice due to the incentive structure -- everyone
benefits more from cooperating than from trying to cheat each other.
This is very similar to how the current network works.


On Wed, Dec 13, 2023 at 12:59 PM Bastien TEINTURIER  wrote:
>
> Hey Keagan,
>
> Thanks for your feedback!
>
> > The question I have before we even get to the starting line of
> > implementation is "What is actually being bought?".
>
> I fully agree, that is exactly why I created this thread and the
> question I was asking in the initial post. And it's not obvious
> what we actually want to buy, because different scenarios seem to
> need slightly different kinds of inbound liquidity guarantees (in
> the ideal case).
>
> > What timelocks ensure is that *if* liquidity exists within the channel
> > that it isn't worth it for the seller to close, but it does very
> > little to actually incentivize that liquidity being there in the first
> > place.
>
> Yes, I fully agree with that (and the rest of your post). I don't think
> timelocks are the right solution here. If a buyer is generating enough
> fees for the seller from their lightning usage, the seller will have an
> incentive to regularly add inbound liquidity towards the buyer, when it
> makes sense in terms of on-chain fees or other operations. That provides
> more utility to the buyer than protecting the remaining liquidity with a
> timelock. We should not force this to happen at defined times, because
> that would be incompatible with the unpredictability of on-chain fee
> fluctuations.
>
> I think we have to accept that in order for lightning to provide the
> most utility, we may need to buy excess liquidity when on-chain fees
> are low, and wait for good mempool conditions to opportunistically
> re-allocate liquidity (and that liquidity providers will have to
> allocate in a way that makes the most sense for them as a whole, not
> to each individual buyer, even though they will strive to satisfy
> both whenever possible).
>
> Curious to see what other people on the list think as well.
>
> Thanks,
> Bastien
>
> Le mer. 13 déc. 2023 à 03:24, Keagan McClelland  
> a écrit :
>>
>> Hey y'all,
>>
>> When these sorts of debates arise it prompts me to want to take a step back 
>> and do a more fundamental analysis of what's going on. The question I have 
>> before we even get to the starting line of implementation is "What is 
>> actually being bought?".
>>
>> It appears to me that what the buyer *really* wants is the persistent 
>> ability to receive payments up to a certain size. What enables this is the 
>> seller maintaining a minimum liquidity provision.
>>
>> An idealized version of this product would be the seller doing a JIT 
>> splice-in of whatever liquidity gets depleted when the buyer receives a 
>> payment. The longer the time between the payment and the re-provisioning, 
>> the worse the quality of service. It's not enough to guareantee that the 
>> integrated average liquidity on the seller's side exceeds that amount since 
>> until the world economy moves towards streaming smaller payments more 
>> continuously, the payment size is the primary issue, not the total volume.
>>
>> Ok, that's an idealized version, but JIT splices on every payment would be 
>> ridiculous since chain fees don't scale with payment size so if the buyer is 
>> receiving micropayments this gets out of hand almost immediately. So we have 
>> to live with a world where for some duration after the payment is made from 
>> the seller to the buyer, the leased liquidity dips below what is promised.
>>
>> So how do timelocks

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-13 Thread Bastien TEINTURIER
Hey Keagan,

Thanks for your feedback!

> The question I have before we even get to the starting line of
> implementation is "What is actually being bought?".

I fully agree, that is exactly why I created this thread and the
question I was asking in the initial post. And it's not obvious
what we actually want to buy, because different scenarios seem to
need slightly different kinds of inbound liquidity guarantees (in
the ideal case).

> What timelocks ensure is that *if* liquidity exists within the channel
> that it isn't worth it for the seller to close, but it does very
> little to actually incentivize that liquidity being there in the first
> place.

Yes, I fully agree with that (and the rest of your post). I don't think
timelocks are the right solution here. If a buyer is generating enough
fees for the seller from their lightning usage, the seller will have an
incentive to regularly add inbound liquidity towards the buyer, when it
makes sense in terms of on-chain fees or other operations. That provides
more utility to the buyer than protecting the remaining liquidity with a
timelock. We should not force this to happen at defined times, because
that would be incompatible with the unpredictability of on-chain fee
fluctuations.

I think we have to accept that in order for lightning to provide the
most utility, we may need to buy excess liquidity when on-chain fees
are low, and wait for good mempool conditions to opportunistically
re-allocate liquidity (and that liquidity providers will have to
allocate in a way that makes the most sense for them as a whole, not
to each individual buyer, even though they will strive to satisfy
both whenever possible).

Curious to see what other people on the list think as well.

Thanks,
Bastien

Le mer. 13 déc. 2023 à 03:24, Keagan McClelland 
a écrit :

> Hey y'all,
>
> When these sorts of debates arise it prompts me to want to take a step
> back and do a more fundamental analysis of what's going on. The question I
> have before we even get to the starting line of implementation is "What is
> actually being bought?".
>
> It appears to me that what the buyer *really* wants is the persistent
> ability to receive payments up to a certain size. What enables this is the
> seller maintaining a minimum liquidity provision.
>
> An idealized version of this product would be the seller doing a JIT
> splice-in of whatever liquidity gets depleted when the buyer receives a
> payment. The longer the time between the payment and the re-provisioning,
> the worse the quality of service. It's not enough to guareantee that the
> integrated average liquidity on the seller's side exceeds that amount since
> until the world economy moves towards streaming smaller payments more
> continuously, the payment size is the primary issue, not the total volume.
>
> Ok, that's an idealized version, but JIT splices on every payment would be
> ridiculous since chain fees don't scale with payment size so if the buyer
> is receiving micropayments this gets out of hand almost immediately. So we
> have to live with a world where for some duration after the payment is made
> from the seller to the buyer, the leased liquidity dips below what is
> promised.
>
> So how do timelocks actually fare as a means of guaranteeing that the
> buyer gets what they really want? I'm not sure they do very well. What
> timelocks ensure is that *if* liquidity exists within the channel that it
> isn't worth it for the seller to close, but it does very little to actually
> incentivize that liquidity being there in the first place. Instead, a
> different scheme would be needed to incentivize the sellers to keep the
> liquidity there. This is partially accomplished by the promise of routing
> fees. If the channel demonstrates a decent volume moving in the direction
> of the buyer, then the opportunity cost of keeping the liquidity on that
> channel is less pronounced. The lease fee is really more of a way to
> compensate the seller for the risk of low routing fee revenue during an
> initial demonstration period.
>
> As others have pointed out, those offering these leases have far more
> reputation risk than those who are buying them, so the ideal scheme would
> be one that makes it trivial for the buyer to prove the seller's
> impropriety and not one that makes it easy for the buyer to lock up the
> seller's liquidity. The risk the buyer incurs could be mitigated by just
> streaming the lease fee over the demonstration period. If they default on a
> payment, then the seller just closes the channel and as long as the buyer
> is responsible for paying the closing fees, the seller could sidestep
> griefing opportunities while not being in the position to use a small
> amount of liquidity to scam a large number of users in rapid succession.
>
> So my question to the list is what can be gained by adding a timelock,
> here?
>
> Keags
>
> On Mon, Dec 11, 2023 at 5:55 AM Bastien TEINTURIER 
> wrote:
>
>> Hey Matt,
>>
>> Thanks for brainstor

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-12 Thread Keagan McClelland
Hey y'all,

When these sorts of debates arise it prompts me to want to take a step back
and do a more fundamental analysis of what's going on. The question I have
before we even get to the starting line of implementation is "What is
actually being bought?".

It appears to me that what the buyer *really* wants is the persistent
ability to receive payments up to a certain size. What enables this is the
seller maintaining a minimum liquidity provision.

An idealized version of this product would be the seller doing a JIT
splice-in of whatever liquidity gets depleted when the buyer receives a
payment. The longer the time between the payment and the re-provisioning,
the worse the quality of service. It's not enough to guareantee that the
integrated average liquidity on the seller's side exceeds that amount since
until the world economy moves towards streaming smaller payments more
continuously, the payment size is the primary issue, not the total volume.

Ok, that's an idealized version, but JIT splices on every payment would be
ridiculous since chain fees don't scale with payment size so if the buyer
is receiving micropayments this gets out of hand almost immediately. So we
have to live with a world where for some duration after the payment is made
from the seller to the buyer, the leased liquidity dips below what is
promised.

So how do timelocks actually fare as a means of guaranteeing that the buyer
gets what they really want? I'm not sure they do very well. What timelocks
ensure is that *if* liquidity exists within the channel that it isn't worth
it for the seller to close, but it does very little to actually incentivize
that liquidity being there in the first place. Instead, a different scheme
would be needed to incentivize the sellers to keep the liquidity there.
This is partially accomplished by the promise of routing fees. If the
channel demonstrates a decent volume moving in the direction of the buyer,
then the opportunity cost of keeping the liquidity on that channel is less
pronounced. The lease fee is really more of a way to compensate the seller
for the risk of low routing fee revenue during an initial demonstration
period.

As others have pointed out, those offering these leases have far more
reputation risk than those who are buying them, so the ideal scheme would
be one that makes it trivial for the buyer to prove the seller's
impropriety and not one that makes it easy for the buyer to lock up the
seller's liquidity. The risk the buyer incurs could be mitigated by just
streaming the lease fee over the demonstration period. If they default on a
payment, then the seller just closes the channel and as long as the buyer
is responsible for paying the closing fees, the seller could sidestep
griefing opportunities while not being in the position to use a small
amount of liquidity to scam a large number of users in rapid succession.

So my question to the list is what can be gained by adding a timelock,
here?

Keags

On Mon, Dec 11, 2023 at 5:55 AM Bastien TEINTURIER  wrote:

> Hey Matt,
>
> Thanks for brainstorming this, that's an interesting variation of what
> I proposed for option 1. It is indeed simpler for bookkeeping, but there
> are still some additional complications to figure out.
>
> Do you think this should support multiple concurrent leases? I think it
> shouldn't because the additional complexity isn't worth it. Maybe buying
> a new lease should simply override the existing one? That isn't entirely
> trivial either, because while we're waiting for the splice transaction
> that contains the new lease to confirm, we need to keep track of the old
> lease as well on commitment transactions based on the previous funding
> output.
>
> What should we do when the lease ends? The seller doesn't want to keep
> the additional output, because it's costly for them if they need to
> force-close. But how do we synchronize to update the commit tx, since
> nodes may not be at exactly the same block height? We'll need to
> introduce a new message for that and negotiate a quiescence session.
>
> Also, if the seller splices in, do you agree that the amount should go
> to their unencumbered output?
>
> I've been prototyping the proposal I made previously, and I'm not very
> satisfied with it. It's a lot of additional complexity that interacts
> with many parts of the codebase (e.g. splicing, force-close management,
> channel reserve), mostly linked to the addition of a new output to the
> commitment transaction.
>
> I'm less and less convinced that we should go down that road: sellers
> will always have ways of being dishonest (by not relaying HTLCs, force
> closing regardless of the CLTV, or getting back some of their funds
> through pending HTLCs). I'm afraid we'll be adding a lot of complexity
> to the protocol (which in practice, means compatibility bugs and force
> closes) without much benefit. It would be a whole lot simpler to not
> add any CLTV on the seller side. Sure, they can still take their funds

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-11 Thread Bastien TEINTURIER
Hey Matt,

Thanks for brainstorming this, that's an interesting variation of what
I proposed for option 1. It is indeed simpler for bookkeeping, but there
are still some additional complications to figure out.

Do you think this should support multiple concurrent leases? I think it
shouldn't because the additional complexity isn't worth it. Maybe buying
a new lease should simply override the existing one? That isn't entirely
trivial either, because while we're waiting for the splice transaction
that contains the new lease to confirm, we need to keep track of the old
lease as well on commitment transactions based on the previous funding
output.

What should we do when the lease ends? The seller doesn't want to keep
the additional output, because it's costly for them if they need to
force-close. But how do we synchronize to update the commit tx, since
nodes may not be at exactly the same block height? We'll need to
introduce a new message for that and negotiate a quiescence session.

Also, if the seller splices in, do you agree that the amount should go
to their unencumbered output?

I've been prototyping the proposal I made previously, and I'm not very
satisfied with it. It's a lot of additional complexity that interacts
with many parts of the codebase (e.g. splicing, force-close management,
channel reserve), mostly linked to the addition of a new output to the
commitment transaction.

I'm less and less convinced that we should go down that road: sellers
will always have ways of being dishonest (by not relaying HTLCs, force
closing regardless of the CLTV, or getting back some of their funds
through pending HTLCs). I'm afraid we'll be adding a lot of complexity
to the protocol (which in practice, means compatibility bugs and force
closes) without much benefit. It would be a whole lot simpler to not
add any CLTV on the seller side. Sure, they can still take their funds
out whenever they want, but that will be reflected in the price. And if
you're an interesting buyer that generates routing activity, they'll
keep that liquidity around (most likely longer than the lease you were
ready to pay for). That better matches the dynamics of how people want
to allocate their liquidity efficiently. And if you pay for liquidity
and don't get it long enough, then it's fine, just don't buy from that
node again, you only lost a small amount in that process!

I know this is controversial, but I think it's hard to appreciate the
additional complexity that these new CLTV-based outputs add. We need
more code that implements this thoroughly (on top of an implementation
that supports splicing) to have informed opinions on whether this
additional complexity really makes sense.

Cheers,
Bastien

Le ven. 8 déc. 2023 à 23:32, Matt Morehouse  a
écrit :

> Unless I'm missing something, we can make option 2 work with CLTV
> enforcement as well.  In fact, I think that makes the bookkeeping much
> simpler.
>
> Suppose the leased amount is X.  No counters are needed.  All we need
> is to ensure the seller's first X sats in the commitment are always
> encumbered by the CLTV.  Anything above X can go to a second output
> that's unencumbered.  That's it.
>
> Here's an example.  Alice leases 10k sats from Bob and also puts up
> 10k sats to make the channel balanced.  The initial commitment
> transaction looks like this:
>
> Alice: 10k sats
> Bob: 10k sats with CLTV
>
> Bob offers a 2k sats HTLC1 to Alice.  The commitment becomes:
>
> Alice: 10k sats
> Bob: 8k sats with CLTV
> HTLC1: 2k sats
>
> HTLC1 is fulfilled:
>
> Alice: 12k sats
> Bob: 8k sats with CLTV
>
> Alice offers a 4k sats HTLC2 to Bob:
>
> Alice: 8k sats
> Bob: 8k sats with CLTV
> HTLC2: 4k sats
>
> HTLC2 is fulfilled.  Since Bob now has a total balance greater than
> 10k sats, the excess goes to an unencumbered output:
>
> Alice: 8k sats
> Bob: 10k sats with CLTV
> Bob: 2k sats
>
> Bob offers a 1k sats HTLC3 to Alice.  The sats always come out of
> Bob's unencumbered output first:
>
> Alice: 8k sats
> Bob: 10k sats with CLTV
> Bob: 1k sats
> HTLC3: 1k sats
>
> Bob offers a 3k sats HTLC4 to Alice.  The sats always come out of
> Bob's unencumbered output first.  The remaining sats come out of the
> encumbered output:
>
> Alice: 8k sats
> Bob: 8k sats with CLTV
> HTLC3: 1k sats
> HTLC4: 3k sats
>
> HTLC3 is fulfilled and HTLC4 is failed.  Bob's total balance will
> increase to 11k sats, so the first 10k sats are encumbered and the
> last 1k are unencumbered:
>
> Alice: 9k sats
> Bob: 10k sats with CLTV
> Bob: 1k sats
>
>
> Alice can never lock up more than 10k sats on Bob's side, since that
> was the agreed lease amount.  Bob can still play games with circular
> routing or force closing with HTLCs outstanding to unlock some of his
> liquidity early, but that is also the case with every other proposal
> so far.  Hence the importance of limiting HTLC value in flight.
>
>
> On Fri, Dec 8, 2023 at 3:48 PM Bastien TEINTURIER 
> wrote:
> >
> > Hey all,
> >
> > I'd like to detail a bit more

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-10 Thread Matt Morehouse
Unless I'm missing something, we can make option 2 work with CLTV
enforcement as well.  In fact, I think that makes the bookkeeping much
simpler.

Suppose the leased amount is X.  No counters are needed.  All we need
is to ensure the seller's first X sats in the commitment are always
encumbered by the CLTV.  Anything above X can go to a second output
that's unencumbered.  That's it.

Here's an example.  Alice leases 10k sats from Bob and also puts up
10k sats to make the channel balanced.  The initial commitment
transaction looks like this:

Alice: 10k sats
Bob: 10k sats with CLTV

Bob offers a 2k sats HTLC1 to Alice.  The commitment becomes:

Alice: 10k sats
Bob: 8k sats with CLTV
HTLC1: 2k sats

HTLC1 is fulfilled:

Alice: 12k sats
Bob: 8k sats with CLTV

Alice offers a 4k sats HTLC2 to Bob:

Alice: 8k sats
Bob: 8k sats with CLTV
HTLC2: 4k sats

HTLC2 is fulfilled.  Since Bob now has a total balance greater than
10k sats, the excess goes to an unencumbered output:

Alice: 8k sats
Bob: 10k sats with CLTV
Bob: 2k sats

Bob offers a 1k sats HTLC3 to Alice.  The sats always come out of
Bob's unencumbered output first:

Alice: 8k sats
Bob: 10k sats with CLTV
Bob: 1k sats
HTLC3: 1k sats

Bob offers a 3k sats HTLC4 to Alice.  The sats always come out of
Bob's unencumbered output first.  The remaining sats come out of the
encumbered output:

Alice: 8k sats
Bob: 8k sats with CLTV
HTLC3: 1k sats
HTLC4: 3k sats

HTLC3 is fulfilled and HTLC4 is failed.  Bob's total balance will
increase to 11k sats, so the first 10k sats are encumbered and the
last 1k are unencumbered:

Alice: 9k sats
Bob: 10k sats with CLTV
Bob: 1k sats


Alice can never lock up more than 10k sats on Bob's side, since that
was the agreed lease amount.  Bob can still play games with circular
routing or force closing with HTLCs outstanding to unlock some of his
liquidity early, but that is also the case with every other proposal
so far.  Hence the importance of limiting HTLC value in flight.


On Fri, Dec 8, 2023 at 3:48 PM Bastien TEINTURIER  wrote:
>
> 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  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  a 
>> écrit :
>>>
>>> On Mon, Dec 4, 2023 at 9:48 AM Bastien TEINTURIER  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 m

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-08 Thread Bastien TEINTURIER
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  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  a
> écrit :
>
>> On Mon, Dec 4, 2023 at 9:48 AM Bastien TEINTURIER 
>> 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 

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-08 Thread Bastien TEINTURIER
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  a
écrit :

> On Mon, Dec 4, 2023 at 9:48 AM Bastien TEINTURIER 
> 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  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 un

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-07 Thread Matt Morehouse
On Mon, Dec 4, 2023 at 9:48 AM Bastien TEINTURIER  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  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 
>>  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 th

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-04 Thread Bastien TEINTURIER
Hi Matt, Zman,

You're both suggesting that we should explore in more detail the idea I
mentioned in my post, where the seller's funds would be split into two
outputs, one with the CLTV lease and the other without it. I've already
discussed that option with Lisa, and I was under the impression that it
could be gamed to bypass the lease.

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

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!

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  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
>

Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-02 Thread Matt Morehouse
On Fri, Dec 1, 2023 at 5:47 PM Bastien TEINTURIER  wrote:
>
> 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.

Could we implement a policy that always encumbers the seller's first
10k sats with a CLTV, then spills any excess over to a normal output?
HTLCs outgoing from the seller would first subtract from the normal
output before dipping into the CLTV output.  If failed, the returned
funds would first add to the CLTV output (up to a total of 10k), then
spill over to the normal output.

Maybe I'm missing something, but I don't think either party can
exploit such a policy.

There's also the question of whether to encumber HTLC outputs with the
lease timelock.  But IIUC the current proposal is to limit the total
HTLC value in flight, which should limit exposure for both parties
regardless of the timelock policy for HTLC outputs.
___
Lightning-dev mailing list
Lightning-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev


Re: [Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-02 Thread ZmnSCPxj via Lightning-dev
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  
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 

[Lightning-dev] Liquidity Ads and griefing subtleties

2023-12-01 Thread Bastien TEINTURIER
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. U