def execute_computation(event, agreement_id, did, service_agreement, consumer_account, consume_callback, workflow_did): """ Consumption of an asset after get the event call. :param event: AttributeDict with the event data. :param agreement_id: id of the agreement, hex str :param did: DID, str :param service_agreement: ServiceAgreement instance :param consumer_account: Account instance of the consumer :param consume_callback: :param secret_store_url: str URL of secret store node for retrieving decryption keys :param parity_url: str URL of parity client to use for secret store encrypt/decrypt :param downloads_path: str path to save downloaded files """ logger.debug(f"consuming asset (agreementId {agreement_id}) after event {event}.") if consume_callback: brizo = BrizoProvider.get_brizo() consume_callback( agreement_id, DIDResolver(Keeper.get_instance().did_registry).resolve(did), DIDResolver(Keeper.get_instance().did_registry).resolve(workflow_did), consumer_account, brizo )
def init_ocn_tokens(ocn, account, amount=100): ocn.accounts.request_tokens(account, amount) Keeper.get_instance().token.token_approve( Keeper.get_instance().dispenser.address, amount, account )
def init_ocn_tokens(ocn, account, amount=100): try: ocn.accounts.request_tokens(account, amount) except (ValueError, OceanInvalidTransaction): print(f'requesting tokens failed: {account.address}, {amount}') Keeper.get_instance().token.token_approve( Keeper.get_instance().dispenser.address, amount, account)
def refund_reward(event, agreement_id, did, service_agreement, price, consumer_account, publisher_address, condition_ids, escrow_condition_id): """ Refund the reward to the publisher address. :param event: AttributeDict with the event data. :param agreement_id: id of the agreement, hex str :param did: DID, str :param service_agreement: ServiceAgreement instance :param price: Asset price, int :param consumer_account: Account instance of the consumer :param publisher_address: ethereum account address of publisher, hex str :param condition_ids: is a list of bytes32 content-addressed Condition IDs, bytes32 :param escrow_condition_id: hex str the id of escrow reward condition at this `agreement_id` """ logger.debug(f"trigger refund (agreement {agreement_id}) after event {event}.") if Keeper.get_instance().condition_manager.get_condition_state(escrow_condition_id) > 1: logger.debug( f'escrow reward condition already fulfilled/aborted: ' f'agreementId={agreement_id}, escrow reward conditionId={escrow_condition_id},' f' publisher={publisher_address}' ) return access_id, lock_id = condition_ids[:2] name_to_parameter = {param.name: param for param in service_agreement.condition_by_name['escrowReward'].parameters} document_id = add_0x_prefix(name_to_parameter['_documentId'].value) asset_id = add_0x_prefix(did_to_id(did)) did_owner = Keeper.get_instance().agreement_manager.get_agreement_did_owner(agreement_id) assert document_id == asset_id, f'document_id {document_id} <=> asset_id {asset_id} mismatch.' assert price == service_agreement.get_price(), 'price mismatch.' try: escrow_condition = Keeper.get_instance().escrow_reward_condition tx_hash = escrow_condition.fulfill( agreement_id, price, Web3Provider.get_web3().toChecksumAddress(did_owner), consumer_account.address, lock_id, access_id, consumer_account ) process_tx_receipt( tx_hash, getattr(escrow_condition.contract.events, escrow_condition.FULFILLED_EVENT)(), 'EscrowReward.Fulfilled' ) except Exception as e: logger.error( f'Error when doing escrow_reward_condition.fulfills (agreementId {agreement_id}): {e}', exc_info=1) raise e
def setup_agreements_enviroment(): consumer_acc = get_consumer_account() publisher_acc = get_publisher_account() keeper = Keeper.get_instance() ddo = get_ddo_sample() ddo._did = DID.did({'0': '0x987654321'}) 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() access_cond_id, lock_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), )
def test_store_token(): ocn_auth = OceanAuth(Keeper.get_instance(), ':memory:') acc = get_publisher_account() token = ocn_auth.store(acc) assert ocn_auth.check(token) == acc.address, 'invalid token, check failed.' # verify it is saved assert ocn_auth.restore(acc) == token, 'Restoring token failed.'
def test_create_compute_service(publisher_ocean_instance): ocn_compute = publisher_ocean_instance.compute cluster = ocn_compute.build_cluster_attributes('kubernetes', '/cluster/url') container = ocn_compute.build_container_attributes( "tensorflow/tensorflow", "latest", "sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc" ) server = ocn_compute.build_server_attributes("1", "xlsize", "16", "0", "128gb", "160gb", 86400) provider_attributes = ocn_compute.build_service_provider_attributes( "Azure", "some description of the compute server instance", cluster, [container], [server]) attributes = ocn_compute.create_compute_service_attributes( "10", 3600 * 24, publisher_ocean_instance.main_account.address, get_timestamp(), provider_attributes) service = publisher_ocean_instance.services.create_compute_service( attributes, 'http://brizo.com:8030/api/v1/services/compute') assert isinstance(service, tuple) and len(service) == 2 assert service[0] == ServiceTypes.CLOUD_COMPUTE assert isinstance(service[1], dict) assert service[1]['templateId'] == SquidKeeper.get_instance( ).get_agreement_template_id(ServiceTypes.CLOUD_COMPUTE) assert service[1]['attributes'] == attributes assert service[1][ 'serviceEndpoint'] == 'http://brizo.com:8030/api/v1/services/compute'
def test_check_token(web3_instance): ocn_auth = OceanAuth(Keeper.get_instance(), ':memory:') acc = get_publisher_account() token = ocn_auth.get(acc) address = ocn_auth.check(token) assert address != '0x0', 'Verifying token failed.' sig = token.split('-')[0] assert ocn_auth.check(sig) == '0x0'
def test_restore_token(publisher_ocean_instance): ocn_auth = OceanAuth(Keeper.get_instance(), ':memory:') acc = get_publisher_account() assert ocn_auth.restore( acc) is None, 'Expecting None when restoring non-existing token.' token = ocn_auth.store(acc) assert ocn_auth.check(token) == acc.address, 'invalid token, check failed.' # verify it is saved assert ocn_auth.restore(acc) == token, 'Restoring token failed.'
def test_get_token(): ocn_auth = OceanAuth(Keeper.get_instance(), ':memory:') acc = get_publisher_account() token = ocn_auth.get(acc) assert isinstance(token, str), 'Invalid auth token type.' assert token.startswith('0x'), 'Invalid auth token.' parts = token.split('-') assert len(parts) == 2, 'Invalid token, timestamp separator is not found.' address = ocn_auth.check(token) assert address != '0x0', 'Verifying token failed.'
def test_get_condition_name_by_address(): keeper = Keeper.get_instance() name = keeper.get_condition_name_by_address( keeper.lock_reward_condition.address) assert name == 'lockReward' name = keeper.get_condition_name_by_address( keeper.access_secret_store_condition.address) assert name == 'accessSecretStore' name = keeper.get_condition_name_by_address( keeper.escrow_reward_condition.address) assert name == 'escrowReward'
def ocean_agreements(): keeper = Keeper.get_instance() w3 = Web3Provider.get_web3() did_resolver = Mock() ddo = get_ddo_sample() service = ddo.get_service(ServiceTypes.ASSET_ACCESS) service.update_value( ServiceAgreementTemplate.TEMPLATE_ID_KEY, w3.toChecksumAddress("0x00bd138abd70e2f00903268f3db08f2d25677c9e")) did_resolver.resolve = MagicMock(return_value=ddo) # consumer_class = Mock # consumer_class.download = MagicMock(return_value='') return OceanAgreements(keeper, did_resolver, AssetConsumer, AssetExecutor, ConfigProvider.get_config())
def test_get_condition_name_by_address(): config = ExampleConfig.get_config() Web3Provider.init_web3(config.keeper_url) ContractHandler.set_artifacts_path(config.keeper_path) keeper = Keeper.get_instance() name = keeper.get_condition_name_by_address( keeper.lock_reward_condition.address) assert name == 'lockReward' name = keeper.get_condition_name_by_address( keeper.access_secret_store_condition.address) assert name == 'accessSecretStore' name = keeper.get_condition_name_by_address( keeper.escrow_reward_condition.address) assert name == 'escrowReward'
def consume_service(service_agreement_id, service_endpoint, account, files, destination_folder, index=None): """ Call the brizo endpoint to get access to the different files that form the asset. :param service_agreement_id: Service Agreement Id, str :param service_endpoint: Url to consume, str :param account: Account instance of the consumer signing this agreement, hex-str :param files: List containing the files to be consumed, list :param index: Index of the document that is going to be downloaded, int :param destination_folder: Path, str :return: True if was downloaded, bool """ signature = Keeper.get_instance().sign_hash( add_ethereum_prefix_and_hash_msg(service_agreement_id), account) 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') consume_url = Brizo._create_consume_url(service_endpoint, service_agreement_id, account, None, signature, index) logger.info( f'invoke consume endpoint with this url: {consume_url}') response = Brizo._http_client.get(consume_url, stream=True) file_name = Brizo._get_file_name(response) Brizo.write_file(response, destination_folder, file_name) else: for i, _file in enumerate(files): consume_url = Brizo._create_consume_url( service_endpoint, service_agreement_id, account, _file, signature, i) logger.info( f'invoke consume endpoint with this url: {consume_url}') response = Brizo._http_client.get(consume_url, stream=True) file_name = Brizo._get_file_name(response) Brizo.write_file(response, destination_folder, file_name or f'file-{i}')
def test_known_token(): token = "0x1d2741dee30e64989ef0203957c01b14f250f5d2f6ccb0c" \ "88c9518816e4fcec16f84e545094eb3f377b7e214ded22676" \ "fbde8ca2e41b4eb1b3565047ecd9acf300-1568372035" pub_address = "0xe2DD09d719Da89e5a3D0F2549c7E24566e947260" ocn_auth = OceanAuth(Keeper.get_instance(), ':memory:') assert ocn_auth.is_token_valid( token), f'Invalid token!! has the token specs changed?' def _get_timestamp(): return int('1568372035') + 10000 ocn_auth._get_timestamp = _get_timestamp address = ocn_auth.check(token) assert address.lower() == pub_address.lower(), f'Recovered address {address} does not match ' \ f'known signer address {pub_address}, if the ' \ f'token generation method is changed please update ' \ f'the token in this test with the new format.'
def fulfill_lock_reward_condition(event, agreement_id, price, consumer_account, lock_condition_id): """ Fulfill the lock reward condition. :param event: AttributeDict with the event data. :param agreement_id: id of the agreement, hex str :param price: Asset price, int :param consumer_account: Account instance of the consumer :param lock_condition_id: hex str the id of the lock reward condition for this `agreement_id` """ if not event: logger.warning( f'`fulfill_lock_reward_condition` got empty event: event listener timed out.' ) return keeper = Keeper.get_instance() if keeper.condition_manager.get_condition_state(lock_condition_id) > 1: logger.debug( f'lock reward condition already fulfilled/aborted: ' f'agreementId={agreement_id}, lockReward conditionId={lock_condition_id}' ) return logger.debug( f"about to lock reward (agreement {agreement_id}) after event {event}." ) approved = keeper.token.token_approve(keeper.lock_reward_condition.address, price, consumer_account) logger.info( f'approval of token transfer was {"" if approved else "NOT"} successful' ) args = (agreement_id, keeper.escrow_reward_condition.address, price, consumer_account) process_fulfill_condition(args, keeper.lock_reward_condition, lock_condition_id, logger, keeper, 10)
def execute_service(service_agreement_id, service_endpoint, account, workflow_ddo): """ :param service_agreement_id: :param service_endpoint: :param account: :return: """ signature = Keeper.get_instance().sign_hash( add_ethereum_prefix_and_hash_msg(service_agreement_id), account) execute_url = Brizo._create_execute_url(service_endpoint, service_agreement_id, account, workflow_ddo.did, signature) logger.info(f'invoke execute endpoint with this url: {execute_url}') response = Brizo._http_client.post(execute_url) print( f'got brizo execute response: {response.content} with status-code {response.status_code} ' ) if response.status_code != 201: raise Exception(response.content.decode('utf-8')) return json.loads(response.content)['workflowId']
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.')
def test_buy_asset(consumer_ocean_instance, publisher_ocean_instance): config = ExampleConfig.get_config() ConfigProvider.set_config(config) keeper = Keeper.get_instance() # :TODO: enable the actual SecretStore # SecretStoreProvider.set_secret_store_class(SecretStore) w3 = Web3Provider.get_web3() pub_acc = get_publisher_account() # Register ddo ddo = get_registered_ddo(publisher_ocean_instance, pub_acc) assert isinstance(ddo, DDO) # 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 cons_ocn = consumer_ocean_instance # restore the http client because we want the actual Brizo server to do the work # not the BrizoMock. # Brizo.set_http_client(requests) consumer_account = get_consumer_account() downloads_path_elements = len( os.listdir( consumer_ocean_instance._config.downloads_path)) if os.path.exists( consumer_ocean_instance._config.downloads_path) else 0 # sign agreement using the registered asset did above service = ddo.get_service(service_type=ServiceTypes.ASSET_ACCESS) sa = ServiceAgreement.from_json(service.as_dictionary()) # This will send the consume request to Brizo which in turn will execute the agreement on-chain cons_ocn.accounts.request_tokens(consumer_account, 100) agreement_id = cons_ocn.assets.order(ddo.did, sa.index, consumer_account, auto_consume=False) event_wait_time = 10 event = keeper.escrow_access_secretstore_template.subscribe_agreement_created( agreement_id, event_wait_time, log_event( keeper.escrow_access_secretstore_template.AGREEMENT_CREATED_EVENT), (), wait=True) assert event, 'no event for EscrowAccessSecretStoreTemplate.AgreementCreated' event = keeper.lock_reward_condition.subscribe_condition_fulfilled( agreement_id, event_wait_time, log_event(keeper.lock_reward_condition.FULFILLED_EVENT), (), wait=True) assert event, 'no event for LockRewardCondition.Fulfilled' # give access publisher_ocean_instance.agreements.conditions.grant_access( agreement_id, ddo.did, consumer_account.address, pub_acc) event = keeper.access_secret_store_condition.subscribe_condition_fulfilled( agreement_id, event_wait_time, log_event(keeper.access_secret_store_condition.FULFILLED_EVENT), (), wait=True) assert event, 'no event for AccessSecretStoreCondition.Fulfilled' assert cons_ocn.agreements.is_access_granted(agreement_id, ddo.did, consumer_account.address) assert cons_ocn.assets.consume(agreement_id, ddo.did, sa.index, consumer_account, config.downloads_path) assert len(os.listdir( config.downloads_path)) == downloads_path_elements + 1 # Check that we can consume only an specific file in passing the index. assert cons_ocn.assets.consume(agreement_id, ddo.did, sa.index, consumer_account, config.downloads_path, 2) assert len(os.listdir( config.downloads_path)) == downloads_path_elements + 1 with pytest.raises(AssertionError): cons_ocn.assets.consume(agreement_id, ddo.did, sa.index, consumer_account, config.downloads_path, -2) with pytest.raises(AssertionError): cons_ocn.assets.consume(agreement_id, ddo.did, sa.index, consumer_account, config.downloads_path, 3) # decrypt the contentUrls using the publisher account instead of consumer account. # if the secret store is working and ACL check is enabled, this should fail # since SecretStore decrypt will fail the checkPermissions check try: cons_ocn.assets.consume(agreement_id, ddo.did, sa.index, pub_acc, config.downloads_path) except RPCError: print('hooray, secret store is working as expected.') publisher_ocean_instance.agreements.conditions.release_reward( agreement_id, sa.get_price(), pub_acc) event = keeper.escrow_reward_condition.subscribe_condition_fulfilled( agreement_id, event_wait_time + 20, log_event(keeper.escrow_reward_condition.FULFILLED_EVENT), (), wait=True) assert event, 'no event for EscrowReward.Fulfilled' assert w3.toHex(event.args['_agreementId']) == agreement_id
def setup_all(): config = ExampleConfig.get_config() Web3Provider.init_web3(config.keeper_url) ContractHandler.set_artifacts_path(config.keeper_path) Keeper.get_instance()
def __init__(self, config=None): """ Initialize Ocean class. >> # Make a new Ocean instance >> ocean = Ocean({...}) This class provides the main top-level functions in ocean protocol: * Publish assets metadata and associated services * Each asset is assigned a unique DID and a DID Document (DDO) * The DDO contains the asset's services including the metadata * The DID is registered on-chain with a URL of the metadata store to retrieve the DDO from >> ddo = ocean.assets.create(metadata, publisher_account) * Discover/Search assets via the current configured metadata store (Aquarius) >> assets_list = ocean.assets.search('search text') * Purchase asset services by choosing a service agreement from the asset's DDO. Purchase goes through the service agreements interface and starts by signing a service agreement then sending the signature to the publisher's Brizo server via the `purchaseEndpoint` in the service definition: >> service_def_id = ddo.get_service(ServiceTypes.ASSET_ACCESS).service_definition_id >> service_agreement_id = ocean.assets.order(did, service_def_id, consumer_account) An instance of Ocean is parameterized by a `Config` instance. :param config: Config instance """ # Configuration information for the market is stored in the Config class # config = Config(filename=config_file, options_dict=config_dict) if not config: config = ConfigProvider.get_config() self._config = config self._web3 = Web3Provider.get_web3(self._config.keeper_url) ContractHandler.set_artifacts_path(self._config.keeper_path) contracts = [ 'DIDRegistry', 'Dispenser', 'TemplateStoreManager', 'OceanToken', 'ConditionStoreManager', 'EscrowAccessSecretStoreTemplate', 'AgreementStoreManager', 'AgreementStoreManager', 'AccessSecretStoreCondition', 'LockRewardCondition', 'HashLockCondition', 'SignCondition', 'EscrowReward' ] self._keeper = Keeper.get_instance(contracts) self._did_resolver = DIDResolver(self._keeper.did_registry) # Initialize the public sub-modules self.tokens = OceanTokens(self._keeper) self.accounts = OceanAccounts(self._keeper, self._config, self.tokens) self.secret_store = OceanSecretStore(self._config) self.templates = OceanTemplates(self._keeper, config) self.agreements = self._make_ocean_agreements() self.assets = OceanAssets(self._keeper, self._did_resolver, self.agreements, AssetConsumer, AssetExecutor, self._config) self.services = OceanServices() self.ocean_providers = OceanProviders(self._keeper, self._did_resolver, self._config) self.auth = OceanAuth(self._keeper, self._config.storage_path) logger.debug('Squid Ocean instance initialized: ') logger.debug( f'\tOther accounts: {sorted([a.address for a in self.accounts.list()])}' ) logger.debug(f'\tDIDRegistry @ {self._keeper.did_registry.address}')
def test_sign_agreement(publisher_ocean_instance, consumer_ocean_instance, registered_ddo): # point consumer_ocean_instance's brizo mock to the publisher's ocean instance BrizoProvider.set_brizo_class(BrizoMock) consumer_ocn = consumer_ocean_instance consumer_acc = consumer_ocn.main_account keeper = Keeper.get_instance() pub_ocn = publisher_ocean_instance publisher_acc = pub_ocn.main_account did = registered_ddo.did asset_id = registered_ddo.asset_id ddo = consumer_ocn.assets.resolve(did) service_agreement = ServiceAgreement.from_ddo(ServiceTypes.ASSET_ACCESS, ddo) price = service_agreement.get_price() # Give consumer some tokens keeper.dispenser.request_vodkas(price * 2, consumer_acc) agreement_id, signature = consumer_ocean_instance.agreements.prepare( did, consumer_acc, ServiceTypesIndices.DEFAULT_ACCESS_INDEX) success = publisher_ocean_instance.agreements.create( did, ServiceTypesIndices.DEFAULT_ACCESS_INDEX, agreement_id, signature, consumer_acc.address, publisher_acc) assert success, 'createAgreement failed.' event = keeper.agreement_manager.subscribe_agreement_created( agreement_id, 10, log_event(keeper.agreement_manager.AGREEMENT_CREATED_EVENT), (), wait=True) assert event, 'no event for AgreementCreated ' # Verify condition types (condition contracts) agreement_values = keeper.agreement_manager.get_agreement(agreement_id) assert agreement_values.did == asset_id, '' template_id = keeper.get_agreement_template_id(service_agreement.type) cond_types = keeper.template_manager.get_template( template_id).condition_types for i, cond_id in enumerate(agreement_values.condition_ids): cond = keeper.condition_manager.get_condition(cond_id) assert cond.type_ref == cond_types[i] assert int(cond.state) == 1 lock_cond_id, access_cond_id, escrow_cond_id = agreement_values.condition_ids # Fulfill lock_reward_condition starting_balance = keeper.token.get_token_balance( keeper.escrow_reward_condition.address) keeper.token.token_approve(keeper.lock_reward_condition.address, price, consumer_acc) tx_hash = keeper.lock_reward_condition.fulfill( agreement_id, keeper.escrow_reward_condition.address, price, consumer_acc) keeper.lock_reward_condition.get_tx_receipt(tx_hash) assert keeper.token.get_token_balance( keeper.escrow_reward_condition.address) == (price + starting_balance), '' assert keeper.condition_manager.get_condition_state(lock_cond_id) == 2, '' event = keeper.lock_reward_condition.subscribe_condition_fulfilled( agreement_id, 10, log_event(keeper.lock_reward_condition.FULFILLED_EVENT), (), wait=True) assert event, 'no event for LockRewardCondition.Fulfilled' # Fulfill access_secret_store_condition tx_hash = keeper.access_secret_store_condition.fulfill( agreement_id, asset_id, consumer_acc.address, publisher_acc) keeper.access_secret_store_condition.get_tx_receipt(tx_hash) assert 2 == keeper.condition_manager.get_condition_state( access_cond_id), '' event = keeper.access_secret_store_condition.subscribe_condition_fulfilled( agreement_id, 10, log_event(keeper.access_secret_store_condition.FULFILLED_EVENT), (), wait=True) assert event, 'no event for AccessSecretStoreCondition.Fulfilled' # Fulfill escrow_reward_condition tx_hash = keeper.escrow_reward_condition.fulfill( agreement_id, price, publisher_acc.address, consumer_acc.address, lock_cond_id, access_cond_id, publisher_acc) keeper.escrow_reward_condition.get_tx_receipt(tx_hash) assert 2 == keeper.condition_manager.get_condition_state( escrow_cond_id), '' event = keeper.escrow_reward_condition.subscribe_condition_fulfilled( agreement_id, 10, log_event(keeper.escrow_reward_condition.FULFILLED_EVENT), (), wait=True) assert event, 'no event for EscrowReward.Fulfilled' publisher_ocean_instance.assets.retire(did)