コード例 #1
0
def create_push_script(datums):  # datums can be ints or strs
    res = []
    for datum in datums:
        if isinstance(datum, (int, long)):
            if datum == -1 or 1 <= datum <= 16:
                res.append(chr(datum + 80))
                continue
            negative = datum < 0
            datum = math.natural_to_string(abs(datum))
            if datum and ord(datum[0]) & 128:
                datum = '\x00' + datum
            if negative:
                datum = chr(ord(datum[0]) + 128) + datum[1:]
            datum = datum[::-1]
        if len(datum) < 76:
            res.append(chr(len(datum)))
        elif len(datum) <= 0xff:
            res.append(76)
            res.append(chr(len(datum)))
        elif len(datum) <= 0xffff:
            res.append(77)
            res.append(pack.IntType(16).pack(len(datum)))
        elif len(datum) <= 0xffffffff:
            res.append(78)
            res.append(pack.IntType(32).pack(len(datum)))
        else:
            raise ValueError('string too long')
        res.append(datum)
    return ''.join(res)
コード例 #2
0
ファイル: netmon.py プロジェクト: CryptoRepairCrew/powerpool
 def _run(self):
     while True:
         if self.net_state['poll_connection'] is None:
             logger.warn(
                 "Couldn't connect to any RPC servers, sleeping for 1")
             sleep(1)
             continue
         try:
             auxblock = self.coinserv.getauxblock()
         except Exception as e:
             logger.warn(
                 "Unable to communicate with aux chain server. {}".format(
                     e))
             sleep(2)
             continue
         #logger.debug("Aux RPC returned: {}".format(auxblock))
         new_merged_work = dict(hash=int(auxblock['hash'], 16),
                                target=pack.IntType(256).unpack(
                                    auxblock['target'].decode('hex')),
                                merged_proxy=self.coinserv,
                                monitor=self)
         self.aux_state['chain_id'] = auxblock['chainid']
         if new_merged_work != self.net_state['merged_work'].get(
                 auxblock['chainid']):
             try:
                 height = self.coinserv.getblockcount()
             except Exception as e:
                 logger.warn(
                     "Unable to communicate with aux chain server. {}".
                     format(e))
                 sleep(2)
                 continue
             logger.info(
                 "New aux work announced! Diff {}. RPC returned: {}".format(
                     bitcoin_data.target_to_difficulty(
                         new_merged_work['target']), new_merged_work))
             self.net_state['merged_work'][
                 auxblock['chainid']] = new_merged_work
             self.aux_state[
                 'difficulty'] = bitcoin_data.target_to_difficulty(
                     pack.IntType(256).unpack(
                         auxblock['target'].decode('hex')))
             # only push the job if there's a new block height discovered.
             if self.aux_state['height'] != height:
                 self.aux_state['height'] = height
                 self.monitor_network.generate_job(push=True,
                                                   flush=self.flush)
                 self.aux_state['work_restarts'] += 1
             else:
                 self.monitor_network.generate_job()
                 self.aux_state['new_jobs'] += 1
         sleep(self.work_interval)
コード例 #3
0
    def update(self, reason=None):
        if reason:
            self.logger.info(
                "Updating {} aux work from a signal recieved!".format(
                    self.config['name']))

        try:
            auxblock = self.call_rpc('getauxblock')
        except RPCException:
            sleep(2)
            return False

        new_merged_work = dict(hash=int(auxblock['hash'], 16),
                               target=pack.IntType(256).unpack(
                                   auxblock['target'].decode('hex')),
                               type=self.config['name'])
        if new_merged_work['hash'] != self.jobmanager.merged_work.get(
                auxblock['chainid'], {'hash': None})['hash']:
            # We fetch the block height so we can see if the hash changed
            # because of a new network block, or because new transactions
            try:
                height = self.call_rpc('getblockcount')
            except RPCException:
                sleep(2)
                return False
            self.logger.info(
                "New aux work announced! Diff {:,.4f}. Height {:,}".format(
                    bitcoin_data.target_to_difficulty(
                        new_merged_work['target']), height))
            # add height to work spec for future logging
            new_merged_work['height'] = height

            self.jobmanager.merged_work[auxblock['chainid']] = new_merged_work
            self.current_net['difficulty'] = bitcoin_data.target_to_difficulty(
                pack.IntType(256).unpack(auxblock['target'].decode('hex')))

            # only push the job if there's a new block height discovered.
            if self.current_net['height'] != height:
                self.current_net['height'] = height
                self.jobmanager.generate_job(push=True,
                                             flush=self.config['flush'])
                self.server[self.prefix + "work_restarts"].incr()
                self.server[self.prefix + "new_jobs"].incr()
            else:
                self.jobmanager.generate_job()
                self.server[self.prefix + "new_jobs"].incr()

        return True
コード例 #4
0
 def from_target_upper_bound(cls, target):
     n = math.natural_to_string(target)
     if n and ord(n[0]) >= 128:
         n = '\x00' + n
     bits2 = (chr(len(n)) + (n + 3 * chr(0))[:3])[::-1]
     bits = pack.IntType(32).unpack(bits2)
     return cls(bits)
コード例 #5
0
def hash160(data):
    if data == '04ffd03de44a6e11b9917f3a29f9443283d9871c9d743ef30d5eddcd37094b64d1b3d8090496b53256786bf5c82932ec23c3b74d9f05a6f95a8b5529352656664b'.decode(
            'hex'):
        return 0x384f570ccc88ac2e7e00b026d1690a3fca63dd0  # hack for people who don't have openssl - this is the only value that p2pool ever hashes
    return pack.IntType(160).unpack(
        hashlib.new('ripemd160',
                    hashlib.sha256(data).digest()).digest())
コード例 #6
0
    def _check_new_jobs(self, signal=False):
        if signal:
            self.last_signal = time.time()
            self.logger.info(
                "Updating {} aux work from a signal recieved!".format(
                    self.config['currency']))

        try:
            auxblock = self.call_rpc('getauxblock')
        except RPCException:
            sleep(2)
            return False

        hash = int(auxblock['hash'], 16)
        if hash != self.last_work['hash']:
            # We fetch the block height so we can see if the hash changed
            # because of a new network block, or because new transactions
            try:
                height = self.call_rpc('getblockcount')
            except RPCException:
                sleep(2)
                return False

            target_int = pack.IntType(256).unpack(
                auxblock['target'].decode('hex'))
            self.last_work.update(
                dict(hash=hash,
                     target=target_int,
                     type=self.config['currency'],
                     height=height,
                     found_block=self.found_block,
                     chainid=auxblock['chainid']))

            # only push the job if there's a new block height discovered.
            new_block = False
            if self.current_net['height'] != height:
                self.current_net['height'] = height
                self._incr("work_restarts")
                self._incr("new_jobs")
                self.new_job.flush = self.config['flush']
                new_block = True
            else:
                self._incr("new_jobs")
                self.new_job.flush = False
            self.new_job.set()
            self.new_job.clear()

            if new_block:
                self.current_net['last_block'] = time.time()
                self.current_net[
                    'difficulty'] = bitcoin_data.target_to_difficulty(
                        target_int)
                self.logger.info(
                    "New aux block announced! Diff {:,.4f}. Height {:,}".
                    format(self.current_net['difficulty'], height))

        return True
コード例 #7
0
class FloatingIntegerType(pack.Type):
    _inner = pack.IntType(32)

    def read(self, file):
        bits, file = self._inner.read(file)
        return FloatingInteger(bits), file

    def write(self, file, item):
        return self._inner.write(file, item.bits)
コード例 #8
0
def script2_to_address(script2, net):
    try:
        pubkey = script2[1:-1]
        script2_test = pubkey_to_script2(pubkey)
    except:
        pass
    else:
        if script2_test == script2:
            return pubkey_to_address(pubkey, net)

    try:
        pubkey_hash = pack.IntType(160).unpack(script2[3:-2])
        script2_test2 = pubkey_hash_to_script2(pubkey_hash)
    except:
        pass
    else:
        if script2_test2 == script2:
            return pubkey_hash_to_address(pubkey_hash, net)
コード例 #9
0
def script2_to_human(script2, net):
    try:
        pubkey = script2[1:-1]
        script2_test = pubkey_to_script2(pubkey)
    except:
        pass
    else:
        if script2_test == script2:
            return 'Pubkey. Address: %s' % (pubkey_to_address(pubkey, net), )

    try:
        pubkey_hash = pack.IntType(160).unpack(script2[3:-2])
        script2_test2 = pubkey_hash_to_script2(pubkey_hash)
    except:
        pass
    else:
        if script2_test2 == script2:
            return 'Address. Address: %s' % (pubkey_hash_to_address(
                pubkey_hash, net), )

    return 'Unknown. Script: %s' % (script2.encode('hex'), )
コード例 #10
0
    def found_block(self, address, worker, header, coinbase_raw, job):
        aux_data = job.merged_data[self.config['name']]
        self.block_stats['solves'] += 1
        self.logger.info("New {} Aux block at height {}".format(
            self.config['name'], aux_data['height']))
        aux_block = (
            pack.IntType(256, 'big').pack(aux_data['hash']).encode('hex'),
            bitcoin_data.aux_pow_type.pack(
                dict(
                    merkle_tx=dict(
                        tx=bitcoin_data.tx_type.unpack(coinbase_raw),
                        block_hash=bitcoin_data.hash256(header),
                        merkle_link=job.merkle_link,
                    ),
                    merkle_link=bitcoin_data.calculate_merkle_link(
                        aux_data['hashes'], aux_data['index']),
                    parent_block_header=bitcoin_data.block_header_type.unpack(
                        header),
                )).encode('hex'),
        )

        retries = 0
        while retries < 5:
            retries += 1
            new_height = aux_data['height'] + 1
            res = False
            try:
                res = self.coinserv.getauxblock(*aux_block)
            except (bitcoinrpc.CoinRPCException, socket.error,
                    ValueError) as e:
                self.logger.error(
                    "{} Aux block failed to submit to the server!".format(
                        self.config['name']),
                    exc_info=True)
                self.logger.error(getattr(e, 'error'))

            if res is True:
                self.logger.info("NEW {} Aux BLOCK ACCEPTED!!!".format(
                    self.config['name']))
                # Record it for the stats
                self.block_stats['accepts'] += 1
                self.recent_blocks.append(
                    dict(height=new_height, timestamp=int(time.time())))

                # submit it to our reporter if configured to do so
                if self.config['send']:
                    self.logger.info(
                        "Submitting {} new block to reporter".format(
                            self.config['name']))
                    # A horrible mess that grabs the required information for
                    # reporting the new block. Pretty failsafe so at least
                    # partial information will be reporter regardless
                    try:
                        hsh = self.coinserv.getblockhash(new_height)
                    except Exception:
                        self.logger.info("", exc_info=True)
                        hsh = ''
                    try:
                        block = self.coinserv.getblock(hsh)
                    except Exception:
                        self.logger.info("", exc_info=True)
                    try:
                        trans = self.coinserv.gettransaction(block['tx'][0])
                        amount = trans['details'][0]['amount']
                    except Exception:
                        self.logger.info("", exc_info=True)
                        amount = -1

                    self.block_stats['last_solve_hash'] = hsh
                    self.reporter.add_block(
                        address,
                        new_height,
                        int(amount * 100000000),
                        -1,
                        "%0.6X" %
                        bitcoin_data.FloatingInteger.from_target_upper_bound(
                            aux_data['target']).bits,
                        hsh,
                        merged=self.config['reporting_id'],
                        worker=worker)

                break  # break retry loop if success
            else:
                self.logger.error(
                    "{} Aux Block failed to submit to the server, "
                    "server returned {}!".format(self.config['name'], res),
                    exc_info=True)
            sleep(1)
        else:
            self.block_stats['rejects'] += 1

        self.block_stats['last_solve_height'] = aux_data['height'] + 1
        self.block_stats['last_solve_worker'] = "{}.{}".format(address, worker)
        self.block_stats['last_solve_time'] = datetime.datetime.utcnow()
コード例 #11
0
    def found_block(self, address, worker, header, coinbase_raw, job, start):
        aux_data = job.merged_data[self.config['currency']]
        new_height = aux_data['height'] + 1
        self.block_stats['solves'] += 1
        stale = new_height <= self.current_net['height']

        self.logger.info("New {} Aux block at height {}".format(
            self.config['currency'], new_height))
        aux_block = (
            pack.IntType(256, 'big').pack(aux_data['hash']).encode('hex'),
            bitcoin_data.aux_pow_type.pack(
                dict(
                    merkle_tx=dict(
                        tx=bitcoin_data.tx_type.unpack(coinbase_raw),
                        block_hash=bitcoin_data.hash256(header),
                        merkle_link=job.merkle_link,
                    ),
                    merkle_link=bitcoin_data.calculate_merkle_link(
                        aux_data['hashes'], aux_data['index']),
                    parent_block_header=bitcoin_data.block_header_type.unpack(
                        header),
                )).encode('hex'),
        )

        retries = 0
        while retries < 5:
            retries += 1
            res = False
            try:
                res = self.call_rpc('getauxblock', *aux_block)
            except (CoinRPCException, socket.error, ValueError) as e:
                self.logger.error(
                    "{} Aux block failed to submit to the server!".format(
                        self.config['currency']),
                    exc_info=True)
                self.logger.error(getattr(e, 'error'))

            if res is True or res is None:
                # Record it for the stats
                self.block_stats['accepts'] += 1
                self.recent_blocks.append(
                    dict(height=new_height, timestamp=int(time.time())))

                # submit it to our reporter if configured to do so
                if self.config['send']:
                    if start:
                        submission_time = time.time() - start
                        self.manager.log_event(
                            "{name}.block_submission_{curr}:{t}|ms".format(
                                name=self.manager.config['procname'],
                                curr=self.config['currency'],
                                t=submission_time * 1000))
                    hsh = hexlify(
                        pack.IntType(256, 'big').pack(aux_data['hash']))
                    self.logger.info("{} BLOCK {}:{} accepted after {}".format(
                        self.config['currency'], hsh, new_height,
                        submission_time))

                    # A bit of a mess that grabs the required information for
                    # reporting the new block. Pretty failsafe so at least
                    # partial information will be reporter regardless
                    block = None
                    amount = 0
                    try:
                        block = self.call_rpc('getblock', hsh)
                    except Exception:
                        self.logger.info("", exc_info=True)
                    else:
                        try:
                            trans = self.call_rpc('gettxout', block['tx'][0],
                                                  0)
                            amount = trans['value']
                        except Exception:
                            self.logger.info("", exc_info=True)

                    self.block_stats['last_solve_hash'] = hsh
                    return dict(
                        address=address,
                        height=new_height,
                        total_subsidy=int(amount * 100000000),
                        fees=None,
                        hex_bits="%0.6X" %
                        bitcoin_data.FloatingInteger.from_target_upper_bound(
                            aux_data['target']).bits,
                        hex_hash=hsh,
                        currency=self.config['currency'],
                        merged=True,
                        algo=self.config['algo'],
                        worker=worker)

                break  # break retry loop if success
            else:
                self.logger.error(
                    "{} Aux Block height {} failed to submit to the server, "
                    "server returned {}!".format(self.config['currency'],
                                                 new_height, res),
                    exc_info=True)
            sleep(1)
        else:
            if stale:
                self.block_stats['stale'] += 1
            else:
                self.block_stats['rejects'] += 1

        self.block_stats['last_solve_height'] = aux_data['height'] + 1
        self.block_stats['last_solve_worker'] = "{}.{}".format(address, worker)
        self.block_stats['last_solve_time'] = datetime.datetime.utcnow()
コード例 #12
0
def pubkey_hash_to_script2(pubkey_hash):
    return '\x76\xa9' + ('\x14' +
                         pack.IntType(160).pack(pubkey_hash)) + '\x88\xac'
コード例 #13
0
def hash256(data, hash_func=sha256d):
    return pack.IntType(256).unpack(sha256d(data))
コード例 #14
0
            self.bits), hex(self.target))


class FloatingIntegerType(pack.Type):
    _inner = pack.IntType(32)

    def read(self, file):
        bits, file = self._inner.read(file)
        return FloatingInteger(bits), file

    def write(self, file, item):
        return self._inner.write(file, item.bits)


address_type = pack.ComposedType([
    ('services', pack.IntType(64)),
    ('address', pack.IPV6AddressType()),
    ('port', pack.IntType(16, 'big')),
])

tx_type = pack.ComposedType([
    ('version', pack.IntType(32)),
    ('tx_ins',
     pack.ListType(
         pack.ComposedType([
             ('previous_output',
              pack.PossiblyNoneType(
                  dict(hash=0, index=2**32 - 1),
                  pack.ComposedType([
                      ('hash', pack.IntType(256)),
                      ('index', pack.IntType(32)),
コード例 #15
0
ファイル: data.py プロジェクト: uingei/cryptokit
def hash256(data):
    return pack.IntType(256).unpack(
        hashlib.sha256(hashlib.sha256(data).digest()).digest())
コード例 #16
0
        def check_merged_block(mm_later):
            aux_work, index, hashes = mm_later
            if hash_int <= aux_work['target']:
                monitor = aux_work['monitor']
                self.server_state['aux_state'][monitor.name]['solves'] += 1
                self.logger.log(36, "New {} Aux Block identified!".format(monitor.name))
                aux_block = (
                    pack.IntType(256, 'big').pack(aux_work['hash']).encode('hex'),
                    bitcoin_data.aux_pow_type.pack(dict(
                        merkle_tx=dict(
                            tx=bitcoin_data.tx_type.unpack(job.coinbase.raw),
                            block_hash=header_hash_int,
                            merkle_link=job.merkle_link,
                        ),
                        merkle_link=bitcoin_data.calculate_merkle_link(hashes, index),
                        parent_block_header=bitcoin_data.block_header_type.unpack(header),
                    )).encode('hex'),
                )

                retries = 0
                while retries < 5:
                    retries += 1
                    new_height = self.server_state['aux_state'][monitor.name]['height'] + 1
                    try:
                        res = aux_work['merged_proxy'].getauxblock(*aux_block)
                    except (CoinRPCException, socket.error, ValueError) as e:
                        self.logger.error("{} Aux block failed to submit to the server {}!"
                                          .format(monitor.name), exc_info=True)
                        self.logger.error(getattr(e, 'error'))

                    if res is True:
                        self.logger.info("NEW {} Aux BLOCK ACCEPTED!!!".format(monitor.name))
                        self.server_state['aux_state'][monitor.name]['block_solve'] = int(time())
                        self.server_state['aux_state'][monitor.name]['accepts'] += 1
                        self.server_state['aux_state'][monitor.name]['recent_blocks'].append(
                            dict(height=new_height, timestamp=int(time())))
                        if monitor.send:
                            self.logger.info("Submitting {} new block to celery".format(monitor.name))
                            try:
                                hsh = aux_work['merged_proxy'].getblockhash(new_height)
                            except Exception:
                                self.logger.info("", exc_info=True)
                                hsh = ''
                            try:
                                block = aux_work['merged_proxy'].getblock(hsh)
                            except Exception:
                                self.logger.info("", exc_info=True)
                            try:
                                trans = aux_work['merged_proxy'].gettransaction(block['tx'][0])
                                amount = trans['details'][0]['amount']
                            except Exception:
                                self.logger.info("", exc_info=True)
                                amount = -1
                            self.celery.send_task_pp(
                                'add_block',
                                self.address,
                                new_height,
                                int(amount * 100000000),
                                -1,
                                "%0.6X" % bitcoin_data.FloatingInteger.from_target_upper_bound(aux_work['target']).bits,
                                hsh,
                                merged=monitor.celery_id)
                        break  # break retry loop if success
                    else:
                        self.logger.error(
                            "{} Aux Block failed to submit to the server, "
                            "server returned {}!".format(monitor.name, res),
                            exc_info=True)
                    sleep(1)
                else:
                    self.server_state['aux_state'][monitor.name]['rejects'] += 1