Build rev reg delta json, potentially starting from existing (earlier) delta.

        Return delta json and its timestamp on the distributed ledger.

        Raise AbsentRevReg for no such revocation registry, or BadRevStateTime for a requested delta to
        a time preceding revocation registry creation.

        :param rr_id: rev reg id
        :param to: time (epoch seconds) of interest; upper-bounds returned timestamp
        :param fro: optional prior time of known delta json
        :param fro_delta: optional known delta as of time fro
        :return: rev reg delta json and ledger timestamp (epoch seconds)

async def _build_rr_delta_json(self, rr_id: str, to: int, fro: int = None, fro_delta: dict = None) -> (str, int):
        """
        Build rev reg delta json, potentially starting from existing (earlier) delta.

        Return delta json and its timestamp on the distributed ledger.

        Raise AbsentRevReg for no such revocation registry, or BadRevStateTime for a requested delta to
        a time preceding revocation registry creation.

        :param rr_id: rev reg id
        :param to: time (epoch seconds) of interest; upper-bounds returned timestamp
        :param fro: optional prior time of known delta json
        :param fro_delta: optional known delta as of time fro
        :return: rev reg delta json and ledger timestamp (epoch seconds)
        """

        LOGGER.debug(
            '_HolderProver._build_rr_delta_json >>> rr_id: %s, to: %s, fro: %s, fro_delta: %s',
            rr_id,
            to,
            fro,
            fro_delta)

        rr_delta_json = None
        ledger_timestamp = None

        get_rr_delta_req_json = await ledger.build_get_revoc_reg_delta_request(self.did, rr_id, fro, to)
        resp_json = await self._submit(get_rr_delta_req_json)
        resp = json.loads(resp_json)
        if resp.get('result', {}).get('data', None) and resp['result']['data'].get('value', None):
            # delta is to some time at or beyond rev reg creation, carry on
            try:
                (_, rr_delta_json, ledger_timestamp) = await ledger.parse_get_revoc_reg_delta_response(resp_json)
            except IndyError:  # ledger replied, but there is no such rev reg
                LOGGER.debug('_HolderProver._build_rr_delta_json: <!< no rev reg exists on %s', rr_id)
                raise AbsentRevReg('No rev reg exists on {}'.format(rr_id))
        else:
            LOGGER.debug(
                '_HolderProver._build_rr_delta_json: <!< Rev reg %s created after asked-for time %s',
                rr_id,
                to)
            raise BadRevStateTime('Rev reg {} created after asked-for time {}'.format(rr_id, to))

        if fro and fro_delta:
            rr_delta_json = await anoncreds.issuer_merge_revocation_registry_deltas(
                json.dumps(fro_delta),
                rr_delta_json)

        rv = (rr_delta_json, ledger_timestamp)
        LOGGER.debug('_HolderProver._build_rr_delta_json <<< %s', rv)
        return rv