Problem: Public key not encoded using type in validator set update

Solution: Use `value` field to use appropriate decoder and re-encode public key in base16
This commit is contained in:
Vanshdeep Singh 2018-09-05 15:07:30 +02:00
parent bda1fb7708
commit 0a7eeaaf26
5 changed files with 36 additions and 11 deletions

View File

@ -115,4 +115,4 @@ class InvalidPowerChange(ValidationError):
class InvalidPublicKey(ValidationError):
"""Raised if proposed power change in validator set is >=1/3 total power"""
"""Raised if public key doesn't match the encoding type"""

View File

@ -33,6 +33,10 @@ properties:
type: string
type:
type: string
enum:
- ed25519-base16
- ed25519-base32
- ed25519-base64
power:
"$ref": "#/definitions/positiveInteger"
required:

View File

@ -21,6 +21,7 @@ from bigchaindb.common.schema import (_validate_schema,
from . import ValidatorElectionVote
from .validator_utils import (new_validator_set,
encode_validator,
encode_pk_to_base16,
validate_asset_public_key)
@ -239,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):

View File

@ -31,7 +31,8 @@ def new_validator_set(validators, updates):
updates_dict = {}
for u in updates:
public_key64 = public_key_to_base64(u['public_key']['value'])
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']}
@ -40,7 +41,28 @@ def new_validator_set(validators, updates):
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):
pk_binary = pk['value'].encode('utf-8')
encoding = pk['type']
decoder = base64.b64decode
@ -51,11 +73,7 @@ def validate_asset_public_key(pk):
decoder = base64.b32decode
elif encoding == 'ed25519-base64':
decoder = base64.b64decode
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:
else:
raise InvalidPublicKey('Invalid `type` specified for public key `value`')
return decoder

View File

@ -429,7 +429,6 @@ def test_upsert_validator_new_election_invalid_power(caplog, b, priv_validator_p
assert caplog.records[0].msg.__class__ == InvalidPowerChange
@pytest.mark.google
@pytest.mark.abci
def test_upsert_validator_approve_with_tendermint(b, priv_validator_path, user_sk, validators):
from bigchaindb.commands.bigchaindb import (run_upsert_validator_new,