diff --git a/bigchaindb/backend/localmongodb/query.py b/bigchaindb/backend/localmongodb/query.py index b7b21d8d..e6fe11ab 100644 --- a/bigchaindb/backend/localmongodb/query.py +++ b/bigchaindb/backend/localmongodb/query.py @@ -4,7 +4,6 @@ from pymongo import DESCENDING from bigchaindb import backend from bigchaindb.backend.exceptions import DuplicateKeyError -from bigchaindb.common.exceptions import MultipleValidatorOperationError from bigchaindb.backend.utils import module_dispatch_registrar from bigchaindb.backend.localmongodb.connection import LocalMongoDBConnection from bigchaindb.common.transaction import Transaction @@ -111,7 +110,8 @@ def get_spent(conn, transaction_id, output): def get_latest_block(conn): return conn.run( conn.collection('blocks') - .find_one(sort=[('height', DESCENDING)])) + .find_one(projection={'_id': False}, + sort=[('height', DESCENDING)])) @register_query(LocalMongoDBConnection) @@ -281,9 +281,9 @@ def get_pre_commit_state(conn, commit_id): def store_validator_set(conn, validators_update): height = validators_update['height'] return conn.run( - conn.collection('validators').update_one( - {"height": height}, - {"$set": validators_update}, + conn.collection('validators').replace_one( + {'height': height}, + validators_update, upsert=True ) ) diff --git a/bigchaindb/core.py b/bigchaindb/core.py index bfcc97e9..08d3888a 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -136,8 +136,11 @@ class App(BaseApplication): # TODO: calculate if an election has concluded # NOTE: ensure the local validator set is updated validator_updates = self.bigchaindb.get_validator_update(self.block_transactions) - validator_set = new_validator_set(self.bigchaindb, self.new_height, validator_updates) - self.bigchaindb.store_validator_set(self.new_height+1, validator_set) + + if validator_updates: + validator_set = new_validator_set(self.bigchaindb, self.new_height, validator_updates) + self.bigchaindb.store_validator_set(self.new_height+1, validator_set) + validator_updates = [encode_validator(v) for v in validator_updates] # Store pre-commit state to recover in case there is a crash @@ -197,7 +200,7 @@ def new_validator_set(bigchain, height, updates): updates_dict = {} for u in updates: updates_dict[u['public_key']] = {'pub_key': {'type': 'ed25519', - 'data': public_key_to_base64(u['public_key']) }, + 'data': public_key_to_base64(u['public_key'])}, 'voting_power': u['power']} new_validators_dict = {**validators_dict, **updates_dict} return list(new_validators_dict.values()) diff --git a/tests/tendermint/test_integration.py b/tests/tendermint/test_integration.py index d7de519f..35fe5074 100644 --- a/tests/tendermint/test_integration.py +++ b/tests/tendermint/test_integration.py @@ -7,7 +7,6 @@ import pytest from abci.server import ProtocolHandler from abci.encoding import read_messages -from copy import deepcopy from io import BytesIO diff --git a/tests/upsert_validator/test_validator_election_vote.py b/tests/upsert_validator/test_validator_election_vote.py index ad77784f..185107db 100644 --- a/tests/upsert_validator/test_validator_election_vote.py +++ b/tests/upsert_validator/test_validator_election_vote.py @@ -218,25 +218,19 @@ def test_get_validator_update(b_mock, valid_election, ed25519_node_keys): @pytest.mark.abci def test_upsert_validator(b, node_key, node_keys, new_validator, ed25519_node_keys): - from bigchaindb.backend import connect from bigchaindb.tendermint_utils import public_key_to_base64 import time import requests - conn = connect() (node_pub, _) = list(node_keys.items())[0] validators = [{'pub_key': {'type': 'ed25519', 'data': node_pub}, 'voting_power': 10}] + latest_block = b.get_latest_block() # reset the validator set - conn.run( - conn.collection('validators').find_one_and_update( - {"height": 1}, - {"$set": {"validators": validators}} - ) - ) + b.store_validator_set(latest_block['height'], validators) power = 1 public_key = '9B3119650DF82B9A5D8A12E38953EA47475C09F0C48A4E6A0ECE182944B24403'