lnd: [bug]: crash-loop on startup: unmatched backend error: -26: mempool min fee not met
Background
During a mempool spike, I had some low-fee-rate on-chain transactions from my lnd wallet that got dropped from default mempools. Then on startup I got into a crash loop with the following error:
unable to start server: unmatched backend error: -26: mempool min fee not met, 3241 < 3909
I was able to unblock by going into my bitcoin.conf
and increasing maxmempool
, but I don’t think that is a sustainable solution.
Your environment
- lnd version 0.15.4-beta commit=v0.15.4-beta
- Linux Ubuntu
- bitcoind version v22.0.0
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 29 (13 by maintainers)
just a little more context on my situation for others to learn from:
mempool min fee not met
maxmempool=1000
inbitcoind.conf
, which increased my mempool size to 1000mb. restart bitcoindIn general my takeaway is that a lot of problems can be avoided if you just run a larger bitcoind mempool. but there are caveats associated with this
I don’t think we should do that either. It will just encourage users to actually do RBF. There were at least two cases I know of where users imported lnd keys into Electrum to create an RBF replacement TX for a funding transaction, putting their funds at risk. This only worked because the original one was already evected from the mempool. But IMO we shouldn’t encourage being able to do that while the original TX is still present. Also the “RBF enabled” label on a block explorer might give users wrong ideas too.
Correct. We recently added this to
chantools
, but it would be cool to have that option withinlnd
as well.Duplicate issue from the last time we had a fee spike: https://github.com/lightningnetwork/lnd/issues/5969/. Other instances across time: https://github.com/lightningnetwork/lnd/issues?q=is%3Aissue+mempool+min+fee+not+met+is%3Aclosed.
There’s not a good way around it afaict: bitcoind will start to increase the min fee needed to get into the mempool and if you want to allow things lower than that to get in, you need to increase the max mempool size.
We likely should properly catch this error and proceed. However that would sort of mask the issue here, since ppl would wonder why their transactions aren’t getting mined.
For case 1, if we do this, then I think we should have a clearer error message to force the user to action. So something like “consider raising your
maxmempool
value to xxx GB”. This way they know what to do and we can just close any other incoming issues, saying “works as expected”.I’m on board with having the relevant RPCs also allow users to get the raw hex. We log it each time, but logs can be spammy at times on trace/debug, so it might be hard for users to find.
@ziggie1984
Yeah tough choice, see my message above. Either way things are sort of hosed…we can choose to force user intervention or handle it in the background and pray to satoshi that things drop enough to let the tx enter the mempool of nodes with default policy.
The issue here is that we never really know if the transaction is “in the mempool” or not. Node policy is less uniform these days, and a big transaction spike can quickly cause the min relay fee to jump up.
I think it’s a good idea to optionally allow RPC calls to print out the full hex of the broadcasted transaction so users can rebroacast on their own. Note that we’ll now also rebroadcast ourselves, so if the min relay fee drops down, then things should propagate.
The way the rebroadcaster works, it’ll keep going until things confirm or the sweeper removes it as a conflict is mined. So on start up, those should be broadcast again.
So to resolve this issue, we just need to make sure that on start up, we don’t refuse to start if we get this error.
See this issue: https://github.com/lightningnetwork/lnd/issues/4616
This code block needs to be updated to catch this error: https://github.com/btcsuite/btcwallet/blob/50978fcf79f8100eb62c185606c66367cc03b03e/wallet/wallet.go#L3463
With this recent PR, transactions should always be above the min relay fee at the time of tx creation. It’s possible that things drop below that value, but until wide spread package relay, there’s really nothing we can do about that.
The choice is essentially to:
Note that even with the second option, the transaction won’t propagate since nodes will send a
feefilter
message telling peers to not send them transactions below that fee rate value.Ok I analysed the situation regarding the startup issue and my analysis showed exactly 2 cases where we end up not starting because we could not broadcast the transaction (mempool-fee was not enough).
So one downside of dropping this transaction is in an Anchor-Channel Case that we will not be able to FeeBump the transaction because the sweeper which sweeps the anchor (CPFP the Commitment) will fail with the
missing input error
so it might be good to keep failing the startup in this case because then by increasing the mempool we make sure that we can CPFP the Commitment? Wdyt? ⚠️Another way would be:
The solution as @Roasbeef described would be to just include a case for the
minrelay broadcast fail
and proceed, but there is a small problem. We mark the Channel asStateCommitmentBroadcasted
which is not quite right if we consider that the commitment was not broadcasted. So I think we should only mark the channel asStateCommitmentBroadcasted
if the transaction successfully got placed in the mempool. Now problem is that we are not gonna rebroadcast the transaction as is, because we remove it and the User has to restart his node to trigger another retry. So I propose to keep the Channel in the stateStateBroadcastCommit
and maybe return the CommitmentTx in thelncli pendingchannels
cmd to allow the user manually broadcast it again if he sees the mempool-minfee go down? Or maybe not remove it and keep rebroadcasting it, but then we should think of a way to hide the error because it would fill the logs and disturb the user ?tweakless
channel type (STATIC_REMOTE_KEY) and a timeout-htlc which we cannot broadcast because of the min-relayfee when restarting. Relevant codepart is here: https://github.com/lightningnetwork/lnd/blob/bbbf7d33fb1527acebb44e2a69d16fbcf24cc2fa/contractcourt/utxonursery.go#L291 which fails here: https://github.com/lightningnetwork/lnd/blob/bbbf7d33fb1527acebb44e2a69d16fbcf24cc2fa/contractcourt/utxonursery.go#L659I think for the second case we should not remove the transaction but keep trying rebroadcasting it (but change the log level for the min-mempool-fee failure, or give the user the possibility to fetch the rawtx in case he wants to broadcast it via other transaction relayers where the purging fee is lower?
Happy to receive feedback in which direction we wanna go, if we have consensus I will code it.
I would do the following:
For case 1 where we are not able to broadcast the Commitment Transaction, still fail lnd to start to let the node-runner know that with the current mempool architecture his Commitment Transaction will not be able to confirm (because the anchor cannot bump a non-existent parent output (without package-relay)
For the second case I would lnd continue to startup successfully but rebroadcast the crib-transaction in a timely manner. Maybe change the log-level for the min-relay-fee not met error, to not spam the log with errors and give the user the possibility via an RPC command to fetch the rawTx for this Crib-Transaction?
Closing as the config issue has been resolved.
Correct, the mempool is truly a murky place unfortunately. Bitcoin nodes have something called a
feefilter
: as they start to increase their min fee amount, they’ll tell their peers not to send things below that fee rate.The only solution to something like this in site is the fabled package relay construction. This would let you send that transaction, then also couple w/ it something to allow the fee to be high enough for acceptance.