def setup_agreements_environment():
    consumer_acc = get_consumer_account()
    publisher_acc = get_publisher_account()
    keeper = Keeper.get_instance()

    ddo = get_ddo_sample()
    ddo._did = DID.did({"0": "0x12341234"})
    keeper.did_registry.register(
        ddo.asset_id,
        checksum=Web3Provider.get_web3().toBytes(hexstr=ddo.asset_id),
        url='aquarius:5000',
        account=publisher_acc,
        providers=None)

    registered_ddo = ddo
    asset_id = registered_ddo.asset_id
    service_agreement = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS,
                                                  ddo)
    agreement_id = ServiceAgreement.create_new_agreement_id()
    price = service_agreement.get_price()
    (lock_cond_id, access_cond_id,
     escrow_cond_id) = service_agreement.generate_agreement_condition_ids(
         agreement_id, asset_id, consumer_acc.address, publisher_acc.address,
         keeper)

    return (
        keeper,
        publisher_acc,
        consumer_acc,
        agreement_id,
        asset_id,
        price,
        service_agreement,
        (lock_cond_id, access_cond_id, escrow_cond_id),
    )
Beispiel #2
0
    def order(self, did: str, consumer_address: str,
              service_index: [int, None]=None, service_type: str=None) -> OrderRequirements:
        """
        Request a specific service from an asset, returns the service requirements that
        must be met prior to consuming the service.

        :param did:
        :param consumer_address:
        :param service_index:
        :param service_type:
        :return: OrderRequirements instance -- named tuple (amount, data_token_address, receiver_address, nonce),
        """
        assert service_type or service_index, f'One of service_index or service_type is required.'
        asset = self.resolve(did)
        if service_type:
            sa = ServiceAgreement.from_ddo(service_type, asset)
        else:
            service = asset.get_service_by_index(service_index)
            sa = ServiceAgreement.from_ddo(service.type, asset)

        dt_address = asset.data_token_address

        _, initialize_url = self._data_provider.get_initialize_endpoint(sa.service_endpoint)
        order_requirements = self._data_provider.get_order_requirements(
            asset.did, initialize_url, consumer_address, sa.index, sa.type, dt_address
        )
        if not order_requirements:
            raise AssertionError('Data service provider or service is not available.')

        assert dt_address == order_requirements.data_token_address
        return order_requirements
def test_agreement_hash():
    """
    This test verifies generating agreement hash using fixed inputs and ddo example.
    This will make it easier to compare the hash generated from different languages.
    """
    did = "did:op:0bc278fee025464f8012b811d1bce8e22094d0984e4e49139df5d5ff7a028bdf"
    template_id = '0x34219511357c43f4af90a4896b972a32809379bfbe8148eab3878e8406e75836'
    agreement_id = '0xf136d6fadecb48fdb2fc1fb420f5a5d1c32d22d9424e47ab9461556e058fefaa'
    ddo = get_ddo_sample()

    sa = ServiceAgreement.from_json(
        ddo.get_service(ServiceTypes.ASSET_ACCESS).as_dictionary())
    assert did == ddo.did
    # Don't generate condition ids, use fixed ids so we get consistent hash
    # (access_id, lock_id, escrow_id) = sa.generate_agreement_condition_ids(
    #     agreement_id, ddo.asset_id, consumer, publisher, keeper)
    access_id = '0x2d7c1d60dc0c3f52aa9bd71ffdbe434a0e58435571e64c893bc9646fea7f6ec1'
    lock_id = '0x1e265c434c14e668695dda1555088f0ea4356f596bdecb8058812e7dcba9ee73'
    escrow_id = '0xe487fa6d435c2f09ef14b65b34521302f1532ac82ba8f6c86116acd8566e2da3'
    print(f'condition ids: \n'
          f'{access_id} \n'
          f'{lock_id} \n'
          f'{escrow_id}')
    agreement_hash = ServiceAgreement.generate_service_agreement_hash(
        template_id,
        (access_id, lock_id, escrow_id),
        sa.conditions_timelocks,
        sa.conditions_timeouts,
        agreement_id,
        generate_multi_value_hash
    )
    print('agreement hash: ', agreement_hash.hex())
    expected = '0xc1bc6cdb161b9d04d5b48bceba51b9092c4da8db08003b96b93647fbe86e330c'
    print('expected hash: ', expected)
    assert agreement_hash.hex() == expected, 'hash does not match.'
def place_order(publisher_account, ddo, consumer_account, service_type):
    keeper = keeper_instance()
    agreement_id = ServiceAgreement.create_new_agreement_id()
    publisher_address = publisher_account.address
    # balance = keeper.token.get_token_balance(consumer_account.address)/(2**18)
    # if balance < 20:
    #     keeper.dispenser.request_tokens(100, consumer_account)

    service_agreement = ServiceAgreement.from_ddo(service_type, ddo)
    condition_ids = service_agreement.generate_agreement_condition_ids(
        agreement_id, ddo.asset_id, consumer_account.address,
        publisher_address, keeper)
    time_locks = service_agreement.conditions_timelocks
    time_outs = service_agreement.conditions_timeouts

    template_name = keeper.template_manager.SERVICE_TO_TEMPLATE_NAME[
        service_type]
    template_id = keeper.template_manager.create_template_id(template_name)
    actor_map = {
        'consumer': consumer_account.address,
        'provider': publisher_address
    }
    actors = [
        actor_map[_type]
        for _type in get_template_actor_types(keeper, template_id)
    ]

    assert keeper.template_manager.contract_concise.isTemplateIdApproved(
        template_id), f'template {template_id} is not approved.'

    keeper_instance().agreement_manager.create_agreement(
        agreement_id, ddo.asset_id, template_id, condition_ids, time_locks,
        time_outs, actors, consumer_account)

    return agreement_id
Beispiel #5
0
def build_and_send_ddo_with_compute_service(client,
                                            alg_diff=False,
                                            asset_type=None):
    pub_wallet = get_publisher_wallet()
    cons_wallet = get_consumer_wallet()

    # publish an algorithm asset (asset with metadata of type `algorithm`)
    alg_ddo = (get_algorithm_ddo_different_provider(client, cons_wallet)
               if alg_diff else get_algorithm_ddo(client, cons_wallet))
    alg_data_token = alg_ddo.as_dictionary()["dataToken"]
    alg_dt_contract = DataToken(alg_data_token)

    mint_tokens_and_wait(alg_dt_contract, cons_wallet, cons_wallet)

    # publish a dataset asset
    if asset_type == "allow_all_published":
        dataset_ddo_w_compute_service = comp_ds_allow_all_published(
            client, pub_wallet)
    elif asset_type == "specific_algo_dids":
        algos = []

        for _ in itertools.repeat(None, 2):
            alg_ddo = get_algorithm_ddo(client, cons_wallet)
            alg_data_token = alg_ddo.as_dictionary()["dataToken"]
            alg_dt_contract = DataToken(alg_data_token)
            mint_tokens_and_wait(alg_dt_contract, cons_wallet, cons_wallet)
            algos.append(alg_ddo)

        dataset_ddo_w_compute_service = comp_ds_specific_algo_dids(
            client, pub_wallet, algos)
    else:
        dataset_ddo_w_compute_service = comp_ds(client, pub_wallet)

    did = dataset_ddo_w_compute_service.did
    ddo = dataset_ddo_w_compute_service
    data_token = dataset_ddo_w_compute_service.data_token_address
    dt_contract = DataToken(data_token)
    mint_tokens_and_wait(dt_contract, cons_wallet, pub_wallet)

    sa = ServiceAgreement.from_ddo(ServiceTypes.CLOUD_COMPUTE,
                                   dataset_ddo_w_compute_service)

    tx_id = send_order(client, ddo, dt_contract, sa, cons_wallet)
    alg_service = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, alg_ddo)
    alg_tx_id = send_order(client, alg_ddo, alg_dt_contract, alg_service,
                           cons_wallet)

    return (
        dataset_ddo_w_compute_service,
        did,
        tx_id,
        sa,
        data_token,
        alg_ddo,
        alg_data_token,
        alg_dt_contract,
        alg_tx_id,
    )
Beispiel #6
0
    def _get_service_endpoint(self, did, asset=None):
        if not asset:
            asset = resolve_asset(did, self._config.aquarius_url)

        return self._data_provider.build_compute_endpoint(
            ServiceAgreement.from_ddo(ServiceTypes.CLOUD_COMPUTE,
                                      asset).service_endpoint)
Beispiel #7
0
def test_assets_consumed(publisher_ocean_instance, consumer_ocean_instance):
    ocn = publisher_ocean_instance
    acct = consumer_ocean_instance.main_account
    consumed_assets = len(ocn.assets.consumer_assets(acct.address))
    asset = create_asset(publisher_ocean_instance)
    service = asset.get_service(service_type=ServiceTypes.ASSET_ACCESS)
    service_dict = service.as_dictionary()
    sa = ServiceAgreement.from_json(service_dict)
    keeper = ocn.keeper

    def grant_access(_, ocn_instance, agr_id, did, cons_address, account):
        ocn_instance.agreements.conditions.grant_access(
            agr_id, did, cons_address, account)

    agreement_id = consumer_ocean_instance.assets.order(
        asset.did, sa.index, acct)
    keeper.lock_reward_condition.subscribe_condition_fulfilled(
        agreement_id,
        15,
        grant_access, (publisher_ocean_instance, agreement_id, asset.did,
                       acct.address, publisher_ocean_instance.main_account),
        wait=True)

    keeper.access_secret_store_condition.subscribe_condition_fulfilled(
        agreement_id,
        15,
        log_event(keeper.access_secret_store_condition.FULFILLED_EVENT), (),
        wait=True)
    assert ocn.agreements.is_access_granted(agreement_id, asset.did,
                                            acct.address)

    assert len(ocn.assets.consumer_assets(acct.address)) == consumed_assets + 1
    publisher_ocean_instance.assets.retire(asset.did)
def download_asset_files(service_index: int,
                         asset: Asset,
                         consumer_wallet: Wallet,
                         destination: str,
                         token_address: str,
                         order_tx_id: str,
                         data_provider: DataServiceProvider,
                         index: [int, None] = None):
    """
    Download asset data files or result files from a compute job.

    :param service_index: identifier of the service inside the asset DDO, str
    :param asset: Asset instance
    :param consumer_wallet: Wallet instance of the consumer
    :param destination: Path, str
    :param token_address: hex str the address of the DataToken smart contract
    :param order_tx_id: hex str the transaction hash of the startOrder tx
    :param data_provider: DataServiceProvider instance
    :param index: Index of the document that is going to be downloaded, int
    :return: Asset folder path, str
    """
    _files = asset.metadata['main']['files']
    sa = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, asset)
    service_endpoint = sa.service_endpoint
    if not service_endpoint:
        logger.error(
            'Consume asset failed, service definition is missing the "serviceEndpoint".'
        )
        raise AssertionError(
            'Consume asset failed, service definition is missing the "serviceEndpoint".'
        )

    service_endpoint = data_provider.build_download_endpoint(service_endpoint)
    if not os.path.isabs(destination):
        destination = os.path.abspath(destination)
    if not os.path.exists(destination):
        os.mkdir(destination)

    asset_folder = os.path.join(destination,
                                f'datafile.{asset.asset_id}.{service_index}')
    if not os.path.exists(asset_folder):
        os.mkdir(asset_folder)

    if index is not None:
        assert isinstance(index,
                          int), logger.error('index has to be an integer.')
        assert index >= 0, logger.error(
            'index has to be 0 or a positive integer.')
        assert index < len(_files), logger.error(
            'index can not be bigger than the number of files')
        indexes = [index]
    else:
        indexes = range(len(_files))

    for i in indexes:
        data_provider.download_service(asset.did, service_endpoint,
                                       consumer_wallet, _files, asset_folder,
                                       service_index, token_address,
                                       order_tx_id, i)
    return asset_folder
Beispiel #9
0
    def _get_service_endpoint_from_agreement(self, agreement_id, ddo=None):
        agreement = self._keeper.agreement_manager.get_agreement(agreement_id)
        _type = self._keeper.get_agreement_type(agreement.template_id)

        if not ddo:
            ddo = self._did_resolver.resolve(id_to_did(agreement.did))
        service = ServiceAgreement.from_ddo(_type, ddo)
        assert service, f'Using agreement_id {agreement_id}, the service type {_type} does not ' \
                        f'have a matching service in the DDO with DID {agreement.did}.'

        compute_service = ServiceAgreement.from_ddo(ServiceTypes.CLOUD_COMPUTE,
                                                    ddo)
        assert service.service_endpoint == compute_service.service_endpoint, \
            f'`Expecting agreement of type `{ServiceTypes.CLOUD_COMPUTE}`, but `agreement_id` {agreement_id} ' \
            f'seems to have type {_type}.'

        return service.service_endpoint
Beispiel #10
0
def place_order(publisher_account, ddo, consumer_account):
    keeper = keeper_instance()
    agreement_id = ServiceAgreement.create_new_agreement_id()
    agreement_template = keeper.escrow_access_secretstore_template
    publisher_address = publisher_account.address
    service_agreement = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS,
                                                  ddo)
    condition_ids = service_agreement.generate_agreement_condition_ids(
        agreement_id, ddo.asset_id, consumer_account.address,
        publisher_address, keeper)
    time_locks = service_agreement.conditions_timelocks
    time_outs = service_agreement.conditions_timeouts
    agreement_template.create_agreement(agreement_id, ddo.asset_id,
                                        condition_ids, time_locks, time_outs,
                                        consumer_account.address,
                                        consumer_account)

    return agreement_id
Beispiel #11
0
def test_compute_norawalgo_allowed(client):
    pub_wallet = get_publisher_wallet()
    cons_wallet = get_consumer_wallet()

    # publish a dataset asset
    dataset_ddo_w_compute_service = get_dataset_ddo_with_compute_service_no_rawalgo(client, pub_wallet)
    did = dataset_ddo_w_compute_service.did
    ddo = dataset_ddo_w_compute_service
    data_token = dataset_ddo_w_compute_service.data_token_address
    dt_contract = DataToken(data_token)
    mint_tokens_and_wait(dt_contract, cons_wallet, pub_wallet)

    # CHECKPOINT 1
    algorithm_meta = {
        "rawcode": "console.log('Hello world'!)",
        "format": 'docker-image',
        "version": '0.1',
        "container": {
            "entrypoint": 'node $ALGO',
            "image": 'node',
            "tag": '10'
        }
    }
    # prepare parameter values for the compute endpoint
    # signature, documentId, consumerAddress, and algorithmDid or algorithmMeta

    sa = ServiceAgreement.from_ddo(ServiceTypes.CLOUD_COMPUTE, dataset_ddo_w_compute_service)
    tx_id = send_order(client, ddo, dt_contract, sa, cons_wallet)
    nonce = get_nonce(client, cons_wallet.address)

    # prepare consumer signature on did
    msg = f'{cons_wallet.address}{did}{nonce}'
    _hash = add_ethereum_prefix_and_hash_msg(msg)
    signature = Web3Helper.sign_hash(_hash, cons_wallet)

    # Start the compute job
    payload = dict({
        'signature': signature,
        'documentId': did,
        'serviceId': sa.index,
        'serviceType': sa.type,
        'consumerAddress': cons_wallet.address,
        'transferTxId': tx_id,
        'dataToken': data_token,
        'output': build_stage_output_dict(dict(), dataset_ddo_w_compute_service, cons_wallet.address, pub_wallet),
        'algorithmDid': '',
        'algorithmMeta': algorithm_meta,
        'algorithmDataToken': ''
    })

    compute_endpoint = BaseURLs.ASSETS_URL + '/compute'
    response = client.post(
        compute_endpoint,
        data=json.dumps(payload),
        content_type='application/json'
    )
    assert response.status == '400 BAD REQUEST', f'start compute job failed: {response.status} , { response.data}'
Beispiel #12
0
def test_download_service(client):
    aqua = Aquarius("http://localhost:5000")
    try:
        for did in aqua.list_assets():
            aqua.retire_asset_ddo(did)
    except (ValueError, Exception):
        pass

    pub_wallet = get_publisher_wallet()
    cons_wallet = get_consumer_wallet()

    ddo = get_dataset_ddo_with_access_service(client, pub_wallet)
    dt_address = ddo.as_dictionary()["dataToken"]
    dt_token = DataToken(dt_address)
    mint_tokens_and_wait(dt_token, cons_wallet, pub_wallet)

    sa = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, ddo)
    tx_id = send_order(client, ddo, dt_token, sa, cons_wallet)
    index = 0
    download_endpoint = BaseURLs.ASSETS_URL + "/download"
    # Consume using url index and auth token
    # (let the provider do the decryption)
    payload = dict({
        "documentId": ddo.did,
        "serviceId": sa.index,
        "serviceType": sa.type,
        "dataToken": dt_address,
        "consumerAddress": cons_wallet.address,
    })
    payload["signature"] = generate_auth_token(cons_wallet)
    payload["transferTxId"] = tx_id
    payload["fileIndex"] = index
    request_url = (download_endpoint + "?" +
                   "&".join([f"{k}={v}" for k, v in payload.items()]))
    response = client.get(request_url)
    assert response.status_code == 200, f"{response.data}"

    # Consume using url index and signature (withOUT nonce), should fail
    _hash = add_ethereum_prefix_and_hash_msg(ddo.did)
    payload["signature"] = Web3Helper.sign_hash(_hash, cons_wallet)
    request_url = (download_endpoint + "?" +
                   "&".join([f"{k}={v}" for k, v in payload.items()]))
    print(
        ">>>> Expecting InvalidSignatureError from the download endpoint <<<<"
    )  # noqa
    response = client.get(request_url)
    assert response.status_code == 400, f"{response.data}"

    # Consume using url index and signature (with nonce)
    nonce = get_nonce(client, cons_wallet.address)
    _hash = add_ethereum_prefix_and_hash_msg(f"{ddo.did}{nonce}")
    payload["signature"] = Web3Helper.sign_hash(_hash, cons_wallet)
    request_url = (download_endpoint + "?" +
                   "&".join([f"{k}={v}" for k, v in payload.items()]))
    response = client.get(request_url)
    assert response.status_code == 200, f"{response.data}"
def test_initialize_on_ipfs_url(client):
    pub_wallet = get_publisher_wallet()
    cons_wallet = get_consumer_wallet()

    ddo = get_dataset_with_ipfs_url_ddo(client, pub_wallet)
    data_token = ddo.data_token_address
    dt_contract = DataToken(data_token)
    sa = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, ddo)

    send_order(client, ddo, dt_contract, sa, cons_wallet)
Beispiel #14
0
def test_download_service(client):
    aqua = Aquarius('http://localhost:5000')
    try:
        for did in aqua.list_assets():
            aqua.retire_asset_ddo(did)
    except (ValueError, Exception):
        pass

    pub_wallet = get_publisher_wallet()
    cons_wallet = get_consumer_wallet()

    ddo = get_dataset_ddo_with_access_service(client, pub_wallet)
    dt_address = ddo.as_dictionary()['dataToken']
    dt_token = DataToken(dt_address)
    mint_tokens_and_wait(dt_token, cons_wallet, pub_wallet)

    sa = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, ddo)
    tx_id = send_order(client, ddo, dt_token, sa, cons_wallet)
    index = 0
    download_endpoint = BaseURLs.ASSETS_URL + '/download'
    # Consume using url index and auth token (let the provider do the decryption)
    payload = dict({
        'documentId': ddo.did,
        'serviceId': sa.index,
        'serviceType': sa.type,
        'dataToken': dt_address,
        'consumerAddress': cons_wallet.address
    })
    payload['signature'] = generate_auth_token(cons_wallet)
    payload['transferTxId'] = tx_id
    payload['fileIndex'] = index
    request_url = download_endpoint + '?' + '&'.join(
        [f'{k}={v}' for k, v in payload.items()])
    response = client.get(request_url)
    assert response.status_code == 200, f'{response.data}'

    # Consume using url index and signature (withOUT nonce), should fail
    _hash = add_ethereum_prefix_and_hash_msg(ddo.did)
    payload['signature'] = Web3Helper.sign_hash(_hash, cons_wallet)
    request_url = download_endpoint + '?' + '&'.join(
        [f'{k}={v}' for k, v in payload.items()])
    print(
        '>>>> Expecting InvalidSignatureError from the download endpoint <<<<')
    response = client.get(request_url)
    assert response.status_code == 401, f'{response.data}'

    # Consume using url index and signature (with nonce)
    nonce = get_nonce(client, cons_wallet.address)
    _hash = add_ethereum_prefix_and_hash_msg(f'{ddo.did}{nonce}')
    payload['signature'] = Web3Helper.sign_hash(_hash, cons_wallet)
    request_url = download_endpoint + '?' + '&'.join(
        [f'{k}={v}' for k, v in payload.items()])
    response = client.get(request_url)
    assert response.status_code == 200, f'{response.data}'
Beispiel #15
0
    def start(self,
              did: str,
              consumer_wallet: Wallet,
              order_tx_id: str,
              nonce: [int, None] = None,
              algorithm_did: [str, None] = None,
              algorithm_meta: [AlgorithmMetadata, None] = None,
              algorithm_tx_id: str = '',
              algorithm_data_token: str = '',
              output: dict = None,
              job_id: str = None):
        """Start a remote compute job on the asset files identified by `did` after
        verifying that the provider service is active and transferring the
        number of data-tokens required for using this compute service.

        :param did: str -- id of asset that has the compute service
        :param consumer_wallet: Wallet instance of the consumer ordering the service
        :param order_tx_id: hex str -- id of the startOrder transaction (tx hash)
        :param nonce: int value to use in the signature
        :param algorithm_did: str -- the asset did (of `algorithm` type) which consist of `did:op:` and
            the assetId hex str (without `0x` prefix)
        :param algorithm_meta: `AlgorithmMetadata` instance -- metadata about the algorithm being run if
            `algorithm` is being used. This is ignored when `algorithm_did` is specified.
        :param algorithm_tx_id: transaction hash of algorithm StartOrder tx (Required when using `algorithm_did`)
        :param algorithm_data_token: datatoken address of this algorithm (Required when using `algorithm_did`)
        :param output: dict object to be used in publishing mechanism, must define
        :param job_id: str identifier of a compute job that was previously started and
            stopped (if supported by the provider's  backend)
        :return: str -- id of compute job being executed
        """
        assert algorithm_did or algorithm_meta, 'either an algorithm did or an algorithm meta must be provided.'

        output = OceanCompute.check_output_dict(
            output, consumer_wallet.address, data_provider=self._data_provider)
        asset = resolve_asset(did,
                              metadata_store_url=self._config.aquarius_url)
        service_endpoint = self._get_service_endpoint(did, asset)

        sa = ServiceAgreement.from_ddo(ServiceTypes.CLOUD_COMPUTE, asset)

        signature = self._sign_message(consumer_wallet,
                                       f'{consumer_wallet.address}{did}',
                                       nonce=nonce)

        job_info = self._data_provider.start_compute_job(
            did, service_endpoint, consumer_wallet.address, signature,
            sa.index, asset.data_token_address, order_tx_id, algorithm_did,
            algorithm_meta, algorithm_tx_id, algorithm_data_token, output,
            job_id)
        return job_info['jobId']
Beispiel #16
0
def test_compute_specific_algo_dids(client):
    pub_wallet = get_publisher_wallet()
    cons_wallet = get_consumer_wallet()

    # publish a dataset asset
    dataset_ddo_w_compute_service = get_dataset_ddo_with_compute_service_specific_algo_dids(client, pub_wallet)
    did = dataset_ddo_w_compute_service.did
    ddo = dataset_ddo_w_compute_service
    data_token = dataset_ddo_w_compute_service.as_dictionary()['dataToken']
    dt_contract = DataToken(data_token)
    mint_tokens_and_wait(dt_contract, cons_wallet, pub_wallet)

    # publish an algorithm asset (asset with metadata of type `algorithm`)
    alg_ddo = get_algorithm_ddo(client, cons_wallet)
    alg_data_token = alg_ddo.as_dictionary()['dataToken']
    alg_dt_contract = DataToken(alg_data_token)
    mint_tokens_and_wait(alg_dt_contract, pub_wallet, cons_wallet)
    # CHECKPOINT 1

    sa = ServiceAgreement.from_ddo(ServiceTypes.CLOUD_COMPUTE, dataset_ddo_w_compute_service)
    tx_id = send_order(client, ddo, dt_contract, sa, cons_wallet)
    nonce = get_nonce(client, cons_wallet.address)

    # prepare consumer signature on did
    msg = f'{cons_wallet.address}{did}{nonce}'
    _hash = add_ethereum_prefix_and_hash_msg(msg)
    signature = Web3Helper.sign_hash(_hash, cons_wallet)

    # Start the compute job
    payload = dict({
        'signature': signature,
        'documentId': did,
        'serviceId': sa.index,
        'serviceType': sa.type,
        'consumerAddress': cons_wallet.address,
        'transferTxId': tx_id,
        'dataToken': data_token,
        'output': build_stage_output_dict(dict(), dataset_ddo_w_compute_service, cons_wallet.address, pub_wallet),
        'algorithmDid': alg_ddo.did,
        'algorithmMeta': {},
        'algorithmDataToken': alg_data_token
    })

    compute_endpoint = BaseURLs.ASSETS_URL + '/compute'
    response = client.post(
        compute_endpoint,
        data=json.dumps(payload),
        content_type='application/json'
    )
    assert response.status == '400 BAD REQUEST', f'start compute job failed: {response.status} , { response.data}'
    def execute(agreement_id, compute_ddo, workflow_ddo, consumer_account,
                brizo, index):
        """

        :param agreement_id:
        :param workflow_ddo:
        :param consumer_account:
        :param index:
        :return:
        """
        service_endpoint = ServiceAgreement.from_ddo(
            ServiceTypes.CLOUD_COMPUTE, compute_ddo).service_endpoint
        return brizo.execute_service(agreement_id, service_endpoint,
                                     consumer_account, workflow_ddo)
Beispiel #18
0
    def _read_dict(self, dictionary):
        """Import a JSON dict into this DDO."""
        values = copy.deepcopy(dictionary)
        self._did = values.pop('id')
        self._created = values.pop('created', None)

        if 'publicKey' in values:
            self._public_keys = []
            for value in values.pop('publicKey'):
                if isinstance(value, str):
                    value = json.loads(value)
                self._public_keys.append(DDO.create_public_key_from_json(value))
        if 'authentication' in values:
            self._authentications = []
            for value in values.pop('authentication'):
                if isinstance(value, str):
                    value = json.loads(value)
                self._authentications.append(DDO.create_authentication_from_json(value))
        if 'service' in values:
            self._services = []
            for value in values.pop('service'):
                if isinstance(value, str):
                    value = json.loads(value)

                if value['type'] == ServiceTypes.ASSET_ACCESS:
                    service = ServiceAgreement.from_json(value)
                elif value['type'] == ServiceTypes.CLOUD_COMPUTE:
                    service = ServiceAgreement.from_json(value)
                else:
                    service = Service.from_json(value)

                self._services.append(service)
        if 'proof' in values:
            self._proof = values.pop('proof')

        self._other_values = values
    def build_access_service(attributes, service_endpoint, template_id):
        """
        Build an authorization service.

        :param attributes: attributes of access service, dict
        :param service_endpoint: identifier of the service inside the asset DDO, str
        :param template_id: hex str the ethereum smart contract address of the
            service agreement template contract.
        :return: ServiceAgreement instance
        """
        sla_template_dict = get_sla_template()
        sla_template = ServiceAgreementTemplate(
            template_id, 'dataAssetAccessServiceAgreement',
            attributes['main']['creator'], sla_template_dict)
        return ServiceAgreement(attributes, sla_template, service_endpoint,
                                ServiceTypes.ASSET_ACCESS,
                                ServiceTypesIndices.DEFAULT_ACCESS_INDEX)
Beispiel #20
0
def build_stage_algorithm_dict(consumer_address,
                               algorithm_did,
                               algorithm_token_address,
                               algorithm_tx_id,
                               algorithm_meta,
                               provider_wallet,
                               receiver_address=None):
    if algorithm_did is not None:
        assert algorithm_token_address and algorithm_tx_id, \
            'algorithm_did requires both algorithm_token_address and algorithm_tx_id.'

        algo_asset = get_asset_from_metadatastore(get_metadata_url(),
                                                  algorithm_did)

        service = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS,
                                            algo_asset)
        _tx, _order_log, _transfer_log = validate_order(
            consumer_address, algorithm_token_address,
            float(service.get_cost()), algorithm_tx_id,
            add_0x_prefix(did_to_id(algorithm_did)) if
            algorithm_did.startswith('did:') else algorithm_did, service.index)
        validate_transfer_not_used_for_other_service(algorithm_did,
                                                     service.index,
                                                     algorithm_tx_id,
                                                     consumer_address,
                                                     algorithm_token_address)
        record_consume_request(algorithm_did, service.index, algorithm_tx_id,
                               consumer_address, algorithm_token_address,
                               service.get_cost())

        algo_id = algorithm_did
        raw_code = ''
        algo_url = get_asset_url_at_index(0, algo_asset, provider_wallet)
        container = algo_asset.metadata['main']['algorithm']['container']
    else:
        algo_id = ''
        algo_url = algorithm_meta.get('url')
        raw_code = algorithm_meta.get('rawcode')
        container = algorithm_meta.get('container')

    return dict({
        'id': algo_id,
        'url': algo_url,
        'rawcode': raw_code,
        'container': container
    })
Beispiel #21
0
def process_consume_request(data: dict):
    did = data.get("documentId")
    token_address = data.get("dataToken")
    consumer_address = data.get("consumerAddress")
    service_id = data.get("serviceId")
    service_type = data.get("serviceType")

    # grab asset for did from the metadatastore associated with
    # the Data Token address
    asset = get_asset_from_metadatastore(get_metadata_url(), did)
    service = ServiceAgreement.from_ddo(service_type, asset)
    if service.type != service_type:
        raise AssertionError(
            f"Requested service with id {service_id} has type {service.type} "
            f"which does not match the requested service type {service_type}."
        )

    return asset, service, did, consumer_address, token_address
Beispiel #22
0
def process_consume_request(data: dict,
                            method: str,
                            user_nonce: UserNonce = None,
                            additional_params: list = None,
                            require_signature: bool = True):

    required_attributes = [
        'documentId', 'serviceId', 'serviceType', 'dataToken',
        'consumerAddress'
    ]
    if additional_params:
        required_attributes += additional_params

    if require_signature:
        required_attributes.append('signature')

    msg, status = check_required_attributes(required_attributes, data, method)
    if msg:
        raise AssertionError(msg)

    did = data.get('documentId')
    token_address = data.get('dataToken')
    consumer_address = data.get('consumerAddress')
    service_id = data.get('serviceId')
    service_type = data.get('serviceType')

    # grab asset for did from the metadatastore associated with the Data Token address
    asset = get_asset_from_metadatastore(get_metadata_url(), did)
    service = ServiceAgreement.from_ddo(service_type, asset)
    if service.type != service_type:
        raise AssertionError(
            f'Requested service with id {service_id} has type {service.type} which '
            f'does not match the requested service type {service_type}.')

    if require_signature:
        assert user_nonce, '`user_nonce` is required when signature is required.'
        # Raises ValueError when signature is invalid
        signature = data.get('signature')
        verify_signature(consumer_address, signature, did,
                         user_nonce.get_nonce(consumer_address))

    return asset, service, did, consumer_address, token_address
def test_agreement():
    template_id = '0xda558ceb3abd482db04ea813810ae9c6cea5bf13ef9943908b1a8b51c4e56c7f'
    agreement_id = '0x' + ('e' * 64)
    access_id = '0x' + ('a' * 64)
    lock_id = '0x' + ('b' * 64)
    escrow_id = '0x' + ('c' * 64)

    signature = ServiceAgreement.generate_service_agreement_hash(
        template_id,
        [access_id, lock_id, escrow_id],
        [0, 0, 0],
        [0, 0, 0],
        agreement_id,
        generate_multi_value_hash
    )

    print({signature})
    assert (
        signature == Web3.toBytes(
            hexstr="0x3450be8127dbe156fad90956fd351df42ffcfabba89d230406a301ceb5b40f92"
        )), "The signature is not correct."
Beispiel #24
0
def ocean_assets_download_destination_file_helper(publisher_ocean_instance,
                                                  metadata, tmpdir):
    """Tests downloading to an existing directory."""
    publisher = get_publisher_wallet()
    metadata_copy = metadata.copy()
    data_provider = DataServiceProvider

    ddo = publisher_ocean_instance.assets.create(metadata_copy, publisher)
    wait_for_ddo(publisher_ocean_instance, ddo.did)
    sa = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, ddo)

    written_path = download_asset_files(
        sa.index,
        ddo,
        publisher,
        tmpdir,
        ddo.data_token_address,
        "test_order_tx_id",
        data_provider,
    )
    assert os.path.exists(written_path)
Beispiel #25
0
def test_ocean_assets_download_failure(publisher_ocean_instance, metadata):
    """Tests that downloading from an empty service raises an AssertionError."""
    publisher = get_publisher_wallet()
    metadata_copy = metadata.copy()
    data_provider = DataServiceProvider

    ddo = publisher_ocean_instance.assets.create(metadata_copy, publisher)
    wait_for_ddo(publisher_ocean_instance, ddo.did)
    sa = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, ddo)
    sa.__dict__["_service_endpoint"] = None
    ddo.__dict__["_services"][1] = sa

    with pytest.raises(AssertionError):
        download_asset_files(
            sa.index,
            ddo,
            publisher,
            "test_destination",
            ddo.data_token_address,
            "test_order_tx_id",
            data_provider,
        )
Beispiel #26
0
def test_market_flow():
    pub_wallet = get_publisher_wallet()

    publisher_ocean = get_publisher_ocean_instance()
    consumer_ocean = get_consumer_ocean_instance()

    # Register Asset
    asset = get_registered_ddo(publisher_ocean, pub_wallet)
    assert isinstance(asset, Asset)
    assert asset.data_token_address

    consumer_wallet = get_consumer_wallet()

    service = asset.get_service(service_type=ServiceTypes.ASSET_ACCESS)
    sa = ServiceAgreement.from_json(service.as_dictionary())

    # Mint data tokens and assign to publisher
    dt = publisher_ocean.get_data_token(asset.data_token_address)
    mint_tokens_and_wait(dt, pub_wallet.address, pub_wallet)

    ######
    # Give the consumer some datatokens so they can order the service
    try:
        tx_id = dt.transfer_tokens(consumer_wallet.address, 10, pub_wallet)
        dt.verify_transfer_tx(tx_id, pub_wallet.address,
                              consumer_wallet.address)
    except (AssertionError, Exception) as e:
        print(e)
        raise

    ######
    # Place order for the download service
    order_requirements = consumer_ocean.assets.order(asset.did,
                                                     consumer_wallet.address,
                                                     sa.index)

    ######
    # Pay for the service
    _order_tx_id = consumer_ocean.assets.pay_for_service(
        order_requirements.amount, order_requirements.data_token_address,
        asset.did, service.index, '0xF9f2DB837b3db03Be72252fAeD2f6E0b73E428b9',
        consumer_wallet)
    ######
    # Download the asset files
    asset_folder = consumer_ocean.assets.download(
        asset.did, sa.index, consumer_wallet, _order_tx_id,
        consumer_ocean.config.downloads_path)

    assert len(os.listdir(asset_folder)) > 1

    orders = consumer_ocean.get_user_orders(consumer_wallet.address,
                                            asset.asset_id)
    assert orders, f'no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}'

    orders = consumer_ocean.get_user_orders(
        consumer_wallet.address,
        consumer_ocean.web3.toChecksumAddress(asset.asset_id))
    assert orders, f'no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}'

    orders = consumer_ocean.get_user_orders(consumer_wallet.address)
    assert orders, f'no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}'
Beispiel #27
0
def test_market_flow(order_type):
    """Tests that an order is correctly placed on the market.

    The parameter implicit_none sends the payload with an empty key as the delegated consumer.
    The parameter explicit_none sends None as the delegated consumer, explicitly."""
    pub_wallet = get_publisher_wallet()

    publisher_ocean = get_publisher_ocean_instance()
    consumer_ocean = get_consumer_ocean_instance()

    # Register Asset
    asset = get_registered_ddo(publisher_ocean, get_metadata(), pub_wallet)
    assert isinstance(asset, Asset)
    assert asset.data_token_address

    consumer_wallet = get_consumer_wallet()

    service = asset.get_service(service_type=ServiceTypes.ASSET_ACCESS)
    sa = ServiceAgreement.from_json(service.as_dictionary())

    # Mint data tokens and assign to publisher
    dt = publisher_ocean.get_data_token(asset.data_token_address)
    mint_tokens_and_wait(dt, pub_wallet.address, pub_wallet)

    ######
    # Give the consumer some datatokens so they can order the service
    try:
        tx_id = dt.transfer_tokens(consumer_wallet.address, 10.0, pub_wallet)
        dt.verify_transfer_tx(tx_id, pub_wallet.address,
                              consumer_wallet.address)
    except (AssertionError, Exception) as e:
        print(e)
        raise

    ######
    # Place order for the download service
    order_requirements = consumer_ocean.assets.order(asset.did,
                                                     consumer_wallet.address,
                                                     sa.index)

    ######
    # Pay for the service
    args = [
        order_requirements.amount,
        order_requirements.data_token_address,
        asset.did,
        service.index,
        "0xF9f2DB837b3db03Be72252fAeD2f6E0b73E428b9",
        consumer_wallet,
    ]

    if order_type == "explicit_none":
        args.append(None)

    _order_tx_id = consumer_ocean.assets.pay_for_service(*args)

    ######
    # Download the asset files
    asset_folder = consumer_ocean.assets.download(
        asset.did,
        sa.index,
        consumer_wallet,
        _order_tx_id,
        consumer_ocean.config.downloads_path,
    )

    assert len(os.listdir(asset_folder)) >= 1

    if order_type == "explicit_none":
        # no need to continue, order worked
        return

    orders = consumer_ocean.get_user_orders(consumer_wallet.address,
                                            asset.asset_id)
    assert (
        orders
    ), f"no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}"

    orders = consumer_ocean.get_user_orders(
        consumer_wallet.address,
        consumer_ocean.web3.toChecksumAddress(asset.asset_id))
    assert (
        orders
    ), f"no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}"

    orders = consumer_ocean.get_user_orders(consumer_wallet.address)
    assert (
        orders
    ), f"no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}"
Beispiel #28
0
def test_payer_market_flow():
    """Tests that an order can be placed for a delegated consumer, other than the payer."""
    pub_wallet = get_publisher_wallet()

    publisher_ocean = get_publisher_ocean_instance()
    consumer_ocean = get_consumer_ocean_instance()
    another_consumer_ocean = get_another_consumer_ocean_instance(
        use_provider_mock=True)

    # Register Asset
    asset = get_registered_ddo(publisher_ocean, get_metadata(), pub_wallet)
    assert isinstance(asset, Asset)
    assert asset.data_token_address

    another_consumer_wallet = get_another_consumer_wallet()
    consumer_wallet = get_consumer_wallet()

    service = asset.get_service(service_type=ServiceTypes.ASSET_ACCESS)
    sa = ServiceAgreement.from_json(service.as_dictionary())

    # Mint data tokens and assign to publisher
    dt = publisher_ocean.get_data_token(asset.data_token_address)
    mint_tokens_and_wait(dt, pub_wallet.address, pub_wallet)

    ######
    # Give the consumer some datatokens so they can order the service
    try:
        tx_id = dt.transfer_tokens(consumer_wallet.address, 10.0, pub_wallet)
        dt.verify_transfer_tx(tx_id, pub_wallet.address,
                              consumer_wallet.address)
    except (AssertionError, Exception) as e:
        print(e)
        raise

    ######
    # Place order for the download service
    order_requirements = consumer_ocean.assets.order(
        asset.did, another_consumer_wallet.address, sa.index)

    ######
    # Pay for the service and have another_consumer_wallet as consumer
    _order_tx_id = consumer_ocean.assets.pay_for_service(
        order_requirements.amount,
        order_requirements.data_token_address,
        asset.did,
        service.index,
        "0xF9f2DB837b3db03Be72252fAeD2f6E0b73E428b9",
        consumer_wallet,
        another_consumer_wallet.address,
    )
    asset_folder = None
    assert asset_folder is None
    if asset_folder is None:
        # Download the asset files
        asset_folder = another_consumer_ocean.assets.download(
            asset.did,
            sa.index,
            another_consumer_wallet,
            _order_tx_id,
            another_consumer_ocean.config.downloads_path,
        )
    assert len(os.listdir(asset_folder)) >= 1

    orders = consumer_ocean.get_user_orders(consumer_wallet.address,
                                            asset.asset_id)
    assert (
        orders
    ), f"no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}"

    orders = consumer_ocean.get_user_orders(
        consumer_wallet.address,
        consumer_ocean.web3.toChecksumAddress(asset.asset_id))
    assert (
        orders
    ), f"no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}"

    orders = consumer_ocean.get_user_orders(consumer_wallet.address)
    assert (
        orders
    ), f"no orders found using the order history: datatoken {asset.asset_id}, consumer {consumer_wallet.address}"
Beispiel #29
0
def buy_asset():
    """
    Requires all ocean services running.

    """
    setup_logging(default_level=logging.INFO)
    ConfigProvider.set_config(ExampleConfig.get_config())
    config = ConfigProvider.get_config()
    providers = {
        'duero': '0xfEF2d5e1670342b9EF22eeeDcb287EC526B48095',
        'nile': '0x4aaab179035dc57b35e2ce066919048686f82972'
    }
    # make ocean instance
    ocn = Ocean()
    acc = get_account(1)
    if not acc:
        acc = ([acc for acc in ocn.accounts.list() if acc.password] or ocn.accounts.list())[0]

    Diagnostics.verify_contracts()
    metadata = example_metadata.metadata.copy()
    metadata['main']['dateCreated'] = get_timestamp()
    keeper = Keeper.get_instance()
    # Register ddo
    did = ''
    if did:
        ddo = ocn.assets.resolve(did)
        logging.info(f'using ddo: {did}')
    else:

        ddo = ocn.assets.create(metadata, acc, providers=[], use_secret_store=True)
        assert ddo is not None, f'Registering asset on-chain failed.'
        did = ddo.did
        logging.info(f'registered ddo: {did}')
        # ocn here will be used only to publish the asset. Handling the asset by the publisher
        # will be performed by the Brizo server running locally
        test_net = os.environ.get('TEST_NET', '')
        if test_net.startswith('nile'):
            provider = keeper.did_registry.to_checksum_address(providers['nile'])
        elif test_net.startswith('duero'):
            provider = keeper.did_registry.to_checksum_address(providers['duero'])
        else:
            provider = '0x068Ed00cF0441e4829D9784fCBe7b9e26D4BD8d0'

        # Wait for did registry event
        event = keeper.did_registry.subscribe_to_event(
            keeper.did_registry.DID_REGISTRY_EVENT_NAME,
            30,
            event_filter={
                '_did': Web3Provider.get_web3().toBytes(hexstr=ddo.asset_id),
                '_owner': acc.address},
            wait=True
        )
        if not event:
            logging.warning(f'Failed to get the did registry event for asset with did {did}.')
        assert keeper.did_registry.get_block_number_updated(ddo.asset_id) > 0, \
            f'There is an issue in registering asset {did} on-chain.'

        keeper.did_registry.add_provider(ddo.asset_id, provider, acc)
        logging.info(f'is {provider} set as did provider: '
                     f'{keeper.did_registry.is_did_provider(ddo.asset_id, provider)}')

    _providers = keeper.did_registry.get_did_providers(ddo.asset_id)

    access_template_name = keeper.template_manager.SERVICE_TO_TEMPLATE_NAME['access']
    template_id = keeper.template_manager.create_template_id(access_template_name)
    approved = keeper.template_manager.is_template_approved(template_id)
    print(f'agreement template approved: {approved}')
    template_data = keeper.template_manager.get_template(template_id)
    print(f'access agreement template: {template_data}')
    cons_ocn = Ocean()
    consumer_account = get_account(0)

    # sign agreement using the registered asset did above
    service = ddo.get_service(service_type=ServiceTypes.ASSET_ACCESS)
    # This will send the order request to Brizo which in turn will execute the agreement on-chain
    cons_ocn.accounts.request_tokens(consumer_account, 10)
    sa = ServiceAgreement.from_json(service.as_dictionary())
    agreement_id = ''
    if not agreement_id:
        agreement_id = cons_ocn.assets.order(
            did, sa.index, consumer_account)

    logging.info('placed order: %s, %s', did, agreement_id)
    event = keeper.agreement_manager.subscribe_agreement_created(
        agreement_id, 60, None, (), wait=True
    )
    assert event, "Agreement event is not found, check the keeper node's logs"
    logging.info(f'Got agreement event, next: lock reward condition')

    event = keeper.lock_reward_condition.subscribe_condition_fulfilled(
        agreement_id, 60, None, (), wait=True
    )
    assert event, "Lock reward condition fulfilled event is not found, check the keeper node's logs"
    logging.info('Got lock reward event, next: wait for the access condition..')

    event = keeper.access_secret_store_condition.subscribe_condition_fulfilled(
        agreement_id, 15, None, (), wait=True
    )
    logging.info(f'Got access event {event}')
    i = 0
    while ocn.agreements.is_access_granted(
            agreement_id, did, consumer_account.address) is not True and i < 30:
        time.sleep(1)
        i += 1

    assert ocn.agreements.is_access_granted(agreement_id, did, consumer_account.address)

    ocn.assets.consume(
        agreement_id,
        did,
        sa.index,
        consumer_account,
        config.downloads_path)
    logging.info('Success buying asset.')

    event = keeper.escrow_reward_condition.subscribe_condition_fulfilled(
        agreement_id,
        30,
        None,
        (),
        wait=True
    )
    assert event, 'no event for EscrowReward.Fulfilled'
    logging.info(f'got EscrowReward.FULFILLED event: {event}')
    logging.info('Done buy asset.')
Beispiel #30
0
def test_ocean_assets_download_indexes(publisher_ocean_instance, metadata):
    """Tests different values of indexes that raise AssertionError."""
    publisher = get_publisher_wallet()
    metadata_copy = metadata.copy()
    data_provider = DataServiceProvider

    ddo = publisher_ocean_instance.assets.create(metadata_copy, publisher)
    wait_for_ddo(publisher_ocean_instance, ddo.did)
    sa = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, ddo)

    config = Config(os.getenv(ENV_CONFIG_FILE))

    index = range(3)
    if config["util"].getboolean("typecheck"):
        with pytest.raises(TypeError):
            download_asset_files(
                sa.index,
                ddo,
                publisher,
                "test_destination",
                ddo.data_token_address,
                "test_order_tx_id",
                data_provider,
                index,
            )
    else:
        with pytest.raises(AssertionError):
            download_asset_files(
                sa.index,
                ddo,
                publisher,
                "test_destination",
                ddo.data_token_address,
                "test_order_tx_id",
                data_provider,
                index,
            )

    index = -1
    with pytest.raises(AssertionError):
        download_asset_files(
            sa.index,
            ddo,
            publisher,
            "test_destination",
            ddo.data_token_address,
            "test_order_tx_id",
            data_provider,
            index,
        )
    index = 4
    with pytest.raises(AssertionError):
        download_asset_files(
            sa.index,
            ddo,
            publisher,
            "test_destination",
            ddo.data_token_address,
            "test_order_tx_id",
            data_provider,
            index,
        )