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()
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
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')
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.')
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!')
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()
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)
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
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
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!')
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()
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
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))
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
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
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
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.')
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!')
def get_bigchain(conf=CONFIG_FILE): if os.path.isfile(conf): bigchaindb.config_utils.autoconfigure(filename=conf, force=True) return bigchaindb.Bigchain()
def _run_init(): bdb = bigchaindb.Bigchain() schema.init_database(connection=bdb.connection)
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)
"""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',
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))
def init_databaseData(): b = bigchaindb.Bigchain() b.init_heartbeat_data() b.init_reassignnode_data()