def serialize(self): r = [] r.append(struct.pack("<i", self.nVersion)) r.append(util.ser_uint256(self.hashPrevBlock)) r.append(util.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)) r.append(util.ser_vector(self.vtx)) return ''.join(r)
def serialize(self): r = [ struct.pack("<i", self.nVersion), util.ser_uint256(self.hashPrevBlock), util.ser_uint256(self.hashMerkleRoot), struct.pack("<I", self.nTime), struct.pack("<I", self.nBits), struct.pack("<I", self.nNonce), util.ser_vector(self.vtx) ] return ''.join(r)
def submit_share(self, job_id, worker_name, session, extranonce1_bin, data, difficulty): job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) ntime = util.flip(data[136:144]) if not job.check_ntime(int(ntime, 16)): raise SubmitException("Ntime out of range") if not job.register_submit(data): log.info("Duplicate from %s, (%s %s)" % \ (worker_name, binascii.hexlify(extranonce1_bin), data)) raise SubmitException("Duplicate share") hash_int = gapcoin_hash.getpowdiff(str(data)) block_hash_bin = util.doublesha(binascii.unhexlify(data[0:168])) block_hash_hex = util.rev(binascii.hexlify(block_hash_bin)) '''log.info("block_hash_hex %s" % block_hash_hex) log.info("shrint %s" % hash_int) log.info("jobint %s" % job.target)%f log.info("target %s" % difficulty)''' if hash_int < difficulty: raise SubmitException("Share less than target") share_diff = float(float(hash_int) / float(pow(2, 48))) if hash_int >= job.target: log.info("BLOCK CANDIDATE! %s" % block_hash_hex) extranonce2_bin = struct.pack('>L', 0) #self.last_block.vtx[0].set_extranonce(extranonce1_bin + extranonce2_bin) #txs = binascii.hexlify(util.ser_vector(self.last_block.vtx)) job.vtx[0].set_extranonce(extranonce1_bin + extranonce2_bin) txs = binascii.hexlify(util.ser_vector(job.vtx)) serialized = str(data) + str(txs) on_submit = self.bitcoin_rpc.submitblock(str(data), str(txs), block_hash_hex) if on_submit: self.update_block() return (block_hash_hex, share_diff, on_submit) return (block_hash_hex, share_diff, None)
def serialize(self): r = [] r.append(struct.pack("<i", self.nVersion)) r.append(util.ser_uint256(self.hashPrevBlock)) r.append(util.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)) r.append(util.ser_uint256(self.hashstateroot)) r.append(util.ser_uint256(self.hashutxoroot)) r.append( binascii.unhexlify( "0000000000000000000000000000000000000000000000000000000000000000ffffffff00" )) r.append(util.ser_vector(self.vtx)) return ''.join(r)
def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty): # Check for job job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) nonce = util.rev(nonce) ntime = util.rev(ntime) extranonce2_bin = binascii.unhexlify(extranonce2) ntime_bin = binascii.unhexlify(ntime) nonce_bin = binascii.unhexlify(nonce) # 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 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") # 1. Build coinbase coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin) coinbase_hash = kshake320_hash.getHash320(coinbase_bin) # 2. Calculate merkle root merkle_root_bin = job.merkletree.withFirst(coinbase_hash) merkle_root_int = util.uint320_from_str(merkle_root_bin) # 3. Serialize header with given merkle, ntime and nonce header_bin = job.serialize_header(merkle_root_bin, int(ntime, 16), int(nonce, 16)) header_hex = binascii.hexlify(header_bin) header_hex = header_hex + "0000000000000000" # 4. Reverse header and compare it with target of the user hash_bin = kshake320_hash.getPoWHash(header_bin) hash_int = util.uint320_from_str(hash_bin) hash_hex = "%080x" % hash_int block_hash_hex = hash_bin[::-1].encode('hex_codec') target_user = float(self.diff_to_target(difficulty)) if hash_int > target_user: log.info("ABOVE TARGET!") raise SubmitException("Share above target") target_info = self.diff_to_target(50) if hash_int <= target_info: log.info("YAY, share with diff above 50") # Algebra tells us the diff_to_target is the same as hash_to_diff share_diff = float(self.diff_to_target(hash_int)) if hash_int <= job.target: # Yay! It is block candidate! log.info("BLOCK CANDIDATE! %s" % block_hash_hex) # Finalize and serialize block object job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16)) if not job.is_valid(): # Should not happen log.info("FINAL JOB VALIDATION FAILED!") # Submit block to the network '''serialized = binascii.hexlify(job.serialize()) on_submit = self.bitcoin_rpc.submitblock(str(serialized), block_hash_hex)''' job.vtx[0].set_extranonce(extranonce1_bin + extranonce2_bin) txs = binascii.hexlify(util.ser_vector(job.vtx)) on_submit = self.bitcoin_rpc.submitblock_wtxs( str(header_hex), str(txs), block_hash_hex) '''if on_submit: self.update_block()''' return (block_hash_hex, share_diff, on_submit) return (block_hash_hex, share_diff, None)