Ejemplo n.º 1
0
    def get_block_by_hash(self, block_hash):
        url = self.url + '/block/{hash}'.format(hash=block_hash)
        LOG.info('GET %s' % url)
        try:
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get block %s from Blockstream.info: %s' %
                      (block_hash, ex))
            return {
                'error':
                'Unable to get block %s from Blockstream.info' % block_hash
            }

        if all(key in data for key in ('height', 'id', 'timestamp',
                                       'merkle_root', 'size')):
            block = {
                'height': data['height'],
                'hash': data['id'],
                'time': data['timestamp'],
                'merkleroot': data['merkle_root'],
                'size': data['size']
            }  # Todo weight?
            return {'block': block}
        else:
            return {'error': 'Received invalid data: %s' % data}
Ejemplo n.º 2
0
    def get_block_by_hash(self, block_hash):
        url = '{api_url}/block/{hash}'.format(api_url=self.url,
                                              hash=block_hash)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get block %s from Blocktrail.com: %s' %
                      (block_hash, ex))
            return {
                'error':
                'Unable to get block %s from Blocktrail.com' % block_hash
            }
        data = data['data'] if data['data'] is not None else {}

        if all(key in data for key in ('height', 'hash', 'timestamp',
                                       'mrkl_root', 'size')):
            block = {
                'height': data['height'],
                'hash': data['hash'],
                'time': data['timestamp'],
                'merkleroot': data['mrkl_root'],
                'size': data['size']
            }

            return {'block': block}
        else:
            return {'error': 'Received invalid data: %s' % data}
Ejemplo n.º 3
0
    def get_block_by_hash(self, block_hash):
        url = self.url + '/block/' + block_hash
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get block %s from %s: %s' %
                      (block_hash, self.url, ex))
            return {
                'error':
                'Unable to get block %s from %s' % (block_hash, self.url)
            }

        block = {}
        if all(key in data
               for key in ('height', 'hash', 'time', 'merkleroot', 'size')):
            block['height'] = data['height']
            block['hash'] = data['hash']
            block['time'] = data['time']
            block['merkleroot'] = data['merkleroot']
            block['size'] = data['size']
            return {'block': block}
        else:
            return {'error': 'Received invalid data: %s' % data}
Ejemplo n.º 4
0
    def get_prime_input_address(self, txid):
        url = self.url + '/tx/' + str(txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error(
                'Unable to get prime input address of transaction %s from %s: %s'
                % (txid, self.url, ex))
            return {
                'error':
                'Unable to get prime input address of transaction %s from %s' %
                (txid, self.url)
            }

        if 'vin' in data:
            tx_inputs = data['vin']

            input_addresses = []
            for i in range(0, len(tx_inputs)):
                input_addresses.append(tx_inputs[i]['addr'])

            if len(input_addresses) > 0:
                prime_input_address = sorted(input_addresses)[0]
                return {'prime_input_address': prime_input_address}

        return {'error': 'Received invalid data: %s' % data}
Ejemplo n.º 5
0
    def get_utxos(self, address, confirmations=3):
        url = self.url + '/addrs/' + address + '/utxo?noCache=1'
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get utxos of address %s from %s: %s' %
                      (address, url, ex))
            return {
                'error':
                'Unable to get utxos of address %s from %s' % (address, url)
            }

        utxos = []
        for output in data:
            if all(key in output for key in ('confirmations', 'txid', 'vout',
                                             'satoshis', 'scriptPubKey')):
                utxo = {
                    'confirmations': output['confirmations'],
                    'output_hash': output['txid'],
                    'output_n': output['vout'],
                    'value': output['satoshis'],
                    'script': output['scriptPubKey']
                }

                if utxo['confirmations'] >= confirmations:
                    utxos.append(utxo)

        return {
            'utxos':
            sorted(utxos,
                   key=lambda k:
                   (k['confirmations'], k['output_hash'], k['output_n']))
        }
Ejemplo n.º 6
0
    def get_balance(self, address):
        url = '{api_url}/address/{address}'.format(api_url=self.url,
                                                   address=address)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error(
                'Unable to get balance of address %s from Blocktrail.com: %s' %
                (address, ex))
            return {
                'error':
                'Unable to get balance of address %s from Blocktrail.com' %
                address
            }

        data = data['data'] if data['data'] is not None else {}

        if all(key in data for key in ('balance', 'received', 'sent')):
            balance = {
                'final':
                data['balance'] - data['unconfirmed_received'] +
                data['unconfirmed_sent'],
                'received':
                data['received'] - data['unconfirmed_received'],
                'sent':
                data['sent'] - data['unconfirmed_sent']
            }
            return {'balance': balance}
        else:
            return {'error': 'Received invalid data: %s' % data}
Ejemplo n.º 7
0
def initialize_database(database, tables, user, password):
    # Try to make a connection, if the database does not exist yet, create the database and create the tables in it
    """
    Check if a database exists, if not create it

    :param database: The name of the database (string)
    :param tables: A dict containing the sql statements to create the tables (dict)
    :param user: The username for the database (string)
    :param password: The password for the database (string)
    """
    cnx = mysql.connector.connect(user=user, password=password)
    cursor = cnx.cursor()

    try:
        cursor.execute("USE {}".format(database))
    except mysql.connector.Error as err:
        LOG.info("Database {} does not exists.".format(database))
        if err.errno == errorcode.ER_BAD_DB_ERROR:
            create_database(cursor=cursor, database=database)
            LOG.info("Database {} created successfully.".format(database))
            cnx.database = database
            create_tables(cursor=cursor, tables=tables)
        else:
            LOG.error(err)

    cursor.close()
    cnx.close()
    def construct_transaction_inputs(self):
        """
        Construct a list of dict object containing the necessary information for the inputs of a transaction

        :return: A list of dicts containing the following keys for each utxo: 'address', 'value', 'output' and 'confirmations'
        """

        if self.unspent_outputs is not None and len(self.unspent_outputs) > 0:
            LOG.info('Found %s utxos for address %s' %
                     (len(self.unspent_outputs), self.sending_address))
        else:
            LOG.error('No utxos found for address %s' % self.sending_address)

        # Construct the transaction inputs
        tx_inputs = [
            {
                'address': utxo.address,
                'value': utxo.value,
                'output':
                utxo.output,  # output needs to be formatted as txid:i
                'confirmations': utxo.confirmations
            } for utxo in self.unspent_outputs
        ]

        return tx_inputs
Ejemplo n.º 9
0
    def get_balance(self, address):
        url = self.url + '/address/{address}'.format(address=address)
        LOG.info('GET %s' % url)
        try:
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error(
                'Unable to get address info for %s from Blockstream.info: %s' %
                (address, ex))
            return {
                'error':
                'Unable to get address info for %s from Blockstream.info' %
                address
            }

        sent_balance = data['chain_stats'][
            'spent_txo_sum']  # Todo fix the sent and received balance because blockstream reports this wrong (also counts when change is sent back to the address itself)
        received_balance = data['chain_stats']['funded_txo_sum']
        final_balance = received_balance - sent_balance

        balance = {
            'final': final_balance,
            'received': received_balance,
            'sent': sent_balance
        }
        return {'balance': balance}
Ejemplo n.º 10
0
    def get_block_by_height(self, height):
        url = '{api_url}/get_block/{network}/{height}'.format(
            api_url=self.url, network=self.network, height=height)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get block %s from Chain.so: %s' %
                      (height, ex))
            return {'error': 'Unable to get block %s from Chain.so' % height}

        if 'data' not in data:
            LOG.error('Invalid response data from Chain.so: %s' % data)
            return {'error': 'Invalid response data from Chain.so: %s' % data}

        data = data['data']

        if all(key in data for key in ('block_no', 'blockhash', 'time',
                                       'merkleroot', 'size')):
            block = {
                'height': data['block_no'],
                'hash': data['blockhash'],
                'time': data['time'],
                'merkleroot': data['merkleroot'],
                'size': data['size']
            }
            return {'block': block}
        else:
            return {'error': 'Received invalid data: %s' % data}
    def get_prime_input_address(self, txid):
        url = '{api_url}/rawtx/{txid}'.format(api_url=self.url, txid=txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error(
                'Unable to get prime input address of tx %s from Blockchain.info: %s'
                % (txid, ex))
            return {
                'error':
                'Unable to get prime input address of tx %s from Blockchain.info'
                % txid
            }

        if 'inputs' in data:
            tx_inputs = data['inputs']

            input_addresses = []
            for i in range(0, len(tx_inputs)):
                if 'prev_out' in tx_inputs[
                        i]:  # Coinbase transactions don't have a input address
                    input_addresses.append(tx_inputs[i]['prev_out']['addr'])

            if len(input_addresses) > 0:
                prime_input_address = sorted(input_addresses)[0]
                return {'prime_input_address': prime_input_address}
            else:
                # transaction was a coinbase transaction, so there are no input addresses
                return {'prime_input_address': None}

        return {'error': 'Received invalid data: %s' % data}
Ejemplo n.º 12
0
    def get_balance(self, address):
        url = '{api_url}/address/{network}/{address}'.format(
            api_url=self.url, network=self.network, address=address)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get balance of address %s from Chain.so: %s' %
                      (address, ex))
            return {
                'error':
                'Unable to get balance of address %s from Chain.so' % address
            }

        if 'data' not in data:
            LOG.error('Invalid response data from Chain.so: %s' % data)
            return {'error': 'Invalid response data from Chain.so: %s' % data}

        data = data['data']

        final_balance = btc2satoshis(btc=data['balance'])
        received_balance = btc2satoshis(btc=data['received_value'])
        sent_balance = received_balance - final_balance

        balance = {
            'final': final_balance,
            'received': received_balance,
            'sent': sent_balance
        }

        return {'balance': balance}
Ejemplo n.º 13
0
    def process_ipfs_hash(self, ipfs_hash):
        LOG.info('Retrieving IPFS object')

        if self.ipfs_object is not None:
            LOG.info(
                'IPFS object given with request, uploading data to local IPFS node to check that hashes are equal'
            )
            local_ipfs_hash = add_json(data=self.ipfs_object)
            if ipfs_hash != local_ipfs_hash:
                LOG.error(
                    'Supplied object does not correspond to the given IPFS hash: %s != %s'
                    % (ipfs_hash, local_ipfs_hash))
                return

        try:
            data = get_json(cid=ipfs_hash)
            if isinstance(data, dict):
                self.json = data
            elif isinstance(data, str):
                self.json = simplejson.loads(data)
            else:
                raise Exception(
                    'IPFS hash does not contain a dict or a json string: %s -> %s'
                    % (ipfs_hash, data))
            LOG.info('Message contains json data: %s' % self.json)
        except Exception as ex:
            LOG.error('IPFS hash does not contain valid json data: %s' % ex)
            return
    def get_block_by_height(self, height):
        url = '{api_url}/block-height/{height}?format=json'.format(
            api_url=self.url, height=height)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get block %s from Blockchain.info: %s' %
                      (height, ex))
            return {
                'error': 'Unable to get block %s from Blockchain.info' % height
            }

        if 'blocks' in data:
            blocks = data['blocks']
            for i in range(0, len(blocks)):
                if blocks[i]['main_chain'] is True and blocks[i][
                        'height'] == height:
                    block = {
                        'height': blocks[i]['height'],
                        'hash': blocks[i]['hash'],
                        'time': blocks[i]['time'],
                        'merkleroot': blocks[i]['mrkl_root'],
                        'size': blocks[i]['size']
                    }
                    return {'block': block}

        return {'error': 'Received invalid data: %s' % data}
Ejemplo n.º 15
0
    def exit_with_error(self, message):
        """
        Log an error message and set the http response with the same error message

        :param message: The error message
        """
        LOG.error(message)
        self.http_response = {'error': message}
Ejemplo n.º 16
0
def add_str(string):
    global IPFS_API

    try:
        cid = IPFS_API.add_str(string=string)
    except Exception as e:
        LOG.error('Unable to store string on IPFS: %s' % e)
        raise Exception('IPFS failure')

    return CID(cid).__str__()
Ejemplo n.º 17
0
def add_file(filename):
    global IPFS_API

    try:
        ipfs_info = IPFS_API.add(filename)
    except Exception as e:
        LOG.error('Unable to store file on IPFS: %s' % e)
        raise Exception('IPFS failure')

    return ipfs_info['Hash'], ipfs_info['Name'], ipfs_info['Size']
Ejemplo n.º 18
0
    def run(self, *args, **kwargs):
        LOG.info('Running Spellbook Script: %s' %
                 os.path.splitext(os.path.basename(__file__))[0])

        if 'message' not in self.json:
            LOG.error('key "message" not found in http POST request')
            return

        message = self.json['message']

        if not valid_op_return(message=message):
            LOG.error(
                'Can not create Notary request: message is not valid to put in a OP_RETURN output: %s'
                % message)
            return

        # Use the number of times the trigger has been triggered as a identifier for the request and as the index of the address in the hot wallet
        request_id = self.triggered + 1

        # Get the address to receive payment
        request_address = get_address_from_wallet(account=BIP44_ACCOUNT,
                                                  index=request_id)

        # Create a new action to send a custom transaction with the OP_RETURN data
        action_id = 'Notary-send-tx_%s' % request_id
        action = get_action(action_id=action_id,
                            action_type=ActionType.SENDTRANSACTION)
        action.transaction_type = TransactionType.SEND2SINGLE
        action.wallet_type = WALLET_TYPE
        action.bip44_account = BIP44_ACCOUNT
        action.bip44_index = request_id
        action.receiving_address = get_address_from_wallet(
            account=BIP44_ACCOUNT, index=0
        )  # always use the first address in the account to receive the transactions
        action.op_return_data = message
        action.save()

        # Create a new trigger that activates when payment is received
        invoice_paid_trigger_id = 'Notary-payment_%s' % request_id
        trigger = get_trigger(trigger_id=invoice_paid_trigger_id,
                              trigger_type=TriggerType.BALANCE)
        trigger.address = request_address
        trigger.amount = NOTARY_COST
        trigger.actions = [action_id]
        trigger.status = 'Active'
        trigger.self_destruct = int(time.time()) + REQUEST_TIMEOUT
        trigger.destruct_actions = True
        trigger.save()

        self.http_response = {
            'request_id': request_id,
            'address': request_address,
            'value': NOTARY_COST,
            'timeout': int(time.time()) + REQUEST_TIMEOUT
        }
Ejemplo n.º 19
0
    def get_transaction(self, txid):
        url = '{api_url}/tx/{txid}?verbose=3'.format(api_url=self.url,
                                                     txid=txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get transaction %s from BTC.com: %s' %
                      (txid, ex))
            return {
                'error': 'Unable to get transaction %s from BTC.com' % txid
            }

        data = data['data'] if data['data'] is not None else {}

        # todo check key names , test by setting testnet wrong on explorers
        tx = TX()
        tx.txid = txid
        tx.wtxid = data['witness_hash']
        tx.lock_time = data['lock_time']
        tx.block_height = data[
            'block_height'] if 'block_height' in data and data[
                'block_height'] != -1 else None
        tx.confirmations = data[
            'confirmations'] if 'confirmations' in data else None

        for item in data['inputs']:
            tx_input = TxInput()
            tx_input.address = item['prev_addresses'][0] if len(
                item['prev_addresses']) > 0 else None
            tx_input.value = item['prev_value']
            tx_input.txid = item['prev_tx_hash']
            tx_input.n = item['prev_position'] if item[
                'prev_position'] is not -1 else None
            tx_input.script = item['script_hex']
            tx_input.sequence = item['sequence']

            tx.inputs.append(tx_input)

        for i, item in enumerate(data['outputs']):
            tx_output = TxOutput()
            tx_output.address = item['addresses'][0] if len(
                item['addresses']) > 0 else None
            tx_output.value = item['value']
            tx_output.n = i
            tx_output.spent = False if item['spent_by_tx'] is None else True
            tx_output.script = item['script_hex']

            if item['script_hex'][:2] == '6a':
                tx_output.op_return = tx.decode_op_return(item['script_hex'])

            tx.outputs.append(tx_output)

        return {'transaction': tx.json_encodable()}
Ejemplo n.º 20
0
    def get_utxos(self, address, confirmations=3):
        url = self.url + '/blocks/tip/height'
        LOG.info('GET %s' % url)
        try:
            r = requests.get(url)
            latest_block_height = int(r.text)
        except Exception as ex:
            LOG.error(
                'Unable to get latest block_height from Blockstream.info: %s' %
                ex)
            return {
                'error':
                'Unable to get latest block_height from Blockstream.info'
            }

        url = self.url + '/address/{address}/utxo'.format(address=address)
        LOG.info('GET %s' % url)
        try:
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error(
                'Unable to get address utxos for %s from Blockstream.info: %s'
                % (address, ex))
            return {
                'error':
                'Unable to get utxos info for %s from Blockstream.info' %
                address
            }

        LOG.info('Got %s utxos' % len(data))

        utxos = []
        for output in data:
            confirmations = latest_block_height - int(
                output['status']['block_height']
            ) + 1 if output['status']['confirmed'] is True else 0
            utxo = {
                'confirmations': confirmations,
                'output_hash': output['txid'],
                'output_n': output['vout'],
                'value': output['value'],
                'script': None
            }  # Blockstream.info does not provide the script for utxos

            if utxo['confirmations'] >= confirmations:
                utxos.append(utxo)

        return {
            'utxos':
            sorted(utxos,
                   key=lambda k:
                   (k['confirmations'], k['output_hash'], k['output_n']))
        }
Ejemplo n.º 21
0
def connect_to_ipfs():
    global IPFS_API

    # Check if IPFS node is running
    multi_address = '/ip4/{host}/tcp/{port}/http'.format(
        host=get_ipfs_api_host(), port=get_ipfs_api_port())
    LOG.info('Trying to connect with IPFS on %s' % multi_address)
    try:
        IPFS_API = ipfshttpclient.connect(multi_address)
        LOG.info('Connected with IPFS')
    except Exception as ex:
        LOG.error('IPFS node is not running: %s' % ex)
Ejemplo n.º 22
0
    def get_transaction(self, txid):
        url = self.url + '/tx/' + str(txid)
        try:
            LOG.info('GET %s' % url)
            r = requests.get(url)
            data = r.json()
        except Exception as ex:
            LOG.error('Unable to get transaction %s from %s: %s' %
                      (txid, self.url, ex))
            return {
                'error':
                'Unable to get transaction %s from %s' % (txid, self.url)
            }

        tx = TX()
        tx.txid = txid
        tx.block_height = data['blockheight'] if 'blockheight' in data else None
        tx.lock_time = data['locktime']

        for item in data['vin']:
            tx_input = TxInput()
            tx_input.address = item['addr'] if 'addr' in item else None
            tx_input.value = item['valueSat'] if 'valueSat' in item else 0
            tx_input.txid = item['txid'] if 'txid' in item else None
            tx_input.n = item['n'] if 'coinbase' not in item else None
            tx_input.script = item['scriptSig'][
                'hex'] if 'scriptSig' in item else None
            if 'coinbase' in item:
                tx_input.script = item['coinbase']
            tx_input.sequence = item['sequence']

            tx.inputs.append(tx_input)

        for item in data['vout']:
            tx_output = TxOutput()
            tx_output.address = item['scriptPubKey']['addresses'][
                0] if 'addresses' in item['scriptPubKey'] else None
            tx_output.value = int(float(item['value']) * 1e8)
            tx_output.n = item['n']
            tx_output.spent = True if 'spentTxId' in item and item[
                'spentTxId'] is not None else False
            tx_output.script = item['scriptPubKey']['hex']
            if item['scriptPubKey']['hex'][:2] == '6a':
                tx_output.op_return = tx.decode_op_return(
                    item['scriptPubKey']['hex'])

            tx.outputs.append(tx_output)

        tx.confirmations = data[
            'confirmations'] if 'confirmations' in data else None

        return {'transaction': tx.json_encodable()}
Ejemplo n.º 23
0
    def parse_transaction(self, data, latest_block_height=None):
        if latest_block_height is None:
            url = self.url + '/blocks/tip/height'
            LOG.info('GET %s' % url)
            try:
                r = requests.get(url)
                latest_block_height = int(r.text)
            except Exception as ex:
                LOG.error(
                    'Unable to get latest block_height from Blockstream.info: %s'
                    % ex)
                return {
                    'error':
                    'Unable to get latest block_height from Blockstream.info'
                }

        tx = TX()
        tx.txid = data['txid']
        tx.lock_time = data['locktime']
        tx.block_height = data['status'][
            'block_height'] if 'block_height' in data['status'] else None
        tx.confirmations = latest_block_height - tx.block_height + 1 if tx.block_height is not None else 0

        for item in data['vin']:
            tx_input = TxInput()
            tx_input.address = item['prevout']['scriptpubkey_address'] if item[
                'prevout'] is not None else None
            tx_input.value = item['prevout']['value'] if item[
                'prevout'] is not None else 0
            tx_input.n = item['vout'] if item['is_coinbase'] is False else None
            tx_input.txid = item['txid']
            tx_input.script = item['scriptsig']
            tx_input.sequence = item['sequence']

            tx.inputs.append(tx_input)

        for i, item in enumerate(data['vout']):
            tx_output = TxOutput()
            tx_output.address = item[
                'scriptpubkey_address'] if 'scriptpubkey_address' in item else None
            tx_output.value = item['value']
            tx_output.n = i
            tx_output.spent = None  # Blockstream does not provide information if a tx output has been spent
            tx_output.script = item['scriptpubkey']
            if item['scriptpubkey'][:2] == '6a':
                tx_output.op_return = tx.decode_op_return(item['scriptpubkey'])

            tx.outputs.append(tx_output)

        return tx
Ejemplo n.º 24
0
def create_database(cursor, database):
    """
    Create a new database

    :param cursor: A MySQL cursor object
    :param database: The name of the database (string)
    """
    LOG.info('Creating database %s' % database)

    try:
        cursor.execute(
            "CREATE DATABASE {} DEFAULT CHARACTER SET 'utf8'".format(database))
    except mysql.connector.Error as err:
        LOG.error("Failed creating database: {}".format(err))
Ejemplo n.º 25
0
def load_from_json_file(filename):
    """
    Load data from a json file

    :return: a dict containing the data from the json file
    """
    data = None
    # Load the json file
    with open(filename, 'r') as input_file:
        try:
            data = simplejson.load(input_file)
        except Exception as ex:
            LOG.error('Failed to load %s: %s' % (filename, ex))

    return data
Ejemplo n.º 26
0
    def push_tx(self, tx):
        url = self.url + '/broadcast?tx={tx}'.format(tx=tx)
        LOG.info('GET %s' % url)
        try:
            r = requests.get(url)
        except Exception as ex:
            LOG.error('Unable to push tx via Blockstream.info: %s' % ex)
            return {'error': 'Unable to push tx Blockstream.info: %s' % ex}

        data = r.text.strip()
        if r.status_code == 200:
            return {'success': True, 'txid': data}
        else:
            LOG.error('Unable to push tx via Blockstream.info: %s' % data)
            return {'error': 'Unable to push tx Blockstream.info: %s' % data}
Ejemplo n.º 27
0
    def get_block_by_height(self, height):
        url = self.url + '/block-height/{height}'.format(height=height)
        LOG.info('GET %s' % url)
        try:
            r = requests.get(url)
            block_hash = r.text
        except Exception as ex:
            LOG.error('Unable to get block %s from Blockstream.info: %s' %
                      (height, ex))
            return {
                'error':
                'Unable to get block %s from Blockstream.info' % height
            }

        return self.get_block_by_hash(block_hash=block_hash)
    def push_tx(self, tx):
        url = '{api_url}/pushtx'.format(api_url=self.url)
        LOG.info('POST %s' % url)
        try:
            r = requests.post(url, data=dict(tx=tx))
        except Exception as ex:
            LOG.error('Unable to push tx via Blockchain.info: %s' % ex)
            return {'error': 'Unable to push tx Blockchain.info: %s' % ex}

        data = r.text.strip()
        if r.status_code == 200 and data == 'Transaction Submitted':
            return {'success': True}
        else:
            LOG.error('Unable to push tx via Blockchain.info: %s' % data)
            return {'error': 'Unable to push tx Blockchain.info: %s' % data}
Ejemplo n.º 29
0
        def _log_to_logger(*args, **kwargs):
            start_time = int(round(time.time() * 1000))
            request_time = datetime.now()

            # Log information about the request before it is processed for debugging purposes
            REQUESTS_LOG.info('%s | %s | %s | %s' % (request_time,
                                                     request.remote_addr,
                                                     request.method,
                                                     request.url))

            if request.headers is not None:
                for key, value in request.headers.items():
                    REQUESTS_LOG.info('  HEADERS | %s: %s' % (key, value))

            if request.json is not None:
                for key, value in request.json.items():
                    REQUESTS_LOG.info('  BODY | %s: %s' % (key, value))

            actual_response = response
            try:
                actual_response = fn(*args, **kwargs)
            except Exception as ex:
                response_status = '500 ' + str(ex)
                LOG.error('%s caused an exception: %s' % (request.url, ex))
                error_traceback = traceback.format_exc()
                for line in error_traceback.split('\n'):
                    LOG.error(line)

                if get_mail_on_exception() is True:
                    variables = {'HOST': get_host(),
                                 'TRACEBACK': error_traceback}
                    body_template = os.path.join('server_exception')
                    sendmail(recipients=get_notification_email(),
                             subject='Exception occurred @ %s' % get_host(),
                             body_template=body_template,
                             variables=variables)

            else:
                response_status = response.status

            end_time = int(round(time.time() * 1000))
            REQUESTS_LOG.info('%s | %s | %s | %s | %s | %s ms' % (request_time,
                                                                  request.remote_addr,
                                                                  request.method,
                                                                  request.url,
                                                                  response_status,
                                                                  end_time - start_time))
            return actual_response
Ejemplo n.º 30
0
def save_to_json_file(filename, data):
    """
    Save data to a json file
    :param filename: The filename of the json file
    :param data: A dict containing the data to save (must be json-encodable)
    """

    # Make sure the destination directory exists
    if not os.path.isdir(os.path.dirname(filename)):
        os.makedirs(os.path.dirname(filename))

    try:
        with open(filename, 'w') as output_file:
            simplejson.dump(data, output_file, indent=4, sort_keys=True)
    except Exception as ex:
        LOG.error('Failed to save data to json file %s: %s' % (filename, ex))