alexbosworth / lightning

Lightning client methods
MIT License
126 stars 32 forks source link

fundPsbt is trying to add change output where not necessary - causes "insufficient funds available to construct transaction" #156

Closed adambor closed 8 months ago

adambor commented 8 months ago

I am using LND with external coinselection, it just so happened that one utxo was almost the same value as the output + fee - so my coinselection algorithm produced a 1-in 1-out transaction. However when trying to pass these parameters to fundPsbt, it returns an error UnexpectedErrorFundingTransaction: wallet couldn't fund PSBT: could not add change address to database: fee estimation not successful: insufficient funds available to construct transaction, here are the params used:

{ 
  inputs: [
    {
      transaction_id: '086e6d5f538fadb464c7c4c631f86b5522cac1eeee5f535dfafe96c47e1208ad',
      transaction_vout: 0
    }
  ],
  outputs: [
    {
      address: 'tb1qd0s3u22y6sp7h57uul5feua8668yeujktr4vlg',
      tokens: 9883
    }
  ],
  fee_tokens_per_vbyte: undefined,
  min_confirmations: undefined
}

The input utxo has 10001 sats (you can check it on testnet: https://mempool.space/testnet/tx/086e6d5f538fadb464c7c4c631f86b5522cac1eeee5f535dfafe96c47e1208ad), this results in 10001-9883 = 118 sats fee, which should be enough for 1-in 1-out p2wpkh transaction. It seems like LND tries to add change output to it even though it is not required, and that change output causes the input value to be insufficient to cover the fees for such a transaction.

Is there a way to tell LND not to add any change output in the fundPsbt call? Or is there a way to generate the psbt on the client side without calling fundPsbt and then just sign it by LND using signPsbt - in that case I guess I would somehow need to get key derivation paths for the inputs, right?

alexbosworth commented 8 months ago

You might look at this lnd issue https://github.com/lightningnetwork/lnd/issues/5739

adambor commented 8 months ago

You might look at this lnd issue lightningnetwork/lnd#5739

Yep, that's exactly the issue. Question is if I can workaround that by creating my own PSBT without using fundPsbt, question is how do I get proper key derivation paths for the inputs (I expect those are required by signPsbt), is there any rpc call that could help with that? Apart from calling getMasterPublicKeys and then going through all the keys?

alexbosworth commented 8 months ago

FundPsbt won't really let you work around paying for a change output that doesn't exist, it will complain that it doesn't have enough funds when you try it

alexbosworth commented 8 months ago

I have an attempt here to just be able to avoid change outputs : https://github.com/alexbosworth/ln-sync/blob/master/chain/get_max_fund_amount.js

A workaround may be possible but ideally this LND issue could be solved, but it needs more signal to prioritize I guess

adambor commented 8 months ago

FundPsbt won't really let you work around paying for a change output that doesn't exist, it will complain that it doesn't have enough funds when you try it

Well, my direction of thought is to not use fundPsbt at all, I just get utxos with getUtxos, run coinselect on that, then construct the psbt on the client side, get the key derivation paths by looping through all keys returned from getMasterPublicKeys, and then sign that psbt with signPsbt call. Or maybe I can even use fundPsbt to give me the derivation paths in the generated psbt, then change that psbt to include only the inputs/outputs I want before signing it with signPsbt.

alexbosworth commented 8 months ago

Sure that could probably work

adambor commented 8 months ago

Turns out signPsbt doesn't require key derivation paths, so you can just create a psbt, specifying txId, vout, witnessUtxo & sighashType for the inputs, then call signPsbt and it will happily sign it and produce a valid transaction.

alexbosworth commented 8 months ago

There's also a potential fix here I think https://github.com/lightningnetwork/lnd/pull/7404