OmniLayer/OmniJ

Reorg RegTests sometimes fail with `ProcessNewBlock, block not accepted`

msgilligan opened this issue · 4 comments

You can see the failure here: https://travis-ci.org/github/OmniLayer/OmniJ/jobs/703305083#L1476-L1488

I suspect his is caused by recent changes to Bitcoin Core / Omni Core, but am not certain.

This commit 1675c21 seems to fix the only failing test on Travis CI, but @Bushstar reports seeing other tests failing with a similar error on his development system.

Running the test on my system and checking the debug.log, ProcessNewBlock is reporting that the new block is a duplicate. This duplicate block is created after a call to invalidate block and replacement blocks generated in place. I'm able to replicate this by generating a block at the same height by using the same time and coinbase address. This appears to be the cause of the problem, tests can generate a block, invalidate it and generate a replacement block using the same coinbase address in the same second.

The solution would be to either use a new coinbase address for each new chain or wait a second after each call to invalidateblock.

This seems to be fixed by PR #188

All other errors similar to this have been cleared up with two exceptions.

Seems that another sleep command is required in the following location.

The other is the reorg failure reported in the issue here. The block generated on my system on this line fails with the same duplicate error even with the sleep(2000) fix.

I've found the cause of the problem. CreateNewBlock calls UpdateTime which will set the block time to be the greater of the system time or the median time of the preceeding 11 blocks plus 1 second as can be seen below.

https://github.com/bitcoin/bitcoin/blob/8b67698420e23db20cfbb9228ca01a68c8ddc10c/src/miner.cpp#L35

With rapidly generated blocks in regtest UpdateTime chooses the median + 1 over system time, the block times get pushed further and further ahead of system time.

On my system the reorg failure had these two blocks times to chooses from in UpdateTime, the nTime from the block set by system time and the median time of the past 11 blocks plus 1.

2020-07-01T12:58:37Z pblock->nTime 1593608317 pindexPrev->GetMedianTimePast()+1 1593608337

The above was logged after the wait of 2 seconds, the median time is 20 seconds ahead of the system time and gets chosen which is the same time used in the previous block hence the duplicate error.

To fix using sleep a time of 23 seconds would possibly be required, testing on my system a 23 second delay works here. The alternative is to generate to different addresses.

Fixed in PR #188.