Submarine swaps allow lightning users to trustlessly swap between on-chain UTXOs and lightning balances. They’re basically atomic swaps for the lightning network, and they’re incredibly useful for Lightning node operators to balance their channels, among other things.
As submarine swaps become increasingly important and more commonly used, it might be a good opportunity to see how we might better scale submarine swaps in an environment where more peers and providers are available to conduct swaps.
Review
A traditional submarine swap is a 2-party atomic swap using two hash-time lock contracts (HTLCs): one on-chain on Bitcoin, and one off-chain on Lightning.
Say we have Alice, who wants to sell on-chain bitcoin in exchange for a lightning payment, and Bob, who wishes to buy Alice’s on-chain funds with his off-chain lightning balance.
First Alice generates a random secret
Alice and Bob construct a 2-of-2 escrow address which gives Bob full spending power if he learns
Example with descriptors:
1 | tr( |
Alice deposits her coins into the 2-of-2 escrow contract, confident she can reclaim them at blockheight
Alice gives Bob a lightning invoice for the same amount of coins, using
And voila! Bob and Alice have swapped on-chain and off-chain coins with one-another, and neither has any opportunity to cheat. To improve privacy and efficiency, Alice and Bob can cooperate once Bob pays the lightning invoice, by using MuSig to co-sign a transaction which surrenders the escrowed coins to Bob.
Efficiency
Some submarine swap providers such as LightningLabs’ Loop batch their on-chain transactions. When sweeping on-chain coins they receive, they do so in batched transactions to better consolidate large amounts of coins in fewer UTXOs. When funding submarine swap escrow contract addresses, they do so in batched transactions as well, with each output funding a distinct submarine swap contract.
There is still an efficiency bottleneck here though, because of the topology of the submarine swap protocol itself. We have many small nodes (users) all interacting only with a single submarine swap provider, such as Loop or Boltz. Users are not aware of each other’s transactions at all, and so each submarine swap is a completely self-contained contract between a single user and a single swap provider. This creates waste.
Every single on-chain to off-chain submarine swap requires a separate funding transaction by users, since users are generally not aware of each other and so cannot batch their funding transactions together. Furthermore, each submarine swap creates its own independent funding output, and so even if funding transactions are batched (as they would be in the case of Loop’s off-chain to on-chain protocol), we still have
Scaling
We can improve efficiency by scaling submarine swaps up from a single-taker protocol to an
This increases complexity and fragility of the protocol, but also improves on-chain efficiency dramatically. Let’s see how it works.
On-Chain -> Off-Chain takers
We’ll first examine the case of on-chain to off-chain swaps by
- The Takers: A group of
parties who want to swap smaller on-chain UTXOs in exchange for off-chain lightning channel balances. - The Maker: An individual or business who wants to exchange their LN balance for on-chain coins.
Instead of funding
The maker creates
random secret preimages (one for every taker). Takers and maker collaborate to create an
-of- taproot hashlock address which pays to the maker if they can reveal .
Here is an example 3-of-3 hashlock expressed with descriptors:
1 | tr( |
Using taproot, we can hide what could become a very large hashlock script off-chain if everyone cooperates, by using the 4-of-4 internal key to handle the cooperative spending path. We use hash160
instead of sha256
to save block space, while preserving the option to use Lightning HTLCs (which use plain sha256
) with the same preimage secrets.
- Takers construct a funding transaction which spends the takers’ UTXOs, paying into the multisig address (with possible change outputs). The takers do not sign the funding transaction yet.
- The takers construct a timeout transaction which returns their money. The timeout transaction distributes the funding transaction output back to the takers. An absolute locktime of blockheight
must be enforced on the timeout transaction. - The takers and maker cooperatively sign the timeout transaction. The maker is OK with this, due to the timelock.
- The maker sets up
lightning HTLC offers which pay each of the takers their respective amounts for the swap. The lightning HTLC paying to taker uses payment hash . Takers may use distinct amounts. Takers cannot claim these HTLC offers yet, because the maker alone knows the preimages for each HTLC. The absolute timelock on each of these lightning HTLCs must be at least , where is a reasonable block delay. - Once all takers have received their lightning HTLC offers, the takers cooperatively sign and publish the funding transaction.
- Everyone waits for the funding transaction to be mined.
The maker now has three choices.
1: Forceful (On-Chain)
The maker can use the preimages
If the maker waits to sneak in their claim transaction at the last possible moment, this will, at worst, give the takers
2: Cooperative (Off-Chain)
The maker can give each of the preimages
If any takers run away with their preimage without giving a signature to the maker in return, the maker still has the option to claim the funding output forcefully on-chain.
Note that it would be irrational for the maker to only give out some of the preimages, and not others, as each preimage is effectively a right to claim some off-chain coins from the maker. If the maker wishes to be fully compensated on-chain, they must eventually reveal all preimages, or else none of them.
3: Timeout
The maker can choose not to reveal any of the preimages. The takers will thus be unable to claim the maker’s lightning HTLC offers. Once blockheight
Performance
If we had instead used
distinct funding transactions with at least one input and one output each distinct inputs to claim the funding UTXOs (possibly batched into a single TX)
In the optimal case, our batched approach reduces the on-chain footprint of these
- One funding transaction with at least
inputs, and at least one output (probably more, due to change outputs) - One input to claim the funding UTXO (possibly batched with other funding UTXO claims)
It’s worth noting that if
Off-Chain -> On-Chain takers
Now let’s see how this same approach works in reverse.
In this scenario, we have:
- The Takers: Multiple smaller parties who want to spend their off-chain lightning channel balances to receive small on-chain UTXOs.
- The Maker: An individual or business who wants to exchange their large on-chain UTXOs for off-chain lightning channel balance.
Instead of funding
- The maker creates
random secret preimages (one for every taker). - Takers and maker collaborate to create a
-of- taproot hashlock address.
Here is an example hashlock address with 3 takers expressed with descriptors:
1 | taker_joint_pubkey = musig( |
Note how in this script, the takers are the joint recipients of 3 distinct hashlock spending branches, where any one of the three preimages for <hash1>
, <hash2>
or <hash3>
can be used by the takers to claim the coins.
- The maker constructs a funding transaction which spends the maker’s UTXOs, paying into the HTLC address (with possible change outputs). The maker does not sign the funding transaction yet.
- The maker constructs a timeout transaction which returns their money. The timeout transaction spends the funding transaction with an absolute locktime of blockheight
. - The takers and maker cooperatively sign the timeout transaction. The takers are OK with this, because of the timelock.
- The takers cooperate to construct
claim transactions, which each split the funding UTXO among the takers using a different taproot hashlock spending branch. The takers cooperatively sign all claim transactions, none of which may be published until one of the secrets is known. The takers are each OK with signing this, because it doesn’t spend any of their own money. Each taker must have a fully signed claim transaction for their respective hash, , so that if taker learns , they will be able to publish that claim transaction. - The maker signs and publishes the funding transaction.
- Everyone waits for the funding transaction to be mined.
- The takers set up
lightning HTLC offers which pay the maker their respective amounts for the swap using the payment hash for each taker . Takers may use distinct amounts. The timelock on each of these HTLCs must be at most , where is a reasonable block delay. The maker must wait until all HTLCs are active to settle any of them. - The maker can use their preimage secrets
to settle any or all of the lightning HTLCs offered by the takers. This reveals at least one preimage to at least one of the takers. Note that a rational maker should claim all or none of the takers’ HTLCs, because exposing even a single will let the takers split the funding UTXO using one of their claim transactions.
Each taker now has two choices:
1: Forceful (On-Chain)
Any taker
If the maker waits to reveal all preimages
2: Cooperative (Off-Chain)
Once the maker has claimed all lightning HTLCs, and the preimages
If anyone fails to sign this new transaction, a taker can always fall back to publishing a forceful claim transaction, as long as they do so before blockheight
Timeout
If, instead of revealing preimages, the maker simply does nothing, then the takers’ lightning HTLC offers will expire at block height
If the takers become unresponsive after the maker publishes the funding transaction, then the maker simply waits until blockheight
Performance
If we had instead used
distinct escrow-funding outputs (possibly batched together in one funding TX) distinct transactions to claim the funding UTXOs, with at least one input and one output each (batching unlikely)
In the optimal case, our batched approach reduces the on-chain footprint of these
- One escrow-funding output (possibly batched in a larger meta-funding TX)
- One claim transaction to split the funding UTXO, with one input and
outputs
In the case where some takers or the maker are uncooperative, the takers will need to use one of the hashlock branches to claim the on-chain funds.
Less Griefing Plz
Although scaling submarine swaps up to multiple parties is clearly possible, the concrete efficiency gains are debatable, because they largely depend on all parties in the procedure cooperating. This is especially true for the on-chain to off-chain takers scenario, where even a single unresponsive taker can force the market maker to burn extra fees publishing a bunch of seemingly unnecessary hashes and preimages.
The same griefing risks exist for traditional submarine swaps, but are more pronounced in a multi-party setting because one bad apple can make the whole swap more expensive for everyone.
To discourage griefing by takers, a maker might implement a combination of techniques:
- Fees. The maker can either add fees onto the invoiced amount which takers must pay (in the case of off-chain to on-chain takers), or reduce the value of the HTLC the maker offers to takers (in the case of on-chain to off-chain takers). This incentivizes makers to offer swapping services and makes some griefing attacks more expensive.
- A deposit system. A maker may force takers to offer up an HTLC for a small percentage of their requested swap amount as a deposit, using a Lightning HOLD invoice. If the taker is cooperative during the swap, the maker can release the deposit back to the taker by canceling the invoice. If the taker misbehaves, the maker can settle the invoice, taking the deposit as punishment. This deposit is not trustless - the maker can take it unilaterally, and so a modicum of trust, accountability, or reputation is needed.
- Anonymous usage tokens. A taker could purchase ecash tokens in bulk from a maker, which can later be redeemed anonymously in exchange for the right to participate in a multi-party submarine swap with that maker.
- Fidelity bonds. These would allow anonymous makers or takers to prove they are committed to transacting honestly by sacrificing some number of bitcoins to earn a persistent maker/taker identity.
Future Work
- Point-time lock contracts (PTLCs) on Lightning would enable significantly more private and efficient on-chain resolution of multi-party submarine swaps in either direction. What would a PTLC-powered multi-party submarine swap look like? How much more efficient would it be, exactly?
- Is it possible to perform
-to- submarine swaps, with on-chain UTXO sellers and buyers paying with Lightning?