-
Couldn't load subscription status.
- Fork 21.5k
Description
Note this attack only works if the attacker can maintain himself as "best peer" for a number of nodes, which, with good standing and decent mining power, may not be unreasonable. He can then cause them to stop making progress in mining, causing him to have a greater share of the hash power, and making it possible for the attack to cascade into a 51% attack by crippling the network's hash rate.
Given a situation where the difficulty of the chain is considerably higher than at a previous point (say the difficulty is a few multiples of what it was at block 1), an attacker can halt mining progress by repeatedly mining and broadcasting NewBlocks at height 1. These blocks may have been mined in the past and kept secret, so there could be a large store of them.
This is possible because the go-eth miner resets every time a NewBlockEvent is received, whether or not the block has the highest TD. See: https://github.com/ethereum/go-ethereum/blob/develop/miner/miner.go#L153 (note it only resets if the block is already in the DB, but all forks are added to the DB)
So by continually sending new, low difficulty blocks at height 1, miners are continuously forced to reset before they find a valid pow, and hence block generation slows down and possibly stops, and the attacking miner can bootstrap himself into owning proportionately more hash power.
I suppose the simplest fix is to check in the miner if the NewBlock is of the current height and only to reset if so (or to mine a bit longer for uncles). If the NewBlock is from way back, the miner should not reset.
This might be far fetched but it works in a network of two peers and I suspect would work if the attacker is clever and best peer for some number of nodes in a larger network (though I have not tested more than 2 peers). Block pool logic may avoid this already, but probably worth not resetting the miner on just any new block anyways.