Ejemplo n.º 1
0
    def replay_block(self, block_to_replay, limit=5):
        """
        Replay all transactions in parent currency to passed in "source" currency.
        Block_to_replay can either be an integer or a block object.
        """

        if block_to_replay == 'latest':
            if self.verbose:
                print("Getting latest %s block header" % source.upper())
            block = get_block(self.source, latest=True, verbose=self.verbose)
            if self.verbose:
                print("Latest %s block is #%s" % (self.source.upper(), block['block_number']))
        else:
            blocknum = block_to_replay if type(block_to_replay) == int else block_to_replay['block_number']
            if blocknum < self.parent_fork_block or blocknum < self.child_fork_block:
                raise Exception("Can't replay blocks mined before the fork")

        if type(block_to_replay) is not dict:
            if self.verbose:
                print("Getting %s block header #%s" % (self.source.upper(), block_to_replay))
            block = get_block(self.source, block_number=int(block_to_replay), verbose=self.verbose)
        else:
            block = block_to_replay

        if self.verbose:
            print("Using %s for pushing to %s" % (self.pusher.name, self.destination.upper()))
            print("Using %s for getting %s transactions" % (self.tx_fetcher.name, self.source.upper()))
            print("Finished getting block header,", len(block['txids']), "transactions in block, will replay", (limit or "all of them"))

        results = []
        enforced_limit = (limit or len(block['txids']))

        for i, txid in enumerate(block['txids'][:enforced_limit]):
            print("outside", txid)
            self._replay_tx(txid, i)
Ejemplo n.º 2
0
    def replay_block(self, block_to_replay, limit=5):
        """
        Replay all transactions in parent currency to passed in "source" currency.
        Block_to_replay can either be an integer or a block object.
        """

        if block_to_replay == 'latest':
            if self.verbose:
                print("Getting latest %s block header" % source.upper())
            block = get_block(self.source, latest=True, verbose=self.verbose)
            if self.verbose:
                print("Latest %s block is #%s" %
                      (self.source.upper(), block['block_number']))
        else:
            blocknum = block_to_replay if type(
                block_to_replay) == int else block_to_replay['block_number']
            if blocknum < self.parent_fork_block or blocknum < self.child_fork_block:
                raise Exception("Can't replay blocks mined before the fork")

        if type(block_to_replay) is not dict:
            if self.verbose:
                print("Getting %s block header #%s" %
                      (self.source.upper(), block_to_replay))
            block = get_block(self.source,
                              block_number=int(block_to_replay),
                              verbose=self.verbose)
        else:
            block = block_to_replay

        if self.verbose:
            print("Using %s for pushing to %s" %
                  (self.pusher.name, self.destination.upper()))
            print("Using %s for getting %s transactions" %
                  (self.tx_fetcher.name, self.source.upper()))
            print("Finished getting block header,", len(block['txids']),
                  "transactions in block, will replay",
                  (limit or "all of them"))

        results = []
        enforced_limit = (limit or len(block['txids']))

        for i, txid in enumerate(block['txids'][:enforced_limit]):
            print("outside", txid)
            self._replay_tx(txid, i)
Ejemplo n.º 3
0
def get_block_adjustments(crypto, points=None, intervals=None, **modes):
    """
    This utility is used to determine the actual block rate. The output can be
    directly copied to the `blocktime_adjustments` setting.
    """
    from moneywagon import get_block
    all_points = []

    if intervals:
        latest_block_height = get_block(crypto, latest=True, **modes)['block_number']
        interval = int(latest_block_height / float(intervals))
        all_points = [x * interval for x in range(1, intervals - 1)]

    if points:
        all_points.extend(points)

    all_points.sort()

    adjustments = []
    previous_point = 0
    previous_time = (crypto_data[crypto.lower()].get('genesis_date').replace(tzinfo=pytz.UTC)
        or get_block(crypto, block_number=0, **modes)['time']
    )

    for point in all_points:
        if point == 0:
            continue
        point_time = get_block(crypto, block_number=point, **modes)['time']
        length = point - previous_point
        minutes = (point_time - previous_time).total_seconds() / 60
        rate = minutes / length
        adjustments.append([previous_point, rate])

        previous_time = point_time
        previous_point = point

    return adjustments
Ejemplo n.º 4
0
def get_block_adjustments(crypto, points=None, intervals=None, **modes):
    """
    This utility is used to determine the actual block rate. The output can be
    directly copied to the `blocktime_adjustments` setting.
    """
    from moneywagon import get_block
    all_points = []

    if intervals:
        latest_block_height = get_block(crypto, latest=True, **modes)['block_number']
        interval = int(latest_block_height / float(intervals))
        all_points = [x * interval for x in range(1, intervals - 1)]

    if points:
        all_points.extend(points)

    all_points.sort()

    adjustments = []
    previous_point = 0
    previous_time = (crypto_data[crypto.lower()].get('genesis_date').replace(tzinfo=pytz.UTC)
        or get_block(crypto, block_number=0, **modes)['time']
    )

    for point in all_points:
        if point == 0:
            continue
        point_time = get_block(crypto, block_number=point, **modes)['time']
        length = point - previous_point
        minutes = (point_time - previous_time).total_seconds() / 60
        rate = minutes / length
        adjustments.append([previous_point, rate])

        previous_time = point_time
        previous_point = point

    return adjustments
Ejemplo n.º 5
0
def replay_block(source,
                 destination,
                 block_to_replay,
                 verbose=False,
                 block_fetcher=None,
                 limit=5):
    """
    Replay all transactions in parent currency to passed in "source" currency,
    and vice versa. Block_to_replay can either be an integer or a block object.
    `block_fetcher` is a callable that will return a block.
    """
    parent_currency, parent_fork_block = crypto_data[source.lower()].get(
        'forked_from') or [None, 0]
    child_currency, child_fork_block = crypto_data[destination.lower()].get(
        'forked_from') or [None, 0]

    if not parent_currency and not child_currency:
        raise Exception("Networks %s and %s are not forks of one another." %
                        (source.upper(), destination.upper()))

    if block_to_replay == 'latest':
        if verbose:
            print("Getting latest %s block" % source.upper())
        block = get_block(source, latest=True, verbose=verbose)
        if verbose:
            print("Latest %s block is #%s" %
                  (source.upper(), block['block_number']))
    elif type(block_to_replay) is not dict:
        if verbose:
            print("Getting %s block #%s" % (source.upper(), block_to_replay))
        block = get_block(source,
                          block_number=int(block_to_replay),
                          verbose=verbose)
    else:
        block = block_to_replay

    bn = block['block_number']
    if bn < parent_fork_block or bn < child_fork_block:
        raise Exception("Can't replay blocks mined before the fork")

    if source.lower() == 'btc':
        pusher = BlockDozer(verbose=verbose)
        service = random.choice([BitpayInsight, ChainSo,
                                 LocalBitcoinsChain])(verbose=verbose)
    elif source.lower() == 'bch':
        pusher = random.choice(
            crypto_data['btc']['services']['push_tx'])(verbose=verbose)
        service = BlockDozer(verbose=verbose)
    else:
        raise Exception("Only BTC and BCH are currently supported")

    if verbose:
        print("Using %s for pushing to %s" %
              (pusher.name, destination.upper()))
        print("Using %s for getting %s transactions" %
              (service.name, source.upper()))
        print("Finished getting block header,", len(block['txids']),
              "transactions in block, will replay", (limit or "all of them"))

    results = []
    enforced_limit = (limit or len(block['txids']))

    for i, txid in enumerate(block['txids'][:enforced_limit]):
        if block_fetcher:
            transaction = block_fetcher(currency=source, txid=txid)
        else:
            transaction = service.get_single_transaction(source, txid=txid)

        first_input = transaction['inputs'][0]
        if first_input.get('coinbase') or first_input.get(
                "addresses") == "coinbase":
            continue  # no point trying to replay coinbases.

        raw_tx = to_rawtx(transaction)

        if verbose:
            print("got tx", i, "of", len(block['txids']))

        try:
            result = pusher.push_tx(destination, raw_tx)
            ret = ['success', result]
        except Exception as exc:
            ret = ['failure', str(exc)]

        if verbose:
            print("Result of push:", ret[0], ret[1])

        yield ret
Ejemplo n.º 6
0
def _make_moneywagon_fetch(Service,
                           service_mode,
                           service_id,
                           address,
                           addresses,
                           xpub,
                           currency,
                           currency_name,
                           block_args,
                           fiat=None,
                           txid=None,
                           random_mode=False,
                           **k):

    if Service:
        if Service.supported_cryptos and currency not in Service.supported_cryptos:
            raise Exception("%s not supported for %s with %s" %
                            (currency_name, service_mode, Service.name))
        services = [Service]
    else:
        services = []  # fallback mode

    modes = dict(report_services=True,
                 services=services,
                 random=random_mode,
                 timeout=10.0,
                 verbose=settings.DEBUG)

    if service_id.startswith("paranoid"):
        modes['paranoid'] = int(service_id[8:])
    elif service_id.startswith("average"):
        modes['average'] = int(service_id[7:])
    elif service_id.startswith("private"):
        modes['private'] = int(service_id[7:])
        if modes['private'] > 30:
            raise Exception("Private mode maximum of 30")

    if address:
        modes['address'] = address
    elif addresses:
        modes['addresses'] = addresses.split(',')

    if service_mode == 'current_price':
        used_services, price = get_current_price(currency, fiat, **modes)
        PriceTick.record_price(price, currency, fiat, used_services[0].name)
        ret = {'current_price': price}
    elif service_mode == 'address_balance':
        used_services, balance = get_address_balance(currency, **modes)
        ret = {'balance': balance}
    elif service_mode == 'unspent_outputs':
        used_services, utxos = get_unspent_outputs(currency, **modes)
        ret = {'utxos': sorted(utxos, key=lambda x: x['output'])}
    elif service_mode == 'historical_transactions':
        used_services, txs = get_historical_transactions(currency, **modes)
        ret = {'transactions': sorted(txs, key=lambda x: x['txid'])}
    elif service_mode == 'single_transaction':
        used_services = None
        tx = CachedTransaction.fetch_full_tx(currency, txid=txid, fiat=fiat)
        ret = {'transaction': tx}
    elif service_mode == 'get_block':
        if block_args['block_number']:
            block_args['block_number'] = int(block_args['block_number'])
        modes.update(block_args)
        used_services, block_data = get_block(currency, **modes)
        ret = {'block': block_data}
    elif service_mode == 'optimal_fee':
        used_services, fee = get_optimal_fee(currency, 1024, **modes)
        ret = {'optimal_fee_per_KiB': fee}
    else:
        raise Exception("Unsupported Service mode")

    if not used_services:
        pass  # private mode does not return services
    elif len(used_services) == 1:
        s = used_services[0]
        if s:
            ret['url'] = s.last_url
            ret['raw_response'] = s.last_raw_response.json()
            ret['service_name'] = s.name
            ret['service_id'] = s.service_id
    else:
        ret['services'] = [{
            'name': s.name,
            'id': s.service_id,
            'raw_response': s.last_raw_response.json()
        } for s in used_services]

    return ret
Ejemplo n.º 7
0
def _make_moneywagon_fetch(Service, service_mode, service_id, address, addresses,
    xpub, currency, currency_name, block_args, fiat=None, txid=None, random_mode=False, **k):

    if Service:
        if Service.supported_cryptos and currency not in Service.supported_cryptos:
            raise Exception("%s not supported for %s with %s" % (
                currency_name, service_mode, Service.name
            ))
        services = [Service]
    else:
        services = [] # fallback mode

    modes = dict(
        report_services=True,
        services=services,
        random=random_mode,
        timeout=10.0,
        verbose=settings.DEBUG
    )

    if service_id.startswith("paranoid"):
        modes['paranoid'] = int(service_id[8:])
    elif service_id.startswith("average"):
        modes['average'] = int(service_id[7:])
    elif service_id.startswith("private"):
        modes['private'] = int(service_id[7:])
        if modes['private'] > 30:
            raise Exception("Private mode maximum of 30")

    if address:
        modes['address'] = address
    elif addresses:
        modes['addresses'] = addresses.split(',')

    if service_mode == 'current_price':
        used_services, price = get_current_price(currency, fiat, **modes)
        PriceTick.record_price(price, currency, fiat, used_services[0].name)
        ret = {'current_price': price}
    elif service_mode == 'address_balance':
        used_services, balance = get_address_balance(currency, **modes)
        ret = {'balance': balance}
    elif service_mode == 'unspent_outputs':
        used_services, utxos = get_unspent_outputs(currency, **modes)
        ret = {'utxos': sorted(utxos, key=lambda x: x['output'])}
    elif service_mode == 'historical_transactions':
        used_services, txs = get_historical_transactions(currency, **modes)
        ret = {'transactions': sorted(txs, key=lambda x: x['txid'])}
    elif service_mode == 'single_transaction':
        used_services = None
        tx = CachedTransaction.fetch_full_tx(currency, txid=txid, fiat=fiat)
        ret = {'transaction': tx}
    elif service_mode == 'get_block':
        if block_args['block_number']:
            block_args['block_number'] = int(block_args['block_number'])
        modes.update(block_args)
        used_services, block_data = get_block(currency, **modes)
        ret = {'block': block_data}
    elif service_mode == 'optimal_fee':
        used_services, fee = get_optimal_fee(currency, 1024, **modes)
        ret = {'optimal_fee_per_KiB': fee}
    else:
        raise Exception("Unsupported Service mode")

    if not used_services:
        pass # private mode does not return services
    elif len(used_services) == 1:
        s = used_services[0]
        if s:
            ret['url'] = s.last_url
            ret['raw_response'] = s.last_raw_response.json()
            ret['service_name'] = s.name
            ret['service_id'] = s.service_id
    else:
        ret['services'] = [
            {'name': s.name, 'id': s.service_id, 'raw_response': s.last_raw_response.json()}
            for s in used_services
        ]

    return ret
Ejemplo n.º 8
0
 def update_confirmations(self):
     current_block = get_block(self.crypto, latest=True)