I'm trying to dig into the monero codebase and understand how hashes are validated to be the solution for the current block. The below code returns true if the hash is valid, but I'm trying to understand why. I can tell it does a quick check on the highest word, but the rest I cannot fully grasp.
What I'd like to accomplish is to determine if the hash was close to the solution, even though it was not valid. What I did try was to make a copy of this function, removing the initial high word check, and reducing the difficulty variable that was passed (divide by 4) which returns true more often than when a block has actually been found.
I've also tried looking into the xmr-stak code, as what I'm really trying to accomplish is to get a list similar to the "Top 10 best results found".
bool check_hash(const crypto::hash &hash, difficulty_type difficulty) {
uint64_t low, high, top, cur;
// First check the highest word, this will most likely fail for a random hash.
mul(swap64le(((const uint64_t *) &hash)[3]), difficulty, top, high);
if (high != 0) {
return false;
}
mul(swap64le(((const uint64_t *) &hash)[0]), difficulty, low, cur);
mul(swap64le(((const uint64_t *) &hash)[1]), difficulty, low, high);
bool carry = cadd(cur, low);
cur = high;
mul(swap64le(((const uint64_t *) &hash)[2]), difficulty, low, high);
carry = cadc(cur, low, carry);
carry = cadc(high, top, carry);
return !carry;
}
Edit: With the help from glv, this is what I have:
uint64_t get_result(const crypto::hash &hash, difficulty_type difficulty) {
uint64_t low, high;
mul(swap64le(((const uint64_t *) &hash)[3]), difficulty, low, high);
return high;
}
To my understanding, this is returning the highest word when multiplying the hash and the difficulty. So, in order to find a block, this value must be zero, but to find a close enough hash, I am checking that this value is below 4 in miner.cpp:
result = get_result(h, local_diff);
if(result < 4) {
// we have a close answer
}