📅 Original date posted:2023-01-04
🗒️ Summary of this message: A proposal for a faster way to move funds from an on-chain address to the Lightning Network using regular swaps, which simplifies the process and reduces trust requirements.
📝 Original message:
Hi Z,
> * Submarine swap/peerswap: Requires confirmation before the swap service
> will send out the HTLC on Lightning.
I might be missing something, but I don't see how this is different from a
normal on-chain to off-chain swap (calling this Loop In for short in the
remainder of the email).
Given some static swap server params (server key, user key, preimage), a
user can derive a tapscript tree and use that to make addresses that any 3rd
party can send to. Services like Loop return a few addrs (including P2TR!)
the client can use depending on their wallet sophistication [1] (in this
case the command is: `loop in --amt=X --external\, external means a 3rd
party will send to the addr). After a 3rd party sends to the script, the
swap can be completed at anytime as soon as the client is online (assuming
swap server is always there).
In the scenario above, the newly created outputs to our swap addr need to be
confirmed before the swap server will initiate the swap. As you mention,
this could even be zero conf assuming all sides take w/e precautions they're
comfortable with. If the swap server goes away for w/e reason, a long
timeout in the swap can let the user sweep the funds via some other
means eventually. This doesn't need to be a direct swap either, and it can
flow multi-hop like any other swap.
In your scheme you say that:
> If so, then the "timer for confirmation" starts as soon as the wallet
> receives on the blockchain, not as soon as the wallet decides to move
> funds from blockchain to Lightning.
Which seems to be the exact same as the flow I described above. For our
newer musig2-enabled swaps, the top level keyspend can be spent by both
parties, so you also emulate the ability for Alice to move the funds on
chain anywhere else w/ the server's cooperation.
Using regular swaps also simplified the "Bob Security" section a lot, as Bob
sends out an HTLC w/ the corresponding swap hash (he watches the chain for
the scripts, then initiates the swap once they're seen).
[1]: https://lightning.engineering/api-docs/api/loop/swap-client/loop-in
-- Laolu
On Tue, Jan 3, 2023 at 5:58 AM ZmnSCPxj via Lightning-dev <
lightning-dev at lists.linuxfoundation.org> wrote:
> Subject: Swap-in-Potentiam: Moving Onchain Funds "Instantly" To Lightning
>
> by Jesse Posner, ZmnSCPxj
>
> Introduction
> ============
>
> Moving funds from an onchain-only address to Lightning Network is slow,
> especially if you desire trust-minimization (which removes solutions
> relying on 0-conf).
>
> Basically, to reduce trust requirements in all onchain transactions,
> onchain receivers *MUST* ensure confirmation of the onchain transaction
> that creates their UTXO.
> In practice, the minimum should be at least 3 blocks, since reorgs of
> up to 2 blocks are common occurences, but even 1 confirmation can
> take an inordinately long time in the real world due to the random
> nature of mining.
>
> This is particularly acute for mobile phone use-cases.
> As mobile phones run on a battery, mobile phone OSs often greatly
> restrict CPU and other resource consumption when an app is not
> currently open by the user.
>
> Now consider this user story, for a wallet app that supports both
> Bitcoin blockchain and Lightning Network operations:
>
> * The user wants to be paid over the Bitcoin blockchain.
> * The user gets an address from their wallet and provides it to
> some other party to receive their payment.
> * The user closes their wallet app, which causes the mobile phone
> OS to kill all its threads.
> * The other party sends their payment over blockchain while the
> user is asleep.
> * The blockchain transaction confirms and time passes.
> * The user wakes up and checks their favorite blockchain explorer,
> and sees they received funds on their wallet address.
> * The user opens their wallet app and decides they need a coffee,
> so they buy coffee over Lightning.
>
> For current solutions to move funds from the blockchain layer to
> Lightning, however, the above user story would need to complete
> over a long time, possibly measurable in dozens of minutes or
> even hours in the worst case, due to the need for confirmation:
>
> * Channel open: Requires confirmation, many nodes require 6 or
> more confirmations.
> * Submarine swap/peerswap: Requires confirmation before the swap
> service will send out the HTLC on Lightning.
> * Splice-in: Channel remains operational, but until the splice
> transaction confirms, the channel operates in "dual mode"
> where both pre-splice and post-splice state is valid, and
> that means only the lower amount of the pre-splice and
> post-splice can be used in the mean time.
> For splice-in, the pre-splice amount will be lower, thus
> the amount being spliced in will not be credited until
> the splice transaction is confirmed.
>
> In this writeup, we present a novel protocol, swap-in-potentiam,
> that can be used for immediate transfer from the blockchain
> layer to the Lightning layer, in the above user story.
>
> Advantages And Limitations
> --------------------------
>
> To whet your appetite, here are the advantages:
>
> * Immediate transfer of already-confirmed-received onchain
> funds to Lightning.
> * Onchain funds can also be transferred to another onchain
> address (subject to normal onchain confirmation rules).
> * This can be "immediate" if sending to a receiver that
> accepts the risk of 0-conf onchain transactions.
> * Minimized trust requirement.
>
> The disadvantages, to help convince you that yes, this is
> technology and not magic beans (and to not oversell this
> tech, Bitcoin media reporting often tend to oversell
> new technologies because the disadvantages are often
> hidden away behind technical minutae):
>
> * Requires a cooperating LSP.
> If LSP is down or refuses to cooperate, onchain funds
> are locked for some time.
> This has a timeout (so if the LSP never comes online
> again, you just wait out the timeout) and the timeout
> starts from when the receiving UTXO is confirmed in a
> blocks, so it will not cause loss of funds, only loss
> of opportunity (i.e. "involuntary HODLing").
> * If you have multiple LSPs, when you generate an address
> you *have to* select one of them at that point, you
> *cannot* commit to multiple LSPs and select one of them
> later when your phone wakes up again.
> This exacerbates the above disadvantage, since you have
> to select one of your LSPs and hope that when your
> phone wakes up the LSP you selected is also up and
> cooperative.
> * The onchain-received funds have to be confirmed first,
> otherwise we still need to wait for confirmation of the
> onchain-received funds.
> This is generally true for many blockchain-only wallets
> anyway and is thus not a worsening, but is also not an
> improvement.
> * If the timeout is too near, actions must be performed
> onchain that require confirmation.
>
> Swap-in-Potentiam
> =================
>
> All onchain fund movements, as noted, require confirmation.
> These include onchain fund movements to the Lightning network.
>
> If the onchain address that the wallet provides was controlled
> solely by that wallet, then any action that requires cooperation
> with a Lightning Network participant --- channel open, swap, or
> splice --- would require an onchain transaction that commits to
> that specific Lightning Network participant.
> Only when the new onchain transaction is confirmed, can that
> Lightning participant rely on the transaction output without
> having to trust the initiator.
>
> From there, we can consider: what if the wallet provides an
> address that *already* commits to that specific Lightning Network
> participant?
>
> If so, then the "timer for confirmation" starts as soon as
> the wallet receives on the blockchain, not as soon as the wallet
> decides to move funds from blockchain to Lightning.
>
> This is a significant difference for a mobile wallet: the mobile
> environment does not support the mobile wallet being online for
> long.
> Thus, the mobile wallet may not have any CPU to make the decision
> to move funds from blockchain to Lightning, until the actual user
> explicitly opens the mobile wallet app.
>
> It has already been generally accepted that due to the limitations
> of the mobile phone environment, a mobile phone wallet with
> Lightning support would need some LSP anyway.
> Thus, a mobile wallet that can receive on the blockchain layer
> and then send on the Lightning layer can commit to a specific,
> different, Lightning participant: the LSP it has channels with.
>
> Thus, the mobile wallet can provide an address that commits to
> one particular Lightning Network participant: its LSP.
>
> The mobile wallet can then initiate a single-hop swap with the
> LSP when the mobile wallet app is in the foreground and has CPU
> to think with.
> If it received funds into the address that have already been
> confirmed, then it can do this single-hop swap immediately with
> its LSP.
> The LSP can immediately resolve this swap, crediting funds to
> channel, while atomically ensuring it has sole claim to the
> onchain UTXO.
>
> The Contract
> ------------
>
> The contract has two participants: Alice the funds owner, and
> Bob its potential swap partner.
>
> Once *any* funds have been confirmed received into an address
> committing to this contract, Alice owns the funds and can
> dispose of them as it likes (with cooperation from Bob).
> The source of the funds need not be Alice, it could be a third
> party that has an obligation to pay Alice onchain.
>
> The contract has only 2 branches:
>
> * Onchain/channel branch: Alice and Bob.
> * Timelock branch: Alice plus a relative timelock (`OP_CSV`)
> measurable in weeks.
>
> Astute readers will realize that the above is really a variant
> of [CLTV-style unidirectional time-limited channels][1],
> themselves a variant of Spilman-style channels:
>
> * Uses an explicit opcode to simplify channel setup (no need
> to pre-sign a timeout transaction between Alice and Bob,
> can just send funds directly to the address).
> * Uses a relative locktime instead of an absolute one to
> allow funding of the channel address (= receive onchain
> funds ready to spend over Lightning) at any time.
>
> The use-cases this enables are:
>
> * If Alice wants to pay to another onchain address, and Bob
> is also online and cooperative, Alice can ask Bob to help
> sign the Onchain/channel branch to move the funds in any
> arbitrary onchain manner.
> * If Alice wants to pay to a Lightning invoice / keysend, and
> has insufficient Lightning outgoing capacity (but has
> sufficient *total* capacity), it can swap with Bob, by
> offerring a transaction that spends via the Onchain/channel
> branch and instantiates a fresh onchain HTLC that Bob can
> then forward over Lightning.
> As soon as Alice offers its signature of that transaction,
> Bob can immediately offer an in-Lightning HTLC to Alice on
> their channel, and then Alice can immediately resolve it
> (thus immediately getting its funds into Lightning).
> * If Bob is offline or uncooperative, Alice can unilterally
> recover its funds after the timeout in the Timelock
> branch.
>
> Trust is required only to the extent that Alice trusts Bob to
> be cooperative so that Alice can dispose of its funds immediately.
> In case Bob turns out to be non-trustworthy, Alice can recover
> its funds via the timelock branch after the timeout period.
> There is no scope for Bob to steal funds (indeed, it is easier
> for Bob to steal Lightning funds than to steal swap-in-potentiam
> funds).
>
> The intent here is that the mobile wallet is Alice, while the
> LSP is Bob.
>
> ### Bob Security
>
> Bob *MUST* ensure that, for each UTXO, it is either asked to
> sign an arbitrary onchain transaction (i.e the first use-case
> above) *OR* it gets offered an onchain HTLC from that UTXO.
> Once Alice has asked Bob to cooperate in either case for a
> particular UTXO, Bob *MUST* ensure that it does not sign the other
> case (and Bob *MUST* refuse to cooperate in the other case once
> one case has been requested).
>
> In addition, Bob *MUST* ensure that, if it is used in the
> "channel" case (i.e. the second use-case above), the timeout of
> the Timelock branch is far enough in the future that it is likely
> that spends using the Onchain/channel branch have confirmed by
> then.
>
> With both invariants enforced by Bob, Bob can ensure that, if
> Alice requests a swap using the Onchain/channel branch, only Bob
> can spend the UTXO (at least before the timeout), and thus can
> safely offer a Lightning HTLC to Alice immediately without any
> additional waiting for onchain confirmations.
>
> As Bob needs to know the UTXO in the first use-case above, this
> requirement prevents the use of blind signing techniques when
> implementing the first use-case.
> Basically, when being asked to sign, Bob must generate the entire
> `SIGHASH` from data that Alice provides, so that Bob is able to
> keep track of UTXOs it is signing for.
>
> ### Remote Swap
>
> While Bob is generally considered "the" LSP of the mobile wallet
> Alice, nothing in the Lightning protocol actually requires that
> Bob be a direct peer of Alice.
> The only real requirement is that Bob is able to send funds to
> Alice over Lightning in exchange for possession of the equivalent
> onchain funds.
>
> Against this, we should note that the mobile wallet is already
> dependent on one or more LSPs anyway, so it may as well just use
> its direct peer LSPs instead of a remote node.
>
> ### Address Derivation
>
> Swap-in-potentiam addresses can be derived from a root public or
> private key.
>
> We only need one keypair each from Alice and Bob.
> Alice can use standard derivation paths for its keypair.
>
> As Bob is intended to be an LSP, we can just use its Lightning
> node ID as the public key.
> Bob needs to be in possession of the corresponding private key
> anyway in order to set up BOLT 8 encrypted transports.
>
> As LSPs are part of the public network, Alice can simply try to
> scan for all published nodes that advertise support for
> swap-in-potentiam.
> Alternately if the wallet has a short list of fixed LSPs it
> will use, it can simply refer to that list.
>
> Thus:
>
> * Alice uses a derived keypair.
> * Bob uses a fixed keypair (its Lightning node ID).
>
> The above is sufficient to derive swap-in-potentiam addresses
> from an `xprv` or `xpub` root key.
>
> Swap-in-potentiam For LSPs
> ==========================
>
> While the original design of swap-in-potentiam has the mobile
> wallet in the "Alice" role and its LSP in the "Bob" role, it
> turns out that LSPs can provide special service to improve
> receiving mobile wallets.
>
> Suppose that the LSP keeps track of statistics, and thus has
> an idea of which of its mobile wallet clients are likely to
> be net receivers.
>
> Net receivers will often have low inbound capacity (since the
> inbound capacity has been used up during previous LN receives).
>
> During times of low onchain fees, an LSP can check which of its
> offline mobile wallet clients have low inbound capacity, and are
> likely to come online in the future to receive.
> In those cases, the LSP can commit funds to a swap-in-potentiam
> with the mobile client, with the LSP as "Alice" and the mobile
> client as "Bob".
> This at least lets the LSP set up half of a swap during a time of
> low fees.
>
> If the transfer to swap-in-potentiam addresses is confirmed by
> the time the mobile wallet client comes online, the LSP can
> immediately initiate a swap, giving inbound capacity towards the
> mobile client.
> This swap can be immediately resolved, and allows the mobile
> wallet client to immediately receive funds over Lightning.
>
> In particular, if "offline receive" as designed by TheBlueMatt
> is implemented, then the LSP already has indication of a pending
> payment towards an offline mobile wallet client.
> The LSP can check if the offline mobile wallet client has
> insufficient incoming capacity to receive the funds, and if so,
> arrange to fund a swap-in-potentiam with that client.
> Then, when the mobile wallet client comes online, the LSP can
> initiate the swap with them, and once the swap completes (and
> thus the mobile wallet client has sufficient incoming capacity)
> the LSP can contact the sender LSP to complete the payment.
>
> In particular, this use-case allows for *immediate* receives as
> soon as the mobile wallet client gets foregrounded and has CPU
> time, **without** requiring 0-conf trusted transactions and
> thus without requiring any kind of semi-custodial trust, even
> if the mobile wallet client had insufficient incoming capacity.
> A channel still has to be set up beforehand (without 0-conf, if
> trusting funds to the LSP is undesirable).
>
> Implementation Sketch
> =====================
>
> The intent is to use Taproot with Schnorr signatures, but
> **without** using the keyspend path (at least initially).
>
> The plan currently is to use a `MuSig(A, B)` as the internal
> pubkey, but with the branches still explicitly laid out as
> tapleaves.
> That is, there are two tapleaf SCRIPTs corresponding to the
> two branches described above:
>
> * `<A> OP_CHECKSIGVERIFY <B> OP_CHECKSIG`
> * `<timelock> OP_CHECKSEQUENCEVERIFY OP_DROP <A> OP_CHECKSIG`
>
> Using an explicit 2-of-2 branch rather than a MuSig allows
> for a simple protocol at least for initial deployment:
> we can have Alice send the signature using `A` in a single
> half-round without having to engage in a 2-round MuSig2 signing
> ritual.
>
> We intend to use Taproot since the mobile wallet client
> may need to use a 2-of-3 or 2-of-2 signing scheme, similar
> to Blockstream Green.
> This allows either Alice or Bob in the contract to secretly
> be a FROST 2-of-3 or MuSig 2-of-2 (or any FROST k-of-n or
> MuSig n-of-n).
> This is also another reason for avoiding a 2-of-2 MuSig
> keyspend path between Alice and Bob, as there is (to our
> knowledge) no publicly-reviewed security proof that
> FROST-in-MuSig and MuSig-in-MuSig are safe (or the
> corresponding variants using MuSig2 for the signing
> ritual).
>
> Later, when we are more confident of the use of MuSig2 and
> FROST inside a MuSig2, and with using MuSig2 with possibly
> untrusted outsiders (who might exploit any mis-implementation
> of the MuSig2 signing protocol if we are not careful with
> designing it), we can seamlessly upgrade the protocol
> to use the keyspend path later, to save witness bytes.
>
> For the Onchain use-case (i.e. Alice wants to spend the UTXO
> to an onchain address), the protocol betweeen Alice and Bob
> would be:
>
> * `request_arbitrary_signature` Alice->Bob: Requests Bob
> to sign a PSBT spending a swap-in-potentiam address
> using the Onchain branch.
> * `response_arbitrary_signature` Bob->Alice: Response to
> the above, returning the requested signature.
> * `reject_arbitrary_signature` Bob->Alice: Sent in
> response to `request_arbitary_signature` if Bob refuses
> to cooperate (e.g. the UTXO being spent has already
> been accepted by Bob in a Channel use-case below).
>
> For the Channel use-case (i.e. Alice wants to spend the UTXO
> to a Lightning receiver), we operate the swap-in-potentiam
> UTXO(s) as a Spilman-like channel over two states:
>
> * HTLC-offering: Offering an amount `N` HTLC from Alice to
> Bob, with any remaining amount to a change address to
> Alice.
> * Resolved: Giving the amount `N` outright to Bob, with any
> remaining amount to a change address to Alice.
>
> The intention is that the channel is initially put into
> the HTLC-offerring state.
> Then Bob offers a corresponding in-Lightning HTLC to Alice
> over their channel.
> When Alice resolves the in-Lightning HTLC, it can then
> send a new signature for the Resolved state.
> Once the channel is in a Resolved state, Bob *SHOULD* sign
> the last state and broadcast it on the blockchain, thereby
> closing the Spilman-like channel.
>
> The protocol messages for the Channel use-case are:
>
> * `request_swap_in` Alice->Bob: Tell Bob the UTXOs with
> the same swap-in-potentiam address to spend, how
> much to put into the Alice->Bob channel direction,
> what channel to move into, and (optionally) a change
> address for Alice.
> * `reject_swap_in` Bob->Alice: Sent in response to
> `request_swap_in` if Bob refuses to cooperate (e.g.
> one of the UTXOs on offer was already signed with
> `response_arbitrary_signature`, or Bob cannot legally
> accept control of funds from one or more of the UTXOs
> offerred).
> * `accept_swap_in` Bob->Alice: Sent in response to
> `request_swap_in`, containing the Bob-side address to
> send funds to later once the state is Resolved.
> * `swap_in_signed` Alice->Bob: Response to
> `accept_swap_in`, containing the Alice-side signature
> for the HTLC-offering state transaction.
> Once Bob receives this, Bob can safely construct a
> new on-Lightning HTLC using BOLT1
> `update_offer_htlc`.
> * `swap_in_resolved` Alice->Bob: Sent after Alice has
> acquired the funds via `update_fulfill_htlc` of the
> corresponding on-Lightning HTLC, containing the
> Alice-side signature for the Resolved state
> transaction.
> The Resolved state transaction spends to the Bob-side
> address given in `accept_swap_in`, and any change to
> the Alice-side change address in `request_swap_in`.
>
> The plan is to reserve only one odd BOLT1 message ID,
> and to embed the actual swap-in-potentiam message ID
> as the first 2 bytes of the BOLT1 message, to reduce
> pollution of the limited BOLT1 message ID space and to
> allow more flexibility for swap-in-potentiam to expand
> to new messages inside its own message ID space.
>
> For a richer future protocol, we will want to consider
> how a swap-in can be combined with a splice-in.
> This is useful if the current total capacity of the
> channel is lower than the available onchain funds.
> The swap-in can be credited immediately (and is limited
> to the current total capacity) while additional funds
> can be added to the channel via splice-in (which is
> credited only once the splice-in is confirmed).
>
> As-is, a similar result can be obtained using openv1,
> wherein a swap-in is combined with a channel open,
> with the swap-in immediately credited while the channel
> open is awaiting confirmation:
>
> * Alice and Bob currently have one or more existing
> channels, and Alice has a UTXO in a swap-in-potentiam
> address whose value exceeds the incoming capacity of
> the existing channel(s).
> * Alice->Bob `open_channel`.
> * Bob->Alice `accept_channel`.
> * Alice->Bob `request_swap_in` with the "change address"
> being the funding address of the channel.
> * Bob->Alice `accept_swap_in` provides the TXID of the
> funding transaction (Alice now knows the "change
> address" and the Bob final Resolved address, letting it
> know the final Resolved state transaction TXID).
> * Alice->Bob `funding_created` with the TXID.
> * Bob->Alice `funding_signed`.
> * Alice->Bob `swap_in_signed` to provide the signature
> spending the swap-in-potentiam address to Bob.
> * Bob then constructs an HTLC over the existing channel,
> which Alice claims, revealing the preimage.
> * Alice->Bob `swap_in_resolved`.
> * Bob then broadcasts the Resolved state transaction,
> which is also the funding transaction of the new channel.
> * Both Alice and Bob await confirmation of the transaction
> in order to use the new channel.
> Alice can still use the existing channel, which has been
> topped-up with fresh outgoing capacity by the swap-in.
>
> (The above is not safe, as Bob can complete the protocol
> by using the HTLC-offerring state transaction; this can
> be fixed by having Alice open *2* channels with the same
> amount, one with the HTLC-offering state transaction as
> the funding tx, the other with the Resolved state
> transaction as the funding tx, and later `error`ing the
> channel corresponding to the transaction that is not
> confirmed; this is left as an exercise to the reader,
> though note that it requires two different change addresses
> for Alice for both HTLC-offerring and Resolved states,
> which can be arranged for the protocol)
>
> --
>
> [1]:
> https://en.bitcoin.it/wiki/Payment_channels#CLTV-style_payment_channels
>
> _______________________________________________
> Lightning-dev mailing list
> Lightning-dev at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20230103/5b5b2cad/attachment-0001.html>