Open ZmnSCPxj opened 6 years ago
Thinking more, it seems that using RBF for onchain withdrawals requires withdrawals to wait for channel funding to confirm at least once, and channel funding to wait for withdrawals to confirm at least once.
The issue with using RBF is the below race condition:
Thus we cannot spend from the change output of an RBF transaction until the RBF transaction confirms deeply enough. At the minimum, we should suspend fundchannel commands if there are pending RBF withdrawals and there are not enough unspent coins, but the RBF withdrawal change output does have enough coins.
There is also the question of the below race condition:
In the above case we should use the transaction U and not T. Of course, deeper reorgs are also theoretically possible. Note that this is also important when we are receiving funds.
RBF gets complicated, so I suppose there is a reason why it is not well-implemented.
Ideally we should be able to accelerate both withdrawals and channel funding.
CPFP could be useful as a workaround, but I generally don't like it because it's quite expensive. If transaction A paid $1 in fees and is stuck, then in order to increase its effective fee to $1.50, you need to generate a child transaction B with $2 in fees. So you'd be spending $2, whereas RBF would only cost $0.50 (assuming equal size).
It's also cheaper to avoid change outputs when opening a channel, see #665.
I opened #668 to keep track of both approaches.
CPFP+RBF is simpler to implement under our current one-peer-one-channel architecture. Of course we probably want to have multiple channels per peer eventually, there are a few FIXME
comments referring to those. Even so CPFP+RBF is still simpler to implement than my full RBF algo.
A more general approach would be to have txaccelerateestimate
and txaccelerate
. Then, not only fundchannel
txid
would be accepted, but also withdraw
txid
(and more generally, txsend
/signpsbt
txid
) as well.
How to implement that is something of an open question however.
We can CPFP by creating a new transaction spending from the change output of any transaction we created ourselves. However, this new CPFP transaction should be RBF-able, so that further txaccelerate
would just replace that transaction instead of chaining yet another CPFP on top of it.
But supporting RBF probably means additional complexity in our wallet logic. In particular, if we implement txaccelerate
as plugin on top of fundinputs
/reserveinputs
/unreserveinputs
/signpsbt
/sendpsbt
we have to be able to "unspend" an input in order to sign a higher-fee RBF. I think.
Thoughts @niftynei @rustyrussell ? I think you are the main people hacking around the new PSBT-based wallet bits currently.
Anyway here is a new proposed interface:
txacceleratestart
txid
=> txacc_id
Starts a transaction acceleration session. No additional funds will be spent, but creates an object, a txacc
session, with a unique txacc_id
, for use with other txaccelerate
.
The txacc
session is automatically destroyed when lightningd
shuts down, or when the transaction originally being accelerated has been confirmed.
txaccelerateestimate
txacc_id
=> total_fee
delta_fee
max_fee
For the given txacc
session, gives an estimate on how much more a succeeding txaccelerate
will cost. This might change when called multiple times, depending on current mempool/blockchain fee estimation.
max_fee
is the amount that can be put into fees. If total_fee
reaches max_fee
and delta_fee
is zero, then it is not possible to accelerate the transaction further, either because of lack of funds in the wallet, or if we are using CPFP to accelerate the transaction and there is insufficient change to accelerate the funds.
This may error with error code TXACCELERATE_ID_NOT_FOUND
if the transaction was already confirmed.
txaccelerate
txacc_id
[total_fee
] => total_fee
delta_fee
max_fee
Actually attempt to accelerate the transaction originally specified in txacceleratestart
. If txaccelerateestimate
was called, uses the most recent estimate, otherwise it will perform the estimation and then apply it immediately.
You may override the total_fee
from the most recent estimation, providing a total_fee
that is equal or larger than the total_fee
from the most recent estimation, but less than the max_fee
.
This may fail with error code TXACCELERATE_ID_NOT_FOUND
if the transaction was already confirmed.
The above interface gives users some protection from lower-level details.
withdraw
/txsend
/sendpsbt
transactions could also be CPFP-ed for now, for simplicity.withdraw
/txsend
/sendpsbt
transaction where all inputs are owned only by our wallet, and which we know to be broadcast already, could in the future be RBFed instead of CPFPed.txid
, so using a txacc_id
gives the user a wrapper around this.max_fee
equal to total_fee
, and once the single-shot CPFP has been, uh, shotted, then we set max_fee
to total_fee
with a delta_fee
of 0 to indicate to the user that it cannot be accelerated further. This allows us to provide this interface minimally (just one shot, and the tx has to have a change output we can CPFP on) without having to handle any kind of RBF yet, at least for now.What do you think? @Sjors @niftynei @rustyrussell @cdecker @darosior ?
Hi @rustyrussell @cdecker Is there any hope to get CPFP or RBF on pending channel open transactions?
The current state of mempool is making this a burning requirement, as a-lot of people inadvertently low ball the channel opening fee and then are stuck in mempool with pending transactions.
This would be an awesome addition to the project and would definitely be helpful in this fee environment
You can do CPFP today if you use an external wallet to make the funding tx and it has a change output.
RBF has been implemented for experimental dual-funding/v2 opens.
On Fri, Mar 26, 2021 at 18:28 Evan Kaloudis @.***> wrote:
This would be an awesome addition to the project and would definitely be helpful in this fee environment
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ElementsProject/lightning/issues/475#issuecomment-808586617, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIMAKPPRS37PWSSS4SSRQTTFUKDJANCNFSM4EJUVVFA .
The withdraw
command worked for me (as CPFP bump).
lightning-cli withdraw NEW_CHANGE_ADDRESS all 100000 0 [FUNDING_UNCONFIRMED_TXID:CURRENT_CHANGE_INDEX]
* 100000 = 100sat/vbyte
RBF has been implemented for experimental dual-funding/v2 opens.
Reviving this old thread, but I got into situation where I opened channel with feerate=low and mempool started filling up. Because I opened from whole utxo (no change), I can't use CPFP.
In this situation RBF bump fee option would be useful even in regular, not dual funding channel.
LND has possibility to do lncli wallet bumpfee --sat_per_byte XXX TXID:NUMBER
but if I understand correctly it is not possible with c-lightning? Would be super useful.
/me now going to quietly panic about potentially stuck channel opening
want to bring this up again. I have 3 closing txs stuck in mempool and no idea what to do
Is a CPFP possible? If yes, how? What about the withdraw command here?
The
withdraw
command worked for me (as CPFP bump).
lightning-cli withdraw NEW_CHANGE_ADDRESS all 100000 0 [FUNDING_UNCONFIRMED_TXID:CURRENT_CHANGE_INDEX]
* 100000 = 100sat/vbyte
Please, I really need help to get those tx confirmed
Hi @Surenic what type of channel close are we talking about here, coop or force?
If it's a coop close, and the outputs are sizable, you should be able to CPFP with the withdraw
command as described above. Lookup the unconfirmed transactions in the mempool to find the correct index
If it's a force close and you initiated the close, you would need to wait till your lock time (or CSV delay) before you are in a position to CPFP the transaction
It is indeed a coop close. How do I know if the outputs are sizable?
And what would be the CHANGE_INDEX then?
Can you help me building the right command? Don't want to make anything wrong
lightning-cli withdraw NEW_CHANGE_ADDRESS all 30000 0 [cadb70f6b467f79a7fe969fe5b465f82d7369d3b4f6e3db2215c5a2ff2778085:CURRENT_CHANGE_INDEX]
Filled in the tx already and set fees to 30 sats/vB
NEW_CHANGE_ADDRESS - can I use any address or does it have to be a CLN Wallet address?
Right now my CLN wallet is completely empty. Would the fees be taken from the original UTXOs or do I need to put some sats on it?
🙏 thank you
Hi @Surenic, here's what you can do:
The fee will be taken from the unconfirmed output, so you don't have to worry about not having any sats on your wallet. Hope this helps
Thank you @saubyk,
unfortunately I get an Unknown UTXO error. I am sure that I have the correct txid and change_index (0), but it doesn't work. I was thinking that the tx is out of my mempool so I even resent it via bitcoin-cli sendwartransaction txhex, but this doesn't work too. I am out ideas now
Not sure if this will help, but you can try lightning-cli sendrawtransaction
once
I did that but the command was calling for allowhighfees
. As I tried to add this it said that allowhighfees has to be true or false :/ If you have a solution to this as I can't find any, it would be nice but otherwise I am giving up on this. Gladly the stuck amount is not much on my side. The peer is Kraken, so they won't do anything too I guess 🤣
But I definitely want to say thank you again for not giving up on helping me :)
edit: allowhighfees is a boolean so I had to set it to true. the tx was then sent with a success message. But anyway, the withdraw command fails with an unknown UTXO. Just to be clear, don't have anything to hide here anymore:
https://mempool.space/tx/cadb70f6b467f79a7fe969fe5b465f82d7369d3b4f6e3db2215c5a2ff2778085
the unconfirmed tx, its tx hash equals the txid? the output, which belongs to me is 0
so this command should be correct?
lightning-cli withdraw bc1qs7665seq49f0dmc0nsv2cnrdmprwrjalsmxdqq all 40000 0 '["cadb70f6b467f79a7fe969fe5b465f82d7369d3b4f6e3db2215c5a2ff2778085:0"]'
hi @Surenic the command you posted should've worked. It would help if you post the exact error message that you're getting when you execute it. My guess is that transaction is not in the mempool and I am unsure if sendrawtransaction
is rebroadcasting it. You can try restarting the node once, and then try again, in case the restart rebroadcasts the pending transactions back into the mempool.
cc @rustyrussell in case you have any other insights
Yes, sorry for that!
This is the output on sending the raw transaction by lightning-cli with allowhighfees=true
Even though I restart the node, the following error occurs on withdraw command
An idea, is to ensure as much as possible that channel funding transactions have a "change" output that is controlled by the built-in onchain wallet.
Then, if the funding transaction takes a long time to confirm on mainnet (due to the well-known congestion problems there), it would be possible to accelerate the channel funding transaction by creating a child transaction from the "change" output. This child transaction would have a larger-than-usual feerate (CPFP) to encourage mining of the channel funding transaction, and pay out to yet another address of the built-in onchain wallet. In addition, the child transaction would be marked RBF so that further increases of the fee can be done.
Using CPFP to speed up the channel funding transaction has the advantage that it requires no change to the Lightning BOLT protocol. Using RBF on the channel funding transaction directly requires that the both ends of the channel sign new versions of the commitment transaction.
While not a priority, I suspect this feature would be necessary before we can practically deploy to mainnet.
At the JSON-RPC level, I imagine:
Further calls to fundchannelaccelerate will be possible and will RBF the child transaction instead.
The fundchannelaccelerate command will silently fail without an error if the specified channel is already confirmed at least once.
Implementation-wise, we would need a new table for pending channel funding transactions. Entries in this table will be removed when the peer enters
CHANNELD_NORMAL
.When initially created only the
funding_tx_change_outnum
column has a non-null value. The first fundchannelaccelerate will fill incpfp_feerate
, with future calls bumping the feerate and recreating the CPFP acceleration transaction. fundchannelaccelerateestimate will compute a fee based on whethercpfp_feerate
exists or not and assuming a simple 1-input 1-output RBF transaction. Care point is when the change output runs out: this will cause acceleration to fail as there is no longer any change to pay with.Since lightningd will now scan UTXOs that appear onchain we should not use
addfunds
especially since the child transaction is RBF.