Пример #1
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,
    )
Пример #2
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}'
Пример #3
0
def publish_asset(metadata, publisher_wallet):
    ocean = Ocean(config=Config(options_dict=get_config_dict()))

    # create compute service
    compute_descriptor = build_compute_descriptor(ocean, publisher_wallet.address)

    # create asset DDO and datatoken
    try:
        asset = ocean.assets.create(metadata, publisher_wallet, [compute_descriptor], dt_name='Compute with data6', dt_symbol='DT-Testx7')
        print(f'Dataset asset created successfully: did={asset.did}, datatoken={asset.data_token_address}')
        #Dataset asset created successfully: did=did:op:2cbDb0Aaa1F546829E31267d1a7F74d926Bb5B1B, datatoken=0x2cbDb0Aaa1F546829E31267d1a7F74d926Bb5B1B
    except Exception as e:
        print(f'Publishing asset failed: {e}')
        return None, None

    dt = DataToken(asset.data_token_address)
    txid = dt.mint_tokens(publisher_wallet.address, 100, publisher_wallet)
    receipt = dt.get_tx_receipt(txid)
    assert receipt and receipt.status == 1, f'datatoken mint failed: tx={txid}, txReceipt={receipt}'


    # Create datatoken liquidity pool for the new asset
    pool = ocean.pool.create(asset.data_token_address, 50, 5, publisher_wallet, 5) #50 datatokens - 5 ocean in pool
    print(f'datatoken liquidity pool was created at address {pool.address}')
    #datatoken liquidity pool was created at address 0xeaD638506951B4a4c3575bbC0c7D1491c17B7A08
    # Now the asset can be discovered and consumed
    dt_cost = ocean.pool.calcInGivenOut(pool.address, ocean.OCEAN_address, asset.data_token_address, 1.0)
    print(f'Asset {asset.did} can now be purchased from pool @{pool.address} '
          f'at the price of {dt_cost} OCEAN tokens.')
    return asset, pool
Пример #4
0
    def is_dispensable(self, dt_address: str, amount: int,
                       to_wallet: Wallet) -> bool:
        """
        :return: bool
        """
        if not amount:
            return False

        token = DataToken(self.web3, dt_address)
        if not self.is_active(dt_address):
            return False

        user_balance = token.balanceOf(to_wallet.address)
        max_balance = self.max_balance(dt_address)

        if user_balance >= max_balance:
            return False

        max_tokens = self.max_balance(dt_address)
        if amount > max_tokens:
            return False

        is_true_minter = self.is_true_minter(dt_address)
        if is_true_minter:
            return True

        contract_balance = self.balance(dt_address)
        if contract_balance >= amount:
            return True

        return False
Пример #5
0
 def cancel_minter(self, dt_address: str, from_wallet: Wallet) -> str:
     """
     :return: hex str transaction hash
     """
     self.send_transaction("removeMinter", (dt_address, ), from_wallet)
     token = DataToken(self.web3, dt_address)
     return token.approveMinter(from_wallet)
Пример #6
0
    def get_user_orders(
        self,
        address: str,
        datatoken: Optional[str] = None,
        service_id: Optional[int] = None,
    ) -> List[Order]:
        """
        :return: List of orders `[Order]`
        """
        dt = DataToken(self.web3, datatoken)
        _orders = []
        for log in dt.get_start_order_logs(
            address, from_all_tokens=not bool(datatoken)
        ):
            a = dict(log.args.items())
            a["amount"] = int(log.args.amount)
            a["marketFee"] = int(log.args.marketFee)
            a = AttributeDict(a.items())

            # 'datatoken', 'amount', 'timestamp', 'transactionId', 'did', 'payer', 'consumer', 'serviceId', 'serviceType'
            order = Order(
                log.address,
                a.amount,
                a.timestamp,
                log.transactionHash,
                f"did:op:{remove_0x_prefix(log.address)}",
                a.payer,
                a.consumer,
                a.serviceId,
                None,
            )
            if service_id is None or order.serviceId == service_id:
                _orders.append(order)

        return _orders
Пример #7
0
def process_order(ocean_instance, publisher_wallet, consumer_wallet, ddo,
                  service_type):
    """Helper function to process a compute order."""
    # Give the consumer some datatokens so they can order the service
    try:
        dt = DataToken(ddo.data_token_address)
        tx_id = dt.transfer_tokens(consumer_wallet.address, 10,
                                   publisher_wallet)
        dt.verify_transfer_tx(tx_id, publisher_wallet.address,
                              consumer_wallet.address)
    except (AssertionError, Exception) as e:
        print(e)
        raise

    # Order compute service from the dataset asset
    order_requirements = ocean_instance.assets.order(ddo.did,
                                                     consumer_wallet.address,
                                                     service_type=service_type)

    # Start the order on-chain using the `order` requirements from previous step
    service = ddo.get_service(service_type)
    consumer = consumer_wallet.address
    if service_type == ServiceTypes.ASSET_ACCESS and order_requirements.computeAddress:
        consumer = order_requirements.computeAddress

    _order_tx_id = ocean_instance.assets.pay_for_service(
        order_requirements.amount,
        order_requirements.data_token_address,
        ddo.did,
        service.index,
        ZERO_ADDRESS,
        consumer_wallet,
        consumer,
    )
    return _order_tx_id, order_requirements, service
Пример #8
0
    def buy_data_tokens(
        self, pool_address: str, amount: int, max_OCEAN_amount: int, from_wallet: Wallet
    ) -> str:
        """
        Buy data tokens from this pool, paying `max_OCEAN_amount` of OCEAN tokens.
        If total spent <= max_OCEAN_amount.
        - Caller is spending OCEAN tokens, and receiving `amount` DataTokens
        - OCEAN tokens are going into pool, DataTokens are going out of pool

        The transaction fails if total spent exceeds `max_OCEAN_amount`.

        :param pool_address: str address of pool contract
        :param amount: int number of data tokens to add to this pool in *base*
        :param max_OCEAN_amount:
        :param from_wallet:
        :return: str transaction id/hash
        """
        ocean_tok = DataToken(self.web3, self.ocean_address)
        if ocean_tok.balanceOf(from_wallet.address) < max_OCEAN_amount:
            raise InsufficientBalance("Insufficient funds for buying DataTokens!")
        if ocean_tok.allowance(from_wallet.address, pool_address) < max_OCEAN_amount:
            ocean_tok.approve(pool_address, max_OCEAN_amount, from_wallet)

        dtoken_address = self.get_token_address(pool_address)
        pool = BPool(self.web3, pool_address)
        return pool.swapExactAmountOut(
            tokenIn_address=self.ocean_address,  # entering pool
            maxAmountIn=max_OCEAN_amount,  # ""
            tokenOut_address=dtoken_address,  # leaving pool
            tokenAmountOut=amount,  # ""
            maxPrice=2 ** 255,  # here we limit by max_num_OCEAN, not price
            from_wallet=from_wallet,
        )
Пример #9
0
    def buy_at_fixed_rate(
        self,
        amount: float,
        wallet: Wallet,
        max_OCEAN_amount: float,
        exchange_id: str = "",
        data_token: str = "",
        exchange_owner: str = "",
    ) -> bool:

        exchange, exchange_id = self.get_exchange_id_fallback_dt_and_owner(
            exchange_id, exchange_owner, data_token)

        amount_base = to_base_18(amount)
        max_OCEAN_amount_base = to_base_18(max_OCEAN_amount)

        # Figure out the amount of ocean tokens to approve before triggering the exchange function to do the swap
        ocean_amount_base = exchange.get_base_token_quote(
            exchange_id, amount_base)
        if ocean_amount_base > max_OCEAN_amount_base:
            raise ValidationError(
                f"Buying {amount} datatokens requires {from_base_18(ocean_amount_base)} OCEAN "
                f"tokens which exceeds the max_OCEAN_amount {max_OCEAN_amount}."
            )
        ocean_token = DataToken(self.ocean_address)
        ocean_token.get_tx_receipt(
            ocean_token.approve(self._exchange_address, ocean_amount_base,
                                wallet))
        tx_id = exchange.buy_data_token(exchange_id,
                                        data_token_amount=amount_base,
                                        from_wallet=wallet)
        return bool(exchange.get_tx_receipt(tx_id).status)
Пример #10
0
def setup_all():
    config = ExampleConfig.get_config()
    ConfigProvider.set_config(config)
    Web3Provider.init_web3(
        provider=get_web3_connection_provider(config.network_url))
    ContractHandler.set_artifacts_path(config.artifacts_path)

    network = Web3Helper.get_network_name()
    wallet = get_ganache_wallet()
    if network in ["ganache", "development"] and wallet:

        print(
            f"sender: {wallet.key}, {wallet.address}, {wallet.password}, {wallet.keysStr()}"
        )
        print(
            f"sender balance: {Web3Helper.from_wei(Web3Helper.get_ether_balance(wallet.address))}"
        )
        assert Web3Helper.from_wei(Web3Helper.get_ether_balance(
            wallet.address)) > 10

        from ocean_lib.models.data_token import DataToken

        OCEAN_token = DataToken(get_ocean_token_address(network))
        amt_distribute = 1000
        amt_distribute_base = to_base_18(float(amt_distribute))
        for w in (get_publisher_wallet(), get_consumer_wallet()):
            if Web3Helper.from_wei(Web3Helper.get_ether_balance(
                    w.address)) < 2:
                Web3Helper.send_ether(wallet, w.address, 4)

            if OCEAN_token.token_balance(w.address) < 100:
                OCEAN_token.transfer(w.address,
                                     amt_distribute_base,
                                     from_wallet=wallet)
Пример #11
0
    def buy_data_tokens(self, pool_address: str, amount: float,
                        max_OCEAN_amount: float, from_wallet: Wallet) -> str:
        """
        Buy data tokens from this pool, paying `max_OCEAN_amount_base` of OCEAN tokens.
        If total spent <= max_OCEAN_amount_base.
        - Caller is spending OCEAN tokens, and receiving `amount_base` DataTokens
        - OCEAN tokens are going into pool, DataTokens are going out of pool

        The transaction fails if total spent exceeds `max_OCEAN_amount_base`.

        :param pool_address: str address of pool contract
        :param amount: int number of data tokens to add to this pool in *base*
        :param max_OCEAN_amount:
        :param from_wallet:
        :return: str transaction id/hash
        """
        ocean_tok = DataToken(self.ocean_address)
        ocean_tok.approve_tokens(pool_address,
                                 max_OCEAN_amount,
                                 from_wallet,
                                 wait=True)

        dtoken_address = self.get_token_address(pool_address)
        pool = BPool(pool_address)
        return pool.swapExactAmountOut(
            tokenIn_address=self.ocean_address,  # entering pool
            maxAmountIn_base=to_base_18(max_OCEAN_amount),  # ""
            tokenOut_address=dtoken_address,  # leaving pool
            tokenAmountOut_base=to_base_18(amount),  # ""
            maxPrice_base=2**255,  # here we limit by max_num_OCEAN, not price
            from_wallet=from_wallet,
        )
Пример #12
0
def resolve_asset(
    did: str,
    metadata_cache_uri: Optional[str] = None,
    web3: Optional[Web3] = None,
    token_address: Optional[str] = None,
) -> V3Asset:
    """Resolve a DID to an URL/DDO or later an internal/external DID.

    :param did: the asset id to resolve, this is part of the ocean
        DID did:op:<32 byte value>
    :param metadata_cache_uri: str the url of the metadata store
    :param web3: Web3 instance
    :param token_address: str the address of the DataToken smart contract

    :return Asset: the resolved DID
    """
    assert metadata_cache_uri or (
        web3 and token_address
    ), "Either metadata_cache_uri or (web3 and token_address) is required."

    if not metadata_cache_uri:
        metadata_cache_uri = DataToken(web3, token_address).get_metadata_url()

    logger.debug(f"found did {did} -> url={metadata_cache_uri}")
    ddo = AquariusProvider.get_aquarius(metadata_cache_uri).get_asset_ddo(did)

    if ddo:
        return V3Asset(dictionary=ddo.as_dictionary())
Пример #13
0
    def get_data_token(self, token_address: str) -> DataToken:
        """
        :param token_address: Token contract address, str
        :return: `Datatoken` instance
        """

        return DataToken(self.web3, token_address)
Пример #14
0
    def buy_at_fixed_rate(self,
                          amount: float,
                          wallet: Wallet,
                          max_OCEAN_amount: float,
                          exchange_id: str = '',
                          data_token: str = '',
                          exchange_owner: str = '') -> bool:

        exchange = self._exchange_contract()
        if not exchange_id:
            assert exchange_owner and data_token, f'exchange_owner and data_token are required when exchange_id is not given.'
            exchange_id = exchange.generateExchangeId(self.ocean_address,
                                                      data_token,
                                                      exchange_owner)

        amount_base = to_base_18(amount)
        max_OCEAN_amount_base = to_base_18(max_OCEAN_amount)

        # Figure out the amount of ocean tokens to approve before triggering the exchange function to do the swap
        ocean_amount_base = exchange.get_base_token_quote(
            exchange_id, amount_base)
        if ocean_amount_base > max_OCEAN_amount_base:
            raise AssertionError(
                f'Buying {amount} datatokens requires {from_base_18(ocean_amount_base)} OCEAN '
                f'tokens which exceeds the max_OCEAN_amount {max_OCEAN_amount}.'
            )
        ocean_token = DataToken(self.ocean_address)
        ocean_token.get_tx_receipt(
            ocean_token.approve(self._exchange_address, ocean_amount_base,
                                wallet))
        tx_id = exchange.buy_data_token(exchange_id,
                                        data_token_amount=amount_base,
                                        from_wallet=wallet)
        return bool(exchange.get_tx_receipt(tx_id).status)
Пример #15
0
def _deployAndMintToken(symbol: str, to_address: str) -> btoken.BToken:
    wallet = get_factory_deployer_wallet(_NETWORK)
    dt_address = DataToken.deploy(
        wallet.web3,
        wallet,
        None,
        "Template Contract",
        "TEMPLATE",
        wallet.address,
        to_base_18(1000),
        DTFactory.FIRST_BLOB,
        to_address,
    )
    dt_factory = DTFactory(
        DTFactory.deploy(wallet.web3, wallet, None, dt_address, to_address)
    )
    token_address = dt_factory.get_token_address(
        dt_factory.createToken(
            symbol, symbol, symbol, DataToken.DEFAULT_CAP_BASE, wallet
        )
    )
    token = DataToken(token_address)
    token.mint(to_address, to_base_18(1000), wallet)

    return btoken.BToken(token.address)
Пример #16
0
def publish_asset(metadata, publisher_wallet):
    ocean = Ocean(config=Config(options_dict=get_config_dict()))

    # create compute service
    compute_descriptor = build_compute_descriptor(ocean, publisher_wallet.address)

    # create asset DDO and datatoken
    try:
        asset = ocean.assets.create(metadata, publisher_wallet, [compute_descriptor],
                        dt_name='Dataset with Compute', dt_symbol='DT-Compute')
        print(f'Dataset asset created successfully: did={asset.did}, datatoken={asset.data_token_address}')
    except Exception as e:
        print(f'Publishing asset failed: {e}')
        return None, None

    dt = DataToken(asset.data_token_address)
    txid = dt.mint_tokens(publisher_wallet.address, 100, publisher_wallet)
    receipt = dt.get_tx_receipt(txid)
    assert receipt and receipt.status == 1, f'datatoken mint failed: tx={txid}, txReceipt={receipt}'

    # Create datatoken liquidity pool for the new asset
    pool = ocean.pool.create(asset.data_token_address, 50, 50, publisher_wallet, 5)
    print(f'datatoken liquidity pool was created at address {pool.address}')

    # Now the asset can be discovered and consumed
    dt_cost = ocean.pool.calcInGivenOut(pool.address, ocean.OCEAN_address, asset.data_token_address, 1.0)
    print(f'Asset {asset.did} can now be purchased from pool @{pool.address} '
          f'at the price of {dt_cost} OCEAN tokens.')
    return asset, pool
Пример #17
0
    def get_user_orders(self, address, datatoken=None, service_id=None):
        dt = DataToken(datatoken)
        _orders = []
        for log in dt.get_start_order_logs(
                self._web3, address, from_all_tokens=not bool(datatoken)):
            a = dict(log.args.items())
            a["amount"] = from_base_18(int(log.args.amount))
            a["marketFee"] = from_base_18(int(log.args.marketFee))
            a = AttributeDict(a.items())

            # 'datatoken', 'amount', 'timestamp', 'transactionId', 'did', 'payer', 'consumer', 'serviceId', 'serviceType'
            order = Order(
                log.address,
                a.amount,
                a.timestamp,
                log.transactionHash,
                f"did:op:{remove_0x_prefix(log.address)}",
                a.payer,
                a.consumer,
                a.serviceId,
                None,
            )
            if service_id is None or order.serviceId == service_id:
                _orders.append(order)

        return _orders
Пример #18
0
def get_datatoken_minter(asset, datatoken_address):
    publisher = Web3Provider.get_web3().toChecksumAddress(asset.publisher)
    dt = DataToken(datatoken_address)
    if not dt.contract_concise.isMinter(publisher):
        raise AssertionError(f'ddo publisher {publisher} is not the current '
                             f'minter for the DataToken contract at {datatoken_address}.')
    return publisher
Пример #19
0
    def pay_for_service(
        amount: float,
        token_address: str,
        did: str,
        service_id: int,
        fee_receiver: str,
        from_wallet: Wallet,
        consumer: str,
    ) -> str:
        """
        Submits the payment for chosen service in DataTokens.

        :param amount:
        :param token_address:
        :param did:
        :param service_id:
        :param fee_receiver:
        :param from_wallet: Wallet instance
        :param consumer: str the address of consumer of the service, defaults to the payer (the `from_wallet` address)
        :return: hex str id of transfer transaction
        """
        amount_base = to_base_18(amount)
        dt = DataToken(token_address)
        balance = dt.balanceOf(from_wallet.address)
        if balance < amount_base:
            raise AssertionError(
                f"Your token balance {balance} is not sufficient "
                f"to execute the requested service. This service "
                f"requires {amount_base} number of tokens.")

        if did.startswith("did:"):
            did = add_0x_prefix(did_to_id(did))

        if fee_receiver is None:
            fee_receiver = ZERO_ADDRESS

        if consumer is None:
            consumer = from_wallet.address

        tx_hash = dt.startOrder(consumer, amount_base, service_id,
                                fee_receiver, from_wallet)

        try:
            dt.verify_order_tx(
                Web3Provider.get_web3(),
                tx_hash,
                did,
                service_id,
                amount_base,
                from_wallet.address,
            )
            return tx_hash
        except (AssertionError, Exception) as e:
            msg = (
                f"Downloading asset files failed. The problem is related to "
                f"the transfer of the data tokens required for the download "
                f"service: {e}")
            logger.error(msg)
            raise AssertionError(msg)
Пример #20
0
 def make_minter(self, dt_address: str, from_wallet: Wallet) -> str:
     """
     :return: hex str transaction hash
     """
     token = DataToken(self.web3, dt_address)
     token.proposeMinter(self.address, from_wallet=from_wallet)
     return self.send_transaction("acceptMinter", (dt_address, ),
                                  from_wallet)
Пример #21
0
def test_order(web3, alice_ocean, alice_wallet):
    asset = get_registered_ddo(alice_ocean, get_metadata(), alice_wallet)
    dt = DataToken(web3, asset.data_token_address)

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

    order_requirements = alice_ocean.assets.order(
        asset.did, alice_wallet.address, sa.index
    )
    assert order_requirements, "Order was unsuccessful."

    _order_tx_id = alice_ocean.assets.pay_for_service(
        web3,
        order_requirements.amount,
        order_requirements.data_token_address,
        asset.did,
        service.index,
        alice_wallet.address,
        alice_wallet,
        sa.get_c2d_address(),
    )

    asset_folder = alice_ocean.assets.download(
        asset.did,
        sa.index,
        alice_wallet,
        _order_tx_id,
        alice_ocean.config.downloads_path,
    )

    assert len(os.listdir(asset_folder)) >= 1, "The asset folder is empty."
    for order_log in dt.get_start_order_logs():
        order_log_dict = dict(order_log.args.items())
        order_log_dict["amount"] = int(order_log.args.amount)
        order_log_dict["marketFee"] = int(order_log.args.marketFee)

        order_args = [
            order_log.address,
            order_log_dict["amount"],
            order_log_dict["timestamp"],
            order_log.transactionHash,
            f"did:op:{remove_0x_prefix(order_log.address)}",
            order_log_dict["payer"],
            order_log_dict["consumer"],
            order_log_dict["serviceId"],
            None,
        ]

        order = Order(*order_args)
        assert order, "The order does not exist."
        assert isinstance(order, tuple), "Order is not a tuple."
        assert (
            order[0] == asset.data_token_address
        ), "The order data token address is different."
        assert order[5] == alice_wallet.address, "The payer is not the supposed one."
        assert order[6] == sa.get_c2d_address(), "The consumer is not the supposed one."
        assert len(order) == 9, "Different number of args."
Пример #22
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}'
Пример #23
0
 def _get_num_assets(_minter):
     dids = [
         add_0x_prefix(did_to_id(a))
         for a in ocn.assets.owner_assets(_minter)
     ]
     dids = [a for a in dids if len(a) == 42]
     return len([
         a for a in dids if DataToken(a).contract_concise.isMinter(_minter)
     ])
Пример #24
0
def run_compute(did, consumer_wallet, algorithm_file, pool_address, order_id=None):
    ocean = Ocean(config=Config(options_dict=get_config_dict()))

    # Get asset DDO/metadata and service
    asset = ocean.assets.resolve(did)
    service = asset.get_service(ServiceTypes.CLOUD_COMPUTE)

    # check the price in ocean tokens
    num_ocean = ocean.pool.calcInGivenOut(pool_address, ocean.OCEAN_address, asset.data_token_address, 1.0)

    # buy datatoken to be able to run the compute service
    dt = DataToken(asset.asset_id)
    dt_balance = dt.token_balance(consumer_wallet.address)
    if dt_balance < 1.0:
        pool = BPool(pool_address)
        txid = ocean.pool.buy_data_tokens(pool_address, 1.0, num_ocean+0.1, consumer_wallet)
        receipt = pool.get_tx_receipt(txid)
        if not receipt or receipt.status != 1:
            print(f'buying data token failed: txId={txid}, txReceipt={receipt}')
            return None, None

    tx_id = order_id
    if not tx_id:
        tx_id = ocean.assets.pay_for_service(1.0, asset.data_token_address, did, service.index,
                                             fee_receiver=asset.publisher, from_wallet=consumer_wallet)

    # load python algorithm to run in the compute job
    with open(algorithm_file) as f:
        algorithm_text = f.read()

    # whether to publish the algorithm results as an Ocean assets
    output_dict = {
        'publishOutput': False,
        'publishAlgorithmLog': False,
    }
    # start the compute job (submit the compute service request)
    algorithm_meta = AlgorithmMetadata(
        {
            'language': 'python',
            'rawcode': algorithm_text,
            'container': {
                'tag': 'latest',
                'image': 'amancevice/pandas',
                'entrypoint': 'python $ALGO'
            }
        }
    )
    job_id = ocean.compute.start(did, consumer_wallet, tx_id, algorithm_meta=algorithm_meta, output=output_dict)

    # check the status of the compute job
    status = ocean.compute.status(did, job_id, consumer_wallet)
    print(f'status of compute job {job_id}: {status}')

    # get the result of the compute run
    result = ocean.compute.result(did, job_id, consumer_wallet)
    print(f'got result of compute job {job_id}: {result}')
    return job_id, status
Пример #25
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)
Пример #27
0
    def get_token_minter(self, token_address):
        """Retrieves token minter.

        This function will be deprecated in the next major release.
        It's only kept for backwards compatibility."""
        from ocean_lib.models.data_token import DataToken  # isort:skip

        dt = DataToken(address=token_address)

        return dt.contract_concise.minter()
Пример #28
0
def test_get_token_minter(web3, alice_wallet, dtfactory_address, alice_address):
    """Tests proper retrieval of token minter from DTFactory."""
    dtfactory = DTFactory(web3, dtfactory_address)

    dt_address = dtfactory.createToken(
        "foo_blob", "DT1", "DT1", to_wei(1000), from_wallet=alice_wallet
    )
    dt = DataToken(web3, dtfactory.get_token_address(dt_address))
    dt.mint(alice_address, to_wei(10), from_wallet=alice_wallet)
    assert dtfactory.get_token_minter(dt.address) == alice_address
Пример #29
0
def validate_order(sender, token_address, num_tokens, tx_id, did, service_id):
    dt_contract = DataToken(token_address)

    try:
        amount = to_base_18(num_tokens)
        tx, order_event, transfer_event = dt_contract.verify_order_tx(
            Web3Provider.get_web3(), tx_id, did, service_id, amount, sender)
        return tx, order_event, transfer_event
    except AssertionError:
        raise
Пример #30
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}'