zawy12 / difficulty-algorithms

See the Issues for difficulty algorithms
MIT License
107 stars 25 forks source link

Cryptonote clone problems after Forks #32

Open zawy12 opened 5 years ago

zawy12 commented 5 years ago

CN forks very often (if not always) result in constant chain splits due to different difficulties. It's either because the new code is not backwards compatible with the old code in how old difficulties were calculated AND nodes popped blocks back to different points, AND/OR nodes just have different code that's not completely incompatible. Once a node has different difficulties in their local database due to one of these things, they will never have the same difficulties in the future. If it gets 10% too higher, it will always be 10% too high even if the code (that recreated the database after that point) is the same. Nodes with a lower difficulty will have a certain percentage of "their" miners' blocks rejected by nodes with higher difficulties, but they will accept all the blocks from the miners with the higher-difficulty nodes. If the lower-difficulty chain pulls ahead from having more miners, the higher difficulty nodes stay on a branch, never accepting the chain with the highest work due to rejecting its blocks. Miners may remain unknowingly married to those nodes on a chain that looks profitable without realizing their blocks have been orphaned. If the higher-difficulty chain pulls ahead, miners with the lower difficulty nodes will have some of their blocks rejected without realizing why.

New code must calculate the old difficulties in the exact same way in order for the new difficulty algorithm to get the correct beginning input difficulties. Otherwise different sync heights will create different chains or mass confusion from different difficulties on the same chain. There's no repair except to find the backwards incompatibility, fix it, and re-fork at the same height, or manually force the N difficulties before the fork to the correct values (an ugly solution). The last test of your fork is to make sure your new difficulties when you sync from 0 are matching the old difficulties when running the pre-fork code. If the last difficulty before the fork is the same in both, then almost assuredly every difficulty before it will be correct.

But there is a way to prevent, stop, and/or cover up the problems and get everyone with the same difficulties, as long as they have the new code and pop blocks back to at least 1 block before the fork. The new code does not have to be backwards compatible and you don't have to create a new difficulty algorithm. I've incorporated this into my difficulty algorithms. You simply put this in the algorithm:

uint64_t difficulty_guess = 100000; //  Dev  changes.  Guess a little lower than expected.
if ( height >= fork_height && height <= fork_height + 1 + N) {return difficulty_guess;}

Where "N" is the number of blocks used in the difficulty algorithm. This forces all the difficulties to be the same no matter what was in the database prior to the fork. This does not resolve all the problems because some nodes will not upgrade their code.

As an example of backwards incompatibility, the following single change caused a lot of problems in Lethean's 269000ish fork. They were lucky a roll back to the fork height was not required. A roll back was not needed bbecause most miners were working on a chain that was not resync'd from zero, and the only wrong difficulties were way back in time to the previous fork, so the correction enabled those who resync'd from 0 to get the same difficulties.

https://github.com/LetheanMovement/lethean/pull/126/files

ghost commented 5 years ago

hi, could you please check my fork and help me out..thanks, i cant seem to get a server running, should i use the vultr servers