From 8dda02dc0e7598137916477fe902c7d5f041ae19 Mon Sep 17 00:00:00 2001 From: Vanshdeep Singh Date: Mon, 3 Sep 2018 15:49:31 +0200 Subject: [PATCH] Problem: Public key format not standardized Solution: Add 'type' field to public key so that it can be decoded properly --- bigchaindb/commands/bigchaindb.py | 5 +++-- .../transaction_validator_election_v2.0.yaml | 11 ++++++++++- bigchaindb/upsert_validator/validator_election.py | 2 +- bigchaindb/upsert_validator/validator_utils.py | 12 ++++++------ tests/commands/test_commands.py | 4 ++-- tests/conftest.py | 3 ++- tests/tendermint/test_core.py | 14 ++++++++------ tests/tendermint/test_integration.py | 2 +- tests/upsert_validator/conftest.py | 2 +- tests/upsert_validator/test_validator_election.py | 2 +- .../test_validator_election_vote.py | 10 +++++----- 11 files changed, 40 insertions(+), 27 deletions(-) diff --git a/bigchaindb/commands/bigchaindb.py b/bigchaindb/commands/bigchaindb.py index 19cb0e2d..9f2cd7ad 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-base58'}, '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/schema/transaction_validator_election_v2.0.yaml b/bigchaindb/common/schema/transaction_validator_election_v2.0.yaml index 2c93886c..9041a991 100644 --- a/bigchaindb/common/schema/transaction_validator_election_v2.0.yaml +++ b/bigchaindb/common/schema/transaction_validator_election_v2.0.yaml @@ -23,7 +23,16 @@ properties: node_id: type: string public_key: - type: string + type: object + additionalProperties: false + required: + - value + - type + properties: + value: + type: string + type: + type: string power: "$ref": "#/definitions/positiveInteger" required: diff --git a/bigchaindb/upsert_validator/validator_election.py b/bigchaindb/upsert_validator/validator_election.py index 7d9a6fbc..2ed6ec53 100644 --- a/bigchaindb/upsert_validator/validator_election.py +++ b/bigchaindb/upsert_validator/validator_election.py @@ -64,7 +64,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['pub_key']['value'])) validators[public_key] = validator['voting_power'] return validators diff --git a/bigchaindb/upsert_validator/validator_utils.py b/bigchaindb/upsert_validator/validator_utils.py index 75c7baf5..7797cc5b 100644 --- a/bigchaindb/upsert_validator/validator_utils.py +++ b/bigchaindb/upsert_validator/validator_utils.py @@ -6,7 +6,7 @@ from bigchaindb.tendermint_utils import public_key_to_base64 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)) @@ -17,20 +17,20 @@ 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')}, + '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['pub_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}, + public_key64 = public_key_to_base64(u['public_key']['value']) + updates_dict[public_key64] = {'pub_key': {'type': 'ed25519-base64', + 'value': public_key64}, 'voting_power': u['power']} new_validators_dict = {**validators_dict, **updates_dict} diff --git a/tests/commands/test_commands.py b/tests/commands/test_commands.py index 7b2f8e28..0d617023 100644 --- a/tests/commands/test_commands.py +++ b/tests/commands/test_commands.py @@ -523,8 +523,8 @@ def mock_get_validators(height): keys = node_keys() pub_key = list(keys.keys())[0] return [ - {'pub_key': {'data': pub_key, - 'type': 'tendermint/PubKeyEd25519'}, + {'pub_key': {'value': pub_key, + 'type': 'ed25519-base64'}, 'voting_power': 10} ] diff --git a/tests/conftest.py b/tests/conftest.py index 7faa66c6..185b735e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -681,6 +681,7 @@ def new_validator(): power = 1 node_id = 'fake_node_id' - return {'public_key': public_key, + return {'public_key': {'value': public_key, + 'type': 'ed25519-base58'}, 'power': power, 'node_id': node_id} diff --git a/tests/tendermint/test_core.py b/tests/tendermint/test_core.py index 40958aa2..715d9d27 100644 --- a/tests/tendermint/test_core.py +++ b/tests/tendermint/test_core.py @@ -227,12 +227,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 = {'pub_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-base58'}, 'power': 20} - node2 = {'public_key': '1888A353B181715CA2554701D06C1665BC42C5D936C55EA9C5DBCBDB8B3F02A3', + node2 = {'public_key': {'value': '1888A353B181715CA2554701D06C1665BC42C5D936C55EA9C5DBCBDB8B3F02A3', + 'type': 'ed25519-base58'}, 'power': 10} validators = [node1] @@ -242,8 +244,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({'pub_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 683404bc..0836dd51 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['pub_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..8e1830c6 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}, + 'pub_key': {'type': 'AC26791624DE60', '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..596c245f 100644 --- a/tests/upsert_validator/test_validator_election.py +++ b/tests/upsert_validator/test_validator_election.py @@ -147,7 +147,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..9b55e28e 100644 --- a/tests/upsert_validator/test_validator_election_vote.py +++ b/tests/upsert_validator/test_validator_election_vote.py @@ -239,7 +239,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-base58'}, 'node_id': 'some_node_id', 'power': power} @@ -281,7 +281,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-base58'}, 'node_id': 'some_node_id', 'power': power} voters = ValidatorElection.recipients(b) @@ -316,7 +316,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-base58'}, 'node_id': 'some_node_id', 'power': power} voters = ValidatorElection.recipients(b) @@ -339,7 +339,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['pub_key']['value'] == public_key64 # ============================================================================ @@ -366,6 +366,6 @@ 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}, + 'value': node_pub}, 'voting_power': 10}) b.store_validator_set(height, validators, 'election_id')