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)
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)
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
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
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
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
def update_confirmations(self): current_block = get_block(self.crypto, latest=True)