From 41b35bb725d85b99059d9becc7ce77b9eb935aed Mon Sep 17 00:00:00 2001 From: Ahmed Muawia Khan Date: Thu, 13 Sep 2018 11:37:19 +0200 Subject: [PATCH] Problem: No way to check Tendermint comptability with BigchainDB server --- bigchaindb/commands/bigchaindb.py | 13 +++++++++++++ bigchaindb/core.py | 13 +++++++++++++ bigchaindb/utils.py | 23 ++++++++++++++++++++++- bigchaindb/version.py | 2 ++ tests/commands/test_commands.py | 16 ++++++++++++++++ tests/tendermint/test_core.py | 3 ++- tests/tendermint/test_integration.py | 4 +++- 7 files changed, 71 insertions(+), 3 deletions(-) diff --git a/bigchaindb/commands/bigchaindb.py b/bigchaindb/commands/bigchaindb.py index 082b2753..322ae9c1 100644 --- a/bigchaindb/commands/bigchaindb.py +++ b/bigchaindb/commands/bigchaindb.py @@ -29,6 +29,7 @@ from bigchaindb.commands.utils import (configure_bigchaindb, from bigchaindb.log import setup_logging from bigchaindb.tendermint_utils import public_key_from_base64 from bigchaindb.commands.election_types import elections +from bigchaindb.version import __tm_supported_versions__ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -279,6 +280,15 @@ def run_start(args): from bigchaindb.start import start start() +def run_tendermint_version(args): + """Show the supported Tendermint version(s)""" + supported_tm_ver = { + "description": "BigchainDB supports the following Tendermint version(s)", + "tendermint": [], + } + [supported_tm_ver["tendermint"].append(ver) for ver in __tm_supported_versions__] + print(json.dumps(supported_tm_ver, indent=4, sort_keys=True)) + def create_parser(): parser = argparse.ArgumentParser( @@ -360,6 +370,9 @@ def create_parser(): action='store_true', help='Skip database initialization') + subparsers.add_parser('tendermint-version', + help='Show the Tendermint supported versions') + return parser diff --git a/bigchaindb/core.py b/bigchaindb/core.py index 62bc6ec3..9424b909 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -20,6 +20,8 @@ from abci.types_pb2 import ( ) from bigchaindb import BigchainDB +from bigchaindb.version import __tm_supported_versions__ +from bigchaindb.utils import check_tendermint_version from bigchaindb.tendermint_utils import (decode_transaction, calculate_hash) from bigchaindb.lib import Block, PreCommitState @@ -113,6 +115,17 @@ class App(BaseApplication): self.abort_if_abci_chain_is_not_synced() + # Check if BigchainDB supports the Tendermint version + try: + if check_tendermint_version(request.version): + logger.info(f"Tendermint version: {request.version}") + else: + logger.error(f"Error: Tendermint version {request.version} not supported." + f" Currently, BigchainDB only supports {__tm_supported_versions__} .Exiting!") + sys.exit(1) + except AttributeError: + logger.debug("Skipping Tendermint version check.") + r = ResponseInfo() block = self.bigchaindb.get_latest_block() if block: diff --git a/bigchaindb/utils.py b/bigchaindb/utils.py index 78777133..dad41ac2 100644 --- a/bigchaindb/utils.py +++ b/bigchaindb/utils.py @@ -9,7 +9,8 @@ import multiprocessing as mp import json import setproctitle - +from packaging import version +from bigchaindb.version import __tm_supported_versions__ from bigchaindb.tendermint_utils import key_from_base64 from bigchaindb.common.crypto import key_pair_from_ed25519_key @@ -185,3 +186,23 @@ def load_node_key(path): priv_key = priv_validator['priv_key']['value'] hex_private_key = key_from_base64(priv_key) return key_pair_from_ed25519_key(hex_private_key) + + +def check_tendermint_version(running_tm_ver): + """ + Check Tendermint compatability with BigchainDB server + + :param running_tm_ver: Version number of the connected Tendermint instance + :type running_tm_ver: str + :return: True/False depending on the compatability with BigchainDB server + :rtype: bool + """ + tm_ver = running_tm_ver.split('-') + if len(tm_ver) >= 1: + for ver in __tm_supported_versions__: + if version.parse(ver) == version.parse(tm_ver[0]): + return True + else: + return False + else: + return False \ No newline at end of file diff --git a/bigchaindb/version.py b/bigchaindb/version.py index 3120eea1..277f5645 100644 --- a/bigchaindb/version.py +++ b/bigchaindb/version.py @@ -4,3 +4,5 @@ __version__ = '2.0.0b5' __short_version__ = '2.0b5' +# supported Tendermint version +__tm_supported_versions__ = ["0.22.8"] diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index a9cb9d6a..09643706 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -30,6 +30,7 @@ def test_make_sure_we_dont_remove_any_command(): assert parser.parse_args(['election', 'approve', 'ELECTION_ID', '--private-key', 'TEMP_PATH_TO_PRIVATE_KEY']).command assert parser.parse_args(['election', 'show', 'ELECTION_ID']).command + assert parser.parse_args(['tendermint-version']).command @patch('bigchaindb.commands.utils.start') @@ -226,6 +227,9 @@ def test_calling_main(start_mock, monkeypatch): subparsers.add_parser.assert_any_call('drop', help='Drop the database') subparsers.add_parser.assert_any_call('start', help='Start BigchainDB') + subparsers.add_parser.assert_any_call('tendermint-version', + help='Show the Tendermint supported ' + 'versions') assert start_mock.called is True @@ -468,6 +472,18 @@ def test_election_approve_called_with_bad_key(caplog, b, bad_validator_path, new 'the eligible voters in this election.' +def test_bigchain_tendermint_version(capsys): + from bigchaindb.commands.bigchaindb import run_tendermint_version + + args = Namespace(config=None) + _, _ = capsys.readouterr() + run_tendermint_version(args) + output_config = json.loads(capsys.readouterr()[0]) + from bigchaindb.version import __tm_supported_versions__ + assert len(output_config["tendermint"]) == len(__tm_supported_versions__) + assert sorted(output_config["tendermint"]) == sorted(__tm_supported_versions__) + + def mock_get_validators(height): keys = node_keys() pub_key = list(keys.keys())[0] diff --git a/tests/tendermint/test_core.py b/tests/tendermint/test_core.py index 31b4e100..cfa5cd39 100644 --- a/tests/tendermint/test_core.py +++ b/tests/tendermint/test_core.py @@ -26,6 +26,7 @@ from bigchaindb.core import (CodeTypeOk, from bigchaindb.lib import Block from bigchaindb.upsert_validator.validator_utils import new_validator_set from bigchaindb.tendermint_utils import public_key_to_base64 +from bigchaindb.version import __tm_supported_versions__ pytestmark = pytest.mark.bdb @@ -168,7 +169,7 @@ def test_init_chain_recognizes_new_chain_after_migration(b): def test_info(b): - r = RequestInfo() + r = RequestInfo(version=__tm_supported_versions__[0]) app = App(b) res = app.info(r) diff --git a/tests/tendermint/test_integration.py b/tests/tendermint/test_integration.py index 490da16b..d16c34ad 100644 --- a/tests/tendermint/test_integration.py +++ b/tests/tendermint/test_integration.py @@ -11,6 +11,7 @@ import pytest from abci.server import ProtocolHandler from abci.encoding import read_messages +from bigchaindb.version import __tm_supported_versions__ from io import BytesIO @@ -24,7 +25,8 @@ def test_app(b, init_chain_request): app = App(b) p = ProtocolHandler(app) - data = p.process('info', types.Request(info=types.RequestInfo(version='2'))) + data = p.process('info', + types.Request(info=types.RequestInfo(version=__tm_supported_versions__[0]))) res = next(read_messages(BytesIO(data), types.Response)) assert res assert res.info.last_block_app_hash == b''