pull down to refresh

I am preparing for a physical move and was recently moving funds off my LND node. Moving funds off LND was surprisingly difficult and demonstrated how lightning isn't really ready for the average user that isn't very technical and knowledgeable about Bitcoin. For me, it was a good learning experience and I think it's worth sharing with the community.

Unfortunate user defaults

To start off, I was running LND on umbrel. I know this isn't everyone's favorite way to run lightning, but it is easy to set up and it did the job for my needs over the past years. Umbrel is aiming to be the „the cloud in your home“, seemingly targeting an audience that isn’t technically illiterate, but also doesn’t require one to be an engineer. Moving funds off your LND is very easy. Umbrel offers a nice user interface to interact with your node. When setting up the withdrawal transaction though, it’s easy to make a mistake. Users have to opt-in to customize the transaction fees, otherwise the node’s default settings will be used. This is where my (admittedly stupid, because I should know better) mistake happened. Not paying attention, thinking that the automatic fee will be based on some sensible defaults based on current mempool conditions, I skipped setting up a custom fee. Unfortunately, the fee setting was set to 1.01sats/vB. The transaction made it into the mempool, but even at the currently low fees this meant that the transaction wasn’t going to be mined in a block in the foreseeable future. Not great if you are trying to shut down your node.

RBF to the rescue?

Upon inspecting the transaction on mempool.space, I noticed that the RBF (Replace by Fee) tag shining in green. I thought great – I haven’t used RBF before, but that’s a good time to try and learn. There isn’t a user interface for bumping the fee of your transaction, but luckily I am comfortable working in a terminal. I ssh’d into my umbrel node and started screening the documentation for bumping the fee on a transaction. (LND has a page that talks about Unconfirmed Bitcoin Transactions)[https://docs.lightning.engineering/lightning-network-tools/lnd/unconfirmed-bitcoin-transactions] which gave useful information about the bumpfee command. You first have to use $ lncli listchaintxns to find the transaction. Then, with $ lncli bumpfee you can bump the fee for an outpoint of a transaction – at least that is what I thought. Unfortunately, this doesn’t seem to be possible if the outpoint isn’t owned by the wallet itself. I’m not sure if this is an LND restriction or a Bitcoin thing? If you know, let me know in the comments!

Mempool Accelerator

So, RBF wasn’t working and my transaction still stuck. At this point, I was considering paying for the (mempool accelerator)[https://mempool.space/accelerator], which honestly seems to be a great service for less technical people, but was also extremely expensive compared to bumping the fees. In my case it would have been more than 10 times as expensive.

Meet CPFP

I wasn’t ready to give up and as I started doing more research, I learned about CPFP (Child Pays for Parent). I had not heard about this before, but the idea is simple. As the receiver of a transaction that is stuck in the mempool, you can broadcast a transaction that spends the UTXO again to another one of your addresses with a higher fee so that miners are incentivized to pick up both of the transactions. This ended up being a good solution, because I was sending from my node to another wallet. It ended up being tricky too though, because by that time, a lot of nodes have dropped the low-fee transaction from their mempool, which meant that the unconfirmed transaction wasn’t showing up in my receiving wallet. I also couldn’t find a way to double-spend from the lightning node, but I was able to point the receiving wallet to use the bitcoin node of my umbrel node from where I posted the transaction. This way, the transaction showed up in my receiving wallet and I was able to create the CPFP transaction. The last hurdle was to broadcast the transaction to the network, because the CPFP transaction requires the low-fee transaction and the low-fee transaction was rejected from the network due to the fees being to low. Luckily, switching the connected node in Electrum and simply retrying until a node accepted the transaction worked out in the end.
Overall, I feel like this experience showed how difficult running a lightning node can be. It’s too easy to make this kind of mistake. Mempool Accelerator and similar products can serve as a life-raft for less technical users, but they come at a high cost. There certainly is a lot of opportunity to improve the user experience for products like Umbrel.
I have had a lot of fear that I will make a mistake with my own node. I want to be as sovereign as possible, but I am not great with technical things. I am working on setting up Alby hub on my umbrel right now. This will be my third attempt to run my own lightning.
reply
559 sats \ 4 replies \ @k00b 28 Sep
@DarthCoin when he sees this
reply
LOL when k00b is making memes... Then is serious stuff. Good one!
reply
😂😂
reply
I am syncing the main chain right now. I will be going to your guide for sure when it is time.
reply
I thought darthcoin posted the memes. Lol
reply
Just wanted to ask - have you tried the LND lightning node on Umbrel? I too use an umbrel and honestly it's been really easy to use, no command line required.
Reading the instructions the 2 most important things seem to be 1) backing up the 24 words associated with the LND 'node' itself.
and 2) backing up the 'channel state' digitally on your computer/another computer for each channel you have open. That way should something happen to the Umbrel you can recover the funds + the state of the channel on another device.
reply
It's been a while since I had a node at all. I don't remember what exactly I tried. I was smoking a lot of weed back then, which never helps me learn new technical things. I am sure it has gotten easier. I'm looking forward to getting into it.
reply
lncli bumpfee is lame. It cannot RBF the original transaction, it can only CPFP if there is a change output going back to your LND wallet. It can RBF that second transaction if the fee was still insufficient. This is because it was introduced for bumping fee of channel opening/closing transactions, which are multisig and cannot be RBF'd by a single peer.
For a primer how to evict the low fee tx and double spend UTXOs read this: https://medium.com/@goryachev/bitcoin-node-security-case-study-e1ca00a378b5
reply
100 sats \ 0 replies \ @anon 29 Sep
The fact that RBF wasn't possible for your problem is a huge design flaw in the Lightning spec. What should happen is multiple transaction variants get signed for all the different fee rates you could possibly need, on both sides. You only need something like 100 variants maximum. Computers are really fast. Signing a bunch of extras isn't a big deal at all.
CPFP is stupid and expensive.
reply
Honestly, even the fancy add-on GUIs will still make these sorts of errors, too. I have provoked this exact same issue and similar, albeit simpler troubleshooting process when using ThunderHub to open a channel. ThunderHub shows a floating point value for sats/vbyte when calculating a proposed fee amount; but then when you submit, the value is truncated to an integer, which will cause your transaction to lag behind half the mempool in a low or concentrated fee rate environment.
What you see in ThunderHub:
What you get in the mempool:
What you need on chain:
I feel your pain. Hopefully devs will continue to iterate and eliminate all these problematic issues so that plebs aren't forced into custodial solutions.
reply
0 sats \ 1 reply \ @OT 28 Sep
Perhaps RBF didn't work as you didn't have any other funds in your wallet?
reply
No, RBF would have failed because Lightning channels are 2-of-2 multisignature wallet scripts. If OP was successful with the RBF, then that would have permanently confused both channel partners, since the transaction would have been maleated to a new transaction hash/ID - basically Mt. Gox-ing yourself.
CPFP or a miner bribe/MEV (i.e., Mempool.space Accelerator) are the correct ways to solve the predicament.
reply