def check_pow( block_number, header_hash, mixhash, nonce, difficulty, is_test=False ) -> bool: """Check if the proof-of-work of the block is valid.""" if len(mixhash) != 32 or len(header_hash) != 32 or len(nonce) != 8: return False cache_gen, mining_gen = get_cache, hashimoto if is_test: cache_size, full_size = 1024, 32 * 1024 # use python implementation to allow overriding cache & dataset size cache_gen = get_cache_slow mining_gen = hashimoto_slow else: cache_size, full_size = ( get_cache_size(block_number), get_full_size(block_number), ) cache = cache_gen(cache_size, block_number) mining_output = mining_gen(block_number, full_size, cache, header_hash, nonce) if mining_output[b"mix digest"] != mixhash: return False result = int.from_bytes(mining_output[b"result"], byteorder="big") return result <= 2 ** 256 // (difficulty or 1)
def mine( block_number, difficulty, mining_hash, start_nonce: int = 0, rounds: int = 1000, is_test: bool = False, ) -> Tuple[Optional[bytes], Optional[bytes]]: cache_gen, mining_gen = get_cache, hashimoto if is_test: cache_size, full_size = 1024, 32 * 1024 # use python implementation to allow overriding cache & dataset size cache_gen = get_cache_slow mining_gen = hashimoto_slow else: cache_size, full_size = ( get_cache_size(block_number), get_full_size(block_number), ) cache = cache_gen(cache_size, block_number) nonce = start_nonce target = (2 ** 256 // (difficulty or 1) - 1).to_bytes(32, byteorder="big") for i in range(1, rounds + 1): # hashimoto expected big-indian byte representation bin_nonce = (nonce + i).to_bytes(8, byteorder="big") o = mining_gen(block_number, full_size, cache, mining_hash, bin_nonce) if o[b"result"] <= target: assert len(bin_nonce) == 8 assert len(o[b"mix digest"]) == 32 return bin_nonce, o[b"mix digest"] return None, None