def to_dict(self): """Transform the Block to a Python dictionary. Returns: dict: The Block as a dict. Raises: OperationError: If the Block doesn't contain any transactions. """ if len(self.transactions) == 0: raise OperationError('Empty block creation is not allowed') block = { 'timestamp': self.timestamp, 'transactions': [tx.to_dict() for tx in self.transactions], 'node_pubkey': self.node_pubkey, 'voters': self.voters, } block_serialized = serialize(block) block_id = hash_data(block_serialized) return { 'id': block_id, 'block': block, 'signature': self.signature, }
def validate(self, bigchain): """Validate a block. Args: bigchain (Bigchain): an instantiated bigchaindb.Bigchain object. Returns: block (Block): The block as a `Block` object if it is valid. Else it raises an appropriate exception describing the reason of invalidity. Raises: OperationError: if a non-federation node signed the block. """ # First, make sure this node hasn't already voted on this block if bigchain.has_previous_vote(self.id, self.voters): return self # Check if the block was created by a federation node possible_voters = (bigchain.nodes_except_me + [bigchain.me]) if self.node_pubkey not in possible_voters: raise OperationError('Only federation nodes can create blocks') if not self.is_signature_valid(): raise InvalidSignature('Block signature invalid') # Finally: Tentative assumption that every blockchain will want to # validate all transactions in each block for tx in self.transactions: # NOTE: If a transaction is not valid, `is_valid` will throw an # an exception and block validation will be canceled. bigchain.validate_transaction(tx) return self
def run_upsert_validator_new(args, bigchain): """Initiates an election to add/update/remove a validator to an existing BigchainDB network :param args: dict args = { 'public_key': the public key of the proposed peer, (str) 'power': the proposed validator power for the new peer, (str) 'node_id': the node_id of the new peer (str) 'sk': the path to the private key of the node calling the election (str) } :param bigchain: an instance of BigchainDB :return: election_id (tx_id) :raises: OperationError if the write transaction fails for any reason """ new_validator = { 'public_key': args.public_key, 'power': args.power, 'node_id': args.node_id } key = load_node_key(args.sk) voters = ValidatorElection.recipients(bigchain) election = ValidatorElection.generate([key.public_key], voters, new_validator, None).sign([key.private_key]) election.validate(bigchain) resp = bigchain.write_transaction(election, 'broadcast_tx_commit') if resp == (202, ''): return election.id else: raise OperationError('Failed to commit election')
def to_dict(self): if len(self.transactions) == 0: raise OperationError('Empty block creation is not allowed') block = { 'timestamp': self.timestamp, 'transactions': [tx.to_dict() for tx in self.transactions], 'node_pubkey': self.node_pubkey, 'voters': self.voters, } block_serialized = serialize(block) block_id = hash_data(block_serialized) return { 'id': block_id, 'block': block, 'signature': self.signature, }
def _validate_block(self, bigchain): """Validate the Block without validating the transactions. Args: bigchain (:class:`~bigchaindb.Bigchain`): An instantiated Bigchain object. Raises: OperationError: If a non-federation node signed the Block. InvalidSignature: If a Block's signature is invalid. """ # Check if the block was created by a federation node possible_voters = (bigchain.nodes_except_me + [bigchain.me]) if self.node_pubkey not in possible_voters: raise OperationError('Only federation nodes can create blocks') # Check that the signature is valid if not self.is_signature_valid(): raise InvalidSignature('Invalid block signature')
def run_upsert_validator_approve(args, bigchain): """Approve an election to add/update/remove a validator to an existing BigchainDB network :param args: dict args = { 'election_id': the election_id of the election (str) 'sk': the path to the private key of the signer (str) } :param bigchain: an instance of BigchainDB :return: a success message :raises: OperationError if the write transaction fails for any reason """ key = load_node_key(args.sk) tx = bigchain.get_transaction(args.election_id) voting_powers = [ v.amount for v in tx.outputs if key.public_key in v.public_keys ] if len(voting_powers) > 0: voting_power = voting_powers[0] else: raise KeypairMismatchException( 'The key you provided does not match any of the eligible voters in this election.' ) inputs = [i for i in tx.to_inputs() if key.public_key in i.owners_before] approval = ValidatorElectionVote.generate( inputs, [([key.public_key], voting_power)], tx.id).sign([key.private_key]) approval.validate(bigchain) resp = bigchain.write_transaction(approval, 'broadcast_tx_commit') if resp == (202, ''): print('Your vote has been submitted.') return approval.id else: raise OperationError('Failed to vote for election')