I’m not sure if this actually makes sense to include in the mainline code, but I’m PRing here in case others think it may be useful. It has proven to be extremely helpful for me in the last few days while testing various mining software.
This enables anyone to “mine” on any chain, including mainnet in realtime, in order to test mining software. The desired difficulty is set via a bitcoind param -forceminerdifficulty=n
. The difficulty is set in bitcoind rather than via a new rpc command or getblocktemplate/submitblock in order to facilitate testing mining/pool software that may be hard to change (for example, in embedded hardware, or pool software running on a different machine).
Backstory
I was recently working on adding segwit commitments to some existing mining software. After doing basic sanity checks, I let it run on testnet (where the difficulty is currently very high) for a few days. I began to notice a subtle race condition that caused a small percentage of blocks to be rejected, with no obvious cause for the breakage.
I didn’t think that my code could’ve caused the problem, and ordinarily I would just re-run on the unpatched code. Problem was, testnet3 has activated segwit, and the unpatched miner could not insert the commitment. So the only way to really simulate (without manually creating lots of peers and transactions in order to stumble upon the problem) would be to mine on mainnet. Obviously that wasn’t realistic.
Solution
Mine on mainnet with a specified difficulty, ignore the work requirement, validate, report success, then throw the block away. This turned out to work beautifully. The time it took me to reproduce the error dropped from ~10hrs to ~30sec.
In this case, specifying the difficulty, rather than simply setting it to the minimum, was crucial. The race condition occurred only after rolling the extranonce a few times.
I believe this approach should work universally. Mining/Pooling software gets a little cranky about stale blocks, but otherwise works fine.