Closed guigzzz closed 6 years ago
I'm not quite clear on the issue here. Is this a platform specific thing?
Ah, I get it - should have looked more closely at the fix. So this is a problem for very small scale factors? I was able to replicate it for scale=1..3, and it goes away for scale=4+.
So for scale=1, we would get 2^64 / 1 == 2^64, which when cast back turns into 0.
I'm a little confused about scale=2, as my assumption would be 2^64/4 = 2^62, which is exactly representable as both a double and as a uint64_t, so I'm not sure why it fails off the top of my head.
Your solution works for scale=1, as we have (2^64-1)/1, which results in 2^64-1, which works perfectly (as it avoids round-tripping through double). However, for scale=2 and scale=3 I still get the same problem.
The fix I ended up using is:
if(scale <=4){
params->threshold=0xFFFFFFFFFFFFFFFFull;
}else{
params->threshold=(uint64_t)(pow(2.0,64) / (scale*scale));
}
I think I'm missing something obvious for scale=2 and scale=3 todo with rounding, but for the moment it escapes me.
Anyway, thanks for both pointing out the problem and providing a fix.
The problem was that the mining puzzle was never actually completing. After debugging (with print statements), it all came down to the threshold being set at 0. I thought that
2^64
could be overflowing the integer, and changing the initialisation of the threshold first to2^63
fixed the problem. A final solution is the following:Changing this line (145 in
mining.hpp
):params->threshold=(uint64_t)(std::pow(2.0, 64) / (scale*scale));
To:params->threshold=(uint64_t)(std::numeric_limits<uint64_t>::max() / (scale*scale));
Fixed the issue.