lnd icon indicating copy to clipboard operation
lnd copied to clipboard

Simplify coin selection logic for app devs

Open saubyk opened this issue 2 years ago • 5 comments

Coin selection process on LND has a potential for simplification from an application development perspective. I’ll take an example to do a simple coin selection operation for an on-chain spend operation on LND.

Listed below are the user operation and programmatic steps to achieve the desired outcome: Step 1: User makes a selection of coins from the displayed list of UTXOs Step 2: The selected UTXOs are locked with LeaseOuput API Step 3: Invoke the Estimate Fee API to calculate the correct amount to send out from the selected UTXOs based on user selection of the transaction fee Step 4: PSBT Fund API is called with the amount and the selected UTXOs as arguments and it returns funded_psbt string. Step 5: PSBT Finalize API is called to sign the inputs and prep for publishing the transaction. It returns raw_final_tx string Step 6: Publish the transaction. This step may fail if the amount is not specified accurately to cover the mining fee. If it fails, steps 2 to 4 have to be repeated correcting the amount in the output

Contrast this with how coin selection is implemented on Core Lightning: Step 1: User makes a selection of coins from the list of UTXOs and the fee rate Step 2: Call Withdraw API with the amount set as all, fee rate and the array of utxos

I believe that by offering a PSBT only path to enable coin selection, the application logic becomes unnecessarily complicated for pure-play coin selection functionality, which has nothing to do with PSBT. Instead a simple argument can be enabled for the SendCoins rpc to take an array of UTXOs and all the other complexities can be abstracted. Ideally, the arguments should be enabled with fundmax flag, so that application logic is further simplified without requiring to estimate the fee. In summary the SendCoins rpc can have the below arguments to enable simple coin selection:

  • array of inputs
  • user preferred fee rate or default
  • fundmax flag

The same argument applies for the process of opening channels with select UTXOs. If this approach is amenable, will open a separate issue for OpenChannel rpc

saubyk avatar Sep 27 '22 01:09 saubyk

In summary the SendCoins rpc can have the below arguments to enable simple coin selection:

I think this makes a ton of sense. Also we have everything we need under the hood to expose a simpler interface like this (it'll do all the locking, etc manually and hide other details from a user).

Roasbeef avatar Sep 28 '22 23:09 Roasbeef

@saubyk, @Roasbeef I'd like to pick up the OpenChannel part if possible. Have started to explore changes in lncli, rpcserver and funding reservation. I think I can submit a draft sometime soon.

hieblmi avatar Sep 29 '22 00:09 hieblmi

Hi @hieblmi thanks for the initiative, much appreciated. Please see the issue I created to define the scope of work for OpenChannel https://github.com/lightningnetwork/lnd/issues/6955 Looking forward to collaborate with you on this.

saubyk avatar Sep 29 '22 02:09 saubyk

In the design of this new API, it may be worth to consider the case where the caller crashes/disconnects before they receive the response. When they come back up, they won't know whether the transaction was published or not, and what the txid is. May not be a big deal for manual operations, but the development of any automated action is difficult without a good resume flow.

For BatchOpenChannel, a request id was added for this situation specifically.

joostjager avatar Sep 29 '22 06:09 joostjager

I've assigned this to me as I'd like to work on the utxo selection for SendCoin next. cc @saubyk

hieblmi avatar Feb 07 '24 15:02 hieblmi

Coin selection process on LND has a potential for simplification from an application development perspective. I’ll take an example to do a simple coin selection operation for an on-chain spend operation on LND.

Listed below are the user operation and programmatic steps to achieve the desired outcome: Step 1: User makes a selection of coins from the displayed list of UTXOs Step 2: The selected UTXOs are locked with LeaseOuput API Step 3: Invoke the Estimate Fee API to calculate the correct amount to send out from the selected UTXOs based on user selection of the transaction fee Step 4: PSBT Fund API is called with the amount and the selected UTXOs as arguments and it returns funded_psbt string. Step 5: PSBT Finalize API is called to sign the inputs and prep for publishing the transaction. It returns raw_final_tx string Step 6: Publish the transaction. This step may fail if the amount is not specified accurately to cover the mining fee. If it fails, steps 2 to 4 have to be repeated correcting the amount in the output

Contrast this with how coin selection is implemented on Core Lightning: Step 1: User makes a selection of coins from the list of UTXOs and the fee rate Step 2: Call Withdraw API with the amount set as all, fee rate and the array of utxos

I believe that by offering a PSBT only path to enable coin selection, the application logic becomes unnecessarily complicated for pure-play coin selection functionality, which has nothing to do with PSBT. Instead a simple argument can be enabled for the SendCoins rpc to take an array of UTXOs and all the other complexities can be abstracted. Ideally, the arguments should be enabled with fundmax flag, so that application logic is further simplified without requiring to estimate the fee. In summary the SendCoins rpc can have the below arguments to enable simple coin selection:

  • array of inputs
  • user preferred fee rate or default
  • fundmax flag

The same argument applies for the process of opening channels with select UTXOs. If this approach is amenable, will open a separate issue for OpenChannel rpc

I think this just needs to include the fee in the response to fund an API, utxos are locked after a call to fund a psbt already https://docs.lightning.engineering/lightning-network-tools/lnd/psbt#advanced-example-fund-psbt-with-manual-coin-selection

The doc stated something about, having the finalise API part in a hardened lnd, so I think that part should still be a separate step.

Chinwendu20 avatar Feb 20 '24 15:02 Chinwendu20

As discussed offline with @Chinwendu20 we currently pursue the following high-level approach to bring manual coin selection support to SendCoins:

  1. Add cli capabilities for lncli sendcoins --utxo bc1p... --utxo bc1p... --addr [--fundmax|--amt]
  2. Add utxo flags to lnrpc.SendCoinsRequest, similar to how we do it in lnrpc.OpenChannelRequest
  3. Thread the outpoints through to btcdwallet's CreateSimpleTx
  4. Add a new coin selection strategy for manual selection in interface wallet.CoinSelectionStrategy (requires btcdwallet PR)
  5. Skip the current auto-coinselection and provide selected outpoints
  6. continue the normal flow

The implementation should take into account

  • spending the total value of selected coins (fundmax)
  • sending a fraction of the total value of selected coins, rest to change output(amt)
  • considering the anchor channel reserve requirement

hieblmi avatar Feb 22 '24 18:02 hieblmi