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
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