Esempio n. 1
0
 def recalculate(self, detailed=False):
     L = self.data
     steps = []
     if detailed:
         detail = []
         PreL = []
         StartL = 0
     else:
         detail = None
         PreL = [None]
         StartL = 2
     Ll = len(L)
     if detailed or Ll > 1:
         while True:
             if detailed:
                 detail += L
             if Ll == 1:
                 break
             steps.append(L[1])
             if Ll % 2:
                 L += [L[-1]]
             L = PreL + [
                 double_sha(L[i] + L[i + 1]) for i in range(StartL, Ll, 2)
             ]
             Ll = len(L)
     self._steps = steps
     self.detail = detail
Esempio n. 2
0
def address_to_pubkeyhash(addr):
    try:
        addr = b58decode(addr, 26)
    except Exception:
        return None

    if addr is None:
        return None

    ver = addr[0]
    cksumA = addr[-4:]
    cksumB = double_sha(addr[:-4])[:4]

    if cksumA != cksumB:
        return None

    return (ver, addr[1:-4])
Esempio n. 3
0
 def withFirst(self, f):
     steps = self._steps
     for s in steps:
         f = double_sha(f + s)
     return f
Esempio n. 4
0
 def hash_steps(self):
     if self._hash_steps is None:
         self._hash_steps = double_sha(b''.join(self._steps))
     return self._hash_steps
Esempio n. 5
0
    def submit(self, connection_ref, _id, _params):
        # TODO: Job ID Check 구현해야함
        # TODO: Diff Check 해서 그냥 Share 기록 or Submit 구별 해야함
        # TODO: Share Result를 Database에 기록 해야함 - Database 는 Redis가 될듯
        session_id = connection_ref.get_session()

        _worker_name = _params[0]
        _split_worker_name = _worker_name.strip().split('.')
        username = _split_worker_name[0]
        if len(_split_worker_name) == 2:
            worker = _split_worker_name[1]
        else:
            worker = None
        _job_id = _params[1]

        _nonce_1 = self.job_manager.get_nonce_from_session_id(session_id)
        _block_template = self.job_manager.get_block_template(_job_id)

        if _block_template is None:
            logger.info('rejected share, worker : %s, reason : job not found' %
                        _worker_name)
            return {'id': _id, 'result': False, 'error': [21, 'job not found']}

        if os.getenv("COIN_TYPE") == 'bitcoin':
            _nonce_2 = _params[2]
            _time = _params[3]
            _time_reverse = hash_util.hex_to_reverse_hex(_time)
            _nonce = _params[4]
            _nonce_reverse = hash_util.hex_to_reverse_hex(_nonce)

            if len(_nonce) != 8:
                logger.info(
                    'rejected share, worker : %s, reason : incorrect size of nonce'
                    % _worker_name)
                return {
                    'id': _id,
                    'result': False,
                    'error': [20, 'incorrect size of nonce']
                }

            coinbase = binascii.hexlify(_block_template.coinbase_tx).split(
                _block_template.extranonce_placeholder)
            serialized_coinbase = binascii.unhexlify(coinbase[0] + _nonce_1 +
                                                     _nonce_2.encode() +
                                                     coinbase[1])

            if os.getenv("COIN_ALGORITHM") == 'keccak':
                coinbase_hash = binascii.hexlify(
                    hash_util.reverse_bytes(
                        hash_util.sha(serialized_coinbase)))
            else:
                coinbase_hash = hash_util.bytes_to_reverse_hash(
                    serialized_coinbase)

            tx_hashes = [coinbase_hash
                         ] + [h['hash'] for h in _block_template.transactions]
            merkle_root_reverse_hex = hash_util.hex_to_reverse_hex(
                hash_util.merkle_root(tx_hashes))

            # Header POW 종류별 구별 해야댐
            header = _block_template.serialize_block_header(
                _time_reverse, _nonce_reverse,
                merkle_root_reverse_hex)  # 80 bytes
            block_hex = _block_template.serialize_block(
                header, None, serialized_coinbase)
            if os.getenv("COIN_ALGORITHM") == 'lyra2rev2':
                import lyra2re2_hash
                header_hash = lyra2re2_hash.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'lyra2rev3':
                import lyra2re3_hash
                header_hash = lyra2re3_hash.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'keccak' or os.getenv(
                    "COIN_ALGORITHM") == 'keccakc':
                import sha3
                header_hash = sha3.keccak_256(header).digest()
            elif os.getenv("COIN_ALGORITHM") == 'x13-bcd':
                import x13bcd_hash
                header_hash = x13bcd_hash.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'neoscrypt':
                import neoscrypt
                header_hash = neoscrypt.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'yescrypt':
                import yescrypt_hash
                header_hash = yescrypt_hash.getHash(header, len(header))
            elif os.getenv("COIN_ALGORITHM") == 'xevan':
                import xevan_hash
                header_hash = xevan_hash.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'phi2':
                import phi2_hash
                header_hash = phi2_hash.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'x16r':
                import x16r_hash
                header_hash = x16r_hash.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'x16s':
                import x16s_hash
                header_hash = x16s_hash.getPoWHash(header)
            elif os.getenv("COIN_ALGORITHM") == 'timetravel10':
                import timetravel10_hash
                header_hash = timetravel10_hash.getPoWHash(header)
            else:
                header_hash = double_sha(header)

        elif os.getenv("COIN_TYPE") == 'zcash':
            _time = _params[2]
            _nonce_2 = _params[3]
            _soln = _params[4]

            _nonce = _nonce_1 + _nonce_2.encode()

            if len(_nonce) != 64:
                return {
                    'id': _id,
                    'result': False,
                    'error': [20, 'incorrect size of nonce']
                }

            if os.getenv("COIN_ALGORITHM") == 'zhash' and len(_soln) != 202:
                return {
                    'id': _id,
                    'result': False,
                    'error': [20, 'incorrect size of solution']
                }
            elif os.getenv("COIN_ALGORITHM") != 'zhash' and len(_soln) != 2694:
                return {
                    'id': _id,
                    'result': False,
                    'error': [20, 'incorrect size of solution']
                }

            n_time_int = int(_time, 16)
            curtime_int = int(_block_template.curtime, 16)

            if n_time_int < curtime_int:
                return {
                    'id': _id,
                    'result': False,
                    'error': [20, 'ntime out of range']
                }

            header = _block_template.serialize_block_header(
                _time.encode(), _nonce)  # 140 bytes

            header_soln = header + binascii.unhexlify(_soln)
            header_hash = double_sha(header_soln)

            block_hex = _block_template.serialize_block(
                header, binascii.unhexlify(_soln), None)
        else:
            raise Exception('invalid coin type')

        header_bignum = uint256_from_str(header_hash)

        share_diff = os.getenv("POW_LIMIT") / header_bignum
        logger.debug('share diff : {0:.8f}'.format(share_diff))

        diff = self.user_diffs[connection_ref.username]

        if share_diff < diff:
            # logger.debug('low difficulty share of %s' % share_diff)
            logger.info(
                'rejected share, worker : %s, reason : low difficulty share' %
                _worker_name)
            self.database_ref.insert_accepted_share(
                username, worker, False, False, _block_template.block_height,
                share_diff, _block_template.pool_reward, diff)
            return {
                'id': _id,
                'result': None,
                'error': [23, 'low difficulty share of %s' % share_diff]
            }

        if not self.job_manager.register_submit(_nonce_1, _nonce_2, _nonce,
                                                _time):
            logger.info(
                'rejected share, worker : %s, reason : duplicate share' %
                _worker_name)
            return {
                'id': _id,
                'result': None,
                'error': [22, 'duplicate share']
            }

        if share_diff >= _block_template.difficulty * 0.99:
            block_hash = binascii.hexlify(
                hash_util.reverse_bytes(header_hash)).decode()
            if os.getenv("COIN") in [
                    'monacoin', 'feathercoin', 'phoenixcoin', 'vertcoin',
                    'shield'
            ]:
                temp_hash = double_sha(header)
                block_hash = binascii.hexlify(
                    hash_util.reverse_bytes(temp_hash)).decode()

            logger.info('Try new block share, worker : %s, share diff : %s' %
                        (_worker_name, share_diff))
            share_result = self.coin_rpc.submit_block(
                binascii.hexlify(block_hex).decode())

            if share_result is None:
                logger.info('Found Block, result : %s, block hash : %s' %
                            (share_result, block_hash))
                result_hash = Interfaces.block_updater.update_block(
                    repeat=False, block_hash=block_hash)
                if result_hash is not None:
                    block_hash = result_hash
                self.database_ref.insert_accepted_share(
                    username, worker, True, True, _block_template.block_height,
                    share_diff, _block_template.pool_reward, diff, block_hash)
            else:
                logger.error(
                    'undefined share_result %s, block hash %s, coinbase tx %s'
                    % (share_result, block_hash,
                       binascii.hexlify(_block_template.coinbase_tx)))
                self.database_ref.insert_accepted_share(
                    username, worker, False, False,
                    _block_template.block_height, share_diff,
                    _block_template.pool_reward, diff)

                if os.getenv("COIN_TYPE") == 'bitcoin':
                    logger.error('Header : %s' %
                                 binascii.hexlify(header).decode())
                else:
                    logger.error('Header : %s' %
                                 binascii.hexlify(header_soln).decode())
                return {
                    'id': _id,
                    'result': None,
                    'error': [20, 'invalid solution']
                }
        else:
            logger.info('accepted share, worker : %s, share diff : %s' %
                        (_worker_name, '{0:.8f}'.format(share_diff)))
            self.database_ref.insert_accepted_share(
                username, worker, True, False, _block_template.block_height,
                share_diff, _block_template.pool_reward, diff)

        return {'id': _id, 'result': True, 'error': None}