Welcome to Latests Strikes, your optimistic-weekly report of the latest Lightning-related news. In this issue, we'll cover a wallet release that made some noise last week (dare I say it also sparked some controversy?), share the word about a mandatory Boltz update, and review some implementations developments.
Wallets & Tools ReleasesWallets & Tools Releases
Get Some CakeGet Some Cake
Cake Wallet rolled out Lightning support last week! A long-awaited addition to the infamous privacy-oriented wallet, this integration leverages Spark to connect users to the wider Lightning network. This sparked some controversy around the use of the term "self-custodial" to qualify this "Lightning" setup, as well as questions around its privacy tradeoffs.
Spark uses a technology called statechains. In a statechain, the ownership of an on-chain UTXO is transferred between users with the help of a central server (or set of servers), known in Spark as the Spark Entity (SE). To achieve this, the private key that can spend the on-chain UTXO is split into 2 "shards" - one for the SE and one for the user. When the user (say, Alice) wants to send the funds to another user (let's call them Bob), the SE deletes their previous shard and collaborate with Bob to derive a new set of shards that still add up to the same underlying private key.
There are very legitimate critics that can be made around Spark's self-custodial qualification. The main point is that users are trusting the Spark entity (and thus its individual constituents, the Spark operators) to actually run the open source code they claim to be running. You trust them to delete "expired" keys and not collude with past owners of the statechains[1]. To make things worse, the first owner in the statechain is often the Spark entity itself, or a partner of the Spark entity.
To put it another way: Spark lacks the guaranteed self-custody that pre-signed transactions provide in Lightning[2]. Calling it self-custodial is, I think, a stretch we should be warier of making.
That is not to say that Spark isn't useful. I've been a proponent of statechains back when Mercury Layer was around (more on them later). I believe it solves a transitory problem of Lightning:
- Lightning requires new users (or their service providers) to commit funds ahead of time while their Lightning usage is still unclear ;
- Lightning is a solution to a problem that isn't evenly distributed yet (instantaneous Bitcoin payments).
The transitory nature of the problem Spark solves is hence twofold, with both faces of the coin strongly coupled. Lightning works remarkably fine for users who already need to perform instantaneous Bitcoin payments on a weekly/daily basis. It has very strong self-custody guarantees, and reasonable privacy assumptions. For these users, it makes sense to commit funds to a channel, just as it makes sense to have funds in a checking account. However, if you just want to receive your first bitcoins on Lightning and have no idea yet of when, where or whether you'll spend them at all, or you're dealing with fairly small amounts (e.g. pocket change), then indeed Lightning is too much, and Spark makes much more sense:
- it let's newcomers play around with Lightning payments with no significant commitment ;
- the trust assumptions are more okay-ish when dealing with pocket change ;
- users can later graduate to an actual Lightning wallet if their Lightning usage increases.
Regarding the privacy implications of using Spark, it is important to note that right now the Spark entity can see every transaction. This can be changed by using blind signing (which Mercury Layer did), and Seth from Cake stated that they'll keep pushing heavily for Spark to prioritize this development. However, given Spark[3] (and related companies[4]) track record around privacy, I am inclined to take this with a grain of salt.
TL;DR: Lightning via Spark in Cake Wallet is a great and useful development, but it's not "self-custodial" Lightning, and privacy guarantees are always preferable to privacy promises.
Boltz Mandatory UpdateBoltz Mandatory Update
If you're running the Boltz client or BTCPay plugin, you should update to at least versions https://github.com/BoltzExchange/boltz-client/releases/tag/v2.11.1 and https://github.com/BoltzExchange/boltz-btcpay-plugin/releases/tag/v2.2.20 (respectively), both released last week, before April 15th. Passed this dateline, older versions will stop working with Boltz' backend.
Implementations ThunderImplementations Thunder
LDK: Contributing to Splice as AcceptorLDK: Contributing to Splice as Acceptor
Rust Lightning fixed an issue where in some cases the acceptor would not contribute to a splice. This arose when both parties wanted to splice simultaneously: in order to get things going, one of them would be picked, at random, to be the splice initiator ; the other party would then not contribute to this splice session, necessitating a second session in order to get their changes added.
PR 4416 fixes this by making the acceptor contribute directly to the elected initiator's splice. Since the acceptor pays for less things in the splice transaction, the fees contributed by the accepting party are reduced to match their desired feerate, and the excess is moved into their change output.
LND: Aux HTLC ValidatorLND: Aux HTLC Validator
Under some timing conditions, several HTLCs could be added to the same channel and overflow the channel's bandwidth limit. An auxiliary HTLC Validator is added to LND to ensure routing is performed with an up-to-date view that includes all the not-yet-committed HTLCs. Those HTLCs are now taken sequentially, and once the bandwidth threshold is reached remaining HTLCs are failed.
Eclair: Interactive Transactions Validation PluginEclair: Interactive Transactions Validation Plugin
PR 3258 introduces a new plugin connector in Eclair for fine-grained control over UTXOs and addresses involved in interactive transactions (e.g. funding channels, closing channels, splicing). This can for example be used to automatically force-close channels[5] based on certain operator-defined heuristics (such as usage of blacklisted UTXOs, or sending to blacklisted addresses), as demonstrated by this example plugin.
That's it for today, I hope you enjoyed this issue! As always, feel free to drop any feedback in the comments or by reaching out on social media. Thank you so much for reading this far, and until next week!
It is important to stress out here that if they collude with a past owner (or are themselves a past owner), the Spark Entity can spend the funds instantly, without having to wait for any timelock. Timelocks are present in statechains, but only as an unilateral recovery path for users. If both as past owner and the SE collude to spend the funds by combining their respective shards, they can do so without any timelock, leaving the user with no recourse. See for example the discussions around this post for more details. ↩
Note that on the self-custody spectrum Ark is hence much closer to Lightning. The base Ark protocol gives similar self-custody guarantees (since the user always has pre-signed transactions they can use to unilaterally exit). The more practical flavors of Ark (e.g. with out-of-round transactions) introduce opt-in trust requirements. See Shinobi's recent X thread. ↩
The Wallet of Satoshi integration of Spark makes (made?) every users transaction publicly auditable. See for example this thread. ↩
The plugin immediately force-closes channels (before they gather enough confirmations to become usable) rather than refusing to cooperate in the transaction because "in some cases only the remote node has access to the fully signed transaction" (see here). I believe in Acinq's case such a situation can arise when dealing with splice-out that sends funds to sanctioned addresses. It should be also possible to optimistically try to reject "infringing" channel operations at the negotiation level. ↩
https://twiiit.com/cakewallet/status/2028531059160182943