The 300 MB default maxmempool Problem
Monday, December 18, 2017Unconfirmed transactions are quite a hassle for bitcoin users. I recently came across an interesting problem which is not the usual “my transaction is stuck” problem.
In the last weeks of 2017, the number of unconfirmed transactions has again reached all-time highs.
Periods with over 100k transactions in my mempool were not unusual.
Bitcoin Core limits the system memory allocated for storing unconfirmed transactions to 300 MB by default.
This serves as an anti-DoS feature.
Fully used 300 MB of RAM equal about 110 MB of actual raw transaction data.
This default value can be changed with the -maxmempool <n>
option where n
is the number of megabytes allocated to store unconfirmed transactions.
$ bitcoin-cli getmempoolinfo
{
"size": 123803, # amount of tx
"bytes": 107840125, # raw tx bytes
"usage": 298526272, # tx in ram bytes
"maxmempool": 300000000, # maxmempool in bytes
"mempoolminfee": 0.00016486 # min tx-fee to get accepted
}
Once 300 MB of system memory is filled, Bitcoin Core starts dropping low-feerate transactions from the mempool for high-feerate transactions.
Additionally, a mempoolminfee
-threshold is set to prevent new low fee transactions from entering the mempool.
A node operator can increase or decrease the maxmempool
option to better fit their system.
I assume that for example, some block-explorers have increased their nodes maxmempool
.
I know that Jochen Hoenicke, for example, has a node running with a maxmempool
of 2GB.
The Problem
Small differences in the mempool are common.
However, with an increased maxmempool
a nodes mempool can differ vastly from a majority of other nodes on the network.
These nodes, especially when they power a block-explorer, still many keep unconfirmed transactions the majority of the network has already dropped.
This can be irritating for users.
I came across a particular form of this problem, when a friend asked me, why he can see a certain low-fee transaction on bitaps.com, but not on blockchain.info.
My local node, with a default 300 MB maxmempool
, responded with an error on calling the getrawtransaction
RPC with the txid.
$ bitcoin-cli getrawtransaction <txid>
error code: -5
error message:
No such mempool transaction.
However, using the bitaps.com API to query the raw transaction worked fine.
I tried rebroadcasting the raw transaction with sendrawtransaction
.
This failed.
$ bitcoin-cli sendrawtransaction <rawtx>
error code: -25
error message:
Missing inputs
Looking at the missing input I noticed that it references an unconfirmed change output from a transaction with equally low fees. However, I again wasn’t able to find the parent transaction for the input in my local mempool or on blockchain.info. Only bitaps.com had it. And this transaction again referenced an unconfirmed low-fee output as an input.
With the context of the maxmempool
-limit this started to make sense.
My take on what happened
My take on what happened is, that bitaps.com has a higher maxmempool
-limit than e.g. blockchain.info and therefore does not drop the transactions.
A user checking bitaps.com sees the transaction, a user checking blockchain.info doesn’t.
The real issue appears when the original sender is not aware of this and has a peer with a larger-than-default mempool. He unknowingly continues to chain transactions to an unconfirmed parent transaction that the vast majority of the network rejects. The broadcasted transaction spends an output that references a dropped transaction and therefore is invalid.
David Harding pointed out that the sender could use BIP-125 Replace-By-Fee to update an unconfirmed transaction with new outputs: