def test_powhash(self): teststart = '700000005d385ba114d079970b29a9418fd0549e7d68a95c7f168621a314201000000000578586d149fd07b22f3a8a347c516de7052f034d2b76ff68e0d6ecff9b77a45489e3fd511732011df0731000' testbin = unhexlify(teststart) hash_bin = qubit_hash.getPoWHash(testbin) self.assertEqual( hash_bin, unhexlify( 'c2674acc5050985aec4527ffb1faf548bace4c503d0220ef7601c5f2182c9f63' ))
def calc_qubit(self): if self.qubit is None: r = [] r.append(struct.pack("<i", self.nVersion)) r.append(ser_uint256(self.hashPrevBlock)) r.append(ser_uint256(self.hashMerkleRoot)) r.append(struct.pack("<I", self.nTime)) r.append(struct.pack("<I", self.nBits)) r.append(struct.pack("<I", self.nNonce)) self.qubit = uint256_from_str(qubit_hash.getPoWHash(''.join(r))) return self.qubit
def calc_hdr_hash(blk_hdr): #hash1 = hashlib.sha256() #hash1.update(blk_hdr) #hash1_o = hash1.digest() #hash2 = hashlib.sha256() #hash2.update(hash1_o) #hash2_o = hash2.digest() #return hash2_o pow_hash = qubit_hash.getPoWHash(blk_hdr) return pow_hash
def block_header_hash(chain, header): import qubit_hash return qubit_hash.getPoWHash(header)
import qubit_hash import weakref import binascii import StringIO from binascii import unhexlify teststart = '700000005d385ba114d079970b29a9418fd0549e7d68a95c7f168621a314201000000000578586d149fd07b22f3a8a347c516de7052f034d2b76ff68e0d6ecff9b77a45489e3fd511732011df0731000' testbin = unhexlify(teststart) hash_bin1 = qubit_hash.getPoWHash(testbin) print("R1: {}".format(hash_bin1.encode('hex'))) hash_bin2 = qubit_hash.getPoWHash(testbin) print("R2: {}".format(hash_bin2.encode('hex'))) assert hash_bin1 == hash_bin2
def QubitHash(x): return qubit_hash.getPoWHash(x)
def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty, ip, submit_time): '''Check parameters and finalize block template. If it leads to valid block candidate, asynchronously submits the block back to the bitcoin network. - extranonce1_bin is binary. No checks performed, it should be from session data - job_id, extranonce2, ntime, nonce - in hex form sent by the client - difficulty - decimal number from session, again no checks performed - submitblock_callback - reference to method which receive result of submitblock() ''' # Check if extranonce2 looks correctly. extranonce2 is in hex form... if len(extranonce2) != self.extranonce2_size * 2: raise SubmitException( "Incorrect size of extranonce2. Expected %d chars" % (self.extranonce2_size * 2)) # Check for job job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) # Check if ntime looks correct if len(ntime) != 8: raise SubmitException("Incorrect size of ntime. Expected 8 chars") if not job.check_ntime(int(ntime, 16)): raise SubmitException("Ntime out of range") # Check nonce if len(nonce) != 8: raise SubmitException("Incorrect size of nonce. Expected 8 chars") # Check for duplicated submit if not job.register_submit(extranonce1_bin, extranonce2, ntime, nonce): log.info("Duplicate from %s, (%s %s %s %s)" % \ (worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce)) raise SubmitException("Duplicate share") # Now let's do the hard work! # --------------------------- # 0. Some sugar extranonce2_bin = binascii.unhexlify(extranonce2) ntime_bin = binascii.unhexlify(ntime) nonce_bin = binascii.unhexlify(nonce) # 1. Build coinbase coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin) coinbase_hash = util.doublesha(coinbase_bin) # 2. Calculate merkle root merkle_root_bin = job.merkletree.withFirst(coinbase_hash) merkle_root_int = util.uint256_from_str(merkle_root_bin) # 3. Serialize header with given merkle, ntime and nonce header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin) # 4. Reverse header and compare it with target of the user if settings.DAEMON_ALGO == 'scrypt': hash_bin = ltc_scrypt.getPoWHash(header_bin) elif settings.DAEMON_ALGO == 'yescrypt': hash_bin = yescrypt_hash.getPoWHash(header_bin) elif settings.DAEMON_ALGO == 'qubit': hash_bin = qubit_hash.getPoWHash(header_bin) else: hash_bin = util.doublesha(header_bin) hash_int = util.uint256_from_str(hash_bin) pow_hash_hex = "%064x" % hash_int header_hex = binascii.hexlify(header_bin) target_user = self.diff_to_target(difficulty) if hash_int > target_user: raise SubmitException("Share is above target") # Mostly for debugging purposes target_info = self.diff_to_target(1000) if hash_int <= target_info: log.info("Yay, share with diff above 1000") # Algebra tells us the diff_to_target is the same as hash_to_diff share_diff = float(self.diff_to_target(hash_int)) on_submit = None aux_submit = None block_hash_bin = util.doublesha(header_bin) block_hash_hex = block_hash_bin[::-1].encode('hex_codec') if hash_int <= job.target: log.info( "MAINNET BLOCK CANDIDATE! %s diff(%f/%f)" % (block_hash_hex, share_diff, self.diff_to_target(job.target))) job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16)) if not job.is_valid(): log.exception("FINAL JOB VALIDATION FAILED!") serialized = binascii.hexlify(job.serialize()) if settings.SOLUTION_BLOCK_HASH: on_submit = self.bitcoin_rpc.submitblock( serialized, block_hash_hex) else: on_submit = self.bitcoin_rpc.submitblock( serialized, pow_hash_hex) '''if on_submit: self.update_block()''' # Check auxiliary merged chains for chain in range(len(job.auxs)): if hash_int <= job.aux_targets[chain]: log.info("FOUND MERGED BLOCK! %s diff(%f/%f)" % (job.auxs[chain]['hash'], share_diff, self.diff_to_target(job.aux_targets[chain]))) coinbase_hex = binascii.hexlify(coinbase_bin) branch_count = job.merkletree.branchCount() branch_hex = job.merkletree.branchHex() merkle_link = util.calculate_merkle_link( job.merkle_hashes, job.tree[job.auxs[chain]['chainid']]) submission = coinbase_hex + block_hash_hex + branch_count + branch_hex + '00000000' + merkle_link + header_hex aux_submit = self.aux_rpc.conns[chain].getauxblock( job.auxs[chain]['hash'], submission) aux_submit.addCallback( Interfaces.share_manager.on_submit_aux_block, worker_name, header_hex, job.auxs[chain]['hash'], submit_time, ip, share_diff) '''if aux_submit: self.update_auxs()''' if settings.SOLUTION_BLOCK_HASH: return (header_hex, block_hash_hex, share_diff, on_submit) else: return (header_hex, pow_hash_hex, share_diff, on_submit)
def test_powhash(self): teststart = '700000005d385ba114d079970b29a9418fd0549e7d68a95c7f168621a314201000000000578586d149fd07b22f3a8a347c516de7052f034d2b76ff68e0d6ecff9b77a45489e3fd511732011df0731000'; testbin = unhexlify(teststart) hash_bin = qubit_hash.getPoWHash(testbin) self.assertEqual(hash_bin, unhexlify('c2674acc5050985aec4527ffb1faf548bace4c503d0220ef7601c5f2182c9f63'))
import qubit_hash import weakref import binascii import StringIO from binascii import unhexlify teststart = '700000005d385ba114d079970b29a9418fd0549e7d68a95c7f168621a314201000000000578586d149fd07b22f3a8a347c516de7052f034d2b76ff68e0d6ecff9b77a45489e3fd511732011df0731000'; testbin = unhexlify(teststart) hash_bin = qubit_hash.getPoWHash(testbin)
import qubit_hash import weakref import binascii import StringIO from binascii import unhexlify teststart = '700000005d385ba114d079970b29a9418fd0549e7d68a95c7f168621a314201000000000578586d149fd07b22f3a8a347c516de7052f034d2b76ff68e0d6ecff9b77a45489e3fd511732011df0731000' testbin = unhexlify(teststart) hash_bin = qubit_hash.getPoWHash(testbin)
def pow_hash_qubit_header(self,header): return rev_hex(qubit_hash.getPoWHash(self.header_to_string(header).decode('hex')).encode('hex'))
import qubit_hash import weakref import binascii import StringIO from binascii import unhexlify teststart = '700000005d385ba114d079970b29a9418fd0549e7d68a95c7f168621a314201000000000578586d149fd07b22f3a8a347c516de7052f034d2b76ff68e0d6ecff9b77a45489e3fd511732011df0731000'; testbin = unhexlify(teststart) hash_bin1 = qubit_hash.getPoWHash(testbin) print("R1: {}".format(hash_bin1.encode('hex'))) hash_bin2 = qubit_hash.getPoWHash(testbin) print("R2: {}".format(hash_bin2.encode('hex'))) assert hash_bin1 == hash_bin2
def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty, ip, submit_time): '''Check parameters and finalize block template. If it leads to valid block candidate, asynchronously submits the block back to the bitcoin network. - extranonce1_bin is binary. No checks performed, it should be from session data - job_id, extranonce2, ntime, nonce - in hex form sent by the client - difficulty - decimal number from session, again no checks performed - submitblock_callback - reference to method which receive result of submitblock() ''' # Check if extranonce2 looks correctly. extranonce2 is in hex form... if len(extranonce2) != self.extranonce2_size * 2: raise SubmitException("Incorrect size of extranonce2. Expected %d chars" % (self.extranonce2_size*2)) # Check for job job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) # Check if ntime looks correct if len(ntime) != 8: raise SubmitException("Incorrect size of ntime. Expected 8 chars") if not job.check_ntime(int(ntime, 16)): raise SubmitException("Ntime out of range") # Check nonce if len(nonce) != 8: raise SubmitException("Incorrect size of nonce. Expected 8 chars") # Check for duplicated submit if not job.register_submit(extranonce1_bin, extranonce2, ntime, nonce): log.info("Duplicate from %s, (%s %s %s %s)" % \ (worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce)) raise SubmitException("Duplicate share") # Now let's do the hard work! # --------------------------- # 0. Some sugar extranonce2_bin = binascii.unhexlify(extranonce2) ntime_bin = binascii.unhexlify(ntime) nonce_bin = binascii.unhexlify(nonce) # 1. Build coinbase coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin) coinbase_hash = util.doublesha(coinbase_bin) # 2. Calculate merkle root merkle_root_bin = job.merkletree.withFirst(coinbase_hash) merkle_root_int = util.uint256_from_str(merkle_root_bin) # 3. Serialize header with given merkle, ntime and nonce header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin) # 4. Reverse header and compare it with target of the user if settings.DAEMON_ALGO == 'scrypt': hash_bin = ltc_scrypt.getPoWHash(header_bin) elif settings.DAEMON_ALGO == 'yescrypt': hash_bin = yescrypt_hash.getPoWHash(header_bin) elif settings.DAEMON_ALGO == 'qubit': hash_bin = qubit_hash.getPoWHash(header_bin) else: hash_bin = util.doublesha(header_bin) hash_int = util.uint256_from_str(hash_bin) pow_hash_hex = "%064x" % hash_int header_hex = binascii.hexlify(header_bin) target_user = self.diff_to_target(difficulty) if hash_int > target_user: raise SubmitException("Share is above target") # Mostly for debugging purposes target_info = self.diff_to_target(1000) if hash_int <= target_info: log.info("Yay, share with diff above 1000") # Algebra tells us the diff_to_target is the same as hash_to_diff share_diff = float(self.diff_to_target(hash_int)) on_submit = None aux_submit = None block_hash_bin = util.doublesha(header_bin) block_hash_hex = block_hash_bin[::-1].encode('hex_codec') if hash_int <= job.target: log.info("MAINNET BLOCK CANDIDATE! %s diff(%f/%f)" % (block_hash_hex, share_diff, self.diff_to_target(job.target))) job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16)) if not job.is_valid(): log.exception("FINAL JOB VALIDATION FAILED!") serialized = binascii.hexlify(job.serialize()) if settings.SOLUTION_BLOCK_HASH: on_submit = self.bitcoin_rpc.submitblock(serialized, block_hash_hex) else: on_submit = self.bitcoin_rpc.submitblock(serialized, pow_hash_hex) '''if on_submit: self.update_block()''' # Check auxiliary merged chains for chain in range(len(job.auxs)): if hash_int <= job.aux_targets[chain]: log.info("FOUND MERGED BLOCK! %s diff(%f/%f)" % (job.auxs[chain]['hash'], share_diff, self.diff_to_target(job.aux_targets[chain]))) coinbase_hex = binascii.hexlify(coinbase_bin) branch_count = job.merkletree.branchCount() branch_hex = job.merkletree.branchHex() merkle_link = util.calculate_merkle_link(job.merkle_hashes, job.tree[job.auxs[chain]['chainid']]) submission = coinbase_hex + block_hash_hex + branch_count + branch_hex + '00000000' + merkle_link + header_hex; aux_submit = self.aux_rpc.conns[chain].getauxblock(job.auxs[chain]['hash'], submission) aux_submit.addCallback(Interfaces.share_manager.on_submit_aux_block, worker_name, header_hex, job.auxs[chain]['hash'], submit_time, ip, share_diff) '''if aux_submit: self.update_auxs()''' if settings.SOLUTION_BLOCK_HASH: return (header_hex, block_hash_hex, share_diff, on_submit) else: return (header_hex, pow_hash_hex, share_diff, on_submit)