From 4d2e58416c0e68838ae2dca313535cb5fc0085b5 Mon Sep 17 00:00:00 2001 From: Zachary Bowen Date: Tue, 10 Jul 2018 17:34:51 +0200 Subject: [PATCH] Problem: Bigchain class is unused and redundant (#2366) * Problem: core.py contains an unused class, `Bigchain` Solution: Remove core.py. Refactor BigchainDB Class to remove inheritance from Bigchain. * Problem: core.py contains an unused class, `Bigchain` Solution: Remove core.py. Refactor BigchainDB Class to remove inheritance from Bigchain. * Fixed flake8 complaint about too many blank lines * Attempting to fix Sphinx docs. This may result in some redundant commits, as I don't know what I'm doing, and I can't experiment without running the CI... Sorry in advance! * Attempting to fix Sphinx docs. This may result in some redundant commits, as I don't know what I'm doing, and I can't experiment without running the CI... Sorry in advance! * Updating from master changed BigchainDB.process_post_response to a private method, so I had to align with that. * Fixed a couple stale references to bigchaindb.Bigchain in docstrings * Missed a reference to `Bigchain` in a patch call... * Merge with master and re-do some changes --- bigchaindb/README.md | 4 +- bigchaindb/__init__.py | 2 +- bigchaindb/commands/bigchaindb.py | 4 +- bigchaindb/core.py | 434 ------------------ bigchaindb/models.py | 6 +- bigchaindb/tendermint/lib.py | 126 ++++- bigchaindb/web/server.py | 4 +- .../generate_http_server_api_documentation.py | 2 +- .../appendices/tendermint-integration.rst | 1 + tests/commands/test_commands.py | 2 +- tests/db/test_bigchain_api.py | 14 +- tests/test_config_utils.py | 3 +- tests/test_core.py | 14 +- tests/web/test_transactions.py | 14 +- 14 files changed, 156 insertions(+), 474 deletions(-) diff --git a/bigchaindb/README.md b/bigchaindb/README.md index 59fbe77c..dbb08afb 100644 --- a/bigchaindb/README.md +++ b/bigchaindb/README.md @@ -4,9 +4,9 @@ A high-level description of the files and subdirectories of BigchainDB. ## Files -### [`core.py`](./core.py) +### [`tendermint/lib.py`](./tendermint/lib.py) -The `Bigchain` class is defined here. Most node-level operations and database interactions are found in this file. This is the place to start if you are interested in implementing a server API, since many of these class methods concern BigchainDB interacting with the outside world. +The `BigchainDB` class is defined here. Most node-level operations and database interactions are found in this file. This is the place to start if you are interested in implementing a server API, since many of these class methods concern BigchainDB interacting with the outside world. ### [`models.py`](./models.py) diff --git a/bigchaindb/__init__.py b/bigchaindb/__init__.py index 0991e511..011737fa 100644 --- a/bigchaindb/__init__.py +++ b/bigchaindb/__init__.py @@ -84,5 +84,5 @@ config = { # the user wants to reconfigure the node. Check ``bigchaindb.config_utils`` # for more info. _config = copy.deepcopy(config) -from bigchaindb.core import Bigchain # noqa +from bigchaindb.tendermint import BigchainDB # noqa from bigchaindb.version import __version__ # noqa diff --git a/bigchaindb/commands/bigchaindb.py b/bigchaindb/commands/bigchaindb.py index 72d31bce..188cb7b3 100644 --- a/bigchaindb/commands/bigchaindb.py +++ b/bigchaindb/commands/bigchaindb.py @@ -97,7 +97,7 @@ def run_configure(args): def run_upsert_validator(args): """Store validators which should be synced with Tendermint""" - b = bigchaindb.tendermint.lib.BigchainDB() + b = bigchaindb.tendermint.BigchainDB() public_key = public_key_from_base64(args.public_key) validator = {'pub_key': {'type': 'ed25519', 'data': public_key}, @@ -113,7 +113,7 @@ def run_upsert_validator(args): def _run_init(): - bdb = bigchaindb.tendermint.lib.BigchainDB() + bdb = bigchaindb.tendermint.BigchainDB() schema.init_database(connection=bdb.connection) diff --git a/bigchaindb/core.py b/bigchaindb/core.py index 14dce4fe..e69de29b 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -1,434 +0,0 @@ -from bigchaindb import exceptions as core_exceptions - -import bigchaindb - -from bigchaindb import backend, config_utils -from bigchaindb.consensus import BaseConsensusRules -from bigchaindb.models import Transaction - - -class Bigchain(object): - """Bigchain API - - Create, read, sign, write transactions to the database - """ - - BLOCK_INVALID = 'invalid' - """return if a block is invalid""" - - BLOCK_VALID = TX_VALID = 'valid' - """return if a block is valid, or tx is in valid block""" - - BLOCK_UNDECIDED = TX_UNDECIDED = 'undecided' - """return if block is undecided, or tx is in undecided block""" - - TX_IN_BACKLOG = 'backlog' - """return if transaction is in backlog""" - - def __init__(self, connection=None): - """Initialize the Bigchain instance - - A Bigchain instance has several configuration parameters (e.g. host). - If a parameter value is passed as an argument to the Bigchain - __init__ method, then that is the value it will have. - Otherwise, the parameter value will come from an environment variable. - If that environment variable isn't set, then the value - will come from the local configuration file. And if that variable - isn't in the local configuration file, then the parameter will have - its default value (defined in bigchaindb.__init__). - - Args: - connection (:class:`~bigchaindb.backend.connection.Connection`): - A connection to the database. - """ - consensusPlugin = bigchaindb.config.get('consensus_plugin') - - if consensusPlugin: - self.consensus = config_utils.load_consensus_plugin(consensusPlugin) - else: - self.consensus = BaseConsensusRules - - def delete_transaction(self, *transaction_id): - """Delete a transaction from the backlog. - - Args: - *transaction_id (str): the transaction(s) to delete - - Returns: - The database response. - """ - - return backend.query.delete_transaction(self.connection, *transaction_id) - - def get_stale_transactions(self): - """Get a cursor of stale transactions. - - Transactions are considered stale if they have been assigned a node, but are still in the - backlog after some amount of time specified in the configuration - """ - - return backend.query.get_stale_transactions(self.connection) - - def validate_transaction(self, transaction): - """Validate a transaction. - - Args: - transaction (Transaction): transaction to validate. - - Returns: - The transaction if the transaction is valid else it raises an - exception describing the reason why the transaction is invalid. - """ - - return self.consensus.validate_transaction(self, transaction) - - def is_new_transaction(self, txid, exclude_block_id=None): - """Return True if the transaction does not exist in any - VALID or UNDECIDED block. Return False otherwise. - - Args: - txid (str): Transaction ID - exclude_block_id (str): Exclude block from search - """ - block_statuses = self.get_blocks_status_containing_tx(txid) - block_statuses.pop(exclude_block_id, None) - for status in block_statuses.values(): - if status != self.BLOCK_INVALID: - return False - return True - - def get_transaction(self, txid, include_status=False): - """Get the transaction with the specified `txid` (and optionally its status) - - This query begins by looking in the bigchain table for all blocks containing - a transaction with the specified `txid`. If one of those blocks is valid, it - returns the matching transaction from that block. Else if some of those - blocks are undecided, it returns a matching transaction from one of them. If - the transaction was found in invalid blocks only, or in no blocks, then this - query looks for a matching transaction in the backlog table, and if it finds - one there, it returns that. - - Args: - txid (str): transaction id of the transaction to get - include_status (bool): also return the status of the transaction - the return value is then a tuple: (tx, status) - - Returns: - A :class:`~.models.Transaction` instance if the transaction - was found in a valid block, an undecided block, or the backlog table, - otherwise ``None``. - If :attr:`include_status` is ``True``, also returns the - transaction's status if the transaction was found. - """ - - response, tx_status = None, None - - blocks_validity_status = self.get_blocks_status_containing_tx(txid) - check_backlog = True - - if blocks_validity_status: - # Disregard invalid blocks, and return if there are no valid or undecided blocks - blocks_validity_status = { - _id: status for _id, status in blocks_validity_status.items() - if status != Bigchain.BLOCK_INVALID - } - if blocks_validity_status: - - # The transaction _was_ found in an undecided or valid block, - # so there's no need to look in the backlog table - check_backlog = False - - tx_status = self.TX_UNDECIDED - # If the transaction is in a valid or any undecided block, return it. Does not check - # if transactions in undecided blocks are consistent, but selects the valid block - # before undecided ones - for target_block_id in blocks_validity_status: - if blocks_validity_status[target_block_id] == Bigchain.BLOCK_VALID: - tx_status = self.TX_VALID - break - - # Query the transaction in the target block and return - response = backend.query.get_transaction_from_block(self.connection, txid, target_block_id) - - if check_backlog: - response = backend.query.get_transaction_from_backlog(self.connection, txid) - - if response: - tx_status = self.TX_IN_BACKLOG - - if response: - if tx_status == self.TX_IN_BACKLOG: - response = Transaction.from_dict(response) - else: - # If we are reading from the bigchain collection the asset is - # not in the transaction so we need to fetch the asset and - # reconstruct the transaction. - response = Transaction.from_db(self, response) - - if include_status: - return response, tx_status - else: - return response - - def get_status(self, txid): - """Retrieve the status of a transaction with `txid` from bigchain. - - Args: - txid (str): transaction id of the transaction to query - - Returns: - (string): transaction status ('valid', 'undecided', - or 'backlog'). If no transaction with that `txid` was found it - returns `None` - """ - _, status = self.get_transaction(txid, include_status=True) - return status - - def get_blocks_status_containing_tx(self, txid): - """Retrieve block ids and statuses related to a transaction - - Transactions may occur in multiple blocks, but no more than one valid block. - - Args: - txid (str): transaction id of the transaction to query - - Returns: - A dict of blocks containing the transaction, - e.g. {block_id_1: 'valid', block_id_2: 'invalid' ...}, or None - """ - - # First, get information on all blocks which contain this transaction - blocks = backend.query.get_blocks_status_from_transaction(self.connection, txid) - if blocks: - # Determine the election status of each block - blocks_validity_status = { - block['id']: self.block_election_status(block) - for block in blocks - } - - # NOTE: If there are multiple valid blocks with this transaction, - # something has gone wrong - if list(blocks_validity_status.values()).count(Bigchain.BLOCK_VALID) > 1: - block_ids = str([ - block for block in blocks_validity_status - if blocks_validity_status[block] == Bigchain.BLOCK_VALID - ]) - raise core_exceptions.CriticalDoubleInclusion( - 'Transaction {tx} is present in ' - 'multiple valid blocks: {block_ids}' - .format(tx=txid, block_ids=block_ids)) - - return blocks_validity_status - - else: - return None - - def get_asset_by_id(self, asset_id): - """Returns the asset associated with an asset_id. - - Args: - asset_id (str): The asset id. - - Returns: - dict if the asset exists else None. - """ - cursor = backend.query.get_asset_by_id(self.connection, asset_id) - cursor = list(cursor) - if cursor: - return cursor[0]['asset'] - - def get_spent(self, txid, output): - """Check if a `txid` was already used as an input. - - A transaction can be used as an input for another transaction. Bigchain - needs to make sure that a given `(txid, output)` is only used once. - - This method will check if the `(txid, output)` has already been - spent in a transaction that is in either the `VALID`, `UNDECIDED` or - `BACKLOG` state. - - Args: - txid (str): The id of the transaction - output (num): the index of the output in the respective transaction - - Returns: - The transaction (Transaction) that used the `(txid, output)` as an - input else `None` - - Raises: - CriticalDoubleSpend: If the given `(txid, output)` was spent in - more than one valid transaction. - """ - # checks if an input was already spent - # checks if the bigchain has any transaction with input {'txid': ..., - # 'output': ...} - transactions = list(backend.query.get_spent(self.connection, txid, - output)) - - # a transaction_id should have been spent at most one time - # determine if these valid transactions appear in more than one valid - # block - num_valid_transactions = 0 - non_invalid_transactions = [] - for transaction in transactions: - # ignore transactions in invalid blocks - # FIXME: Isn't there a faster solution than doing I/O again? - txn, status = self.get_transaction(transaction['id'], - include_status=True) - if status == self.TX_VALID: - num_valid_transactions += 1 - # `txid` can only have been spent in at most on valid block. - if num_valid_transactions > 1: - raise core_exceptions.CriticalDoubleSpend( - '`{}` was spent more than once. There is a problem' - ' with the chain'.format(txid)) - # if its not and invalid transaction - if status is not None: - transaction.update({'metadata': txn.metadata}) - non_invalid_transactions.append(transaction) - - if non_invalid_transactions: - return Transaction.from_dict(non_invalid_transactions[0]) - - # Either no transaction was returned spending the `(txid, output)` as - # input or the returned transactions are not valid. - - def get_owned_ids(self, owner): - """Retrieve a list of ``txid`` s that can be used as inputs. - - Args: - owner (str): base58 encoded public key. - - Returns: - :obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s - pointing to another transaction's condition - """ - return self.get_outputs_filtered(owner, spent=False) - - def get_outputs_filtered(self, owner, spent=None): - """Get a list of output links filtered on some criteria - - Args: - owner (str): base58 encoded public_key. - spent (bool): If ``True`` return only the spent outputs. If - ``False`` return only unspent outputs. If spent is - not specified (``None``) return all outputs. - - Returns: - :obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s - pointing to another transaction's condition - """ - outputs = self.fastquery.get_outputs_by_public_key(owner) - if spent is None: - return outputs - elif spent is True: - return self.fastquery.filter_unspent_outputs(outputs) - elif spent is False: - return self.fastquery.filter_spent_outputs(outputs) - - def get_transactions_filtered(self, asset_id, operation=None): - """Get a list of transactions filtered on some criteria - """ - txids = backend.query.get_txids_filtered(self.connection, asset_id, - operation) - for txid in txids: - tx, status = self.get_transaction(txid, True) - if status == self.TX_VALID: - yield tx - - # TODO: check that the votings structure is correctly constructed - def validate_block(self, block): - """Validate a block. - - Args: - block (Block): block to validate. - - Returns: - The block if the block is valid else it raises and exception - describing the reason why the block is invalid. - """ - return self.consensus.validate_block(self, block) - - def write_block(self, block): - """Write a block to bigchain. - - Args: - block (Block): block to write to bigchain. - """ - - # Decouple assets from block - assets, block_dict = block.decouple_assets() - metadatas, block_dict = block.decouple_metadata(block_dict) - - # write the assets - if assets: - self.write_assets(assets) - - if metadatas: - self.write_metadata(metadatas) - - # write the block - return backend.query.store_block(self.connection, block_dict) - - def get_assets(self, asset_ids): - """Return a list of assets that match the asset_ids - - Args: - asset_ids (:obj:`list` of :obj:`str`): A list of asset_ids to - retrieve from the database. - - Returns: - list: The list of assets returned from the database. - """ - return backend.query.get_assets(self.connection, asset_ids) - - def get_metadata(self, txn_ids): - """Return a list of metadata that match the transaction ids (txn_ids) - - Args: - txn_ids (:obj:`list` of :obj:`str`): A list of txn_ids to - retrieve from the database. - - Returns: - list: The list of metadata returned from the database. - """ - return backend.query.get_metadata(self.connection, txn_ids) - - def write_assets(self, assets): - """Writes a list of assets into the database. - - Args: - assets (:obj:`list` of :obj:`dict`): A list of assets to write to - the database. - """ - return backend.query.store_assets(self.connection, assets) - - def write_metadata(self, metadata): - """Writes a list of metadata into the database. - - Args: - metadata (:obj:`list` of :obj:`dict`): A list of metadata to write to - the database. - """ - return backend.query.write_metadata(self.connection, metadata) - - def text_search(self, search, *, limit=0, table='assets'): - """Return an iterator of assets that match the text search - - Args: - search (str): Text search string to query the text index - limit (int, optional): Limit the number of returned documents. - - Returns: - iter: An iterator of assets that match the text search. - """ - objects = backend.query.text_search(self.connection, search, limit=limit, - table=table) - - # TODO: This is not efficient. There may be a more efficient way to - # query by storing block ids with the assets and using fastquery. - # See https://github.com/bigchaindb/bigchaindb/issues/1496 - for obj in objects: - tx, status = self.get_transaction(obj['id'], True) - if status == self.TX_VALID: - yield obj diff --git a/bigchaindb/models.py b/bigchaindb/models.py index 8d9aae6f..33689d0c 100644 --- a/bigchaindb/models.py +++ b/bigchaindb/models.py @@ -14,7 +14,7 @@ class Transaction(Transaction): """Validate transaction spend Args: - bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. + bigchain (BigchainDB): an instantiated bigchaindb.tendermint.BigchainDB object. Returns: The transaction (Transaction) if the transaction is valid else it @@ -108,8 +108,8 @@ class Transaction(Transaction): asset from the asset table and reconstructs the transaction. Args: - bigchain (:class:`~bigchaindb.Bigchain`): An instance of Bigchain - used to perform database queries. + bigchain (:class:`~bigchaindb.tendermint.BigchainDB`): An instance + of BigchainDB used to perform database queries. tx_dict_list (:list:`dict` or :obj:`dict`): The transaction dict or list of transaction dict as returned from the database. diff --git a/bigchaindb/tendermint/lib.py b/bigchaindb/tendermint/lib.py index 7275eed6..ed7aec15 100644 --- a/bigchaindb/tendermint/lib.py +++ b/bigchaindb/tendermint/lib.py @@ -14,9 +14,9 @@ except ImportError: from sha3 import sha3_256 import requests + import bigchaindb from bigchaindb import backend, config_utils -from bigchaindb import Bigchain from bigchaindb.models import Transaction from bigchaindb.common.exceptions import (SchemaValidationError, ValidationError, @@ -24,15 +24,45 @@ from bigchaindb.common.exceptions import (SchemaValidationError, from bigchaindb.tendermint.utils import encode_transaction, merkleroot from bigchaindb.tendermint import fastquery from bigchaindb import exceptions as core_exceptions +from bigchaindb.consensus import BaseConsensusRules logger = logging.getLogger(__name__) -class BigchainDB(Bigchain): +class BigchainDB(object): + """Bigchain API - def __init__(self, connection=None, **kwargs): - super().__init__(**kwargs) + Create, read, sign, write transactions to the database + """ + BLOCK_INVALID = 'invalid' + """return if a block is invalid""" + + BLOCK_VALID = TX_VALID = 'valid' + """return if a block is valid, or tx is in valid block""" + + BLOCK_UNDECIDED = TX_UNDECIDED = 'undecided' + """return if block is undecided, or tx is in undecided block""" + + TX_IN_BACKLOG = 'backlog' + """return if transaction is in backlog""" + + def __init__(self, connection=None): + """Initialize the Bigchain instance + + A Bigchain instance has several configuration parameters (e.g. host). + If a parameter value is passed as an argument to the Bigchain + __init__ method, then that is the value it will have. + Otherwise, the parameter value will come from an environment variable. + If that environment variable isn't set, then the value + will come from the local configuration file. And if that variable + isn't in the local configuration file, then the parameter will have + its default value (defined in bigchaindb.__init__). + + Args: + connection (:class:`~bigchaindb.backend.connection.Connection`): + A connection to the database. + """ config_utils.autoconfigure() self.mode_list = ('broadcast_tx_async', 'broadcast_tx_sync', @@ -40,12 +70,20 @@ class BigchainDB(Bigchain): self.tendermint_host = bigchaindb.config['tendermint']['host'] self.tendermint_port = bigchaindb.config['tendermint']['port'] self.endpoint = 'http://{}:{}/'.format(self.tendermint_host, self.tendermint_port) + + consensusPlugin = bigchaindb.config.get('consensus_plugin') + + if consensusPlugin: + self.consensus = config_utils.load_consensus_plugin(consensusPlugin) + else: + self.consensus = BaseConsensusRules + self.connection = connection if connection else backend.connect(**bigchaindb.config['database']) def post_transaction(self, transaction, mode): """Submit a valid transaction to the mempool.""" if not mode or mode not in self.mode_list: - raise ValidationError(('Mode must be one of the following {}.') + raise ValidationError('Mode must be one of the following {}.' .format(', '.join(self.mode_list))) payload = { @@ -86,7 +124,7 @@ class BigchainDB(Bigchain): # else: # return (500, 'Error while validating the transaction') - def _process_status_code(self, status_code, failure_msg): + def process_status_code(self, status_code, failure_msg): return (202, '') if status_code == 0 else (500, failure_msg) def store_transaction(self, transaction): @@ -237,6 +275,37 @@ class BigchainDB(Bigchain): else: return transaction + def get_transactions_filtered(self, asset_id, operation=None): + """Get a list of transactions filtered on some criteria + """ + txids = backend.query.get_txids_filtered(self.connection, asset_id, + operation) + for txid in txids: + tx, status = self.get_transaction(txid, True) + if status == self.TX_VALID: + yield tx + + def get_outputs_filtered(self, owner, spent=None): + """Get a list of output links filtered on some criteria + + Args: + owner (str): base58 encoded public_key. + spent (bool): If ``True`` return only the spent outputs. If + ``False`` return only unspent outputs. If spent is + not specified (``None``) return all outputs. + + Returns: + :obj:`list` of TransactionLink: list of ``txid`` s and ``output`` s + pointing to another transaction's condition + """ + outputs = self.fastquery.get_outputs_by_public_key(owner) + if spent is None: + return outputs + elif spent is True: + return self.fastquery.filter_unspent_outputs(outputs) + elif spent is False: + return self.fastquery.filter_spent_outputs(outputs) + def get_spent(self, txid, output, current_transactions=[]): transactions = backend.query.get_spent(self.connection, txid, output) @@ -343,6 +412,51 @@ class BigchainDB(Bigchain): logger.warning('Invalid transaction (%s): %s', type(e).__name__, e) return False + def text_search(self, search, *, limit=0, table='assets'): + """Return an iterator of assets that match the text search + + Args: + search (str): Text search string to query the text index + limit (int, optional): Limit the number of returned documents. + + Returns: + iter: An iterator of assets that match the text search. + """ + objects = backend.query.text_search(self.connection, search, limit=limit, + table=table) + + # TODO: This is not efficient. There may be a more efficient way to + # query by storing block ids with the assets and using fastquery. + # See https://github.com/bigchaindb/bigchaindb/issues/1496 + for obj in objects: + tx, status = self.get_transaction(obj['id'], True) + if status == self.TX_VALID: + yield obj + + def get_assets(self, asset_ids): + """Return a list of assets that match the asset_ids + + Args: + asset_ids (:obj:`list` of :obj:`str`): A list of asset_ids to + retrieve from the database. + + Returns: + list: The list of assets returned from the database. + """ + return backend.query.get_assets(self.connection, asset_ids) + + def get_metadata(self, txn_ids): + """Return a list of metadata that match the transaction ids (txn_ids) + + Args: + txn_ids (:obj:`list` of :obj:`str`): A list of txn_ids to + retrieve from the database. + + Returns: + list: The list of metadata returned from the database. + """ + return backend.query.get_metadata(self.connection, txn_ids) + @property def fastquery(self): return fastquery.FastQuery(self.connection) diff --git a/bigchaindb/web/server.py b/bigchaindb/web/server.py index 05d378b6..646f6f17 100644 --- a/bigchaindb/web/server.py +++ b/bigchaindb/web/server.py @@ -11,7 +11,7 @@ from flask_cors import CORS import gunicorn.app.base from bigchaindb import utils -from bigchaindb import Bigchain +from bigchaindb.tendermint import BigchainDB from bigchaindb.web.routes import add_routes from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware @@ -67,7 +67,7 @@ def create_app(*, debug=False, threads=1, bigchaindb_factory=None): """ if not bigchaindb_factory: - bigchaindb_factory = Bigchain + bigchaindb_factory = BigchainDB app = Flask(__name__) app.wsgi_app = StripContentTypeMiddleware(app.wsgi_app) diff --git a/docs/server/generate_http_server_api_documentation.py b/docs/server/generate_http_server_api_documentation.py index 69bcd699..2256c355 100644 --- a/docs/server/generate_http_server_api_documentation.py +++ b/docs/server/generate_http_server_api_documentation.py @@ -5,7 +5,7 @@ import os import os.path from bigchaindb.common.transaction import Transaction, Input, TransactionLink -from bigchaindb.core import Bigchain +from bigchaindb.tendermint import BigchainDB from bigchaindb.tendermint import lib from bigchaindb.web import server diff --git a/docs/server/source/appendices/tendermint-integration.rst b/docs/server/source/appendices/tendermint-integration.rst index 175cbe80..bc800400 100644 --- a/docs/server/source/appendices/tendermint-integration.rst +++ b/docs/server/source/appendices/tendermint-integration.rst @@ -8,6 +8,7 @@ Tendermint Integration .. automodule:: bigchaindb.tendermint.lib :special-members: __init__ + :noindex: .. automodule:: bigchaindb.tendermint.core :special-members: __init__ diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index a81a6938..17403e8c 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -90,7 +90,7 @@ def test_bigchain_run_init_when_db_exists(mocker, capsys): def test__run_init(mocker): from bigchaindb.commands.bigchaindb import _run_init bigchain_mock = mocker.patch( - 'bigchaindb.commands.bigchaindb.bigchaindb.tendermint.lib.BigchainDB') + 'bigchaindb.commands.bigchaindb.bigchaindb.tendermint.BigchainDB') init_db_mock = mocker.patch( 'bigchaindb.commands.bigchaindb.schema.init_database', autospec=True, diff --git a/tests/db/test_bigchain_api.py b/tests/db/test_bigchain_api.py index b6c8a2ad..c285401a 100644 --- a/tests/db/test_bigchain_api.py +++ b/tests/db/test_bigchain_api.py @@ -280,7 +280,7 @@ class TestBigchainApi(object): @pytest.mark.usefixtures('inputs') def test_write_transaction(self, b, user_pk, user_sk): - from bigchaindb import Bigchain + from bigchaindb.tendermint import BigchainDB from bigchaindb.models import Transaction input_tx = b.get_owned_ids(user_pk).pop() @@ -294,7 +294,7 @@ class TestBigchainApi(object): tx_from_db, status = b.get_transaction(tx.id, include_status=True) assert tx_from_db.to_dict() == tx.to_dict() - assert status == Bigchain.TX_IN_BACKLOG + assert status == BigchainDB.TX_IN_BACKLOG @pytest.mark.usefixtures('inputs') def test_read_transaction(self, b, user_pk, user_sk): @@ -439,7 +439,7 @@ class TestBigchainApi(object): from bigchaindb.common.exceptions import InputDoesNotExist from bigchaindb.common.transaction import Input, TransactionLink from bigchaindb.models import Transaction - from bigchaindb import Bigchain + from bigchaindb.tendermint import BigchainDB # Create an input for a non existing transaction input = Input(Ed25519Sha256(public_key=b58decode(user_pk)), @@ -449,7 +449,7 @@ class TestBigchainApi(object): asset_id='mock_asset_link') with pytest.raises(InputDoesNotExist): - tx.validate(Bigchain()) + tx.validate(BigchainDB()) def test_count_backlog(self, b, user_pk, alice): from bigchaindb.backend import query @@ -970,9 +970,9 @@ class TestMultipleInputs(object): def test_get_owned_ids_calls_get_outputs_filtered(): - from bigchaindb.core import Bigchain - with patch('bigchaindb.core.Bigchain.get_outputs_filtered') as gof: - b = Bigchain() + from bigchaindb.tendermint import BigchainDB + with patch('bigchaindb.tendermint.BigchainDB.get_outputs_filtered') as gof: + b = BigchainDB() res = b.get_owned_ids('abc') gof.assert_called_once_with('abc', spent=False) assert res == gof() diff --git a/tests/test_config_utils.py b/tests/test_config_utils.py index a96e1405..30dcfd60 100644 --- a/tests/test_config_utils.py +++ b/tests/test_config_utils.py @@ -35,6 +35,7 @@ def test_bigchain_instance_raises_when_not_configured(request, monkeypatch): import bigchaindb from bigchaindb import config_utils from bigchaindb.common import exceptions + from bigchaindb.tendermint import BigchainDB assert 'CONFIGURED' not in bigchaindb.config # We need to disable ``bigchaindb.config_utils.autoconfigure`` to avoid reading @@ -42,7 +43,7 @@ def test_bigchain_instance_raises_when_not_configured(request, monkeypatch): monkeypatch.setattr(config_utils, 'autoconfigure', lambda: 0) with pytest.raises(exceptions.ConfigurationError): - bigchaindb.Bigchain() + BigchainDB() def test_load_consensus_plugin_loads_default_rules_without_name(): diff --git a/tests/test_core.py b/tests/test_core.py index b563c385..9f6150e6 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -26,10 +26,10 @@ def config(request, monkeypatch): def test_bigchain_class_default_initialization(config): - from bigchaindb.core import Bigchain + from bigchaindb.tendermint import BigchainDB from bigchaindb.consensus import BaseConsensusRules from bigchaindb.backend.connection import Connection - bigchain = Bigchain() + bigchain = BigchainDB() assert isinstance(bigchain.connection, Connection) assert bigchain.connection.host == config['database']['host'] assert bigchain.connection.port == config['database']['port'] @@ -38,7 +38,7 @@ def test_bigchain_class_default_initialization(config): def test_bigchain_class_initialization_with_parameters(config): - from bigchaindb.core import Bigchain + from bigchaindb.tendermint import BigchainDB from bigchaindb.backend import connect from bigchaindb.consensus import BaseConsensusRules init_db_kwargs = { @@ -48,7 +48,7 @@ def test_bigchain_class_initialization_with_parameters(config): 'name': 'this_is_the_db_name', } connection = connect(**init_db_kwargs) - bigchain = Bigchain(connection=connection, **init_db_kwargs) + bigchain = BigchainDB(connection=connection, **init_db_kwargs) assert bigchain.connection == connection assert bigchain.connection.host == init_db_kwargs['host'] assert bigchain.connection.port == init_db_kwargs['port'] @@ -58,13 +58,13 @@ def test_bigchain_class_initialization_with_parameters(config): def test_get_blocks_status_containing_tx(monkeypatch): from bigchaindb.backend import query as backend_query - from bigchaindb.core import Bigchain + from bigchaindb.tendermint import BigchainDB blocks = [ {'id': 1}, {'id': 2} ] monkeypatch.setattr(backend_query, 'get_blocks_status_from_transaction', lambda x: blocks) - monkeypatch.setattr(Bigchain, 'block_election_status', lambda x, y, z: Bigchain.BLOCK_VALID) - bigchain = Bigchain(public_key='pubkey', private_key='privkey') + monkeypatch.setattr(BigchainDB, 'block_election_status', lambda x, y, z: BigchainDB.BLOCK_VALID) + bigchain = BigchainDB(public_key='pubkey', private_key='privkey') with pytest.raises(Exception): bigchain.get_blocks_status_containing_tx('txid') diff --git a/tests/web/test_transactions.py b/tests/web/test_transactions.py index c81a9db8..7c52ea94 100644 --- a/tests/web/test_transactions.py +++ b/tests/web/test_transactions.py @@ -372,7 +372,7 @@ def test_transactions_get_list_good(client): asset_id = '1' * 64 - with patch('bigchaindb.core.Bigchain.get_transactions_filtered', get_txs_patched): + with patch('bigchaindb.tendermint.BigchainDB.get_transactions_filtered', get_txs_patched): url = TX_ENDPOINT + '?asset_id=' + asset_id assert client.get(url).json == [ ['asset_id', asset_id], @@ -389,7 +389,7 @@ def test_transactions_get_list_good(client): def test_transactions_get_list_bad(client): def should_not_be_called(): assert False - with patch('bigchaindb.core.Bigchain.get_transactions_filtered', + with patch('bigchaindb.tendermint.BigchainDB.get_transactions_filtered', lambda *_, **__: should_not_be_called()): # Test asset id validated url = TX_ENDPOINT + '?asset_id=' + '1' * 63 @@ -404,7 +404,7 @@ def test_transactions_get_list_bad(client): @pytest.mark.tendermint def test_return_only_valid_transaction(client): - from bigchaindb import Bigchain + from bigchaindb.tendermint import BigchainDB def get_transaction_patched(status): def inner(self, tx_id, include_status): @@ -415,13 +415,13 @@ def test_return_only_valid_transaction(client): # UNDECIDED or VALID block, as well as transactions from the backlog. # As the endpoint uses `get_transaction`, we don't have to test # against invalid transactions here. - with patch('bigchaindb.core.Bigchain.get_transaction', - get_transaction_patched(Bigchain.TX_UNDECIDED)): + with patch('bigchaindb.tendermint.BigchainDB.get_transaction', + get_transaction_patched(BigchainDB.TX_UNDECIDED)): url = '{}{}'.format(TX_ENDPOINT, '123') assert client.get(url).status_code == 404 - with patch('bigchaindb.core.Bigchain.get_transaction', - get_transaction_patched(Bigchain.TX_IN_BACKLOG)): + with patch('bigchaindb.tendermint.BigchainDB.get_transaction', + get_transaction_patched(BigchainDB.TX_IN_BACKLOG)): url = '{}{}'.format(TX_ENDPOINT, '123') assert client.get(url).status_code == 404