Problem: Upsert validator not migrated to Tendermint 0.19.0 (#2252)

* Problem: Upsert validator not migrated to Tendermint 0.19.0

Solution: Migrate the same to Tendermint 0.19.0

* Problem: There are no tests for public key encoding/decoding

Solution: Add necessary tests
This commit is contained in:
Vanshdeep Singh 2018-05-02 16:21:28 +02:00 committed by Ahmed Muawia Khan
parent fd48abebae
commit 920d69b0c4
6 changed files with 66 additions and 12 deletions

View File

@ -21,7 +21,7 @@ from bigchaindb.commands.utils import (
configure_bigchaindb, start_logging_process, input_on_stderr)
from bigchaindb.backend.query import VALIDATOR_UPDATE_ID, PRE_COMMIT_ID
from bigchaindb.tendermint.lib import BigchainDB
from bigchaindb.tendermint.utils import public_key_from_base64
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@ -100,8 +100,9 @@ def run_upsert_validator(args):
"""Store validators which should be synced with Tendermint"""
b = bigchaindb.Bigchain()
public_key = public_key_from_base64(args.public_key)
validator = {'pub_key': {'type': 'ed25519',
'data': args.public_key},
'data': public_key},
'power': args.power}
validator_update = {'validator': validator,
'update_id': VALIDATOR_UPDATE_ID}

View File

@ -6,7 +6,9 @@ from abci.application import BaseApplication, Result
from abci.types_pb2 import ResponseEndBlock, ResponseInfo, Validator
from bigchaindb.tendermint import BigchainDB
from bigchaindb.tendermint.utils import decode_transaction, calculate_hash
from bigchaindb.tendermint.utils import (decode_transaction,
calculate_hash,
amino_encoded_public_key)
from bigchaindb.tendermint.lib import Block, PreCommitState
from bigchaindb.backend.query import PRE_COMMIT_ID
@ -148,9 +150,8 @@ class App(BaseApplication):
def encode_validator(v):
pub_key = v['pub_key']['data']
# NOTE: tendermint expects public to be encoded in go-wire format
# so `01` has to be appended
pub_key = bytes.fromhex('01{}'.format(pub_key))
ed25519_public_key = v['pub_key']['data']
# NOTE: tendermint expects public to be encoded in go-amino format
pub_key = amino_encoded_public_key(ed25519_public_key)
return Validator(pub_key=pub_key,
power=v['power'])

View File

@ -1,4 +1,5 @@
import base64
import hashlib
import json
from binascii import hexlify
@ -65,3 +66,23 @@ def merkleroot(hashes):
for i in range(0, len(hashes)-1, 2)
]
return merkleroot(parent_hashes)
def public_key64_to_address(base64_public_key):
"""Note this only compatibile with Tendermint 0.19.0 """
ed25519_public_key = public_key_from_base64(base64_public_key)
encoded_public_key = amino_encoded_public_key(ed25519_public_key)
return hashlib.new('ripemd160', encoded_public_key).hexdigest().upper()
def public_key_from_base64(base64_public_key):
return base64.b64decode(base64_public_key).hex().upper()
def public_key_to_base64(ed25519_public_key):
ed25519_public_key = bytes.fromhex(ed25519_public_key)
return base64.b64encode(ed25519_public_key).decode('utf-8')
def amino_encoded_public_key(ed25519_public_key):
return bytes.fromhex('1624DE6220{}'.format(ed25519_public_key))

View File

@ -346,7 +346,8 @@ class MockResponse():
def test_upsert_validator(mock_autoconfigure, mock_store_validator_update):
from bigchaindb.commands.bigchaindb import run_upsert_validator
args = Namespace(public_key='BOB_PUBLIC_KEY', power='10', config={})
args = Namespace(public_key='CJxdItf4lz2PwEf4SmYNAu/c/VpmX39JEgC5YpH7fxg=',
power='10', config={})
run_upsert_validator(args)
assert mock_store_validator_update.called

View File

@ -99,17 +99,19 @@ def test_app(tb):
assert block0['app_hash'] == new_block_hash
@pytest.mark.skip(reason='Not working with Tendermint 0.19.0')
@pytest.mark.abci
def test_upsert_validator(b, alice):
from bigchaindb.backend.query import VALIDATOR_UPDATE_ID
from bigchaindb.backend import query, connect
from bigchaindb.models import Transaction
from bigchaindb.tendermint.utils import public_key_to_base64
import time
conn = connect()
public_key = '1718D2DBFF00158A0852A17A01C78F4DCF3BA8E4FB7B8586807FAC182A535034'
power = 1
validator = {'pub_key': {'type': 'ed25519',
validator = {'pub_key': {'type': 'AC26791624DE60',
'data': public_key},
'power': power}
validator_update = {'validator': validator,
@ -124,11 +126,13 @@ def test_upsert_validator(b, alice):
code, message = b.write_transaction(tx, 'broadcast_tx_commit')
assert code == 202
time.sleep(5)
validators = b.get_validators()
validators = [(v['pub_key']['data'], v['voting_power']) for v in validators]
validators = [(v['pub_key']['value'], v['voting_power']) for v in validators]
assert ((public_key, power) in validators)
public_key64 = public_key_to_base64(public_key)
assert ((public_key64, power) in validators)
@pytest.mark.abci

View File

@ -42,3 +42,29 @@ def test_merkleroot():
hashes = [sha3_256(i.encode()).digest() for i in 'abc']
assert merkleroot(hashes) == (
'78c7c394d3158c218916b7ae0ebdea502e0f4e85c08e3b371e3dfd824d389fa3')
SAMPLE_PUBLIC_KEY = {
"address": "53DC09497A6ED73B342C78AB1E916076A03A8B95",
"pub_key": {
"type": "AC26791624DE60",
"value": "7S+T/do70jvneAq0M1so2X3M1iWTSuwtuSAr3nVpfEw="
}
}
def test_convert_base64_public_key_to_address():
from bigchaindb.tendermint.utils import public_key64_to_address
address = public_key64_to_address(SAMPLE_PUBLIC_KEY['pub_key']['value'])
assert address == SAMPLE_PUBLIC_KEY['address']
def test_public_key_encoding_decoding():
from bigchaindb.tendermint.utils import (public_key_from_base64,
public_key_to_base64)
public_key = public_key_from_base64(SAMPLE_PUBLIC_KEY['pub_key']['value'])
base64_public_key = public_key_to_base64(public_key)
assert base64_public_key == SAMPLE_PUBLIC_KEY['pub_key']['value']