HPCE / hpce-2017-cw5

1 stars 6 forks source link

Issue with mining threshold always set to 0 #5

Closed guigzzz closed 6 years ago

guigzzz commented 6 years ago

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 to 2^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.

m8pple commented 6 years ago

I'm not quite clear on the issue here. Is this a platform specific thing?

m8pple commented 6 years ago

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.