Thanks flound1129! That is correct, some blocks like 2103797 reward 20.36265624 rather than (25*math.pow(0.95,4)) 20.36265625. The mystery remains, why your node rejects it and all the others seem fine with it.
It's not really a mystery, pow(0.95,4)*25 at https://github.com/DNotesCoin/DNotes/blob/master/src/main.cpp#L851-L853 evaluates to 20.362656249999997 on my system, which evaluates to False in the comparison at https://github.com/DNotesCoin/DNotes/blob/master/src/main.cpp#L1431 when the coinbase transaction vtx[0].getValueOut() == 20.36265625 and thus the block is considered invalid.
Expected behavior when casting a floating point value to an int is that the number is truncated (not rounded). See https://stackoverflow.com/questions/9695329/c-how-to-round-a-double-to-an-int
Patching main.cpp in the following manner (assuming rounding is the desired behavior) appears to fix the issue:
index 4773964..48d7b3c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -850,7 +850,7 @@ int64 static GetBlockValue(int nHeight, int64 nFees)
{
int yearsElapsed = nHeight / 525949;
double nReductionPercentage = pow(0.95,yearsElapsed);
- nSubsidy = nSubsidy * nReductionPercentage;
+ nSubsidy = (int64) ((nSubsidy * nReductionPercentage)+0.5);
}
return nSubsidy + nFees;
}
Appreciate it flound1129! There was 8 or so blocks that reported 20.36265624 reward after the reward change, all of the rest have been 20.36265625, and at the point where it was 20.36265625 is the block your node started rejecting blocks. There have been no other reports of incident since, so I assume the problem is isolated to your specific setup, or as for on the network your machine. The problem is to make changes to the block reward would require forking the network, which creates an even bigger problem and across the entire network. I'll have to check, but I don't believe this can be changed just on your side without impacting the rest of the network.
This doesn't change the block reward, it fixes the truncation. Adding 0.5 is the recommended way to do this in c++.
Again, see https://stackoverflow.com/questions/9695329/c-how-to-round-a-double-to-an-int
nSubsidy is in satoshis.
I don't know whether this will result in the correct behavior across all platforms, so you should probably pass it to your devs and/or do some quick testing to make sure the returned number is still correct on your systems.
I'd also be happy with an official fix from the DNotes team.