def get_bigchain(conf=CONFIG_FILE, ledger_id=None):
    if os.path.isfile(conf):
        bigchaindb.config_utils.autoconfigure(filename=conf, force=True)

    if ledger_id is not None:
        return bigchaindb.Bigchain(dbname='bigchaindb_examples_{}'.format(ledger_id))
    else:
        return bigchaindb.Bigchain()
Exemple #2
0
def validate_fulfillments(signed_transaction):
    """Verify the signature of a transaction

    A valid transaction should have been signed `current_owner` corresponding private key.

    Args:
        signed_transaction (dict): a transaction with the `signature` included.

    Returns:
        bool: True if the signature is correct, False otherwise.
    """
    for fulfillment in signed_transaction['transaction']['fulfillments']:
        fulfillment_message = get_fulfillment_message(signed_transaction,
                                                      fulfillment)
        try:
            parsed_fulfillment = cc.Fulfillment.from_uri(
                fulfillment['fulfillment'])
        except (TypeError, ValueError, ParsingError):
            return False

        # TODO: might already break on a False here
        is_valid = parsed_fulfillment.validate(
            message=serialize(fulfillment_message), now=timestamp())

        # if transaction has an input (i.e. not a `CREATE` transaction)
        # TODO: avoid instantiation, pass as argument!
        bigchain = bigchaindb.Bigchain()
        input_condition = get_input_condition(bigchain, fulfillment)
        is_valid = is_valid and parsed_fulfillment.condition_uri == input_condition[
            'condition']['uri']

        if not is_valid:
            return False

    return True
Exemple #3
0
def init():
    """ init leveldb database by conn"""
    logger.info('leveldb init...')
    conn_bigchain = get_conn('bigchain')
    conn_header = get_conn('header')

    logger.info('leveldb init...')
    logger.info('leveldb/header init...')
    logger.info('leveldb/header init host...' +
                str(bigchaindb.config['database']['host']))
    logger.info('leveldb/header init public_key...' +
                str(bigchaindb.config['keypair']['public']))
    logger.info('leveldb/header init private_key...' +
                str(bigchaindb.config['keypair']['private']))

    update(conn_header, 'host', bigchaindb.config['database']['host'])
    update(conn_header, 'public_key', bigchaindb.config['keypair']['public'])
    update(conn_header, 'private_key', bigchaindb.config['keypair']['private'])

    block_num = int(get_withdefault(conn_header, 'block_num', 0))
    genesis_block_id = get_withdefault(conn_header, 'genesis_block_id', '0')
    if block_num == 0:
        genesis_block = r.db('bigchain').table('bigchain').order_by(
            r.asc(r.row['block']['timestamp'])).limit(1).run(
                bigchaindb.Bigchain().conn)[0]
        genesis_block_id = genesis_block['id']
        insert(conn_bigchain, genesis_block_id, genesis_block)
        insert(conn_header, 'genesis_block_id', genesis_block_id)
        insert(conn_header, 'block_num', 1)
        insert(conn_header, 'current_block_id', genesis_block_id)
    logger.info('leveldb/header genesis_block_id...' + str(genesis_block_id))
    logger.info('leveldb init done')
Exemple #4
0
def _run_init():
    # Try to access the keypair, throws an exception if it does not exist
    b = bigchaindb.Bigchain()

    schema.init_database(connection=b.connection)

    b.create_genesis_block()
    logger.info('Genesis block created.')
Exemple #5
0
def init():
    # Try to access the keypair, throws an exception if it does not exist
    b = bigchaindb.Bigchain()

    init_database()

    logger.info('Create genesis block.')
    b.create_genesis_block()
    logger.info('Done, have fun!')
Exemple #6
0
def test_bigchain_instance_raises_when_not_configured(monkeypatch):
    from bigchaindb import config_utils
    assert 'CONFIGURED' not in bigchaindb.config

    # We need to disable ``bigchaindb.config_utils.autoconfigure`` to avoid reading
    # from existing configurations
    monkeypatch.setattr(config_utils, 'autoconfigure', lambda: 0)

    with pytest.raises(bigchaindb.core.KeypairNotFoundException):
        bigchaindb.Bigchain()
Exemple #7
0
def run_set_replicas(args):
    b = bigchaindb.Bigchain()
    for table in ['bigchain', 'backlog', 'votes']:
        # See https://www.rethinkdb.com/api/python/config/
        table_config = r.table(table).config().run(b.conn)
        num_shards = len(table_config['shards'])
        try:
            r.table(table).reconfigure(shards=num_shards,
                                       replicas=args.num_replicas).run(b.conn)
        except r.ReqlOpFailedError as e:
            logger.warn(e)
Exemple #8
0
def test_bigchain_instance_is_initialized_when_conf_provided():
    from bigchaindb import config_utils
    assert 'CONFIGURED' not in bigchaindb.config

    config_utils.dict_config({'keypair': {'public': 'a', 'private': 'b'}})

    assert bigchaindb.config['CONFIGURED'] is True
    b = bigchaindb.Bigchain()

    assert b.me
    assert b.me_private
Exemple #9
0
def sign_tx(transaction, signing_keys, bigchain=None):
    """Sign a transaction

    A transaction signed with the `current_owner` corresponding private key.

    Args:
        transaction (dict): transaction to sign.
        signing_keys (list): list of base58 encoded private keys to create the fulfillments of the transaction.
        bigchain (obj): bigchain instance used to get the details of the previous transaction outputs. Useful
                        if the `Bigchain` instance was instantiated with parameters that override the config file.

    Returns:
        dict: transaction with the `fulfillment` fields populated.

    """
    # validate sk
    if not isinstance(signing_keys, list):
        signing_keys = [signing_keys]

    # create a mapping between sk and vk so that we can match the private key to the current_owners
    key_pairs = {}
    for sk in signing_keys:
        signing_key = crypto.SigningKey(sk)
        vk = signing_key.get_verifying_key().to_ascii().decode()
        key_pairs[vk] = signing_key

    tx = copy.deepcopy(transaction)

    bigchain = bigchain if bigchain is not None else bigchaindb.Bigchain()

    for fulfillment in tx['transaction']['fulfillments']:
        fulfillment_message = get_fulfillment_message(transaction, fulfillment)
        # TODO: avoid instantiation, pass as argument!
        input_condition = get_input_condition(bigchain, fulfillment)
        parsed_fulfillment = cc.Fulfillment.from_dict(
            input_condition['condition']['details'])
        # for the case in which the type of fulfillment is not covered by this method
        parsed_fulfillment_signed = parsed_fulfillment

        # single current owner
        if isinstance(parsed_fulfillment, cc.Ed25519Fulfillment):
            parsed_fulfillment_signed = fulfill_simple_signature_fulfillment(
                fulfillment, parsed_fulfillment, fulfillment_message,
                key_pairs)
        # multiple current owners
        elif isinstance(parsed_fulfillment, cc.ThresholdSha256Fulfillment):
            parsed_fulfillment_signed = fulfill_threshold_signature_fulfillment(
                fulfillment, parsed_fulfillment, fulfillment_message,
                key_pairs)

        signed_fulfillment = parsed_fulfillment_signed.serialize_uri()
        fulfillment.update({'fulfillment': signed_fulfillment})

    return tx
Exemple #10
0
def init():
    conn = get_conn()
    dbname = bigchaindb.config['database']['name']

    if r.db_list().contains(dbname).run(conn):
        raise DatabaseAlreadyExistsException(
            'Database `{}` already exists'.format(dbname))

    logger.info('Create:')
    logger.info(' - database `%s`', dbname)
    try:
        r.db_create(dbname).run(conn)
    except r.ReqlOpFailedError as e:
        logger.info(e.message)
        return

    logger.info(' - tables')
    # create the tables
    r.db(dbname).table_create('bigchain').run(conn)
    r.db(dbname).table_create('backlog').run(conn)

    logger.info(' - indexes')
    # create the secondary indexes
    # to order blocks by timestamp
    r.db(dbname).table('bigchain').index_create(
        'block_timestamp', r.row['block']['timestamp']).run(conn)
    # to order blocks by block number
    r.db(dbname).table('bigchain').index_create(
        'block_number', r.row['block']['block_number']).run(conn)
    # to order transactions by timestamp
    r.db(dbname).table('backlog').index_create(
        'transaction_timestamp', r.row['transaction']['timestamp']).run(conn)
    # to query the bigchain for a transaction id
    r.db(dbname).table('bigchain').index_create(
        'transaction_id', r.row['block']['transactions']['id'],
        multi=True).run(conn)
    # compound index to read transactions from the backlog per assignee
    r.db(dbname).table('backlog')\
        .index_create('assignee__transaction_timestamp', [r.row['assignee'], r.row['transaction']['timestamp']])\
        .run(conn)
    # secondary index for payload hash
    r.db(dbname).table('bigchain')\
        .index_create('payload_hash', r.row['block']['transactions']['transaction']['data']['hash'], multi=True)\
        .run(conn)

    # wait for rethinkdb to finish creating secondary indexes
    r.db(dbname).table('backlog').index_wait().run(conn)
    r.db(dbname).table('bigchain').index_wait().run(conn)

    logger.info(' - genesis block')
    b = bigchaindb.Bigchain()
    b.create_genesis_block()
    logger.info('Done, have fun!')
Exemple #11
0
def test_bigchain_instance_raises_when_not_configured(request, monkeypatch):
    import bigchaindb
    from bigchaindb import config_utils
    from bigchaindb.common import exceptions
    assert 'CONFIGURED' not in bigchaindb.config

    # We need to disable ``bigchaindb.config_utils.autoconfigure`` to avoid reading
    # from existing configurations
    monkeypatch.setattr(config_utils, 'autoconfigure', lambda: 0)

    with pytest.raises(exceptions.ConfigurationError):
        bigchaindb.Bigchain()
Exemple #12
0
def transform_create(tx):
    """Change the owner and signature for a ``CREATE`` transaction created by a node"""

    # XXX: the next instruction opens a new connection to the DB, consider using a singleton or a global
    #      if you need a Bigchain instance.
    b = bigchaindb.Bigchain()
    transaction = tx['transaction']
    payload = None
    if transaction['data'] and 'payload' in transaction['data']:
        payload = transaction['data']['payload']
    new_tx = create_tx(b.me, transaction['fulfillments'][0]['current_owners'], None, 'CREATE', payload=payload)
    return new_tx
Exemple #13
0
def main():
    for app in APPS:
        app_name = '{}'.format(app['name'])
        if 'num_accounts' in app:
            ledger_name = 'bigchain'.format(app['ledger'])
            bigchain = Bigchain()
            accounts = retrieve_accounts(bigchain, app_name)
            assets = []
            for i in range(app['num_assets']):
                user = accounts[random.randint(0, app['num_accounts'] - 1)]
                asset = create_asset(bigchain=bigchain,
                                     user_pub=user['vk'],
                                     user_priv=user['sk'],
                                     asset=app['payload_func'](i))
                assets.append(asset)
            logging.info(
                '{} assets initialized for app {} on ledger {}'.format(
                    len(assets), app_name, ledger_name))
        elif 'accounts' in app:
            bigchain = bigchaindb.Bigchain()
            accounts_by_name = get_accounts_by_name(
                retrieve_accounts(bigchain, app['name']))
            for account in app['accounts']:
                for ledger in account['ledgers']:
                    ledger_name = 'bigchaindb_examples_{}'.format(ledger['id'])
                    account_name = '{}-{}'.format(account['name'],
                                                  ledger['id'])
                    bigchain = bigchaindb.Bigchain(dbname=ledger_name)
                    assets = []
                    for i in range(ledger['num_assets']):
                        asset = create_asset(
                            bigchain=bigchain,
                            to=accounts_by_name[account_name]['vk'],
                            payload=app['payload_func'](i))
                        assets.append(asset)
                    logging.info(
                        '{} assets initialized for account {} in app {} on ledger {}'
                        .format(len(assets), account['name'], app_name,
                                ledger_name))
Exemple #14
0
def get_fulfillment_message(transaction, fulfillment, serialized=False):
    """Get the fulfillment message for signing a specific fulfillment in a transaction

    Args:
        transaction (dict): a transaction
        fulfillment (dict): a specific fulfillment (for a condition index) within the transaction
        serialized (Optional[bool]): False returns a dict, True returns a serialized string

    Returns:
        str|dict: fulfillment message
    """
    b = bigchaindb.Bigchain()

    # data to sign contains common transaction data
    fulfillment_message = {
        'operation': transaction['transaction']['operation'],
        'timestamp': transaction['transaction']['timestamp'],
        'data': transaction['transaction']['data'],
        'version': transaction['version'],
        'id': transaction['_id']
    }
    # and the condition which needs to be retrieved from the output of a previous transaction
    # or created on the fly it this is a `CREATE` transaction
    fulfillment_message.update({
        'input': fulfillment['input'],
        'condition': None,
    })

    # if `TRANSFER` transaction
    if fulfillment['input']:
        # get previous condition
        previous_tx = b.get_transaction(fulfillment['input']['txid'])
        conditions = sorted(previous_tx['transaction']['conditions'],
                            key=lambda d: d['cid'])
        fulfillment_message['condition'] = conditions[fulfillment['input']
                                                      ['cid']]
    # if `CREATE` transaction
    # there is no previous transaction so we need to create one on the fly
    else:
        current_owner = transaction['transaction']['fulfillments'][0][
            'current_owners'][0]
        condition = json.loads(
            cc.Ed25519Fulfillment(public_key=current_owner).serialize_json())
        fulfillment_message['condition'] = {
            'condition': {
                'details': condition
            }
        }
    if serialized:
        return serialize(fulfillment_message)
    return fulfillment_message
Exemple #15
0
def _run_load(tx_left, stats):
    logstats.thread.start(stats)
    b = bigchaindb.Bigchain()

    while True:
        tx = b.create_transaction(b.me, USER_PUBLIC_KEY, None, 'CREATE')
        tx_signed = b.sign_transaction(tx, b.me_private)
        b.write_transaction(tx_signed)

        stats['transactions'] += 1

        if tx_left is not None:
            tx_left -= 1
            if tx_left == 0:
                break
Exemple #16
0
def _run_load(tx_left, stats):
    logstats.thread.start(stats)
    b = bigchaindb.Bigchain()

    while True:
        tx = Transaction.create([b.me], [([b.me], 1)])
        tx = tx.sign([b.me_private])
        b.write_transaction(tx)

        stats['transactions'] += 1

        if tx_left is not None:
            tx_left -= 1
            if tx_left == 0:
                break
Exemple #17
0
def run_upsert_validator(args):
    """Store validators which should be synced with Tendermint"""

    b = bigchaindb.Bigchain()
    validator = {'pub_key': {'type': 'ed25519',
                             'data': args.public_key},
                 'power': args.power}
    validator_update = {'validator': validator,
                        'update_id': VALIDATOR_UPDATE_ID}
    try:
        query.store_validator_update(b.connection, validator_update)
    except MultipleValidatorOperationError:
        logger.error('A validator update is pending to be applied. '
                     'Please re-try after the current update has '
                     'been processed.')
Exemple #18
0
def init():
    # Try to access the keypair, throws an exception if it does not exist
    b = bigchaindb.Bigchain()

    conn = get_conn()
    dbname = get_database_name()
    create_database(conn, dbname)

    table_names = ['bigchain', 'backlog', 'votes']
    for table_name in table_names:
        create_table(conn, dbname, table_name)
    create_bigchain_secondary_index(conn, dbname)
    create_backlog_secondary_index(conn, dbname)
    create_votes_secondary_index(conn, dbname)

    logger.info('Create genesis block.')
    b.create_genesis_block()
    logger.info('Done, have fun!')
Exemple #19
0
def get_bigchain(conf=CONFIG_FILE):
    if os.path.isfile(conf):
        bigchaindb.config_utils.autoconfigure(filename=conf, force=True)
    return bigchaindb.Bigchain()
Exemple #20
0
def _run_init():
    bdb = bigchaindb.Bigchain()

    schema.init_database(connection=bdb.connection)
Exemple #21
0
def run_set_shards(args):
    b = bigchaindb.Bigchain()
    r.table('bigchain').reconfigure(shards=args.num_shards,
                                    replicas=1).run(b.conn)
    r.table('backlog').reconfigure(shards=args.num_shards,
                                   replicas=1).run(b.conn)
Exemple #22
0
"""This module provides the blueprint for some basic API endpoints.

For more information please refer to the documentation in Apiary:
 - http://docs.bigchaindb.apiary.io/
"""
import flask
from flask_restful import Resource, reqparse

import bigchaindb
from server.models import accounts

bigchain = bigchaindb.Bigchain()


class AccountListApi(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('app',
                            type=str,
                            choices=('ontherecord', ),
                            location='args',
                            required=True)
        app = parser.parse_args()['app']
        result = accounts.retrieve_accounts(bigchain, app)
        return flask.jsonify({'accounts': result})


class ConnectorListApi(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('app',
Exemple #23
0
def main():
    for app in APPS:
        app_name = '{}'.format(app['name'])
        if 'num_accounts' in app:
            ledger_name = 'bigchaindb_examples_{}'.format(app['ledger'])
            bigchain = get_bigchain(ledger_id=app['ledger'])
            accounts = retrieve_accounts(bigchain, app_name)
            assets = []
            for i in range(app['num_assets']):
                asset = create_asset(bigchain=bigchain,
                                     to=accounts[random.randint(
                                         0, app['num_accounts'] - 1)]['vk'],
                                     payload=app['payload_func'](i))
                assets.append(asset)
            logging.info(
                '{} assets initialized for app {} on ledger {}'.format(
                    len(assets), app_name, ledger_name))
        elif app_name == 'different_users':
            bigchain = bigchaindb.Bigchain()
            accounts_by_name = get_accounts_by_name(
                retrieve_accounts(bigchain, app['name']))
            admin_account = app['accounts'][0]
            [user_assets, account_assets] = admin_account['ledgers']
            bigchain = bigchaindb.Bigchain(dbname='bigchaindb_examples_0')
            assets = []

            for user_asset_ind in range(user_assets['num_assets']):
                payload = {
                    'app': 'different_users',
                    'content': {
                        'asset_name': 'user{}'.format(user_asset_ind),
                    },
                }
                user_asset = create_asset(bigchain=bigchain,
                                          to=accounts_by_name['admin-0']['vk'],
                                          payload=payload)
                assets.append(user_asset)

            user_0_asset_id = assets[0]['id']
            user_1_asset_id = assets[1]['id']

            for account_asset_ind in range(account_assets['num_assets']):
                account = app['accounts'][account_asset_ind + 1]
                ledger = account['ledgers'][0]
                account_name = '{}-{}'.format(account['name'], ledger['id'])
                authorized = {}
                if account_asset_ind < 3:
                    authorized[str(len(authorized))] = user_0_asset_id
                if account_asset_ind > 1:
                    authorized[str(len(authorized))] = user_1_asset_id
                payload = {
                    'app': 'different_users',
                    'content': {
                        'asset_name': accounts_by_name[account_name]['vk'],
                        'authorized': authorized,
                    },
                }
                account_asset = create_asset(
                    bigchain=bigchain,
                    to=accounts_by_name['admin-0']['vk'],
                    payload=payload)
                assets.append(account_asset)

            account_ind = 0
            for account in app['accounts']:
                account_ind += 10
                if account['name'] != 'admin':
                    for ledger in account['ledgers']:
                        ledger_name = 'bigchaindb_examples_{}'.format(
                            ledger['id'])
                        account_name = '{}-{}'.format(account['name'],
                                                      ledger['id'])
                        bigchain = bigchaindb.Bigchain(dbname=ledger_name)
                        for i in range(ledger['num_assets']):
                            asset = create_asset(
                                bigchain=bigchain,
                                to=accounts_by_name[account_name]['vk'],
                                payload=app['payload_func'](i + account_ind))
                            assets.append(asset)

            logging.info('{} assets initialized in app {}'.format(
                len(assets), app_name))
        elif 'accounts' in app:
            bigchain = bigchaindb.Bigchain()
            accounts_by_name = get_accounts_by_name(
                retrieve_accounts(bigchain, app['name']))
            for account in app['accounts']:
                for ledger in account['ledgers']:
                    ledger_name = 'bigchaindb_examples_{}'.format(ledger['id'])
                    account_name = '{}-{}'.format(account['name'],
                                                  ledger['id'])
                    bigchain = bigchaindb.Bigchain(dbname=ledger_name)
                    assets = []
                    for i in range(ledger['num_assets']):
                        asset = create_asset(
                            bigchain=bigchain,
                            to=accounts_by_name[account_name]['vk'],
                            payload=app['payload_func'](i))
                        assets.append(asset)
                    logging.info(
                        '{} assets initialized for account {} in app {} on ledger {}'
                        .format(len(assets), account['name'], app_name,
                                ledger_name))
Exemple #24
0
def init_databaseData():
    b = bigchaindb.Bigchain()

    b.init_heartbeat_data()

    b.init_reassignnode_data()