11 min read

Griefing Bitcoin's Testnet

A deep dive into manipulation of block generation on testnet and a call to reset the network to fix several issues.
Griefing Bitcoin's Testnet

It's time to reset Bitcoin's test network, also known as "testnet" or "testnet3" to be more specific.

Why? As I outlined in my email to the Bitcoin development mailing list a month ago, the fundamental principle of testnet has been broken. Testnet coins are supposed to be plentiful and free so that developers can experiment and test their Bitcoin software without having to spend money or put real value at risk when debugging software.

How did this come to pass?

  1. Testnet hasn't been reset in 13 years.
  2. The block reward is close to 0, making it hard to mine.
  3. People have been using it for airdrops and other activities promising actual value.
  4. This has created economic demand for TBTC.
  5. People are buying / selling TBTC on multiple sites.
  6. Testnet has a weird quirk we should fix because it's somewhat responsible for getting us to this point.

Why have testnet mining rewards dried up? Because it's currently at block height 2,811,000, which would be the equivalent of the year 2061 on mainnet. As such, the block reward is only ~0.006 TBTC. How did this happen? It's due to a phenomenon I wrote about several years ago:

Bitcoin Testnet Block Storms
A deep dive into how 10 lines of code resulted in far-reaching unintended consequences for the Bitcoin test network.

On mainnet, Bitcoin produces 144 blocks per day, give or take a few blocks. On testnet... it's a bit more volatile, as you can see in this next chart. Due to some slightly different consensus rules, every once in a while there will be a day in which over 10,000 blocks are produced - the equivalent of several months worth of blocks in a single day.

How it Started

I first got clued into testnet accruing value because I've been well known for many years to give away testnet coins to developers. Doing searches for testnet coins on Google / Reddit / X will often result in my username coming up. As such, when I started getting deluged with requests for testnet coins earlier this year from non-developers, I started digging. It ended up being this "SatoshiVM" project which claims to be building a zero knowledge rollup second layer.

It's not quite as clear what this project is doing, but it's a sketchy airdrop.

SatoshiVM has a bunch of red flags:

I think this is the first large scale scam I've seen run on testnet, though it's far from the first time testnet has been used for scams. It's not uncommon for malicious folks to prey upon people's naïveté and sell them testnet bitcoin at mainnet bitcoin exchange rates. As an aside, the latter scam is why it's important for every wallet that supports testnet to have a bold disclaimer on the main screen that testnet coins have no value!

Testnet Has Accrued Value

To be quite clear, because a variety of vitriolic folks have accused me of undertaking the actions described in this essay because I "personally dislike" their project:

The sole reason I'm advocating for a testnet reset is because testnet is supposed to be free for developers to use. Other than that, everyone should be free to use testnet for whatever development purpose they wish.

Here's some of the evidence that testnet coins are being traded for real value:

This is a web site acting as a brokerage and selling coins for a bit over a buck. Note that they even call out the difficulty in acquiring testnet coins for why they have accrued value.

Here's another site operating a full fledged order book for trading between testnet and mainnet coins.

This is some kind of decentralized exchange running on testnet with a variety of tokens being traded.

Phase 1: Minting Cheap Blocks

Creating a slew of low difficulty blocks is rather trivial.

  1. Trigger the minimum difficulty rule
  2. Laptop GPU can mine 1 block every ~10 sec
  3. Keep going until timestamp is too far ahead (2 hours)
  4. Wait
  5. Repeat

It's been 9 years since I last did any mining on testnet. I wrote a guide for how I did it back then, though I had a (cheap, previously used) ASIC at the time.

How to Solo Mine on Bitcoin’s Testnet
I’m a Bitcoin engineer, so I often need to test new code but I don’t want to risk losing valuable bitcoins in case there is a bug…

This time around I was hoping to just CPU mine on a desktop. So I gave this guide a shot, using the very old bfgminer software:

[Guide] Solo mine testnet bitcoins with bfgminer, Bitcoin Core, and a CPU/GPU
[Guide] Solo mine testnet bitcoins with bfgminer, Bitcoin Core, and a CPU/GPU

But it turns out CPU mining is too slow even at difficulty 1, so I had to spend some time getting bfgminer working with my GPU.

In my bitcoin.conf, I set each newly received block to trigger a bash script via:

blocknotify=/path/to/trigger_miner.sh

The bash script basically checks to see if the miner is running. If it's not running, it runs it for 60 seconds before killing the mining process.

#!/bin/bash
pgrep -fl bfgminer
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
~/code/bfgminer/bfgminer -S opencl:auto -o http://127.0.0.1:18332 -u [username] -p [password] --generate-to mwnsh33QHVXYDLWUvZwRizzp72SEaRLnf2 --coinbase-sig "Mined by Lopp (⌐■_■)" & 
else
echo "bfgminer running - do nothing"
fi

sleep 60
pkill bfgminer

For evidence it worked, I just checked testnet block explorers to ensure my calling card was in place.

And then we can see slews of empty blockes being mined like so:

Success!

However, after I had been running this for nearly a full day I noticed that I was not mining as many empty blocks. From looking at the timestamps of other miners' blocks, they were adjusting their timestamps forward in time too! This was a bit surprising because I had assumed that miners would have to do that manually. Upon closer inspection of mining template logic, it looks like if the median time past of the 6 most recent blocks is in the future of the system clock, it uses the median time past + 1 second. This actually makes sense because it's a consensus rule that if you mine a block with a timestamp that's earlier than the "median time past" it will be considered invalid and rejected by other nodes.

For a deep dive into the timestamp boundary conditions and their effectiveness, check out this essay I published in 2019:

Bitcoin Timestamp Security
A deep dive into the game theory behind keeping timestamps of bitcoin blocks reasonably accurate.

As such, this rule meant that by continually trying to push the time forward, I was working against myself and shrinking my effective window of time warping. So I turned off the automatic empty block mining that was triggering after each block.

But for the several days I was running the Phase 1 script, we can see that I successfully increased the number of testnet blocks by 300%!

Public Reactions

The interesting aspect of my non-disruptive Phase 1 script (it wasn't actually slowing down anyone's transactions from confirming) is that it caught the attention of projects I didn't even know were operating at the time. I started receiving telegram messages from folks connected to the project asking what I was doing. And then their project lead tried to turn himself into a victim, making a lot of nonsensical claims.

After doing some poking around this motoswap project it became pretty clear that it's run by BSV folks. Thus it's unsurprising to see them use a common tribalistic narrative to frame his failure as "it's us against the maxis." For some reason Danny keeps telling his adherents that they're going to switch from testnet to mainnet and it will break mainnet. But of course this is completely false: the only thing that will happen if they switch to mainnet is that the degen traders will get priced out of using the DEX.

This fellow is so dumb that he can't spell the name of his own project correctly. But anyone who has been following this space for a few years should be well aware that it takes a special kind of stupidity to believe that Craig Wright is reputable or BSV is a good idea.

This fellow clearly sees the writing on the wall and may be afraid he won't be able to keep selling testnet coins.

I took the opportunity of the above folks' ignorance to get a little spicy. The funny thing about my timestamp manipulation is that it also caused all of the hashrate estimates to go bonkers. Mempool.space was showing that I had tripled the network hashrate and added over 1 Petahash per second, even though in reality I was only using a 500 Megahash per second GPU that would turn on for a few seconds at a time!

Phase 2: Perpetual Block Storms

Phase 1 of mining low difficulty blocks was just a proof of concept for Phase 2, which causes far more chaos on the network. I first noticed this chaos occurring naturally back in 2015:

How did I execute Phase 2? It's actually the same steps as Phase 1, but just ensuring that the steps get triggered for the block right before each difficulty adjustment. What was the result of Phase 2? We can see that under normal conditions, testnet produces ~150 blocks per day. But when perpetual block storm mode is activated, we can easily top 20,000 blocks per day!

This is pretty crazy because we're talking about a 150X to 250X speedup in terms of block generation and thus overall data throughput on the blockchain. As you might expect, a lot of folks running infrastructure and services on testnet are not adequately prepared to scale over 100X without warning...

Public Reactions

Unsurprisingly, the first folks to notice testnet acting weirder than usual were those running projects trading coins for actual value.

One day went by and then...

I found it quite amusing that this degen project tried to spin their infrastructure failure into a positive by claiming credit for "breaking testnet."

Additionally, the following testnet faucet operator had an odd reaction. It does make me wonder about his incentives, as you can see from the rant on his web site that he seems to be fine with airdrops and trading occurring on testnet. He's free to support that standpoint, of course, though I suspect he'll find that he's not in the rough consensus of the rest of developers who use testnet.

I think it's safe to say that folks have been successfully griefed.

This cancellation attempt is a quizzical perspective, because my status as a (fairly rare) Bitcoin Core contributor has nothing to do with my manipulation of testnet. I only ever modified code running locally on my own machine. Bitcoin Core as an organization played no part in my actions...

I also noticed that the block storms broke mempool.space's infrastructure. Here you can see their mempool charts stopped updating once the storms hit.

Phase 3: TBD!

At the moment I'm giving testnet3 a breather to give developers time to harden their infrastructure and/or switch networks. Some have told me they're switching to signet, which is a test network that is far less chaotic because blocks are not minted with proof of work.

Note that everything I've done thus far has required effectively zero hashrate or electricity. I spent more time (a couple hours) getting the OpenCL drivers working on my Linux machine (for mining with my GPU) than I did actually writing the scripts to trigger block storms.

I won't go into details at this time and ruin surprises, but the game theory gets really interesting when you start considering what can be done with a relatively small amount of hashrate.

What could it mean? ;-)

Suffice to say that it's a very bad idea to use testnet for anything of real value. Testnet is not secure, and I'm happy to prove it to folks who refuse to believe it. I'll reiterate: I don't care if folks are using testnet to test out controversial things like inscriptions / runes / ordinals / exchanges / etc. But if you're going to do those things for actual value, you're far better off using something like dogecoin or litecoin. You know, a production network that isn't intentionally hobbled.

Resetting Testnet

The code changes for Bitcoin Core that will launch testnet4 are currently being worked upon by several contributors.

This was a unique bit of work because it's not every day that you have to mint a new genesis block. I found that this old tool still works quite well.

./generate-genesis -timestamp 1714658825 -psz "CCN 02/May/2024 Bitcoin Testnet Could Need Reset After 13 Years"
Ctrl Hash:	0x000000005611bbf1419574641c1d880d2872645ec62eb2efd605fab98d0760d2
Target:		0x00000000ffff0000000000000000000000000000000000000000000000000000
Blk Hash:	0x372e42462a9898504ccd14c037bf98436289ba1ef27088433aad521fca09bf21
Mkl Hash:	0xa2927b35a7444dd3e3ef24145a8c7054a4810c88d8cbed3896adfecae832b6fe
Nonce:		836015000
Timestamp:	1714658825
Pubkey:		000000000000000000000000000000000000000000000000000000000000000000
Coins:		5000000000
Psz:		'CCN 02/May/2024 Bitcoin Testnet Could Need Reset After 13 Years'

So now we have a potential new genesis block for testnet4:

CCN 02/May/2024 Bitcoin Testnet Could Need Reset After 13 Years
000000005611bbf1419574641c1d880d2872645ec62eb2efd605fab98d0760d2

I am hopeful that testnet4 will be finalized and available in the next few months.

Key Takeaways

I suspect that if a test network continues operating for long enough such that testnet tokens become scarce, it's likely to accrue value. As such, the only way to ensure that testnet doesn't accrue value is to instill a culture of regular resets.

Note for anyone currently running infrastructure on testnet3: I highly advise that you start planning to migrate your infrastructure to testnet4 this summer / fall.