Ejemplo n.º 1
0
    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,
        }
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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')
Ejemplo n.º 4
0
    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,
        }
Ejemplo n.º 5
0
    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')
Ejemplo n.º 6
0
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')