Problem: No way to check Tendermint comptability with BigchainDB server

This commit is contained in:
Ahmed Muawia Khan 2018-09-13 11:37:19 +02:00
parent 35e35ecd57
commit 41b35bb725
7 changed files with 71 additions and 3 deletions

View File

@ -29,6 +29,7 @@ from bigchaindb.commands.utils import (configure_bigchaindb,
from bigchaindb.log import setup_logging from bigchaindb.log import setup_logging
from bigchaindb.tendermint_utils import public_key_from_base64 from bigchaindb.tendermint_utils import public_key_from_base64
from bigchaindb.commands.election_types import elections from bigchaindb.commands.election_types import elections
from bigchaindb.version import __tm_supported_versions__
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -279,6 +280,15 @@ def run_start(args):
from bigchaindb.start import start from bigchaindb.start import start
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(): def create_parser():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
@ -360,6 +370,9 @@ def create_parser():
action='store_true', action='store_true',
help='Skip database initialization') help='Skip database initialization')
subparsers.add_parser('tendermint-version',
help='Show the Tendermint supported versions')
return parser return parser

View File

@ -20,6 +20,8 @@ from abci.types_pb2 import (
) )
from bigchaindb import BigchainDB 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, from bigchaindb.tendermint_utils import (decode_transaction,
calculate_hash) calculate_hash)
from bigchaindb.lib import Block, PreCommitState from bigchaindb.lib import Block, PreCommitState
@ -113,6 +115,17 @@ class App(BaseApplication):
self.abort_if_abci_chain_is_not_synced() 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() r = ResponseInfo()
block = self.bigchaindb.get_latest_block() block = self.bigchaindb.get_latest_block()
if block: if block:

View File

@ -9,7 +9,8 @@ import multiprocessing as mp
import json import json
import setproctitle import setproctitle
from packaging import version
from bigchaindb.version import __tm_supported_versions__
from bigchaindb.tendermint_utils import key_from_base64 from bigchaindb.tendermint_utils import key_from_base64
from bigchaindb.common.crypto import key_pair_from_ed25519_key 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'] priv_key = priv_validator['priv_key']['value']
hex_private_key = key_from_base64(priv_key) hex_private_key = key_from_base64(priv_key)
return key_pair_from_ed25519_key(hex_private_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

View File

@ -4,3 +4,5 @@
__version__ = '2.0.0b5' __version__ = '2.0.0b5'
__short_version__ = '2.0b5' __short_version__ = '2.0b5'
# supported Tendermint version
__tm_supported_versions__ = ["0.22.8"]

View File

@ -30,6 +30,7 @@ def test_make_sure_we_dont_remove_any_command():
assert parser.parse_args(['election', 'approve', 'ELECTION_ID', '--private-key', assert parser.parse_args(['election', 'approve', 'ELECTION_ID', '--private-key',
'TEMP_PATH_TO_PRIVATE_KEY']).command 'TEMP_PATH_TO_PRIVATE_KEY']).command
assert parser.parse_args(['election', 'show', 'ELECTION_ID']).command assert parser.parse_args(['election', 'show', 'ELECTION_ID']).command
assert parser.parse_args(['tendermint-version']).command
@patch('bigchaindb.commands.utils.start') @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('drop', help='Drop the database')
subparsers.add_parser.assert_any_call('start', help='Start BigchainDB') 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 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.' '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): def mock_get_validators(height):
keys = node_keys() keys = node_keys()
pub_key = list(keys.keys())[0] pub_key = list(keys.keys())[0]

View File

@ -26,6 +26,7 @@ from bigchaindb.core import (CodeTypeOk,
from bigchaindb.lib import Block from bigchaindb.lib import Block
from bigchaindb.upsert_validator.validator_utils import new_validator_set from bigchaindb.upsert_validator.validator_utils import new_validator_set
from bigchaindb.tendermint_utils import public_key_to_base64 from bigchaindb.tendermint_utils import public_key_to_base64
from bigchaindb.version import __tm_supported_versions__
pytestmark = pytest.mark.bdb pytestmark = pytest.mark.bdb
@ -168,7 +169,7 @@ def test_init_chain_recognizes_new_chain_after_migration(b):
def test_info(b): def test_info(b):
r = RequestInfo() r = RequestInfo(version=__tm_supported_versions__[0])
app = App(b) app = App(b)
res = app.info(r) res = app.info(r)

View File

@ -11,6 +11,7 @@ import pytest
from abci.server import ProtocolHandler from abci.server import ProtocolHandler
from abci.encoding import read_messages from abci.encoding import read_messages
from bigchaindb.version import __tm_supported_versions__
from io import BytesIO from io import BytesIO
@ -24,7 +25,8 @@ def test_app(b, init_chain_request):
app = App(b) app = App(b)
p = ProtocolHandler(app) 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)) res = next(read_messages(BytesIO(data), types.Response))
assert res assert res
assert res.info.last_block_app_hash == b'' assert res.info.last_block_app_hash == b''