Return-Path: <bastien.teinturier@acinq.fr>
Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])
 by lists.linuxfoundation.org (Postfix) with ESMTP id CB653C0032
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Wed, 18 Oct 2023 14:35:56 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by smtp2.osuosl.org (Postfix) with ESMTP id A4F8F400DA
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Wed, 18 Oct 2023 14:35:56 +0000 (UTC)
DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org A4F8F400DA
Authentication-Results: smtp2.osuosl.org;
 dkim=pass (2048-bit key) header.d=acinq.fr header.i=@acinq.fr
 header.a=rsa-sha256 header.s=google header.b=TiExUDv+
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -2.088
X-Spam-Level: 
X-Spam-Status: No, score=-2.088 tagged_above=-999 required=5
 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
 DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001,
 RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, T_SPF_PERMERROR=0.01]
 autolearn=ham autolearn_force=no
Received: from smtp2.osuosl.org ([127.0.0.1])
 by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id KsTDbPwav2SG
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Wed, 18 Oct 2023 14:35:54 +0000 (UTC)
Received: from mail-ot1-x32e.google.com (mail-ot1-x32e.google.com
 [IPv6:2607:f8b0:4864:20::32e])
 by smtp2.osuosl.org (Postfix) with ESMTPS id 3E5B7404FE
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Wed, 18 Oct 2023 14:35:54 +0000 (UTC)
DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 3E5B7404FE
Received: by mail-ot1-x32e.google.com with SMTP id
 46e09a7af769-6c4b9e09521so4540353a34.3
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Wed, 18 Oct 2023 07:35:54 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=acinq.fr; s=google; t=1697639753; x=1698244553;
 darn=lists.linuxfoundation.org; 
 h=cc:to:subject:message-id:date:from:in-reply-to:references
 :mime-version:from:to:cc:subject:date:message-id:reply-to;
 bh=zin0xJTfYoFKaOBDKGDywG1vVBKJRze9t2yk5ki+5Hc=;
 b=TiExUDv+00ELdLB5ao9FKDWMXKOytofx4/gMPM0TWl21wJQF33z9344ZCdt2h/gAeL
 m28Ytkkud3VaueYqu3b53Ek3uxOMO6k8VEukVrBIJds1+aw9N67r+0tpLpemmLcqF7Z6
 LXgMyNkQumIBCz5JD9iYnM2oxHWdn+W6Anw2EKxFg09MUL7eoc6Ynfpofli1Jv9lFIFf
 Hay0onrigcrxsNtJqVX0c0JWwBjZwHRk5sb156zz0m+J5XDwulLK7bd3BMU3B9XymePN
 q/TlRSSJtspRQ1LdcF2jR91rShenMb8LLxLO48JaLiwBlePOXCaooivs1aDhVOkurwGo
 qltQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1697639753; x=1698244553;
 h=cc:to:subject:message-id:date:from:in-reply-to:references
 :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id
 :reply-to;
 bh=zin0xJTfYoFKaOBDKGDywG1vVBKJRze9t2yk5ki+5Hc=;
 b=g7Vto16YzQcEOxOsa528mmGkbJFithq9LAxCEwvf3B/NkMcAYTFY6Ku2WGSASp5I/8
 Ul+jk/4fs2V9jA6VBWTQ5Mw9Fea7j+nAoWSoDuoXN30Fn9VDO3hKMCNDI1idXFNRbHCE
 GPOz/mdJV9eg70glqR10dBX9ip00YTm227PznVfw5vBtIT1O9LfHbFRdsUNav1nMKXc8
 9fVEmBYLuQHfKuF9mQ1qR3N7I1l5xdjK2TN7y6oba6jFDA1o5O4hoj0WqpiZ5gtuykWq
 eD0M/hLRXxia4TxlZ+D4r2UyvaoXcgnfJriauxJhZHv6rg1c4ii3A5Y3wjKd/5ZTGOn2
 kiHg==
X-Gm-Message-State: AOJu0YyF75S9mbuLSfweaW4g9baLnLZh/keR3Eyi25zy32Gj5DuaC3Pf
 5Izyd4dS9zUjqGvKXQL0MPXm3bcu9BpCh/74DNX7qg==
X-Google-Smtp-Source: AGHT+IE97JDyVfN0XJjy0TVU6lXEo1aCqdt4YxmymyEi3rEYiBusxdw4iJs3XUa3zshWOMpdP4KBeX9g3eXT2G3tTis=
X-Received: by 2002:a05:6871:c84:b0:1ea:29a:861e with SMTP id
 vf4-20020a0568710c8400b001ea029a861emr5218740oab.12.1697639752988; Wed, 18
 Oct 2023 07:35:52 -0700 (PDT)
MIME-Version: 1.0
References: <CACdvm3MuKmzQ1EFMJDc0ahhrG6xpD6Rr9Vh=ZTpVHa12ZALB0w@mail.gmail.com>
 <CALZpt+E+od+nejiZDeMfQ+qLNMc8UnU=G1YVsH+REut6+Jj-Bg@mail.gmail.com>
In-Reply-To: <CALZpt+E+od+nejiZDeMfQ+qLNMc8UnU=G1YVsH+REut6+Jj-Bg@mail.gmail.com>
From: Bastien TEINTURIER <bastien@acinq.fr>
Date: Wed, 18 Oct 2023 16:35:40 +0200
Message-ID: <CACdvm3OJsg2Br91aDL8=eACTW1WkdQcUSCvpWyniuEZf+qSAuA@mail.gmail.com>
To: Antoine Riard <antoine.riard@gmail.com>
Content-Type: multipart/alternative; boundary="0000000000006f1e2b0607fe8e71"
X-Mailman-Approved-At: Wed, 18 Oct 2023 16:39:50 +0000
Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>,
 "lightning-dev\\\\@lists.linuxfoundation.org"
 <lightning-dev@lists.linuxfoundation.org>
Subject: Re: [bitcoin-dev] [Lightning-dev] Batch exchange withdrawal to
	lightning requires covenants
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Wed, 18 Oct 2023 14:35:56 -0000

--0000000000006f1e2b0607fe8e71
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hey Z-man, Antoine,

Thank you for your feedback, responses inline.

z-man:

> Then if I participate in a batched splice, I can disrupt the batched
> splice by broadcasting the old state and somehow convincing miners to
> confirm it before the batched splice.

Correct, I didn't mention it in my post but batched splices cannot use
0-conf, the transaction must be confirmed to remove the risk of double
spends using commit txs associated with the previous funding tx.

But interestingly, with the protocol I drafted, the LSP can finalize and
broadcast the batched splice transaction while users are offline. With a
bit of luck, when the users reconnect, that transaction will already be
confirmed so it will "feel 0-conf".

Also, we need a mechanism like the one you describe when we detect that
a splice transaction has been double-spent. But this isn't specific to
batched transactions, 2-party splice transactions can also be double
spent by either participant. So we need that mechanism anyway? The spec
doesn't have a way of aborting a splice after exchanging signatures, but
you can always do it as an RBF operation (which actually just does a
completely different splice). This is what Greg mentioned in his answer.

> part of the splice proposal is that while a channel is being spliced,
> it should not be spliced again, which your proposal seems to violate.

The spec doesn't require that, I'm not sure what made you think that.
While a channel is being spliced, it can definitely be spliced again as
an RBF attempt (this is actually a very important feature), which double
spends the other unconfirmed splice attempts.

ariard:

> It is uncertain to me if secure fee-bumping, even with future
> mechanisms like package relay and nversion=3D3, is robust enough for
> multi-party transactions and covenant-enable constructions under usual
> risk models.

I'm not entirely sure why you're bringing this up in this context...
I agree that we most likely cannot use RBF on those batched transactions
we will need to rely on CPFP and potentially package relay. But why is
it different from non-multi-party transactions here?

> See test here:
>
https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72=
f1efcf

I'd argue that this is quite different from the standard replacement
cycling attack, because in this protocol wallet users can only
unilaterally double-spend with a commit tx, on which they cannot set
the feerate. The only participant that can "easily" double-spend is
the exchange, and they wouldn't have an incentive to here, users are
only withdrawing funds, there's no opportunity of stealing funds?

Thanks,
Bastien

Le mar. 17 oct. 2023 =C3=A0 21:10, Antoine Riard <antoine.riard@gmail.com> =
a
=C3=A9crit :

> Hi Bastien,
>
> > The naive way of enabling lightning withdrawals is to make the user
> > provide a lightning invoice that the exchange pays over lightning. The
> > issue is that in most cases, this simply shifts the burden of making an
> > on-chain transaction to the user's wallet provider: if the user doesn't
> > have enough inbound liquidity (which is likely), a splice transaction
> > will be necessary. If N users withdraw funds from an exchange, we most
> > likely will end up with N separate splice transactions.
>
> It is uncertain to me if secure fee-bumping, even with future mechanisms
> like package relay and nversion=3D3, is robust enough for multi-party
> transactions and covenant-enable constructions under usual risk models.
>
> See test here:
>
> https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d=
72f1efcf
>
> Appreciated expert eyes of folks understanding both lightning and core
> mempool on this.
> There was a lot of back and forth on nversion=3D3 design rules, though th=
e
> test is normally built on glozow top commit of the 3 Oct 2023.
>
> Best,
> Antoine
>
> Le mar. 17 oct. 2023 =C3=A0 14:03, Bastien TEINTURIER <bastien@acinq.fr> =
a
> =C3=A9crit :
>
>> Good morning list,
>>
>> I've been trying to design a protocol to let users withdraw funds from
>> exchanges directly into their lightning wallet in an efficient way
>> (with the smallest on-chain footprint possible).
>>
>> I've come to the conclusion that this is only possible with some form of
>> covenants (e.g. `SIGHASH_ANYPREVOUT` would work fine in this case). The
>> goal of this post is to explain why, and add this usecase to the list of
>> useful things we could do if we had covenants (insert "wen APO?" meme).
>>
>> The naive way of enabling lightning withdrawals is to make the user
>> provide a lightning invoice that the exchange pays over lightning. The
>> issue is that in most cases, this simply shifts the burden of making an
>> on-chain transaction to the user's wallet provider: if the user doesn't
>> have enough inbound liquidity (which is likely), a splice transaction
>> will be necessary. If N users withdraw funds from an exchange, we most
>> likely will end up with N separate splice transactions.
>>
>> Hence the idea of batching those into a single transaction. Since we
>> don't want to introduce any intermediate transaction, we must be able
>> to create one transaction that splices multiple channels at once. The
>> issue is that for each of these channels, we need a signature from the
>> corresponding wallet user, because we're spending the current funding
>> output, which is a 2-of-2 multisig between the wallet user and the
>> wallet provider. So we run into the usual availability problem: we need
>> signatures from N users who may not be online at the same time, and if
>> one of those users never comes online or doesn't complete the protocol,
>> we must discard the whole batch.
>>
>> There is a workaround though: each wallet user can provide a signature
>> using `SIGHASH_SINGLE | SIGHASH_ANYONECANPAY` that spends their current
>> funding output to create a new funding output with the expected amount.
>> This lets users sign *before* knowing the final transaction, which the
>> exchange can create by batching pairs of inputs/outputs. But this has
>> a fatal issue: at that point the wallet user has no way of spending the
>> new funding output (since it is also a 2-of-2 between the wallet user
>> and the wallet provider). The wallet provider can now blackmail the user
>> and force them to pay to get their funds back.
>>
>> Lightning normally fixes this by exchanging signatures for a commitment
>> transaction that sends the funds back to their owners *before* signing
>> the parent funding/splice transaction. But here that is impossible,
>> because we don't know yet the `txid` of the batch transaction (that's
>> the whole point, we want to be able to sign before creating the batch)
>> so we don't know the new `prevout` we should spend from. I couldn't find
>> a clever way to work around that, and I don't think there is one (but
>> I would be happy to be wrong).
>>
>> With `SIGHASH_ANYPREVOUT`, this is immediately fixed: we can exchange
>> anyprevout signatures for the commitment transaction, and they will be
>> valid to spend from the batch transaction. We are safe from signature
>> reuse, because funding keys are rotated at each splice so we will never
>> create another output that uses the same 2-of-2 script.
>>
>> I haven't looked at other forms of covenants, but most of them likely
>> address this problem as well.
>>
>> Cheers,
>> Bastien
>> _______________________________________________
>> Lightning-dev mailing list
>> Lightning-dev@lists.linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
>>
>

--0000000000006f1e2b0607fe8e71
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hey Z-man, Antoine,<br><br>Thank you for your feedback, re=
sponses inline.<br><br>z-man:<br><br>&gt; Then if I participate in a batche=
d splice, I can disrupt the batched<br>&gt; splice by broadcasting the old =
state and somehow convincing miners to<br>&gt; confirm it before the batche=
d splice.<br><br>Correct, I didn&#39;t mention it in my post but batched sp=
lices cannot use<br>0-conf, the transaction must be confirmed to remove the=
 risk of double<br>spends using commit txs associated with the previous fun=
ding tx.<br><br>But interestingly, with the protocol I drafted, the LSP can=
 finalize and<br>broadcast the batched splice transaction while users are o=
ffline. With a<br>bit of luck, when the users reconnect, that transaction w=
ill already be<br>confirmed so it will &quot;feel 0-conf&quot;.<br><br>Also=
, we need a mechanism like the one you describe when we detect that<br>a sp=
lice transaction has been double-spent. But this isn&#39;t specific to<br>b=
atched transactions, 2-party splice transactions can also be double<br>spen=
t by either participant. So we need that mechanism anyway? The spec<br>does=
n&#39;t have a way of aborting a splice after exchanging signatures, but<br=
>you can always do it as an RBF operation (which actually just does a<br>co=
mpletely different splice). This is what Greg mentioned in his answer.<br><=
br>&gt; part of the splice proposal is that while a channel is being splice=
d,<br>&gt; it should not be spliced again, which your proposal seems to vio=
late.<br><br>The spec doesn&#39;t require that, I&#39;m not sure what made =
you think that.<br>While a channel is being spliced, it can definitely be s=
pliced again as<br>an RBF attempt (this is actually a very important featur=
e), which double<br>spends the other unconfirmed splice attempts.<br><br>ar=
iard:<br><br>&gt; It is uncertain to me if secure fee-bumping, even with fu=
ture<br>&gt; mechanisms like package relay and nversion=3D3, is robust enou=
gh for<br>&gt; multi-party transactions and covenant-enable constructions u=
nder usual<br>&gt; risk models.<br><br>I&#39;m not entirely sure why you&#3=
9;re bringing this up in this context...<br>I agree that we most likely can=
not use RBF on those batched transactions<br>we will need to rely on CPFP a=
nd potentially package relay. But why is<br>it different from non-multi-par=
ty transactions here?<br><br>&gt; See test here:<br>&gt; <a href=3D"https:/=
/github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf"=
>https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d7=
2f1efcf</a><br><br>I&#39;d argue that this is quite different from the stan=
dard replacement<br>cycling attack, because in this protocol wallet users c=
an only<br>unilaterally double-spend with a commit tx, on which they cannot=
 set<br>the feerate. The only participant that can &quot;easily&quot; doubl=
e-spend is<br>the exchange, and they wouldn&#39;t have an incentive to here=
, users are<br>only withdrawing funds, there&#39;s no opportunity of steali=
ng funds?<br><br>Thanks,<br>Bastien<br></div><br><div class=3D"gmail_quote"=
><div dir=3D"ltr" class=3D"gmail_attr">Le=C2=A0mar. 17 oct. 2023 =C3=A0=C2=
=A021:10, Antoine Riard &lt;<a href=3D"mailto:antoine.riard@gmail.com">anto=
ine.riard@gmail.com</a>&gt; a =C3=A9crit=C2=A0:<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div dir=3D"ltr">Hi Bastien,<div><br></div=
><div>&gt; The naive way of enabling lightning withdrawals is to make the u=
ser<br>&gt; provide a lightning invoice that the exchange pays over lightni=
ng. The<br>&gt; issue is that in most cases, this simply shifts the burden =
of making an<br>&gt; on-chain transaction to the user&#39;s wallet provider=
: if the user doesn&#39;t<br>&gt; have enough inbound liquidity (which is l=
ikely), a splice transaction<br>&gt; will be necessary. If N users withdraw=
 funds from an exchange, we most<br>&gt; likely will end up with N separate=
 splice transactions.<br></div><div><br></div><div>It is uncertain to me if=
 secure fee-bumping, even with future mechanisms like package relay and=C2=
=A0nversion=3D3, is robust enough for multi-party transactions and covenant=
-enable constructions under usual risk models.</div><div><br></div><div>See=
 test here:</div><div><a href=3D"https://github.com/ariard/bitcoin/commit/1=
9d61fa8cf22a5050b51c4005603f43d72f1efcf" target=3D"_blank">https://github.c=
om/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf</a><br></=
div><div><br></div><div>Appreciated expert eyes of folks understanding both=
 lightning and core mempool on this.</div><div>There was a lot of back and =
forth on nversion=3D3 design rules, though the test is normally built on gl=
ozow top commit of the 3 Oct 2023.</div><div><br></div><div>Best,</div><div=
>Antoine</div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=
=3D"gmail_attr">Le=C2=A0mar. 17 oct. 2023 =C3=A0=C2=A014:03, Bastien TEINTU=
RIER &lt;<a href=3D"mailto:bastien@acinq.fr" target=3D"_blank">bastien@acin=
q.fr</a>&gt; a =C3=A9crit=C2=A0:<br></div><blockquote class=3D"gmail_quote"=
 style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);p=
adding-left:1ex"><div dir=3D"ltr">Good morning list,<br><br>I&#39;ve been t=
rying to design a protocol to let users withdraw funds from<br>exchanges di=
rectly into their lightning wallet in an efficient way<br>(with the smalles=
t on-chain footprint possible).<br><br>I&#39;ve come to the conclusion that=
 this is only possible with some form of<br>covenants (e.g. `SIGHASH_ANYPRE=
VOUT` would work fine in this case). The<br>goal of this post is to explain=
 why, and add this usecase to the list of<br>useful things we could do if w=
e had covenants (insert &quot;wen APO?&quot; meme).<br><br>The naive way of=
 enabling lightning withdrawals is to make the user<br>provide a lightning =
invoice that the exchange pays over lightning. The<br>issue is that in most=
 cases, this simply shifts the burden of making an<br>on-chain transaction =
to the user&#39;s wallet provider: if the user doesn&#39;t<br>have enough i=
nbound liquidity (which is likely), a splice transaction<br>will be necessa=
ry. If N users withdraw funds from an exchange, we most<br>likely will end =
up with N separate splice transactions.<br><br>Hence the idea of batching t=
hose into a single transaction. Since we<br>don&#39;t want to introduce any=
 intermediate transaction, we must be able<br>to create one transaction tha=
t splices multiple channels at once. The<br>issue is that for each of these=
 channels, we need a signature from the<br>corresponding wallet user, becau=
se we&#39;re spending the current funding<br>output, which is a 2-of-2 mult=
isig between the wallet user and the<br>wallet provider. So we run into the=
 usual availability problem: we need<br>signatures from N users who may not=
 be online at the same time, and if<br>one of those users never comes onlin=
e or doesn&#39;t complete the protocol,<br>we must discard the whole batch.=
<br><br>There is a workaround though: each wallet user can provide a signat=
ure<br>using `SIGHASH_SINGLE | SIGHASH_ANYONECANPAY` that spends their curr=
ent<br>funding output to create a new funding output with the expected amou=
nt.<br>This lets users sign *before* knowing the final transaction, which t=
he<br>exchange can create by batching pairs of inputs/outputs. But this has=
<br>a fatal issue: at that point the wallet user has no way of spending the=
<br>new funding output (since it is also a 2-of-2 between the wallet user<b=
r>and the wallet provider). The wallet provider can now blackmail the user<=
br>and force them to pay to get their funds back.<br><br>Lightning normally=
 fixes this by exchanging signatures for a commitment<br>transaction that s=
ends the funds back to their owners *before* signing<br>the parent funding/=
splice transaction. But here that is impossible,<br>because we don&#39;t kn=
ow yet the `txid` of the batch transaction (that&#39;s<br>the whole point, =
we want to be able to sign before creating the batch)<br>so we don&#39;t kn=
ow the new `prevout` we should spend from. I couldn&#39;t find<br>a clever =
way to work around that, and I don&#39;t think there is one (but<br>I would=
 be happy to be wrong).<br><br>With `SIGHASH_ANYPREVOUT`, this is immediate=
ly fixed: we can exchange<br>anyprevout signatures for the commitment trans=
action, and they will be<br>valid to spend from the batch transaction. We a=
re safe from signature<br>reuse, because funding keys are rotated at each s=
plice so we will never<br>create another output that uses the same 2-of-2 s=
cript.<br><br>I haven&#39;t looked at other forms of covenants, but most of=
 them likely<br>address this problem as well.<br><br>Cheers,<br>Bastien<br>=
</div>
_______________________________________________<br>
Lightning-dev mailing list<br>
<a href=3D"mailto:Lightning-dev@lists.linuxfoundation.org" target=3D"_blank=
">Lightning-dev@lists.linuxfoundation.org</a><br>
<a href=3D"https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev=
" rel=3D"noreferrer" target=3D"_blank">https://lists.linuxfoundation.org/ma=
ilman/listinfo/lightning-dev</a><br>
</blockquote></div>
</blockquote></div>

--0000000000006f1e2b0607fe8e71--