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.

        * A valid election is one where voters are validators and votes are
          alloacted according to the voting power of each validator node.

        Args:
            bigchain (BigchainDB): an instantiated bigchaindb.lib.BigchainDB object.

        Returns:
            ValidatorElection object

        Raises:
            ValidationError: If the election is invalid
        """
        input_conditions = []

        duplicates = any(txn for txn in current_transactions
                         if txn.id == self.id)
        if bigchain.get_transaction(self.id) or duplicates:
            raise DuplicateTransaction(
                'transaction `{}` already exists'.format(self.id))

        if not self.inputs_valid(input_conditions):
            raise InvalidSignature('Transaction signature is invalid.')

        current_validators = self.get_validators(bigchain)

        # NOTE: Proposer should be a single node
        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
        if self.asset['data']['power'] >= (1 / 3) * sum(
                current_validators.values()):
            raise InvalidPowerChange(
                '`power` change must be less than 1/3 of total power')

        # NOTE: Check if the proposer is a validator.
        [election_initiator_node_pub_key] = self.inputs[0].owners_before
        if election_initiator_node_pub_key not in current_validators.keys():
            raise InvalidProposer(
                'Public key is not a part of the validator set')

        # NOTE: Check if all validators have been assigned votes equal to their voting power
        if not self.is_same_topology(current_validators, self.outputs):
            raise UnequalValidatorSet(
                'Validator set much be exactly same to the outputs of election'
            )

        return self
Esempio n. 2
0
    def validate(self, bigchain, current_transactions=[]):
        """Validate election transaction

        NOTE:
        * A valid election is initiated by an existing validator.

        * A valid election is one where voters are validators and votes are
          allocated according to the voting power of each validator node.

        Args:
            :param bigchain: (BigchainDB) an instantiated bigchaindb.lib.BigchainDB object.
            :param current_transactions: (list) A list of transactions to be validated along with the election

        Returns:
            Election: a Election object or an object of the derived Election subclass.

        Raises:
            ValidationError: If the election is invalid
        """
        input_conditions = []

        duplicates = any(txn for txn in current_transactions
                         if txn.id == self.id)
        if bigchain.is_committed(self.id) or duplicates:
            raise DuplicateTransaction(
                'transaction `{}` already exists'.format(self.id))

        if not self.inputs_valid(input_conditions):
            raise InvalidSignature('Transaction signature is invalid.')

        current_validators = self.get_validators(bigchain)

        # NOTE: Proposer should be a single node
        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: Check if the proposer is a validator.
        [election_initiator_node_pub_key] = self.inputs[0].owners_before
        if election_initiator_node_pub_key not in current_validators.keys():
            raise InvalidProposer(
                'Public key is not a part of the validator set')

        # NOTE: Check if all validators have been assigned votes equal to their voting power
        if not self.is_same_topology(current_validators, self.outputs):
            raise UnequalValidatorSet(
                'Validator set much be exactly same to the outputs of election'
            )

        return self