Exemplo n.º 1
0
def is_valid_batch(batch):
    # validate batch signature
    header = BatchHeader()
    header.ParseFromString(batch.header)

    context = create_context('secp256k1')
    public_key = Secp256k1PublicKey.from_hex(header.signer_public_key)
    if not context.verify(batch.header_signature, batch.header, public_key):
        LOGGER.debug("batch failed signature validation: %s",
                     batch.header_signature)
        return False

    # validate all transactions in batch
    for txn in batch.transactions:
        if not is_valid_transaction(txn):
            return False

        txn_header = TransactionHeader()
        txn_header.ParseFromString(txn.header)
        if txn_header.batcher_public_key != header.signer_public_key:
            LOGGER.debug(
                "txn batcher public_key does not match signer"
                "public_key for batch: %s txn: %s", batch.header_signature,
                txn.header_signature)
            return False

    return True
Exemplo n.º 2
0
def is_valid_batch(batch):
    # validate batch signature
    header = BatchHeader()
    header.ParseFromString(batch.header)

    if not signing.verify(batch.header, batch.header_signature,
                          header.signer_public_key):
        LOGGER.debug("batch failed signature validation: %s",
                     batch.header_signature)
        return False

    # validate all transactions in batch
    for txn in batch.transactions:
        if not is_valid_transaction(txn):
            return False

        txn_header = TransactionHeader()
        txn_header.ParseFromString(txn.header)
        if txn_header.batcher_public_key != header.signer_public_key:
            LOGGER.debug(
                "txn batcher public_key does not match signer"
                "public_key for batch: %s txn: %s", batch.header_signature,
                txn.header_signature)
            return False

    return True
Exemplo n.º 3
0
def validate_batch(batch):
    # validate batch signature
    header = BatchHeader()
    header.ParseFromString(batch.header)
    valid = signing.verify(batch.header, batch.header_signature,
                           header.signer_pubkey)

    if not valid:
        LOGGER.debug("batch failed signature validation: %s",
                     batch.header_signature)

    # validate all transactions in batch
    total = len(batch.transactions)
    index = 0
    while valid and index < total:
        txn = batch.transactions[index]
        valid = validate_transaction(txn)
        if valid:
            txn_header = TransactionHeader()
            txn_header.ParseFromString(txn.header)
            if txn_header.batcher_pubkey != header.signer_pubkey:
                LOGGER.debug(
                    "txn batcher pubkey does not match signer"
                    "pubkey for batch: %s txn: %s", batch.header_signature,
                    txn.header_signature)
                valid = False
        index += 1

    return valid
Exemplo n.º 4
0
    def is_batch_signer_authorized(self,
                                   batch,
                                   state_root=None,
                                   from_state=False):
        """ Check the batch signing key against the allowed transactor
            permissions. The roles being checked are the following, from first
            to last:
                "transactor.batch_signer"
                "transactor"
                "default"

            The first role that is set will be the one used to enforce if the
            batch signer is allowed.

            Args:
                batch (Batch): The batch that is being verified.
                state_root(string): The state root of the previous block. If
                    this is None, the current state root hash will be
                    retrieved.
                from_state (bool): Whether the identity value should be read
                    directly from state, instead of using the cached values.
                    This should be used when the state_root passed is not from
                    the current chain head.

        """
        if state_root is None:
            state_root = self._current_root_func()
            LOGGER.debug("authorized Chain head is %s.", state_root)
            if state_root == INIT_ROOT_KEY:
                LOGGER.debug("Chain head is not set yet. Permit all.")
                return True

        self._cache.update_view(state_root)

        header = BatchHeader()
        header.ParseFromString(batch.header)

        role = self._cache.get_role("transactor.batch_signer", state_root,
                                    from_state)

        if role is None:
            role = self._cache.get_role("transactor", state_root, from_state)

        if role is None:
            policy_name = "default"
        else:
            policy_name = role.policy_name

        policy = self._cache.get_policy(policy_name, state_root, from_state)
        if policy is None:
            allowed = True
        else:
            allowed = self._allowed(header.signer_public_key, policy)

        if allowed:
            return self.is_transaction_signer_authorized(
                batch.transactions, state_root, from_state)
        LOGGER.debug("Batch Signer: %s is not permitted.",
                     header.signer_public_key)
        return False
Exemplo n.º 5
0
def is_valid_batch(batch):
    # batch structure verification
    header = BatchHeader()
    header.ParseFromString(batch.header)

    # check whether a batch has duplicate transactions
    if len(header.transaction_ids) != len(set(header.transaction_ids)):
        LOGGER.debug("Batch has duplicate transactions. Dropping batch: %s",
                     batch.header_signature)
        return False

    # validate the transaction_ids field in batch header contains a list of
    # transaction header_signatures and must be the same order as the
    # transactions field
    if len(batch.transactions) > len(header.transaction_ids):
        LOGGER.debug("Batch has extra transactions. Dropping batch: %s",
                     batch.header_signature)
        return False
    if len(batch.transactions) < len(header.transaction_ids):
        LOGGER.debug("Batch lacks transactions. Dropping batch: %s",
                     batch.header_signature)
        return False

    for header_txn_id, txn in zip(header.transaction_ids, batch.transactions):
        if header_txn_id != txn.header_signature:
            LOGGER.debug(
                "The header.transaction_ids does not match the "
                "order of transactions in the batch: %s txn: %s",
                batch.header_signature, header_txn_id)
            return False

    return True
Exemplo n.º 6
0
    def handle(self, connection_id, message_content):
        batch_header = BatchHeader()
        for batch in message_content.batches:
            batch_header.ParseFromString(batch.header)
            if batch_header.signer_public_key == self._whitelist_public_key:
                # There is a whitelisted batch, so allow it to continue
                return HandlerResult(status=HandlerStatus.PASS)

            batch_header.Clear()

        if self._is_batch_pool_full():
            if not self._applying_backpressure:
                self._applying_backpressure = True
                LOGGER.info(
                    'Applying back pressure on client submitted batches')

            self._batches_rejected_count.inc()
            self._batches_rejected_gauge.set_value(
                self._batches_rejected_gauge.get_value() + 1)

            response = ClientBatchSubmitResponse(
                status=ClientBatchSubmitResponse.QUEUE_FULL)
            return HandlerResult(
                status=HandlerStatus.RETURN,
                message_out=response,
                message_type=Message.CLIENT_BATCH_SUBMIT_RESPONSE
            )

        if self._applying_backpressure:
            self._applying_backpressure = False
            self._batches_rejected_gauge.set_value(0)
            LOGGER.info('Ending back pressure on client submitted batches')

        return HandlerResult(status=HandlerStatus.PASS)
Exemplo n.º 7
0
def is_batch_signer_authorized(batch, allowed_pubkeys):
    header = BatchHeader()
    header.ParseFromString(batch.header)
    if header.signer_pubkey not in allowed_pubkeys:
        LOGGER.info("Batch was signed by an unauthorized signing key %s",
                    header.signer_pubkey)
        return False
    return True
Exemplo n.º 8
0
    def is_batch_signer_authorized(self, batch, state_root=None):
        """ Check the batch signing key against the allowed transactor
            permissions. The roles being checked are the following, from first
            to last:
                "transactor.batch_signer"
                "transactor"
                "default"

            The first role that is set will be the one used to enforce if the
            batch signer is allowed.

            Args:
                batch (Batch): The batch that is being verified.
                state_root(string): The state root of the previous block. If
                    this is None, the current state root hash will be
                    retrieved.
        """
        if state_root is None:
            state_root = self._current_root_func()
            if state_root == INIT_ROOT_KEY:
                LOGGER.debug("Chain head is not set yet. Permit all.")
                return True

        identity_view = \
            self._identity_view_factory.create_identity_view(state_root)

        header = BatchHeader()
        header.ParseFromString(batch.header)

        role = \
            identity_view.get_role("transactor.batch_signer")

        if role is None:
            role = identity_view.get_role("transactor")

        if role is None:
            policy_name = "default"
        else:
            policy_name = role.policy_name

        policy = identity_view.get_policy(policy_name)
        if policy is None:
            allowed = True
        else:
            allowed = self._allowed(header.signer_pubkey, policy)

        if allowed:
            return self.is_transaction_signer_authorized(
                batch.transactions, identity_view)
        LOGGER.debug("Batch Signer: %s is not permitted.",
                     header.signer_pubkey)
        return False
Exemplo n.º 9
0
    def get_batch_by_transaction(self, transaction_id):
        """
        Check to see if the requested transaction_id is in the current chain.
        If so, find the batch that has the transaction referenced by the
        transaction_id and return the batch. This is done by finding the block
        and searching for the batch.

        :param transaction_id (string): The id of the transaction that is being
            requested.
        :return:
        The batch that has the transaction.
        """
        block = self.get_block_by_transaction_id(transaction_id)
        # Find batch in block
        for batch in block.batches:
            batch_header = BatchHeader()
            batch_header.ParseFromString(batch.header)
            if transaction_id in batch_header.transaction_ids:
                return batch
Exemplo n.º 10
0
def validate_batch(batch):
    # validate batch signature
    header = BatchHeader()
    header.ParseFromString(batch.header)
    valid = signing.verify(batch.header, batch.header_signature,
                           header.signer_pubkey)

    # validate all transactions in batch
    total = len(batch.transactions)
    index = 0
    while valid and index < total:
        txn = batch.transactions[index]
        valid = validate_transaction(txn)
        if valid:
            txn_header = TransactionHeader()
            txn_header.ParseFromString(txn.header)
            if txn_header.batcher_pubkey != header.signer_pubkey:
                valid = False
        index += 1

    return valid
    def check_off_chain_batch_roles(self, batch):
        """ Check the batch signing key against the allowed off-chain
            transactor permissions. The roles being checked are the following,
            from first to last:
                "transactor.batch_signer"
                "transactor"

            The first role that is set will be the one used to enforce if the
            batch signer is allowed.

            Args:
                batch (Batch): The batch that is being verified.
                state_root(string): The state root of the previous block. If
                    this is None, the current state root hash will be
                    retrieved.

        """
        if self._permissions is None:
            return True
        header = BatchHeader()
        header.ParseFromString(batch.header)
        policy = None
        if "transactor.batch_signer" in self._permissions:
            policy = self._permissions["transactor.batch_signer"]

        elif "transactor" in self._permissions:
            policy = self._permissions["transactor"]

        allowed = True
        if policy is not None:
            allowed = self._allowed(header.signer_public_key, policy)

        if allowed:
            return self.check_off_chain_transaction_roles(batch.transactions)

        LOGGER.debug(
            "Batch Signer: %s is not permitted by local"
            " configuration.", header.signer_public_key)
        return False
Exemplo n.º 12
0
    def is_batch_signer_authorized(self, batch, state_root=None):
        """ Check the batch signing key against the allowed transactor
            permissions. The roles being checked are the following, from first
            to last:
                "transactor.batch_signer"
                "transactor"
                "default"

            The first role that is set will be the one used to enforce if the
            batch signer is allowed.

            Args:
                batch (Batch): The batch that is being verified.
                state_root(string): The state root of the previous block; if
                    this is specified, do not read cached values. If this is
                    None, the current state root hash and cached values will be
                    used.

        """
        if state_root is None:
            state_root_func = self._current_root_func
            from_state = False
            if not self._chain_head_set:
                if self._current_root_func() == INIT_ROOT_KEY:
                    if not self._log_guard.chain_head_not_yet_set:
                        LOGGER.debug("Chain head is not set yet. Permit all.")
                        self._log_guard.chain_head_not_yet_set = True
                    return True
                self._chain_head_set = True
        else:

            def state_root_func():
                return state_root

            from_state = True

        self._cache.update_view(state_root_func())

        header = BatchHeader()
        header.ParseFromString(batch.header)

        role = self._cache.get_role("transactor.batch_signer", state_root_func,
                                    from_state)

        if role is None:
            role = self._cache.get_role("transactor", state_root_func,
                                        from_state)

        if role is None:
            policy_name = "default"
        else:
            policy_name = role.policy_name

        policy = self._cache.get_policy(policy_name, state_root_func,
                                        from_state)
        if policy is None:
            allowed = True
        else:
            allowed = self._allowed(header.signer_public_key, policy)

        if allowed:
            return self.is_transaction_signer_authorized(
                batch.transactions, state_root_func, from_state)
        LOGGER.debug("Batch Signer: %s is not permitted.",
                     header.signer_public_key)
        return False