diff --git a/bigchaindb/upsert_validator/validator_election.py b/bigchaindb/upsert_validator/validator_election.py index 3c909b06..a1fd6996 100644 --- a/bigchaindb/upsert_validator/validator_election.py +++ b/bigchaindb/upsert_validator/validator_election.py @@ -73,6 +73,8 @@ class ValidatorElection(Transaction): def validate(self, bigchain, current_transactions=[]): """Validate election transaction + For more details refer BEP-21: https://github.com/bigchaindb/BEPs/tree/master/21 + NOTE: * A valid election is initiated by an existing validator. @@ -80,15 +82,13 @@ class ValidatorElection(Transaction): alloacted according to the voting power of each validator node. Args: - bigchain (BigchainDB): an instantiated bigchaindb.tendermint.BigchainDB object. + bigchain (BigchainDB): an instantiated bigchaindb.lib.BigchainDB object. Returns: - The transaction (Transaction) if the transaction is valid else it - raises an exception describing the reason why the transaction is - invalid. + `True` if the election is valid Raises: - ValidationError: If the transaction is invalid + ValidationError: If the election is invalid """ input_conditions = [] @@ -103,7 +103,7 @@ class ValidatorElection(Transaction): current_validators = self.current_validators(bigchain) # NOTE: Proposer should be a single node - if len(self.inputs) != 1: + if len(self.inputs) != 1 or len(self.inputs[0].owners_before) != 1: raise MultipleInputsError('`tx_signers` must be a list instance of length one') # NOTE: change more than 1/3 of the current power is not allowed diff --git a/tests/upsert_validator/test_validator_election.py b/tests/upsert_validator/test_validator_election.py index e4a84868..e67b3e8d 100644 --- a/tests/upsert_validator/test_validator_election.py +++ b/tests/upsert_validator/test_validator_election.py @@ -3,6 +3,8 @@ import pytest from bigchaindb.upsert_validator import ValidatorElection from bigchaindb.common.exceptions import (DuplicateTransaction, UnequalValidatorSet, + InvalidProposer, + MultipleInputsError, InvalidPowerChange) pytestmark = [pytest.mark.tendermint, pytest.mark.bdb] @@ -27,6 +29,30 @@ def test_upsert_validator_invalid_power_election(b_mock, new_validator, node_key election.validate(b_mock) +def test_upsert_validator_invalid_proposed_election(b_mock, new_validator, node_key): + from bigchaindb.common.crypto import generate_key_pair + + alice = generate_key_pair() + voters = ValidatorElection.recipients(b_mock) + election = ValidatorElection.generate([alice.public_key], + voters, + new_validator, None).sign([alice.private_key]) + with pytest.raises(InvalidProposer): + election.validate(b_mock) + + +def test_upsert_validator_invalid_inputs_election(b_mock, new_validator, node_key): + from bigchaindb.common.crypto import generate_key_pair + + alice = generate_key_pair() + voters = ValidatorElection.recipients(b_mock) + election = ValidatorElection.generate([node_key.public_key, alice.public_key], + voters, + new_validator, None).sign([node_key.private_key, alice.private_key]) + with pytest.raises(MultipleInputsError): + election.validate(b_mock) + + def test_upsert_validator_invalid_election(b_mock, new_validator, node_key): voters = ValidatorElection.recipients(b_mock) valid_election = ValidatorElection.generate([node_key.public_key],