Was Ethereum Hacked by F2Pool?
TL;DR: Was Ethereum Hacked by F2Pool? Yes, in the MIT sense of the word “hack”, and probably no, in the alarmist media sense.
A distracting story about my local supermarket
Every morning in my local supermarket, the staff go around with a sticker gun and slap “30% off” stickers on all the produce that is about to go out of date, in an attempt to make some money off old cheese and bread, rather than throwing it away at the end of the day.
From 8PM onward you can buy such discounted items at an even greater discount, namely 66% off. As a result, a glut of customers arrive at that time to get really cheap Gruyere and Roqueford.
Keep this discount policy in mind, as I proceed to explain a recent publication by Aviv Yaish et al., which discloses how the Ethereum mining pool F2Pool has managed to “front-run” other mining pools for the last two years.
I had to go dust off my knowledge of peer-to-peer latency computations and difficulty computations for Ethereum. The last time I was looking at this kind of stuff was in 2017, when I published a paper that contains a section on orphan blocks and the time it takes reported blocks to travel through the network for the Bitcoin network. It also gets complicated quite quickly.
So let’s start off with a quick summary of proof-of-work and why it needs a “difficulty” factor using a simple analogy:
All the miners in a proof-of-work blockchain are playing a lottery or a gambling game to win the right to add the next block. You can imagine them all as repeatedly throwing a handful of dice over and over again, as quickly as they can. The first one to throw all ones wins, has their block accepted, and gets the block reward — in Bitcoin it’s BTC, and in Ethereum it’s ETH. Then the game starts again for the next block.
And everyone agrees on exactly how many dice need to be thrown in each hand.
The problem is that as more miners join, and the ones that are there get faster at throwing the dice, scooping them up, and throwing them faster, the time it takes for someone to win each game gets shorter and shorter.
But the aim of the game is that someone wins, on average, every ten minutes in Bitcoin (for Ethereum it’s every ten seconds).
So something needs to be done. To get around this, proof-of-work blockchains use a “difficulty equation”. If blocks start arriving too quickly, the protocol requires the player to throw more dice per round. Imagine the first game started with each throw involving six dice, so you had about a 1 in 50 000 chance of winning.
Now, many rounds on, there are so many players that each throw involves eighteen dice. Back in the good old days if you played you stood a reasonable chance of winning, but at the moment there are so many players that your odds are much much lower. About one in a hundred trillion in fact.
But that’s okay, because a hundred trillion dice throws are being made every ten minutes (in Bitcoin) or every ten seconds (in Ethereum) thanks to all those mining farms, so it all works out. Blocks keep getting found on time, but generally speaking not too soon.
The difficulty adjustment
In Bitcoin, every 2016 blocks the protocol requires miners to look at the average time it took for blocks to arrive, and adjust the difficulty (i.e. the number of dice thrown each time) accordingly. That’s meant to take about two weeks. If the 2016 blocks were found within a week the difficulty would have to double, and if it took a month, the difficulty would halve.
Ethereum is a bit more complicated. It adjusts the difficulty on the fly, block by block. This has an advantage over Bitcoin — if the number of miners were to suddenly drop dramatically, Bitcoin would take a very long time to adjust the odds, but Ethereum would adjust almost immediately.
It also has a disadvantage, and that is what Yaish et al. discovered.
And this is because the Ethereum difficulty doesn’t drop in a continuous manner; it drops in a discrete manner. Every nine seconds, if a block hasn’t been found, the players can remove one of the dice they have to throw. For the first nine seconds, for example, they might be throwing 18 dice. For the next nine seconds they only have to throw 17, and so on, until after 99 seconds without finding a block is reached — after that, the number of dice stays fixed — in our example the lowest number would be just nine dice.
And then eventually someone should find a block.
To summarize: in Ethereum the number of dice you have to throw to find a block is equal to:
- the number of dice that had to be thrown to find the previous block,
- plus an adjustment which might increase or decrease the number of dice by one, and
- the number of dice is reduced for every nine seconds that pass without finding a block.
So what’s the problem?
Let’s go back to our dice example. Imagine that a first block is found, and then everyone has to throw 18 dice to find the second block. Nine seconds pass, everyone is now throwing 17 dice, and suddenly that second block is found. You now have a choice:
- start looking for the third block by throwing 18 dice again, or
- look for a replacement for the second block by throwing 18 dice, and lie about the time at which your search is conducted by claiming that it is eight seconds after the first block was found
Lying about the time?
Yes — because it takes time for messages on the Ethereum peer to peer network to reach everyone, there’s a bit of flexibility in whether Ethereum nodes accept the timestamp on received blocks. It’s a bit like postal voting in California — your vote is accepted up to seven days after the election day, provided the postmark has a date on or before election day. As a result, if you can find someone at the post office willing to “back-date” your postal vote, you could technically vote after the election.
And in Ethereum, the miner “postmarks” their own submitted blocks.
What’s the vigorish?
Yaish has determined that precisely one mining pool out there is using the above strategy: F2Pool.
Why would a mining pool like F2Pool try to replace a block, rather than just mining the top of the chain like everyone else? The answer is — it allows them to “steal a block”. Let’s say Etherpool mines a block at midnight, nine seconds after the previous block. If competing mining pool F2Pool mines on top of that block, they only stand a chance of getting the next block after midnight.
But if they mine a replacement for Etherpool’s midnight block and succeed, they can then mine on top of their midnight block, and potential get two blocks rather than just one, thereby also getting two block rewards.
And for the first nine seconds after the midnight block is found by Etherpool, it is equally likely that F2Pool can find a replacement midnight block or a new block. So they might as well mine that replacement block.
(If you have some knowledge of probability theory in mathematics, you can run the numbers and see under what circumstances the expected monetary returns for mining a replacement block are higher than just doing the traditional thing of mining the head of the chain.)
It does look to me that Yaish et al. have uncovered and publicized a generally overlooked “feature” of the current difficulty equation for Ethereum, namely that it is beneficial to keep mining with an adjusted 8 second timestamp for a few seconds after a 9 second period has been reached.
In fact, probably for longer than F2Pool currently does.
Is this a hack?
The basic reasoning by Yaish seems sound, the empirical and theoretical evidence in the paper backs it up, but I do have a problem strong language used, namely labeling it as an attack or hacking. It seems a bit excessive.
My initial opinion is that it’s a “hack” in the MIT use of the word, not in the media’s appropriation of the word “hacking” to mean what we used to describe as “cracking”, and that Yaish may be using media-attracting language to describe an aspect of the difficulty equation that one mining pool spotted and has secretly been taking advantage of.
Presumably the others are now rushing to take advantage of it too.
Let’s put it this way — the difficulty equation worked, and still works. The advantage F2Pool had is similar to the advantage a mining pool gets if all its miners are using better mining equipment, or uses a more efficient algorithm to compute the hashes.
And this kind of stuff has been going on since cryptocurrency mining began. Some people noticed that you could stop a hash round early with some clever mathematics that allowed you to predict the probability part-way through your hashing that your efforts this time were unlikely to succeed, for example. Similarly, people used to mine with their CPUs, then GPUs, and now there is no point unless you buy a dedicated ASIC miner, or preferably a warehouse full of them.
Those things aren’t considered hacks either.
What are the implications?
That doesn’t mean that there aren’t implications to all the miners switching their mining strategy to that used by F2Pool.
My assumption is that initially all the miners will switch to doing this — it is more profitable.
That means that once every now and again all the miners won’t be mining the tip of the chain, so one block cycle will be wasted. The next block will be easier to mine because it will already be in the second difficulty reduction. I couldn’t find a figure for the proportion of “weak blocks”, as I now call blocks mined at 9s with no uncle.
A guesstimate using fig 8 in Yaish et al.’s paper is that roughly 125000 in 2000000 blocks, or about 6% are “weak blocks”.
And the attack is also valid against 10s and slightly older blocks, but its effectiveness drops — I’d need to run calculations as to how the payoff drops and where the inflection point is.
My current conclusion is that from a user perspective everything will look about the same, except for one thing: the variance in block times will rise. Which, in simple terms, means that although blocks will continue to arrive, on average, at a rate of one every 10–13 seconds, there will be more blocks that took a long time to find, and more that took a short time.
So actually, not quite the same, and the bus waiting time paradox will kick in: the average time to get a transaction into a block will be slightly higher.
(The “bus waiting time paradox”? Think of it this way — in Helsinki the busses arrive at your stop every ten minutes, exactly, because they’re efficient in Finland. So your average waiting time is five minutes. In London the traffic gets snarled up, and the busses end up bunched together in batches of six. So although there are six busses an hour, they all arrive at your stop at the same time. Hence your average waiting time in London is half an hour.)
Back to the supermarket. Can you guess what started happening?
Someone noticed a month or so ago that it is a good idea to turn up at 7:45 to start putting those reduced items in your basket. Then you hang around until 8 o’clock before going to the checkout line. That way you avoid the disappointment of finding that the reduced cost cheese you really wanted is no longer available.
Pretty soon other bargain hunters got wind of the tactic, and as a result, all the good stuff is gone as soon as the clock strikes eight, and sometimes well before then.
One upshot of this is that the queues at the checkout are now massive for the first fifteen minutes after eight o’clock.
Another result of that is the supermarket is back to being almost empty from quarter-past eight till closing.
I guess pretty soon we’ll be seeing what the effect of the Yaish et al. discovery on mining pool tactics will be. I suspect that from an Ethereum user’s perspective it will pretty much look like business as usual.
But only time will tell.
About the author
Keir Finlow-Bates is a blockchain researcher, smart contract developer, inventor, and writer. He lives in Finland with his wife and eight children.
If you found this article insightful or educational, you’ll love his book, Move Over Brokers Here Comes The Blockchain, which explains blockchain through the use of analogies without oversimplifying the topic.