These are notes. If they are incorrect, that’s part of the deal. I need to take a look at the “new” non-final mempool, and these notes will contain whatever thoughts enter my head along the way.
I am not a Bitcoin development expert. If you notice errors in this please let me know and I will update it. Contact information is included at the end of this article.
The evolution of the mempool
Craig’s original mempool
In the original source code, the “mempool” was in fact a temporary in-memory pool of transactions. If the node was restarted, then the node would have to repopulate it’s mempool from other nodes. If all nodes shut down at the same time, then the mempool would be empty and anyone wanting their transaction mined would need to rebroadcast.
The notion of non-final transactions was part of the original design:
- If the transaction lock time was 0, it was final.
- Otherwise, if the transaction lock time was less than the height of the longest chain, it was final.
- Otherwise, if any transaction input had a sequence number lower than the highest possible value (0xFFFFFFFF) the transaction was non-final.
- Otherwise, the transaction was final.
Transactions in the mempool were retained as long as the node continued running. The mining code considered them and ruled them out based on whether they were final or not. Those that had a pending lock time would eventually become final, and viable for mining.
Transactions with too low a fee had a way to get mined, as the first 100 transactions in each block given that they were under 10 kilobytes in size was free.
The evolved Bitcoin Core mempool
At some point along the way, persistence was added to the mempool and an expiry period for transactions that remained in there past a certain amount of time. Non-final transactions became undesirable, and were no longer accepted. The mempool was now a place where only immediately mineable transactions were found.
Transactions in the mempool expire after a default period of 2 weeks, although miners can override this. Anyone whose transaction was stuck in the mempool, and wasn’t getting mined because the fee was too low, could now do something called child pays for parent. By paying a higher fee for a transaction whose parent was still unconfirmed, it’s fee would be counted towards the fee of it’s parent for the purposes of getting that parent mined in a timely fashion.
The lock time field of a transaction was also repurposed by Bitcoin Core, with a new magic value of 500,000,000. If the value is above this, it is interpreted as a timestamp that is compared to a block time according to BIP 113. Values below this continue to be interpreted as a block height.
Sequence numbers of transaction inputs were similarly repurposed by Bitcoin Core according to BIP 68. These now had timestamp-based constraints on when they could be mined.
A Genesis upgraded mempool for Bitcoin SV
For transactions confirmed after the Genesis upgrade height, the Genesis specification clearly lays out the new rules.
The key difference here is that the sequence numbers of transaction inputs are solely used as a sequence number, and the complicated BIP68 time-based mining constraints have been removed.
The non-final mempool
This was committed to the Bitcoin SV repository in October 2019, and I haven’t spent the time to be sure, but it was likely included in the Bitcoin SV 1.0.0 release. It restores the mempool acceptance of non-final transactions to Bitcoin SV.
Transactions in the non-final mempool expire after 4 weeks. However this mempool is limited to 50 megabytes, and if it is full any further transactions are dropped. In order for the transactions in the non-final mempool to not just be in a kind of transaction purgatory, and for the mempool to fulfill it’s purpose, every 10 minutes a check is run to see if they have finalised. If their lock time, whether height or timestamp has now passed, the transaction is finalised and moved into the main mempool.
Transactions with higher input sequence numbers, can replace those that already exist in the mempool. And if the sequence numbers are all the finalised value (0xFFFFFFFF), then the transaction is removed from the non-final mempool and moved to the main mempool.
I’m not going to go into this in detail, because I haven’t done any research and do not plan to at this stage. But my understanding is that much of the past alarmism about the dangers of double-spending is due to differences in mempool configuration, and the possibility of constructing transactions in a way where it is possible to get different nodes to have different transactions that spend the same coins.
When Bitcoin Cash split from the original Bitcoin, Bitcoin SV, there was a difference in blockchain heights. With all of it’s rented hash-power, Bitcoin Cash was longer by hundreds of blocks. This was useful due to the way that Electrum Core (which both Electron Cash and ElectrumSV are derived from) constructed transactions. All transactions get a lock time of the next block height, and non-final sequence numbers for their inputs.
The way that the Electrum Core code constructed it’s transactions meant that Bitcoin SV nodes would reject the transactions created by Electron Cash for Bitcoin Cash. The transaction would be considered final on Bitcoin Cash, as the lock time was the height of the next block. But on Bitcoin SV the inputs were non-final, and the lock time height of the transaction was way higher than the height of the blockchain. This was why it was rejected.
As the Bitcoin Cash transaction was invalid due to it’s non-final state on Bitcoin SV, and would be until the height of the blockchain reached the lock time height of the transaction, the user had plenty of time to make a new transaction in ElectrumSV and move the coins in a different way on Bitcoin SV, easily splitting them.
With the Genesis upgrade, this no longer works. The non-final mempool means that the Bitcoin Cash transaction is now very likely replayed and stored by Bitcoin SV miners. And then anyone trying to make a new Bitcoin SV-only transaction will find that they get a mempool conflict error, indicating a double-spend, when they try to split their coins in this way.
Web site and downloads
If you need some assistance with something, please submit an issue at the following link. But please, fill out a template otherwise we will not have the information we need and you will have to wait longer for assistance.
Report an issue: github.com/electrumsv/electrumsv/issues
We do not provide support over Twitter, and will request you submit an issue. Support over twitter is much more difficult, and we prefer to avoid it completely.
You can reach us for discussion in one of two possible locations.