From bee9468bd0b698f85bbb105fc7bb4f36508bf897 Mon Sep 17 00:00:00 2001 From: Zachary Bowen Date: Wed, 5 Sep 2018 10:51:32 +0200 Subject: [PATCH 1/6] Problem: `test_make_sure_we_dont_remove_any_command` does not check for `upsert-validator show` (#2499). Solution: Extend the test. --- tests/commands/test_commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 7b2f8e28..8c1325a9 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(): '--private-key', 'TEMP_PATH_TO_PRIVATE_KEY']).command assert parser.parse_args(['upsert-validator', 'approve', 'ELECTION_ID', '--private-key', 'TEMP_PATH_TO_PRIVATE_KEY']).command + assert parser.parse_args(['upsert-validator', 'show', 'ELECTION_ID']).command @pytest.mark.tendermint From f6bee3b63e910272e096ff4ded69cf0efdac763b Mon Sep 17 00:00:00 2001 From: vrde Date: Wed, 5 Sep 2018 16:04:37 +0200 Subject: [PATCH 2/6] Problem: default config is slow (#2516) Solution: update the suggested `config.toml` file to increase the allowed network speed, and avoid rechecking transactions. --- .../network-setup.md | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/docs/server/source/simple-deployment-template/network-setup.md b/docs/server/source/simple-deployment-template/network-setup.md index f42ca9ef..6b8057ef 100644 --- a/docs/server/source/simple-deployment-template/network-setup.md +++ b/docs/server/source/simple-deployment-template/network-setup.md @@ -8,7 +8,7 @@ Code is Apache-2.0 and docs are CC-BY-4.0 Note 1: These instructions will also work for a "network" with only one node. -Note 2: You might not need to set up your own network yet. You should start by creating a proof-of-concept app that writes to [the BigchainDB Testnet](https://testnet.bigchaindb.com/), and if that goes well, then you can look into setting up your own network. +Note 2: You might not need to set up your own network yet. You should start by creating a proof-of-concept app that writes to [the BigchainDB Testnet](https://testnet.bigchaindb.com/), and if that goes well, then you can look into setting up your own network. Note 3: If you want to set up a node or network so that you can contribute to developing and testing the BigchainDB code, then see [the docs about contributing to BigchainDB](https://docs.bigchaindb.com/projects/contributing/en/latest/index.html). @@ -169,51 +169,51 @@ Share the `node_id`, `pub_key.value` and hostname of your Node with all other Me At this point the Coordinator should have received the data from all the Members, and should combine them in the `.tendermint/config/genesis.json` file: ```json -{ +{ "genesis_time":"0001-01-01T00:00:00Z", "chain_id":"test-chain-la6HSr", - "consensus_params":{ - "block_size_params":{ + "consensus_params":{ + "block_size_params":{ "max_bytes":"22020096", "max_txs":"10000", "max_gas":"-1" }, - "tx_size_params":{ + "tx_size_params":{ "max_bytes":"10240", "max_gas":"-1" }, - "block_gossip_params":{ + "block_gossip_params":{ "block_part_size_bytes":"65536" }, - "evidence_params":{ + "evidence_params":{ "max_age":"100000" } }, - "validators":[ - { - "pub_key":{ + "validators":[ + { + "pub_key":{ "type":"AC26791624DE60", "value":"" }, "power":10, "name":"" }, - { - "pub_key":{ + { + "pub_key":{ "type":"AC26791624DE60", "value":"" }, "power":10, "name":"" }, - { - "...":{ + { + "...":{ }, }, - { - "pub_key":{ + { + "pub_key":{ "type":"AC26791624DE60", "value":"" }, @@ -242,14 +242,18 @@ The Member must copy the `genesis.json` file in the local `.tendermint/config` d The Member must edit the `.tendermint/config/config.toml` file and make the following changes: ``` -... - +moniker = "Name of our node" create_empty_blocks = false -... +log_level = "main:info,state:info,*:error" persistent_peers = "@:26656,\ @:26656,\ @:26656," + +send_rate = 102400000 +recv_rate = 102400000 + +recheck = false ``` ## Member: Start MongoDB From 9bf09324df1c63b7fbef0b24830deb5bd80b4dae Mon Sep 17 00:00:00 2001 From: Lev Berman Date: Wed, 5 Sep 2018 17:18:17 +0200 Subject: [PATCH 3/6] Problem: Txs posted in async/sync can be lost. (#2514) Solution: Document when the transactions posted in the async and sync modes can be lost. Describe how they are stored. Mention that BigchainDB does not store or expose rejected transactions. --- docs/server/source/http-client-server-api.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/server/source/http-client-server-api.rst b/docs/server/source/http-client-server-api.rst index 0f47acb5..eadfe983 100644 --- a/docs/server/source/http-client-server-api.rst +++ b/docs/server/source/http-client-server-api.rst @@ -154,7 +154,15 @@ Transactions is in a committed block. .. note:: - + In the async and sync modes, after a successful HTTP response is returned, the transaction may still be rejected later on. All the transactions are recorded internally by Tendermint in WAL (Write-Ahead Log) before the HTTP response is returned. Nevertheless, the following should be noted: + + - Transactions in WAL including the failed ones are not exposed in any of the BigchainDB or Tendermint APIs. + - Transactions are never fetched from WAL. WAL is never replayed. + - A critical failure (e.g. the system is out of disk space) may occur preventing transactions from being stored in WAL, even when the HTTP response indicates a success. + - If a transaction fails the validation because it conflicts with the other transactions of the same block, Tendermint includes it into its block, but BigchainDB does not store these transactions and does not offer any information about them in the APIs. + + .. note:: + The posted transaction should be valid. The relevant `BigchainDB Transactions Spec `_ From 2656302c600f664f94b23b3e6896db0ff6f5d09d Mon Sep 17 00:00:00 2001 From: Vanshdeep Singh Date: Thu, 6 Sep 2018 11:27:52 +0200 Subject: [PATCH 4/6] Problem: Bigchaindb crashes when restarted after init chain (#2519) Solution: Return appropirate height so that Tendermint doesn't execute init_chain more than once --- bigchaindb/core.py | 13 +++++++------ tests/tendermint/test_integration.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/bigchaindb/core.py b/bigchaindb/core.py index a0983472..075525bc 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -232,12 +232,13 @@ class App(BaseApplication): # register a new block only when new transactions are received if self.block_txn_ids: self.bigchaindb.store_bulk_transactions(self.block_transactions) - block = Block(app_hash=self.block_txn_hash, - height=self.new_height, - transactions=self.block_txn_ids) - # NOTE: storing the block should be the last operation during commit - # this effects crash recovery. Refer BEP#8 for details - self.bigchaindb.store_block(block._asdict()) + + block = Block(app_hash=self.block_txn_hash, + height=self.new_height, + transactions=self.block_txn_ids) + # NOTE: storing the block should be the last operation during commit + # this effects crash recovery. Refer BEP#8 for details + self.bigchaindb.store_block(block._asdict()) logger.debug('Commit-ing new block with hash: apphash=%s ,' 'height=%s, txn ids=%s', data, self.new_height, diff --git a/tests/tendermint/test_integration.py b/tests/tendermint/test_integration.py index 683404bc..b860abdf 100644 --- a/tests/tendermint/test_integration.py +++ b/tests/tendermint/test_integration.py @@ -101,7 +101,7 @@ def test_app(b, init_chain_request): block0 = b.get_latest_block() assert block0 - assert block0['height'] == 1 + assert block0['height'] == 2 # when empty block is generated hash of previous block should be returned assert block0['app_hash'] == new_block_hash From 699494613ffeeaa343e9c59d37f48995718c2621 Mon Sep 17 00:00:00 2001 From: Lev Berman Date: Thu, 6 Sep 2018 15:49:00 +0200 Subject: [PATCH 5/6] Problem: The commit mode behaves incorrectly. (#2510) * Problem: The commit mode behaves incorrectly. Solution: Parse the Tendermint response properly. The functionality was disabled in https://github.com/bigchaindb/bigchaindb/pull/2235/files#diff-c6511560546a7dc577e7e647b5bfdaceL68 and was not fixed since then. * Add a test case for the sync mode. * Do not strictly expect deliver_tx in the response. * Fix post_mock in web/test_transactions.py. * Check for the error field first. --- bigchaindb/lib.py | 39 ++++++++++++---------------- tests/tendermint/test_integration.py | 19 +++++++------- tests/web/test_transactions.py | 6 +++++ 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/bigchaindb/lib.py b/bigchaindb/lib.py index 017151db..fae4c76a 100644 --- a/bigchaindb/lib.py +++ b/bigchaindb/lib.py @@ -56,9 +56,10 @@ class BigchainDB(object): A connection to the database. """ config_utils.autoconfigure() + self.mode_commit = 'broadcast_tx_commit' self.mode_list = ('broadcast_tx_async', 'broadcast_tx_sync', - 'broadcast_tx_commit') + self.mode_commit) self.tendermint_host = bigchaindb.config['tendermint']['host'] self.tendermint_port = bigchaindb.config['tendermint']['port'] self.endpoint = 'http://{}:{}/'.format(self.tendermint_host, self.tendermint_port) @@ -96,29 +97,23 @@ class BigchainDB(object): def _process_post_response(self, response, mode): logger.debug(response) - if response.get('error') is not None: - return (500, 'Internal error') + + error = response.get('error') + if error: + return (500, error) + + result = response['result'] + if mode == self.mode_commit: + check_tx_code = result.get('check_tx', {}).get('code', 0) + deliver_tx_code = result.get('deliver_tx', {}).get('code', 0) + error_code = check_tx_code or deliver_tx_code + else: + error_code = result.get('code', 0) + + if error_code: + return (500, 'Transaction validation failed') return (202, '') - # result = response['result'] - # if mode == self.mode_list[2]: - # return self._process_commit_mode_response(result) - # else: - # status_code = result['code'] - # return self._process_status_code(status_code, - # 'Error while processing transaction') - - # def _process_commit_mode_response(self, result): - # check_tx_status_code = result['check_tx']['code'] - # if check_tx_status_code == 0: - # deliver_tx_status_code = result['deliver_tx']['code'] - # return self._process_status_code(deliver_tx_status_code, - # 'Error while commiting the transaction') - # else: - # return (500, 'Error while validating the transaction') - - def process_status_code(self, status_code, failure_msg): - return (202, '') if status_code == 0 else (500, failure_msg) def store_bulk_transactions(self, transactions): txns = [] diff --git a/tests/tendermint/test_integration.py b/tests/tendermint/test_integration.py index b860abdf..d3f01612 100644 --- a/tests/tendermint/test_integration.py +++ b/tests/tendermint/test_integration.py @@ -130,12 +130,13 @@ def test_post_transaction_responses(tendermint_ws_url, b): code, message = b.write_transaction(tx_transfer, 'broadcast_tx_commit') assert code == 202 - # NOTE: DOESN'T WORK (double spend) - # Tendermint crashes with error: Unexpected result type - # carly = generate_key_pair() - # double_spend = Transaction.transfer(tx.to_inputs(), - # [([carly.public_key], 1)], - # asset_id=tx.id)\ - # .sign([alice.private_key]) - # code, message = b.write_transaction(double_spend, 'broadcast_tx_commit') - # assert code == 500 + carly = generate_key_pair() + double_spend = Transaction.transfer( + tx.to_inputs(), + [([carly.public_key], 1)], + asset_id=tx.id, + ).sign([alice.private_key]) + for mode in ('broadcast_tx_sync', 'broadcast_tx_commit'): + code, message = b.write_transaction(double_spend, mode) + assert code == 500 + assert message == 'Transaction validation failed' diff --git a/tests/web/test_transactions.py b/tests/web/test_transactions.py index 7c7f2b7a..97386da0 100644 --- a/tests/web/test_transactions.py +++ b/tests/web/test_transactions.py @@ -416,6 +416,12 @@ def test_transactions_get_list_bad(client): def test_post_transaction_valid_modes(mock_post, client, mode): from bigchaindb.models import Transaction from bigchaindb.common.crypto import generate_key_pair + + def _mock_post(*args, **kwargs): + return Mock(json=Mock(return_value={'result': {'code': 0}})) + + mock_post.side_effect = _mock_post + alice = generate_key_pair() tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], From cbfbfa8fc4886f5d13872c508d8c18e596fb5d7b Mon Sep 17 00:00:00 2001 From: Vanshdeep Singh Date: Thu, 6 Sep 2018 16:06:36 +0200 Subject: [PATCH 6/6] Problem: Public key format not standardized (#2508) Solution: Add 'type' field to public key so that it can be decoded properly --- bigchaindb/commands/bigchaindb.py | 5 +- bigchaindb/common/exceptions.py | 4 ++ .../transaction_validator_election_v2.0.yaml | 15 ++++- .../upsert_validator/validator_election.py | 13 ++++- .../upsert_validator/validator_utils.py | 56 ++++++++++++++++--- tests/commands/test_commands.py | 7 ++- tests/conftest.py | 8 +-- tests/tendermint/test_core.py | 14 +++-- tests/tendermint/test_integration.py | 2 +- tests/upsert_validator/conftest.py | 2 +- .../test_validator_election.py | 15 ++++- .../test_validator_election_vote.py | 17 +++--- 12 files changed, 119 insertions(+), 39 deletions(-) diff --git a/bigchaindb/commands/bigchaindb.py b/bigchaindb/commands/bigchaindb.py index 19cb0e2d..5f23953b 100644 --- a/bigchaindb/commands/bigchaindb.py +++ b/bigchaindb/commands/bigchaindb.py @@ -124,7 +124,8 @@ def run_upsert_validator_new(args, bigchain): """ new_validator = { - 'public_key': public_key_from_base64(args.public_key), + 'public_key': {'value': public_key_from_base64(args.public_key), + 'type': 'ed25519-base16'}, 'power': args.power, 'node_id': args.node_id } @@ -207,7 +208,7 @@ def run_upsert_validator_show(args, bigchain): new_validator = election.asset['data'] - public_key = public_key_to_base64(new_validator['public_key']) + public_key = public_key_to_base64(new_validator['public_key']['value']) power = new_validator['power'] node_id = new_validator['node_id'] status = election.get_status(bigchain) diff --git a/bigchaindb/common/exceptions.py b/bigchaindb/common/exceptions.py index adaff5c6..099ef92e 100644 --- a/bigchaindb/common/exceptions.py +++ b/bigchaindb/common/exceptions.py @@ -112,3 +112,7 @@ class UnequalValidatorSet(ValidationError): class InvalidPowerChange(ValidationError): """Raised if proposed power change in validator set is >=1/3 total power""" + + +class InvalidPublicKey(ValidationError): + """Raised if public key doesn't match the encoding type""" diff --git a/bigchaindb/common/schema/transaction_validator_election_v2.0.yaml b/bigchaindb/common/schema/transaction_validator_election_v2.0.yaml index 2c93886c..d849d516 100644 --- a/bigchaindb/common/schema/transaction_validator_election_v2.0.yaml +++ b/bigchaindb/common/schema/transaction_validator_election_v2.0.yaml @@ -23,7 +23,20 @@ properties: node_id: type: string public_key: - type: string + type: object + additionalProperties: false + required: + - value + - type + properties: + value: + type: string + type: + type: string + enum: + - ed25519-base16 + - ed25519-base32 + - ed25519-base64 power: "$ref": "#/definitions/positiveInteger" required: diff --git a/bigchaindb/upsert_validator/validator_election.py b/bigchaindb/upsert_validator/validator_election.py index d7e63cf2..0b36c268 100644 --- a/bigchaindb/upsert_validator/validator_election.py +++ b/bigchaindb/upsert_validator/validator_election.py @@ -19,7 +19,10 @@ from bigchaindb.common.schema import (_validate_schema, TX_SCHEMA_COMMON, TX_SCHEMA_CREATE) from . import ValidatorElectionVote -from .validator_utils import (new_validator_set, encode_validator) +from .validator_utils import (new_validator_set, + encode_validator, + encode_pk_to_base16, + validate_asset_public_key) class ValidatorElection(Transaction): @@ -58,7 +61,7 @@ class ValidatorElection(Transaction): validators = {} for validator in bigchain.get_validators(height): # NOTE: we assume that Tendermint encodes public key in base64 - public_key = public_key_from_ed25519_key(key_from_base64(validator['pub_key']['data'])) + public_key = public_key_from_ed25519_key(key_from_base64(validator['public_key']['value'])) validators[public_key] = validator['voting_power'] return validators @@ -155,6 +158,7 @@ class ValidatorElection(Transaction): _validate_schema(TX_SCHEMA_COMMON, tx) _validate_schema(TX_SCHEMA_CREATE, tx) _validate_schema(TX_SCHEMA_VALIDATOR_ELECTION, tx) + validate_asset_public_key(tx['asset']['data']['public_key']) @classmethod def create(cls, tx_signers, recipients, metadata=None, asset=None): @@ -236,7 +240,10 @@ class ValidatorElection(Transaction): updated_validator_set = [v for v in updated_validator_set if v['voting_power'] > 0] bigchain.store_validator_set(new_height+1, updated_validator_set, election.id) - return [encode_validator(election.asset['data'])] + + validator16 = encode_pk_to_base16(election.asset['data']) + return [encode_validator(validator16)] + return [] def get_validator_update_by_election_id(self, election_id, bigchain): diff --git a/bigchaindb/upsert_validator/validator_utils.py b/bigchaindb/upsert_validator/validator_utils.py index 75c7baf5..b0f8a81e 100644 --- a/bigchaindb/upsert_validator/validator_utils.py +++ b/bigchaindb/upsert_validator/validator_utils.py @@ -1,12 +1,14 @@ import codecs +import base64 +import binascii from abci.types_pb2 import (Validator, PubKey) -from bigchaindb.tendermint_utils import public_key_to_base64 +from bigchaindb.common.exceptions import InvalidPublicKey def encode_validator(v): - ed25519_public_key = v['public_key'] + ed25519_public_key = v['public_key']['value'] # NOTE: tendermint expects public to be encoded in go-amino format pub_key = PubKey(type='ed25519', data=bytes.fromhex(ed25519_public_key)) @@ -16,22 +18,60 @@ def encode_validator(v): def decode_validator(v): - return {'pub_key': {'type': v.pub_key.type, - 'data': codecs.encode(v.pub_key.data, 'base64').decode().rstrip('\n')}, + return {'public_key': {'type': 'ed25519-base64', + 'value': codecs.encode(v.pub_key.data, 'base64').decode().rstrip('\n')}, 'voting_power': v.power} def new_validator_set(validators, updates): validators_dict = {} for v in validators: - validators_dict[v['pub_key']['data']] = v + validators_dict[v['public_key']['value']] = v updates_dict = {} for u in updates: - public_key64 = public_key_to_base64(u['public_key']) - updates_dict[public_key64] = {'pub_key': {'type': 'ed25519', - 'data': public_key64}, + decoder = get_public_key_decoder(u['public_key']) + public_key64 = base64.b64encode(decoder(u['public_key']['value'])).decode('utf-8') + updates_dict[public_key64] = {'public_key': {'type': 'ed25519-base64', + 'value': public_key64}, 'voting_power': u['power']} new_validators_dict = {**validators_dict, **updates_dict} return list(new_validators_dict.values()) + + +def encode_pk_to_base16(validator): + pk = validator['public_key'] + decoder = get_public_key_decoder(pk) + public_key16 = base64.b16encode(decoder(pk['value'])).decode('utf-8') + + validator['public_key']['value'] = public_key16 + return validator + + +def validate_asset_public_key(pk): + pk_binary = pk['value'].encode('utf-8') + decoder = get_public_key_decoder(pk) + try: + pk_decoded = decoder(pk_binary) + if len(pk_decoded) != 32: + raise InvalidPublicKey('Public key should be of size 32 bytes') + + except binascii.Error as e: + raise InvalidPublicKey('Invalid `type` specified for public key `value`') + + +def get_public_key_decoder(pk): + encoding = pk['type'] + decoder = base64.b64decode + + if encoding == 'ed25519-base16': + decoder = base64.b16decode + elif encoding == 'ed25519-base32': + decoder = base64.b32decode + elif encoding == 'ed25519-base64': + decoder = base64.b64decode + else: + raise InvalidPublicKey('Invalid `type` specified for public key `value`') + + return decoder diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 8c1325a9..5a5d2deb 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -353,7 +353,7 @@ def test_upsert_validator_new_with_tendermint(b, priv_validator_path, user_sk, v from bigchaindb.commands.bigchaindb import run_upsert_validator_new new_args = Namespace(action='new', - public_key='8eJ8q9ZQpReWyQT5aFCiwtZ5wDZC4eDnCen88p3tQ6ie', + public_key='HHG0IQRybpT6nJMIWWFWhMczCLHt6xcm7eP52GnGuPY=', power=1, node_id='unique_node_id_for_test_upsert_validator_new_with_tendermint', sk=priv_validator_path, @@ -444,6 +444,7 @@ def test_upsert_validator_approve_with_tendermint(b, priv_validator_path, user_s config={}) election_id = run_upsert_validator_new(new_args, b) + assert election_id args = Namespace(action='approve', election_id=election_id, @@ -524,8 +525,8 @@ def mock_get_validators(height): keys = node_keys() pub_key = list(keys.keys())[0] return [ - {'pub_key': {'data': pub_key, - 'type': 'tendermint/PubKeyEd25519'}, + {'public_key': {'value': pub_key, + 'type': 'ed25519-base64'}, 'voting_power': 10} ] diff --git a/tests/conftest.py b/tests/conftest.py index 12cd65e3..9ef51e21 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -649,9 +649,8 @@ def validators(b, node_keys): (public_key, private_key) = list(node_keys.items())[0] validator_set = [{'address': 'F5426F0980E36E03044F74DD414248D29ABCBDB2', - 'pub_key': { - 'data': public_key, - 'type': 'ed25519'}, + 'public_key': {'value': public_key, + 'type': 'ed25519-base64'}, 'voting_power': 10}] validator_update = {'validators': validator_set, @@ -687,6 +686,7 @@ def new_validator(): power = 1 node_id = 'fake_node_id' - return {'public_key': public_key, + return {'public_key': {'value': public_key, + 'type': 'ed25519-base16'}, 'power': power, 'node_id': node_id} diff --git a/tests/tendermint/test_core.py b/tests/tendermint/test_core.py index 64ee2887..c98ee1ea 100644 --- a/tests/tendermint/test_core.py +++ b/tests/tendermint/test_core.py @@ -415,12 +415,14 @@ def test_store_pre_commit_state_in_end_block(b, alice, init_chain_request): def test_new_validator_set(b): - node1 = {'pub_key': {'type': 'ed25519', - 'data': 'FxjS2/8AFYoIUqF6AcePTc87qOT7e4WGgH+sGCpTUDQ='}, + node1 = {'public_key': {'type': 'ed25519-base64', + 'value': 'FxjS2/8AFYoIUqF6AcePTc87qOT7e4WGgH+sGCpTUDQ='}, 'voting_power': 10} - node1_new_power = {'public_key': '1718D2DBFF00158A0852A17A01C78F4DCF3BA8E4FB7B8586807FAC182A535034', + node1_new_power = {'public_key': {'value': '1718D2DBFF00158A0852A17A01C78F4DCF3BA8E4FB7B8586807FAC182A535034', + 'type': 'ed25519-base16'}, 'power': 20} - node2 = {'public_key': '1888A353B181715CA2554701D06C1665BC42C5D936C55EA9C5DBCBDB8B3F02A3', + node2 = {'public_key': {'value': '1888A353B181715CA2554701D06C1665BC42C5D936C55EA9C5DBCBDB8B3F02A3', + 'type': 'ed25519-base16'}, 'power': 10} validators = [node1] @@ -430,8 +432,8 @@ def test_new_validator_set(b): updated_validators = [] for u in updates: - updated_validators.append({'pub_key': {'type': 'ed25519', - 'data': public_key_to_base64(u['public_key'])}, + updated_validators.append({'public_key': {'type': 'ed25519-base64', + 'value': public_key_to_base64(u['public_key']['value'])}, 'voting_power': u['power']}) assert updated_validator_set == updated_validators diff --git a/tests/tendermint/test_integration.py b/tests/tendermint/test_integration.py index d3f01612..e91c2be4 100644 --- a/tests/tendermint/test_integration.py +++ b/tests/tendermint/test_integration.py @@ -40,7 +40,7 @@ def test_app(b, init_chain_request): pk = codecs.encode(init_chain_request.validators[0].pub_key.data, 'base64').decode().strip('\n') [validator] = b.get_validators(height=1) - assert validator['pub_key']['data'] == pk + assert validator['public_key']['value'] == pk assert validator['voting_power'] == 10 alice = generate_key_pair() diff --git a/tests/upsert_validator/conftest.py b/tests/upsert_validator/conftest.py index 20906ada..c9bb4870 100644 --- a/tests/upsert_validator/conftest.py +++ b/tests/upsert_validator/conftest.py @@ -22,7 +22,7 @@ def mock_get_validators(network_validators): validators = [] for public_key, power in network_validators.items(): validators.append({ - 'pub_key': {'type': 'AC26791624DE60', 'data': public_key}, + 'public_key': {'type': 'ed25519-base64', 'value': public_key}, 'voting_power': power }) return validators diff --git a/tests/upsert_validator/test_validator_election.py b/tests/upsert_validator/test_validator_election.py index d09d6403..4c3849e4 100644 --- a/tests/upsert_validator/test_validator_election.py +++ b/tests/upsert_validator/test_validator_election.py @@ -24,6 +24,19 @@ def test_upsert_validator_valid_election(b_mock, new_validator, node_key): assert election.validate(b_mock) +def test_upsert_validator_invalid_election_public_key(b_mock, new_validator, node_key): + from bigchaindb.common.exceptions import InvalidPublicKey + + for iv in ['ed25519-base32', 'ed25519-base64']: + new_validator['public_key']['type'] = iv + voters = ValidatorElection.recipients(b_mock) + + with pytest.raises(InvalidPublicKey): + ValidatorElection.generate([node_key.public_key], + voters, + new_validator, None).sign([node_key.private_key]) + + def test_upsert_validator_invalid_power_election(b_mock, new_validator, node_key): voters = ValidatorElection.recipients(b_mock) new_validator['power'] = 30 @@ -147,7 +160,7 @@ def test_upsert_validator_show(caplog, ongoing_election, b): from bigchaindb.commands.bigchaindb import run_upsert_validator_show election_id = ongoing_election.id - public_key = public_key_to_base64(ongoing_election.asset['data']['public_key']) + public_key = public_key_to_base64(ongoing_election.asset['data']['public_key']['value']) power = ongoing_election.asset['data']['power'] node_id = ongoing_election.asset['data']['node_id'] status = ValidatorElection.ONGOING diff --git a/tests/upsert_validator/test_validator_election_vote.py b/tests/upsert_validator/test_validator_election_vote.py index 6c92af99..4504977a 100644 --- a/tests/upsert_validator/test_validator_election_vote.py +++ b/tests/upsert_validator/test_validator_election_vote.py @@ -228,8 +228,7 @@ def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys): (node_pub, _) = list(node_keys.items())[0] - validators = [{'pub_key': {'type': 'ed25519', - 'data': node_pub}, + validators = [{'public_key': {'type': 'ed25519-base64', 'value': node_pub}, 'voting_power': 10}] latest_block = b.get_latest_block() @@ -239,7 +238,7 @@ def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys): power = 1 public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403' public_key64 = public_key_to_base64(public_key) - new_validator = {'public_key': public_key, + new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base16'}, 'node_id': 'some_node_id', 'power': power} @@ -268,7 +267,7 @@ def test_upsert_validator(b, node_key, node_keys, ed25519_node_keys): new_validator_set = b.get_validators() validator_pub_keys = [] for v in new_validator_set: - validator_pub_keys.append(v['pub_key']['data']) + validator_pub_keys.append(v['public_key']['value']) assert (public_key64 in validator_pub_keys) @@ -281,7 +280,7 @@ def test_get_validator_update(b, node_keys, node_key, ed25519_node_keys): power = 1 public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403' public_key64 = public_key_to_base64(public_key) - new_validator = {'public_key': public_key, + new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base16'}, 'node_id': 'some_node_id', 'power': power} voters = ValidatorElection.recipients(b) @@ -316,7 +315,7 @@ def test_get_validator_update(b, node_keys, node_key, ed25519_node_keys): # remove validator power = 0 - new_validator = {'public_key': public_key, + new_validator = {'public_key': {'value': public_key, 'type': 'ed25519-base16'}, 'node_id': 'some_node_id', 'power': power} voters = ValidatorElection.recipients(b) @@ -339,7 +338,7 @@ def test_get_validator_update(b, node_keys, node_key, ed25519_node_keys): # assert that the public key is not a part of the current validator set for v in b.get_validators(10): - assert not v['pub_key']['data'] == public_key64 + assert not v['public_key']['value'] == public_key64 # ============================================================================ @@ -365,7 +364,7 @@ def gen_vote(election, i, ed25519_node_keys): def reset_validator_set(b, node_keys, height): validators = [] for (node_pub, _) in node_keys.items(): - validators.append({'pub_key': {'type': 'ed25519', - 'data': node_pub}, + validators.append({'public_key': {'type': 'ed25519-base64', + 'value': node_pub}, 'voting_power': 10}) b.store_validator_set(height, validators, 'election_id')