def get_result(self, request: Request):
        self._validate_request_type(request)
        req_ts = request.operation.get(TIMESTAMP)
        revoc_reg_def_id = request.operation.get(REVOC_REG_DEF_ID)
        # Get root hash corresponding with given timestamp
        past_root = self.database_manager.ts_store.get_equal_or_prev(req_ts)
        # Path to corresponding ACCUM record in state
        path = RevocRegEntryHandler.make_state_path_for_revoc_reg_entry_accum(revoc_reg_def_id=revoc_reg_def_id)
        entry_state = StateValue()
        if past_root is not None:
            encoded_entry, proof = self._get_value_from_state(path,
                                                              head_hash=past_root,
                                                              with_proof=True)
            entry_state.proof = proof
            if encoded_entry:
                revoc_reg_entry_accum, seq_no, last_update_time = decode_state_value(encoded_entry)
                entry_state = StateValue(root_hash=past_root,
                                         value=revoc_reg_entry_accum,
                                         seq_no=seq_no,
                                         update_time=last_update_time,
                                         proof=proof)

        return self.make_result(request=request,
                                data=entry_state.value,
                                last_seq_no=entry_state.seq_no,
                                update_time=entry_state.update_time,
                                proof=entry_state.proof)
    def _return_txn_author_agreement_aml(self, request, proof, data=None):
        if data is not None:
            value, last_seq_no, last_update_time = decode_state_value(
                data, serializer=config_state_serializer)
            return self.make_result(request, value, last_seq_no,
                                    last_update_time, proof)

        return self.make_result(request, None, proof=proof)
예제 #3
0
 def get_frozen_ledgers(config_state, is_committed=True):
     if not config_state:
         return {}
     encoded = config_state.get(StaticLedgersFreezeHelper.make_state_path_for_frozen_ledgers(),
                                isCommitted=is_committed)
     if not encoded:
         return {}
     state_frozen_ledgers, _, _ = decode_state_value(encoded)
     frozen_ledgers = {int(key): value for (key, value) in state_frozen_ledgers.items()}
     return frozen_ledgers
예제 #4
0
    def _return_txn_author_agreement(self, request, proof, head_hash=None, digest=None, data=None):
        if digest is not None:
            head_hash = head_hash if head_hash else self.state.committedHeadHash
            data = self.state.get_for_root_hash(head_hash, self._state_path_taa_digest(digest.decode()))

        if data is not None:
            value, last_seq_no, last_update_time = decode_state_value(data, serializer=config_state_serializer)
            return self.make_config_result(request, value, last_seq_no, last_update_time, proof)

        return self.make_config_result(request, None, proof=proof)
예제 #5
0
 def get_taa_data(self,
                  digest: Optional[str] = None,
                  version: Optional[str] = None,
                  isCommitted: bool = True) -> Optional[Tuple[Dict, str]]:
     data = None
     if digest is None:
         digest = self.get_taa_digest(version=version,
                                      isCommitted=isCommitted)
     if digest is not None:
         data = self.config_state.get(self._state_path_taa_digest(digest),
                                      isCommitted=isCommitted)
     if data is not None:
         data = decode_state_value(data, serializer=config_state_serializer)
     return None if data is None else (data, digest)
예제 #6
0
    def lookup(self, path, is_committed=True, with_proof=False) -> (str, int):
        """
        Queries state for data on specified path

        :param path: path to data
        :param is_committed: queries the committed state root if True else the uncommitted root
        :param with_proof: creates proof if True
        :return: data
        """
        assert path is not None
        head_hash = self.state.committedHeadHash if is_committed else self.state.headHash
        encoded, proof = self._get_value_from_state(path, head_hash, with_proof=with_proof)
        if encoded:
            value, last_seq_no, last_update_time = decode_state_value(encoded)
            return value, last_seq_no, last_update_time, proof
        return None, None, None, proof
예제 #7
0
 def _get_reg_entry_by_timestamp(self, timestamp, path_to_reg_entry):
     reg_entry = None
     seq_no = None
     last_update_time = None
     reg_entry_proof = None
     past_root = self.database_manager.ts_store.get_equal_or_prev(timestamp)
     if past_root:
         encoded_entry, reg_entry_proof = self._get_value_from_state(
             path_to_reg_entry, head_hash=past_root, with_proof=True)
         if encoded_entry:
             reg_entry, seq_no, last_update_time = decode_state_value(
                 encoded_entry)
     return StateValue(root_hash=past_root,
                       value=reg_entry,
                       seq_no=seq_no,
                       update_time=last_update_time,
                       proof=reg_entry_proof)
예제 #8
0
    def get_result(self, request: Request):
        """
        For getting reply we need:
        1. Get REVOC_REG_ENTRY by "TO" timestamp from state
        2. If FROM is given in request, then Get REVOC_REG_ENTRY by "FROM" timestamp from state
        3. Get ISSUANCE_TYPE for REVOC_REG_DEF (revoked/issued strategy)
        4. Compute issued and revoked indices by corresponding strategy
        5. Make result
           5.1 Now, if "FROM" is presented in request, then STATE_PROOF_FROM and ACCUM (revocation entry for "FROM" timestamp)
               will added into data section
           5.2 If not, then only STATE_PROOF for "TO" revocation entry will added
        :param request:
        :return: Reply
        """
        self._validate_request_type(request)
        req_ts_from = request.operation.get(FROM, None)
        req_ts_to = request.operation.get(TO)
        revoc_reg_def_id = request.operation.get(REVOC_REG_DEF_ID)
        reply = None
        """
        Get root hash for "to" timestamp
        Get REVOC_REG_ENTRY and ACCUM record for timestamp "to"
        """
        path_to_reg_entry = RevocRegEntryHandler.make_state_path_for_revoc_reg_entry(
            revoc_reg_def_id=revoc_reg_def_id)
        path_to_reg_entry_accum = RevocRegEntryHandler.make_state_path_for_revoc_reg_entry_accum(
            revoc_reg_def_id=revoc_reg_def_id)

        entry_to = self._get_reg_entry_by_timestamp(req_ts_to,
                                                    path_to_reg_entry)
        accum_to = self._get_reg_entry_accum_by_timestamp(
            req_ts_to, path_to_reg_entry_accum)
        entry_from = StateValue()
        accum_from = StateValue()

        if accum_to.value and entry_to.value:
            """Get issuance type from REVOC_REG_DEF"""
            encoded_revoc_reg_def = self.state.get_for_root_hash(
                entry_to.root_hash, revoc_reg_def_id)
            if encoded_revoc_reg_def:
                revoc_reg_def, _, _ = decode_state_value(encoded_revoc_reg_def)
                strategy_cls = self.get_revocation_strategy(
                    revoc_reg_def[VALUE][ISSUANCE_TYPE])
                issued_to = entry_to.value[VALUE].get(ISSUED, [])
                revoked_to = entry_to.value[VALUE].get(REVOKED, [])
                if req_ts_from:
                    """Get REVOC_REG_ENTRY and ACCUM records for timestamp from if exist"""
                    entry_from = self._get_reg_entry_by_timestamp(
                        req_ts_from, path_to_reg_entry)
                    accum_from = self._get_reg_entry_accum_by_timestamp(
                        req_ts_from, path_to_reg_entry_accum)
                if req_ts_from and entry_from.value and accum_from.value:
                    """Compute issued/revoked lists corresponding with ISSUANCE_TYPE strategy"""
                    issued_from = entry_from.value[VALUE].get(ISSUED, [])
                    revoked_from = entry_from.value[VALUE].get(REVOKED, [])
                    result_issued, result_revoked = strategy_cls.get_delta(
                        {
                            ISSUED: issued_to,
                            REVOKED: revoked_to
                        }, {
                            ISSUED: issued_from,
                            REVOKED: revoked_from
                        })
                else:
                    result_issued, result_revoked = strategy_cls.get_delta(
                        {
                            ISSUED: issued_to,
                            REVOKED: revoked_to
                        }, None)
                reply = {
                    REVOC_REG_DEF_ID: revoc_reg_def_id,
                    REVOC_TYPE: revoc_reg_def.get(REVOC_TYPE),
                    VALUE: {
                        ACCUM_TO:
                        accum_to.value if entry_from.value else entry_to.value,
                        ISSUED:
                        result_issued,
                        REVOKED:
                        result_revoked
                    }
                }
                """If we got "from" timestamp, then add state proof into "data" section of reply"""
                if req_ts_from:
                    reply[STATE_PROOF_FROM] = accum_from.proof
                    reply[VALUE][ACCUM_FROM] = accum_from.value

        if accum_to and entry_to:
            seq_no = accum_to.seq_no if entry_from.value else entry_to.seq_no
            update_time = accum_to.update_time if entry_from.value else entry_to.update_time
            proof = accum_to.proof if entry_from.value else entry_to.proof
            if reply is None and req_ts_from is not None:
                # TODO: change this according to INDY-2115
                reply = {}
                accum_from = self._get_reg_entry_accum_by_timestamp(
                    req_ts_from, path_to_reg_entry_accum)
                reply[STATE_PROOF_FROM] = accum_from.proof
                reply[VALUE] = {}
                reply[VALUE][ACCUM_TO] = None
                reply[VALUE][ACCUM_FROM] = accum_from.value
        else:
            seq_no = None
            update_time = None
            proof = None

        return self.make_result(request=request,
                                data=reply,
                                last_seq_no=seq_no,
                                update_time=update_time,
                                proof=proof)
예제 #9
0
 def _decode_state_value(self, encoded):
     if encoded:
         value, last_seq_no, last_update_time = decode_state_value(encoded)
         return value, last_seq_no, last_update_time
     return None, None, None
 def _decode_state_value(self, encoded):
     if encoded:
         value, last_seq_no, last_update_time = decode_state_value(
             encoded, serializer=config_state_serializer)
         return value, last_seq_no, last_update_time
     return None, None, None