from last known template.'''
return self.last_block.broadcast_args
- def add_template(self, block):
+ def add_template(self, block,block_height):
'''Adds new template to the registry.
It also clean up templates which should
not be used anymore.'''
if new_block:
# Tell the system about new block
# It is mostly important for share manager
- self.on_block_callback(prevhash)
+ self.on_block_callback(prevhash, block_height)
# Everything is ready, let's broadcast jobs!
self.on_template_callback(new_block)
template = self.block_template_class(Interfaces.timestamper, self.coinbaser, JobIdGenerator.get_new_id())
template.fill_from_rpc(data)
- self.add_template(template)
+ self.add_template(template,data['height'])
log.info("Update finished, %.03f sec, %d txes" % \
(Interfaces.timestamper.time() - start, len(template.vtx)))
def diff_to_target(self, difficulty):
'''Converts difficulty to target'''
- diff1 = 0x00000000ffff0000000000000000000000000000000000000000000000000000
+ diff1 = 0x0000ffff00000000000000000000000000000000000000000000000000000000
return diff1 / difficulty
def get_job(self, job_id):
return j
- def submit_share(self, job_id, worker_name, extranonce1_bin, extranonce2, ntime, nonce,
+ def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce,
difficulty):
'''Check parameters and finalize block template. If it leads
to valid block candidate, asynchronously submits the block
# Check nonce
if len(nonce) != 8:
raise SubmitException("Incorrect size of nonce. Expected 8 chars")
-
+
+ # normalize the case to prevent duplication of valid shares by the client
+ ntime = ntime.lower()
+ nonce = nonce.lower()
+ extranonce2 = extranonce2.lower()
+
# Check for duplicated submit
if not job.register_submit(extranonce1_bin, extranonce2, ntime, nonce):
log.info("Duplicate from %s, (%s %s %s %s)" % \
header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin)
# 4. Reverse header and compare it with target of the user
- hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
+ hash_bin = util.scrypt(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
hash_int = util.uint256_from_str(hash_bin)
block_hash_hex = "%064x" % hash_int
header_hex = binascii.hexlify(header_bin)
target_user = self.diff_to_target(difficulty)
- if hash_int > target_user:
+ if hash_int > target_user and \
+ ( 'prev_jobid' not in session or session['prev_jobid'] < job_id \
+ or 'prev_diff' not in session or hash_int > self.diff_to_target(session['prev_diff']) ):
raise SubmitException("Share is above target")
# Mostly for debugging purposes
if hash_int <= target_info:
log.info("Yay, share with diff above 100000")
+ # Algebra tells us the diff_to_target is the same as hash_to_diff
+ share_diff = int(self.diff_to_target(hash_int))
+
# 5. Compare hash with target of the network
if hash_int <= job.target:
# Yay! It is block candidate!
serialized = binascii.hexlify(job.serialize())
on_submit = self.bitcoin_rpc.submitblock(serialized)
- return (header_hex, block_hash_hex, on_submit)
+ return (header_hex, block_hash_hex, share_diff, on_submit)
- return (header_hex, block_hash_hex, None)
\ No newline at end of file
+ return (header_hex, block_hash_hex, share_diff, None)