Does that mean that SPV miners would jump on the next block and verify it while mining, and if the block was proven to be invalid they would switch to the correct chain? That would be the best of both worlds, I think.
Think of it that the mining pool has 2 nodes, an SPV node and a fully validating node. The block generation core is connected to both nodes, though an arbitration node.
Headers are in lower case and full blocks are in upper case.
Normally, both SPV and the full node agree.
Block D is found, so the miner broadcasts d (the header) and then broadcasts D.
The header d is received first
a <- b <- c <- d
A <- B <- C
At this stage, the arbitrator says that the two nodes disagree, so the pool mines empty blocks on d.
Soon after, block D arrives and is validated.
a <- b <- c <- d
A <- B <- C <- D
The two nodes are back in agreement. This means that the pool mines full blocks (including transactions) on D.
The benefit is that any hashing done between when d is received and when D is received is not wasted. It can be used to find empty blocks (which still pay the minting fee).
The problem is what happens if an invalid block is found.
In this case, a miner finds E but it is bad, it also broadcasts e.
a <- b <- c <- d <- e
A <- B <- C <- D
The problem is that, since E is bad, it is not accepted by the full node. This means that the header-only/empty block chain stays ahead.
If a majority is SPV-mining, then they will build f, g, h and so on. These are all empty blocks.
a <- b <- c <- d <- e <- f <- g <- h
A <- B <- C <- D
A timeout prevents this. The pool will only mine on e with empty blocks for one minute. Once it sees that block E is invalid or if it doesn't arrive, it switches to building on D again.
Block E* is found by one of those miners and e* is broadcast.
e* is received but it doesn't become the main SPV chain, since it was received later than e.
a <- b <- c <- d <- e
<- e*
A <- B <- C <- D
Soon afterwards E* is received.
a <- b <- c <- d <- e
<- e*
A <- B <- C <- D <- E*
The SPV node and the full node still disagree, so the miner stays in non-SPV mode.
Eventually, a miner builds on E* producing F. He broadcasts f and then F.
a <- b <- c <- d <- e
<- e* <- f
A <- B <- C <- D <- E*
and then F is received and validated.
a <- b <- c <- d <- e
<- e* <- f
A <- B <- C <- D <- E* <- F
At this point, SPV mining can be reactivated, since both nodes agree on the longest chain again.
It would have been safe to switch back once e* was received though.
Build empty blocks on a block header if
- The header is the longest chain (ties allowed)
- The header was received less than 1 minute ago
- The header chain is longer than the fully validated chain
- The header is the earliest received header that meets the previous rules