コード例 #1
0
ファイル: miner.py プロジェクト: kmod/bitcoin_mining
    def verify(self, extranonce2, ntime, nonce):
        return
        coinbase = self.coinb1 + self.extranonce1 + extranonce2 + self.coinb2
        coinbase_hash_bin = doublesha(binascii.unhexlify(coinbase))
        merkle_root = build_merkle_root(self.merkle_branch, coinbase_hash_bin)
        merkle_root = ser_uint256_be(uint256_from_str(merkle_root))
        preheader = self.version + self.prevhash + merkle_root.encode("hex") + ntime + self.nbits
        preheader_bin = preheader.decode("hex")
        preheader_bin = ''.join([preheader_bin[i*4:i*4+4][::-1] for i in range(0,19)])

        hash_bin = doublesha(preheader_bin + nonce.decode("hex")[::-1])
        print hash_bin.encode("hex")
        val = struct.unpack("<I", hash_bin[-4:])[0]
        assert val < THRESH, (val, THRESH)
コード例 #2
0
ファイル: sha_mining.py プロジェクト: kmod/bitcoin_mining
    def _target(self, job_id, extranonce2, ntime, preheader_bin):
        try:
            start = time.time()

            first_sha = hashlib.sha256(preheader_bin)

            if sys.maxint > 2**32:
                max_nonce = 2**32
            else:
                max_nonce = 2**31 - 1
            i = 0
            while i < max_nonce:
                if i % 100000 == 0:
                    print i, "%.1f kh/s" % (i * .001 / (time.time() - start + .001))
                    if self._quit:
                        print "QUITTING WORKER"
                        break

                nonce_bin = struct.pack(">I", i)
                if TEST:
                    nonce_bin = "b2957c02".decode("hex")[::-1]

                # header_bin = preheader_bin + nonce_bin
                # hash_bin = doublesha(header_bin)
                # assert hash_bin == finish_dsha(first_sha, nonce_bin)
                hash_bin = finish_dsha(first_sha, nonce_bin)

                val = struct.unpack("<I", hash_bin[-4:])[0]
                if val < THRESH:
                    nonce = nonce_bin[::-1].encode("hex")
                    print nonce, extranonce2, ntime
                    print hash_bin.encode("hex")
                    hash_int = uint256_from_str(hash_bin)
                    block_hash_hex = "%064x" % hash_int
                    print block_hash_hex


                    self._cl.submit(job_id, extranonce2, ntime, nonce)
                    break
                elif val < THRESH*10:
                    print "almost: %d (<%d)" % (val, THRESH)
                i += 1
                # elif i == 0:
                    # print hash_bin.encode("hex")
            self._done_ev.set()
        except:
            traceback.print_exc()
            os._exit(1)
コード例 #3
0
    def _target(self, job_id, extranonce2, ntime, preheader_bin):
        try:
            start = time.time()

            first_sha = hashlib.sha256(preheader_bin)

            if sys.maxint > 2**32:
                max_nonce = 2**32
            else:
                max_nonce = 2**31 - 1
            i = 0
            while i < max_nonce:
                if i % 100000 == 0:
                    print i, "%.1f kh/s" % (i * .001 /
                                            (time.time() - start + .001))
                    if self._quit:
                        print "QUITTING WORKER"
                        break

                nonce_bin = struct.pack(">I", i)
                if TEST:
                    nonce_bin = "b2957c02".decode("hex")[::-1]

                # header_bin = preheader_bin + nonce_bin
                # hash_bin = doublesha(header_bin)
                # assert hash_bin == finish_dsha(first_sha, nonce_bin)
                hash_bin = finish_dsha(first_sha, nonce_bin)

                val = struct.unpack("<I", hash_bin[-4:])[0]
                if val < THRESH:
                    nonce = nonce_bin[::-1].encode("hex")
                    print nonce, extranonce2, ntime
                    print hash_bin.encode("hex")
                    hash_int = uint256_from_str(hash_bin)
                    block_hash_hex = "%064x" % hash_int
                    print block_hash_hex

                    self._cl.submit(job_id, extranonce2, ntime, nonce)
                    break
                elif val < THRESH * 10:
                    print "almost: %d (<%d)" % (val, THRESH)
                i += 1
                # elif i == 0:
                # print hash_bin.encode("hex")
            self._done_ev.set()
        except:
            traceback.print_exc()
            os._exit(1)
コード例 #4
0
ファイル: miner.py プロジェクト: sycomix/bitcoin_mining
    def verify(self, extranonce2, ntime, nonce):
        return
        coinbase = self.coinb1 + self.extranonce1 + extranonce2 + self.coinb2
        coinbase_hash_bin = doublesha(binascii.unhexlify(coinbase))
        merkle_root = build_merkle_root(self.merkle_branch, coinbase_hash_bin)
        merkle_root = ser_uint256_be(uint256_from_str(merkle_root))
        preheader = self.version + self.prevhash + merkle_root.encode(
            "hex") + ntime + self.nbits
        preheader_bin = preheader.decode("hex")
        preheader_bin = ''.join(
            [preheader_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 19)])

        hash_bin = doublesha(preheader_bin + nonce.decode("hex")[::-1])
        print hash_bin.encode("hex")
        val = struct.unpack("<I", hash_bin[-4:])[0]
        assert val < THRESH, (val, THRESH)
コード例 #5
0
    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
           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
        hash_bin = yac_scrypt.getPoWHash(
            ''.join([header_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 20)]),
            int(ntime, 16))
        hash_int = util.uint256_from_str(hash_bin)
        scrypt_hash_hex = "%064x" % hash_int
        header_hex = binascii.hexlify(header_bin)
        header_hex = header_hex + "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"

        target_user = self.diff_to_target(difficulty)
        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
        target_info = self.diff_to_target(100000)
        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!
            log.info("We found a block candidate! %s" % scrypt_hash_hex)

            # 6. 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.error("Final job validation failed!")

            # 7. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            on_submit = self.bitcoin_rpc.submitblock(serialized,
                                                     scrypt_hash_hex)

            return (header_hex, scrypt_hash_hex, share_diff, on_submit)

        return (header_hex, scrypt_hash_hex, share_diff, None)
コード例 #6
0
    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
           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
        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 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
        target_info = self.diff_to_target(100000)
        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! 
            log.info("We found a block candidate! %s" % block_hash_hex)
           
            # 6. 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.error("Final job validation failed!")
                            
            # 7. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            on_submit = self.bitcoin_rpc.submitblock(serialized)
            
            return (header_hex, block_hash_hex, share_diff, on_submit)
        
        return (header_hex, block_hash_hex, share_diff, None)
コード例 #7
0
    def submit_share(self,
                     job_id,
                     worker_name,
                     session,
                     extranonce1_bin,
                     extranonce2,
                     ntime,
                     nonce,
                     difficulty,
                     ip=False):
        '''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
			- submitblock_callback - reference to method which receive result of submitblock()
			- difficulty is checked to see if its lower than the vardiff minimum target or pool target
			  from conf/config.py and if it is the share is rejected due to it not meeting the requirements for a share
			  
		'''
        log.debug("Session: %s" % session)

        # Share Difficulty should never be 0 or below
        if difficulty <= 0:
            log.exception(
                "Worker %s @ IP: %s seems to be submitting Fake Shares" %
                (worker_name, ip))
            raise SubmitException(
                "Diff is %s Share Rejected Reporting to Admin" % (difficulty))

        # 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, worker_name, ip)
        if job == None:
            if settings.REJECT_STALE_SHARES:
                # Reject stale share
                raise SubmitException("Job '%s' not found" % job_id)
            else:
                # Accept stale share but do not continue checking, return a bunch of nothingness
                log.info("Accepted Stale Share from %s, (%s %s %s %s)" % \
                 (worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce))
                return (None, None, None, None, None, None)

        # Check if ntime looks correct
        check_result, error_message = util.check_ntime(ntime)
        if not check_result:
            raise SubmitException(error_message)

        if not job.check_ntime(int(ntime, 16), getattr(settings, 'NTIME_AGE')):
            raise SubmitException("Ntime out of range")

        # Check nonce
        check_result, error_message = util.check_nonce(nonce)
        if not check_result:
            raise SubmitException(error_message)

        # 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 = util.get_ntime_bin(ntime)
        nonce_bin = util.get_nonce_bin(nonce)
        target_user = self.diff_to_target(difficulty)
        target_info = self.diff_to_target(100000)

        # 1. Build coinbase
        coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin)
        coinbase_hash = util.get_coinbase_hash(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. Convert header into hex according to hash algorythim
        block_hash = util.get_hash_hex(header_bin, ntime, nonce)

        # 5a Compare it with target of the user
        check_result, message = util.check_header_target(
            block_hash['int'], target_user)
        if not check_result:
            log.debug(
                "Oops, somthing is wrong: target_user=%s, difficulty=%s, share_diff=%s"
                % (target_user, difficulty,
                   int(self.diff_to_target(block_hash['int']))))
            raise SubmitException("%s. Hash: %s" %
                                  (message, block_hash['hex']))

        # Mostly for debugging purposes, just a celebratory message that's being carried over from older versions
        check_result, message = util.check_above_yay_target(
            block_hash['int'], target_info)
        if check_result:
            log.info(message)

        # Algebra tells us the diff_to_target is the same as hash_to_diff
        if settings.VDIFF_FLOAT:
            share_diff = float(self.diff_to_target(block_hash['int']))
        else:
            share_diff = int(self.diff_to_target(block_hash['int']))

        log.debug("share_diff: %s" % share_diff)
        log.debug("job.target: %s" % job.target)
        log.debug("block_hash_int: %s" % block_hash['int'])

        # 6. Compare hash with target of the network
        if util.is_block_candidate(block_hash['int'], job.target):
            # Yay! It is block candidate!
            log.info("We found a block candidate! for %i: %s | %s" %
                     (job.height, block_hash['hex'], block_hash['check_hex']))

            # 7. 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(difficulty):
                # Should not happen
                log.exception(
                    "FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)"
                )

            # 8. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            on_submit = self.bitcoin_rpc.submitblock(serialized,
                                                     block_hash['check_hex'],
                                                     block_hash['hex'])

            if on_submit:
                self.update_block()

            return (block_hash['header_hex'], block_hash['solution_hex'],
                    share_diff, job.prevhash_hex, job.height, on_submit)

        # Not a potential Block
        return (block_hash['header_hex'], block_hash['solution_hex'],
                share_diff, job.prevhash_hex, job.height, None)
コード例 #8
0
    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)
コード例 #9
0
    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)
コード例 #10
0
    def submit_share(self,
                     job_id,
                     worker_name,
                     session,
                     extranonce1_bin,
                     extranonce2,
                     ntime,
                     nonce,
                     difficulty,
                     ip=False):
        '''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
            - submitblock_callback - reference to method which receive result of submitblock()
            - difficulty is checked to see if its lower than the vardiff minimum target or pool target
              from conf/config.py and if it is the share is rejected due to it not meeting the requirements for a share
              
        '''
        if settings.VARIABLE_DIFF == True:
            # Share Diff Should never be 0
            if difficulty < settings.VDIFF_MIN_TARGET:
                log.exception(
                    "Worker %s @ IP: %s seems to be submitting Fake Shares" %
                    (worker_name, ip))
                raise SubmitException(
                    "Diff is %s Share Rejected Reporting to Admin" %
                    (difficulty))
        else:
            if difficulty < settings.POOL_TARGET:
                log.exception(
                    "Worker %s @ IP: %s seems to be submitting Fake Shares" %
                    (worker_name, ip))
                raise SubmitException(
                    "Diff is %s Share Rejected Reporting to Admin" %
                    (difficulty))

        # 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))

            # normalize the case to prevent duplication of valid shares by the client
            ntime = ntime.lower()
            nonce = nonce.lower()
            extranonce2 = extranonce2.lower()

        # Check for job
        job = self.get_job(job_id, worker_name, ip)
        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")

        # 0. Some sugar
        extranonce2_bin = binascii.unhexlify(extranonce2)
        ntime_bin = binascii.unhexlify(ntime)
        nonce_bin = binascii.unhexlify(nonce)

        # Check for duplicated submit
        if not job.register_submit(extranonce1_bin, extranonce2_bin, ntime_bin,
                                   nonce_bin):
            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!
        # ---------------------------

        # 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
        hash_bin = algolib.getPoWHash(''.join(
            [header_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 20)]))
        hash_int = util.uint256_from_str(hash_bin)
        scrypt_hash_hex = "%064x" % hash_int
        header_hex = binascii.hexlify(header_bin)
        if settings.CUSTOM_HEADER != None:
            header_hex = header_hex + settings.CUSTOM_HEADER

        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(100000)
        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!
            log.info("We found a block candidate! %s" % scrypt_hash_hex)

            block_hash_bin = util.doublesha(''.join(
                [header_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 20)]))
            block_hash_hex = block_hash_bin[::-1].encode('hex_codec')

            # 6. 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.exception(
                    "FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)"
                )

            # 7. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            on_submit = self.bitcoin_rpc.submitblock(serialized,
                                                     block_hash_hex,
                                                     scrypt_hash_hex)
            if on_submit:
                self.update_block()

            if settings.SOLUTION_BLOCK_HASH:
                return (header_hex, block_hash_hex, share_diff, on_submit)
            else:
                return (header_hex, scrypt_hash_hex, share_diff, on_submit)

        if settings.SOLUTION_BLOCK_HASH:
            block_hash_bin = util.doublesha(''.join(
                [header_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 20)]))
            block_hash_hex = block_hash_bin[::-1].encode('hex_codec')
            return (header_hex, block_hash_hex, share_diff, None)
        else:
            return (header_hex, scrypt_hash_hex, share_diff, None)
コード例 #11
0
    def submit_share(self, job_id, worker_name, extranonce1_bin, extranonce2, ntime, nonce,
                     difficulty):
        '''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
        hash_bin = util.doublesha(''.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:
            # For testing purposes ONLY
            if not config.ACCEPT_SHARES_ABOVE_TARGET:
                raise SubmitException("Share is above target")

        # 5. Compare hash with target of the network
        if hash_int <= job.target or \
                (nonce == config.ACCEPT_INVALID_BLOCK__NONCE):
            # Yay! It is block candidate!
            log.info("We found a block candidate! %s" % block_hash_hex)

            # 6. 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.error("Final job validation failed!")

            # 7. Get block value for statistical purposes
            block_value = job.get_value()

            # 8. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            on_submit = self.bitcoin_rpc.submitblock(serialized)

            return (header_hex, block_hash_hex, block_value, on_submit)

        return (header_hex, block_hash_hex, None, None)
コード例 #12
0
    def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce,
                     difficulty, ip=False):
        '''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, worker_name, ip)
        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
        hash_bin = algo.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))

        hash_int = util.uint256_from_str(hash_bin)
        scrypt_hash_hex = "%064x" % hash_int
        header_hex = binascii.hexlify(header_bin)
        
	if coindef.header() = True:
           header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
コード例 #13
0
    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
           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.COINDAEMON_ALGO == 'scrypt':
            hash_bin = ltc_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
        elif settings.COINDAEMON_ALGO  == 'scrypt-jane':
            hash_bin = yac_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]), int(ntime, 16))
        elif settings.COINDAEMON_ALGO == 'quark':
            hash_bin = quark_hash.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
        else:
            hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))

        hash_int = util.uint256_from_str(hash_bin)
        scrypt_hash_hex = "%064x" % hash_int
        header_hex = binascii.hexlify(header_bin)
        if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'scrypt-jane':
            header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
        elif settings.COINDAEMON_ALGO == 'quark':
            header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
        else: pass
                 
        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(100000)
        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! 
            log.info("We found a block candidate! %s" % scrypt_hash_hex)

            # Reverse the header and get the potential block hash (for scrypt only) 
            #if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'sha256d':
            #   if settings.COINDAEMON_Reward == 'POW':
            block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
            block_hash_hex = block_hash_bin[::-1].encode('hex_codec')
            #else:   block_hash_hex = hash_bin[::-1].encode('hex_codec')
            #else:  block_hash_hex = hash_bin[::-1].encode('hex_codec')
            # 6. 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.exception("FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)")
                            
            # 7. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            if settings.BLOCK_CHECK_SCRYPT_HASH:
                on_submit = self.bitcoin_rpc.submitblock(serialized, scrypt_hash_hex)
            else:
                on_submit = self.bitcoin_rpc.submitblock(serialized, block_hash_hex)
            if on_submit:
                self.update_block()

            if settings.SOLUTION_BLOCK_HASH:
                return (header_hex, block_hash_hex, share_diff, on_submit)
            else:
                return (header_hex, scrypt_hash_hex, share_diff, on_submit)
        
        if settings.SOLUTION_BLOCK_HASH:
        # Reverse the header and get the potential block hash (for scrypt only) only do this if we want to send in the block hash to the shares table
            block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
            block_hash_hex = block_hash_bin[::-1].encode('hex_codec')
            return (header_hex, block_hash_hex, share_diff, None)
        else:
            return (header_hex, scrypt_hash_hex, share_diff, None)
コード例 #14
0
ファイル: miner.py プロジェクト: kmod/bitcoin_mining
    def run(self):
        difficulty = 1
        while True:
            s = self.f.readline()
            if not s:
                break

            if TEST:
                s = """{"params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000",
        "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008",
        "072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [],
        "00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"}"""
                extranonce1 = "08000002"

            s = s.strip()
            assert s
            d = simplejson.loads(s)

            # if d.get('method', None) == "mining.notify" and self.done:
                # continue

            print d

            if d.get('error', None):
                raise Exception()

            if d['id'] == 1 and 'method' not in d:
                subscription, extranonce1, extranonce2_size = d['result']

            elif d.get('method', None) == "mining.set_difficulty":
                difficulty = d['params'][0]

            elif d.get('method', None) == "mining.notify":
                print "stopping worker"
                self.w.stop()
                print "stopped"

                params, clean_jobs = d['params'][:-1], d['params'][:-1]
                j = JobInfo(extranonce1, *params)
                self.jobs[j.id] = j

                extranonce2 = ((int(time.time()) << 16) + os.getpid()) & 0xffffffff
                extranonce2 = struct.pack(">I", extranonce2).encode("hex")
                if TEST:
                    extranonce2 = "00000001"
                print "extranonce2 = %s" % extranonce2

                coinbase = j.coinb1 + extranonce1 + extranonce2 + j.coinb2
                coinbase_hash_bin = doublesha(binascii.unhexlify(coinbase))
                merkle_root = build_merkle_root(j.merkle_branch, coinbase_hash_bin)
                merkle_root = ser_uint256_be(uint256_from_str(merkle_root))

                # ntime = "504e86ed"
                ntime = j.ntime
                if TEST:
                    ntime = "504e86ed"

                preheader = j.version + j.prevhash + merkle_root.encode("hex") + ntime + j.nbits
                preheader_bin = preheader.decode("hex")
                preheader_bin = ''.join([preheader_bin[i*4:i*4+4][::-1] for i in range(0,19)])

                self.w.start(difficulty, j.id, extranonce2, ntime, preheader_bin)

            else:
                assert d['id'] < self.mid
コード例 #15
0
ファイル: template_registry.py プロジェクト: tuaris/TidePool
	def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty, ip=False):
		'''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
			- submitblock_callback - reference to method which receive result of submitblock()
			- difficulty is checked to see if its lower than the vardiff minimum target or pool target
			  from conf/config.py and if it is the share is rejected due to it not meeting the requirements for a share
			  
		'''
		log.debug("Session: %s" % session)

		# Share Difficulty should never be 0 or below
		if difficulty <= 0 :
			log.exception("Worker %s @ IP: %s seems to be submitting Fake Shares"%(worker_name,ip))
			raise SubmitException("Diff is %s Share Rejected Reporting to Admin"%(difficulty))

		# 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, worker_name, ip)
		if job == None:
			if settings.REJECT_STALE_SHARES:
				# Reject stale share
				raise SubmitException("Job '%s' not found" % job_id)
			else:
				# Accept stale share but do not continue checking, return a bunch of nothingness
				log.info("Accepted Stale Share from %s, (%s %s %s %s)" % \
					(worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce))
				return (None, None, None, None, None, None)

		# Check if ntime looks correct
		check_result, error_message = util.check_ntime(ntime)
		if not check_result:
			raise SubmitException(error_message)

		if not job.check_ntime(int(ntime, 16), getattr(settings, 'NTIME_AGE')):
			raise SubmitException("Ntime out of range")

		# Check nonce
		check_result, error_message = util.check_nonce(nonce)
		if not check_result:
			raise SubmitException(error_message)

		# 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 = util.get_ntime_bin(ntime)
		nonce_bin = util.get_nonce_bin(nonce)
		target_user = self.diff_to_target(difficulty)
		target_info = self.diff_to_target(100000)

		# 1. Build coinbase
		coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin)
		coinbase_hash = util.get_coinbase_hash(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. Convert header into hex according to hash algorythim
		block_hash = util.get_hash_hex(header_bin, ntime, nonce)

		# 5a Compare it with target of the user
		check_result, message = util.check_header_target(block_hash['int'], target_user)
		if not check_result:
			log.debug("Oops, somthing is wrong: target_user=%s, difficulty=%s, share_diff=%s" % (target_user, difficulty, int(self.diff_to_target(block_hash['int']))))
			raise SubmitException("%s. Hash: %s" % (message, block_hash['hex']))

		# Mostly for debugging purposes, just a celebratory message that's being carried over from older versions
		check_result, message = util.check_above_yay_target(block_hash['int'], target_info)
		if check_result:
			log.info(message)

		# Algebra tells us the diff_to_target is the same as hash_to_diff
		if settings.VDIFF_FLOAT:
			share_diff = float(self.diff_to_target(block_hash['int']))
		else:
			share_diff = int(self.diff_to_target(block_hash['int']))

		log.debug("share_diff: %s" % share_diff)
		log.debug("job.target: %s" % job.target)
		log.debug("block_hash_int: %s" % block_hash['int'])

		# 6. Compare hash with target of the network
		if util.is_block_candidate(block_hash['int'], job.target):
			# Yay! It is block candidate!
			log.info("We found a block candidate! for %i: %s | %s" % (job.height, block_hash['hex'], block_hash['check_hex']))

			# 7. 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(difficulty):
				# Should not happen
				log.exception("FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)")

			# 8. Submit block to the network
			serialized = binascii.hexlify(job.serialize())
			on_submit = self.bitcoin_rpc.submitblock(serialized, block_hash['check_hex'], block_hash['hex'])

			if on_submit:
				self.update_block()

			return (block_hash['header_hex'], block_hash['solution_hex'], share_diff, job.prevhash_hex, job.height, on_submit)

		# Not a potential Block
		return (block_hash['header_hex'], block_hash['solution_hex'], share_diff, job.prevhash_hex, job.height, None)
コード例 #16
0
    def _target(self, difficulty, job_id, extranonce2, ntime, preheader_bin):
        try:
            start = time.time()

            if sys.maxint > 2**32:
                max_nonce = 2**32
            else:
                max_nonce = 2**31 - 1
            i = 0

            THRESH = 0x00010000 / difficulty
            # # THRESH = 1 << difficulty
            # # THRESH /= 4
            # THRESH = 0x00002000
            print "thresh:", THRESH

            hashes_per_thresh = (1 << 32) / THRESH

            if TEST:
                print preheader_bin.encode("hex")
                preheader_bin = "01000000f615f7ce3b4fc6b8f61e8f89aedb1d0852507650533a9e3b10b9bbcc30639f279fcaa86746e1ef52d3edb3c4ad8259920d509bd073605c9bf1d59983752a6b06b817bb4ea78e011d012d59d4".decode("hex")[:-4]

            while i < max_nonce:
                if TEST:
                    i = 0x012d59d4

                if self._quit:
                    print "QUITTING WORKER"
                    break
                if i and i % 10000 == 0:
                    hashrate = i * 1.0 / (time.time() - start + .001)
                    print i, "%.1f kh/s (%.1fs/share))" % (hashrate * 0.001, hashes_per_thresh / hashrate)

                nonce_bin = struct.pack(">I", i)

                header_bin = preheader_bin + nonce_bin
                hash_bin = scrypt.hash(header_bin, header_bin, 1024, 1, 1, 32)

                # print
                # print header_bin.encode("hex")
                # print hash_bin.encode("hex")

                val = struct.unpack("<I", hash_bin[-4:])[0]
                # print val
                # print
                if val < THRESH:
                    nonce = nonce_bin[::-1].encode("hex")
                    print nonce, extranonce2, ntime
                    print hash_bin.encode("hex")
                    hash_int = uint256_from_str(hash_bin)
                    block_hash_hex = "%064x" % hash_int
                    print block_hash_hex


                    self._cl.submit(job_id, extranonce2, ntime, nonce)
                elif val < THRESH*10:
                    print "almost: %d (<%d)" % (val, THRESH)
                i += 1
                # elif i == 0:
                    # print hash_bin.encode("hex")
            self._done_ev.set()
        except:
            traceback.print_exc()
            os._exit(1)
コード例 #17
0
    def submit_share(self, job_id, worker_name, extranonce1_bin, extranonce2,
                     ntime, nonce, difficulty):
        '''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()
        '''
        global rsk_last_received_share_time
        global rsk_submitted_shares
        start = Interfaces.timestamper.time()
        logid = util.id_generator()
        log.info(
            json.dumps({
                "rsk": "[RSKLOG]",
                "tag": "[SHARE_RECEIVED_START]",
                "uuid": logid,
                "start": start,
                "elapsed": 0
            }))
        # 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")

        # Convert from hex to binary
        extranonce2_bin = binascii.unhexlify(extranonce2)
        ntime_bin = binascii.unhexlify(ntime)
        nonce_bin = binascii.unhexlify(nonce)

        # Check for duplicated submit
        if not job.register_submit(extranonce1_bin, extranonce2_bin, ntime_bin,
                                   nonce_bin):
            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!
        # ---------------------------

        # 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

        # header 80-bytes (19*4 + 4)
        header_le = ''.join(
            [header_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 20)])
        hash_bin = util.doublesha(header_le)

        hash_int = util.uint256_from_str(hash_bin)
        block_hash_hex = "%064x" % hash_int
        header_hex = binascii.hexlify(header_bin)

        log.info(
            json.dumps({
                "rsk": "[RSKLOG]",
                "tag": "[SHARE_RECEIVED_HEX]",
                "uuid": logid,
                "start": Interfaces.timestamper.time(),
                "elapsed": 0,
                "data": block_hash_hex
            }))

        if not settings.RSK_DEV_MODE:
            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(100000)
        if hash_int <= target_info:
            log.info("Yay, share with diff above 100000")

        # 5. Compare hash with target of the network
        log.info("Hash_Int: %s, Job.Target %s" % (hash_int, job.target))
        btc_solution = hash_int <= job.target
        rsk_solution = False

        if self.rootstock_rpc is not None:
            rsk_solution = hash_int <= self.rootstock_rpc.rsk_target and self._is_rsk_tag_in_coinbase(
                coinbase_bin)

        on_submit_rsk = None
        on_submit = None

        if btc_solution or rsk_solution:
            log.info("We found a block candidate! %s" % block_hash_hex)
            job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin,
                         int(ntime, 16), int(nonce, 16))

            if btc_solution:
                serialized = binascii.hexlify(job.serialize())
                on_submit = self.bitcoin_rpc.submitblock(serialized)
                log.info(
                    json.dumps({
                        "rsk": "[RSKLOG]",
                        "tag": "[BTC_SUBMITBLOCK]",
                        "uuid": util.id_generator(),
                        "start": start,
                        "elapsed": Interfaces.timestamper.time(),
                        "data": block_hash_hex
                    }))

            if rsk_solution:
                if rsk_last_received_share_time is None:
                    rsk_last_received_share_time = int(round(time() * 1000))
                    rsk_submitted_shares = 0
                last_received_share_time_now = int(round(time() * 1000))
                if last_received_share_time_now - rsk_last_received_share_time >= 1000:
                    rsk_submitted_shares = 0
                    rsk_last_received_share_time = last_received_share_time_now

                if last_received_share_time_now - rsk_last_received_share_time < 1000 and rsk_submitted_shares < 3:
                    rsk_submitted_shares += 1
                else:
                    return (header_hex, block_hash_hex, on_submit,
                            on_submit_rsk)

                serialized = binascii.hexlify(job.serialize())

                block_header_hex = binascii.hexlify(header_le)
                coinbase_hex = binascii.hexlify(coinbase_bin)
                coinbase_hash_hex = binascii.hexlify(coinbase_hash)
                merkle_hashes_array = [
                    binascii.hexlify(x) for x in job.merkletree._steps
                ]
                merkle_hashes_array.insert(0, coinbase_hash_hex)
                merkle_hashes = ' '.join(merkle_hashes_array)
                txn_count = hex(len(merkle_hashes_array))[2:]

                on_submit_rsk = self.rootstock_rpc.submitBitcoinBlockPartialMerkle(
                    block_hash_hex, block_header_hex, coinbase_hex,
                    merkle_hashes, txn_count)

                log.info(
                    json.dumps({
                        "rsk": "[RSKLOG]",
                        "tag": "[RSK_SUBMITBLOCK]",
                        "uuid": util.id_generator(),
                        "start": start,
                        "elapsed": Interfaces.timestamper.time(),
                        "data": block_hash_hex
                    }))

        return (header_hex, block_hash_hex, on_submit, on_submit_rsk)
コード例 #18
0
    def submit_share(self, job_id, worker_name, extranonce1_bin, extranonce2,
                     ntime, nonce, difficulty, payment_type):
        '''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):
            logger.log('bad_client', worker_name, "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
        hash_bin = util.doublesha(''.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)

        #logger.log('share', worker_name, 'HASH %064x' % hash_int, 'TARGET %064x' % job.target, 'DIFF %d' % difficulty)

        if hash_int > target_user:
            logger.log('bad_client', 'Share is above target')
            raise SubmitException("Share is above target")

        if payment_type == 'PPS':
            logger.log('share', worker_name, 'HASH %064x' % hash_int,
                       'TARGET %064x' % job.target, 'DIFF %d' % difficulty)
            logger.log('pplns', worker_name, 'HASH %064x' % hash_int,
                       'DIFF %d' % difficulty, 'PAY 0')
        if payment_type == 'PPLNS':
            logger.log('pplns', worker_name, 'HASH %064x' % hash_int,
                       'DIFF %d' % difficulty, 'PAY 1')

        # 5. Compare hash with target of the network
        if hash_int <= job.target:
            # Yay! It is block candidate!
            logger.log('block', worker_name, block_hash_hex)

            # 6. 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
                logger.log('error', "Final job validation failed!")

            # 7. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            on_submit = self.bitcoin_rpc.submitblock(serialized)
            logger.log('submitblock', serialized)
            return (True, worker_name, block_hash_hex)

        return (False, worker_name, block_hash_hex)
コード例 #19
0
ファイル: template_registry.py プロジェクト: sumory/BTC
    def submit_share(self, job_id, worker_name, extranonce1_bin, extranonce2, ntime, nonce,
                     difficulty, payment_type):
        '''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):
            logger.log('bad_client', worker_name, "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
        hash_bin = util.doublesha(''.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)        

        #logger.log('share', worker_name, 'HASH %064x' % hash_int, 'TARGET %064x' % job.target, 'DIFF %d' % difficulty)

        if hash_int > target_user:
            logger.log('bad_client', 'Share is above target')
            raise SubmitException("Share is above target")

        if payment_type == 'PPS':    
            logger.log('share', worker_name, 'HASH %064x' % hash_int, 'TARGET %064x' % job.target, 'DIFF %d' % difficulty)
            logger.log('pplns', worker_name, 'HASH %064x' % hash_int, 'DIFF %d' % difficulty, 'PAY 0')
        if payment_type == 'PPLNS':
            logger.log('pplns', worker_name, 'HASH %064x' % hash_int, 'DIFF %d' % difficulty, 'PAY 1')

        # 5. Compare hash with target of the network        
        if hash_int <= job.target:
            # Yay! It is block candidate! 
            logger.log('block', worker_name, block_hash_hex)
           
            # 6. 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
                logger.log('error', "Final job validation failed!")
                            
            # 7. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            on_submit = self.bitcoin_rpc.submitblock(serialized)
            logger.log('submitblock', serialized)
            return (True, worker_name, block_hash_hex)
        
        return (False, worker_name, block_hash_hex)
コード例 #20
0
ファイル: template_registry.py プロジェクト: Neozonz/blockie
    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
           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.COINDAEMON_ALGO == 'scrypt':
            hash_bin = ltc_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
        elif settings.COINDAEMON_ALGO  == 'scrypt-jane':
            hash_bin = yac_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]), int(ntime, 16))
        elif settings.COINDAEMON_ALGO == 'quark':
            hash_bin = quark_hash.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
        else:
            hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))

        hash_int = util.uint256_from_str(hash_bin)
        scrypt_hash_hex = "%064x" % hash_int
        header_hex = binascii.hexlify(header_bin)
        if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'scrypt-jane':
            header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
        elif settings.COINDAEMON_ALGO == 'quark':
            header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"
        else: pass
                 
        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(100000)
        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! 
            log.info("We found a block candidate! %s" % scrypt_hash_hex)

            # Reverse the header and get the potential block hash (for scrypt only) 
            #if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'sha256d':
            #   if settings.COINDAEMON_Reward == 'POW':
            block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
            block_hash_hex = block_hash_bin[::-1].encode('hex_codec')
            #else:   block_hash_hex = hash_bin[::-1].encode('hex_codec')
            #else:  block_hash_hex = hash_bin[::-1].encode('hex_codec')
            # 6. 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.exception("FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)")
                            
            # 7. Submit block to the network
            serialized = binascii.hexlify(job.serialize())
            #just try both block hash and scrypt hash when checking for block creation
            on_submit = self.bitcoin_rpc.submitblock(serialized, block_hash_hex, scrypt_hash_hex)

            if on_submit:
                self.update_block()

            if settings.SOLUTION_BLOCK_HASH:
                return (header_hex, block_hash_hex, share_diff, on_submit)
            else:
                return (header_hex, scrypt_hash_hex, share_diff, on_submit)

        
        if settings.SOLUTION_BLOCK_HASH:
        # Reverse the header and get the potential block hash (for scrypt only) only do this if we want to send in the block hash to the shares table
            block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]))
            block_hash_hex = block_hash_bin[::-1].encode('hex_codec')
            return (header_hex, block_hash_hex, share_diff, None)
        else:
            return (header_hex, scrypt_hash_hex, share_diff, None)
コード例 #21
0
ファイル: miner.py プロジェクト: sycomix/bitcoin_mining
    def run(self):
        difficulty = 1
        while True:
            s = self.f.readline()
            if not s:
                break

            if TEST:
                s = """{"params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000",
        "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008",
        "072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [],
        "00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"}"""
                extranonce1 = "08000002"

            s = s.strip()
            assert s
            d = simplejson.loads(s)

            # if d.get('method', None) == "mining.notify" and self.done:
            # continue

            print d

            if d.get('error', None):
                raise Exception()

            if d['id'] == 1 and 'method' not in d:
                subscription, extranonce1, extranonce2_size = d['result']

            elif d.get('method', None) == "mining.set_difficulty":
                difficulty = d['params'][0]

            elif d.get('method', None) == "mining.notify":
                print "stopping worker"
                self.w.stop()
                print "stopped"

                params, clean_jobs = d['params'][:-1], d['params'][:-1]
                j = JobInfo(extranonce1, *params)
                self.jobs[j.id] = j

                extranonce2 = (
                    (int(time.time()) << 16) + os.getpid()) & 0xffffffff
                extranonce2 = struct.pack(">I", extranonce2).encode("hex")
                if TEST:
                    extranonce2 = "00000001"
                print "extranonce2 = %s" % extranonce2

                coinbase = j.coinb1 + extranonce1 + extranonce2 + j.coinb2
                coinbase_hash_bin = doublesha(binascii.unhexlify(coinbase))
                merkle_root = build_merkle_root(j.merkle_branch,
                                                coinbase_hash_bin)
                merkle_root = ser_uint256_be(uint256_from_str(merkle_root))

                # ntime = "504e86ed"
                ntime = j.ntime
                if TEST:
                    ntime = "504e86ed"

                preheader = j.version + j.prevhash + merkle_root.encode(
                    "hex") + ntime + j.nbits
                preheader_bin = preheader.decode("hex")
                preheader_bin = ''.join([
                    preheader_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 19)
                ])

                self.w.start(difficulty, j.id, extranonce2, ntime,
                             preheader_bin)

            else:
                assert d['id'] < self.mid