From 40754ca46a10578cfdf0f460a7c33ba37bb2ffde Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Mon, 27 Jan 2020 19:14:12 +0100 Subject: [PATCH] new ocean.utils.services * refactor all .order() methods to use one single method * remove `index` parameter from ocean.assets.order() * update compute test flow --- integration/ocean/AssetOwners.test.ts | 4 +- integration/ocean/Compute.test.ts | 44 +++- integration/ocean/ConsumeAssetBrizo.test.ts | 11 +- integration/ocean/ConsumeBigAsset.test.ts | 4 +- integration/utils/ddo-metadata-generator.ts | 4 +- src/ddo/Service.ts | 4 +- src/ocean/OceanAssets.ts | 95 +------- src/ocean/OceanCompute.ts | 82 +------ src/ocean/utils/OceanUtils.ts | 8 + src/ocean/utils/ServiceUtils.ts | 113 +++++++++ src/squid.ts | 3 +- test/testdata/ddo-compute.json | 248 -------------------- test/testdata/ddo.json | 144 +++++++++++- 13 files changed, 336 insertions(+), 428 deletions(-) create mode 100644 src/ocean/utils/ServiceUtils.ts delete mode 100644 test/testdata/ddo-compute.json diff --git a/integration/ocean/AssetOwners.test.ts b/integration/ocean/AssetOwners.test.ts index 5133513..d26fcd8 100644 --- a/integration/ocean/AssetOwners.test.ts +++ b/integration/ocean/AssetOwners.test.ts @@ -90,9 +90,7 @@ describe('Asset Owners', () => { ) } catch {} - const { index } = ddo.findServiceByType('access') - - await ocean.assets.order(ddo.id, index, account2) + await ocean.assets.order(ddo.id, account2) // Access granted const { length: finalLength2 } = await ocean.assets.consumerAssets( diff --git a/integration/ocean/Compute.test.ts b/integration/ocean/Compute.test.ts index 2d36885..0389617 100644 --- a/integration/ocean/Compute.test.ts +++ b/integration/ocean/Compute.test.ts @@ -18,13 +18,45 @@ describe('Compute', () => { before(async () => { ocean = await Ocean.getInstance(config) ;[account] = await ocean.accounts.list() - ddoAsset = await ocean.assets.create(metadataAsset as MetaData, account, [ - computeServiceExample - ]) - ddoAlgorithm = await ocean.assets.create(metadataAlgorithm as MetaData, account) + }) - // order compute service - agreementId = await ocean.compute.order(account, ddoAsset.id) + it('should authenticate the consumer account', async () => { + await account.authenticate() + }) + + it('should publish a dataset and an algorithm', async () => { + const stepsAsset = [] + ddoAsset = await ocean.assets + .create(metadataAsset as MetaData, account, [computeServiceExample]) + .next(step => stepsAsset.push(step)) + + assert.instanceOf(ddoAsset, DDO) + assert.deepEqual(stepsAsset, [0, 1, 2, 3, 4, 5, 6, 7]) + + const stepsAlgorithm = [] + ddoAlgorithm = await ocean.assets + .create(metadataAlgorithm as MetaData, account) + .next(step => stepsAlgorithm.push(step)) + + assert.instanceOf(ddoAlgorithm, DDO) + assert.deepEqual(stepsAlgorithm, [0, 1, 2, 3, 4, 5, 6, 7]) + }) + + it('should order the compute service', async () => { + const steps = [] + try { + await account.requestTokens( + +computeServiceExample.attributes.main.price * + 10 ** -(await ocean.keeper.token.decimals()) + ) + + agreementId = await ocean.compute + .order(account, ddoAsset.id) + .next(step => steps.push(step)) + } catch {} + + assert.isDefined(agreementId) + assert.deepEqual(steps, [0, 1, 2, 3]) }) it('should start a compute job', async () => { diff --git a/integration/ocean/ConsumeAssetBrizo.test.ts b/integration/ocean/ConsumeAssetBrizo.test.ts index 53c5924..b1269b8 100644 --- a/integration/ocean/ConsumeAssetBrizo.test.ts +++ b/integration/ocean/ConsumeAssetBrizo.test.ts @@ -50,18 +50,17 @@ describe('Consume Asset (Brizo)', () => { }) it('should order the asset', async () => { - const accessService = ddo.findServiceByType('access') + const steps = [] try { await consumer.requestTokens( +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) ) - } catch {} - const steps = [] - agreementId = await ocean.assets - .order(ddo.id, accessService.index, consumer) - .next(step => steps.push(step)) + agreementId = await ocean.assets + .order(ddo.id, consumer) + .next(step => steps.push(step)) + } catch {} assert.isDefined(agreementId) assert.deepEqual(steps, [0, 1, 2, 3]) diff --git a/integration/ocean/ConsumeBigAsset.test.ts b/integration/ocean/ConsumeBigAsset.test.ts index b1d1f22..c6059cd 100644 --- a/integration/ocean/ConsumeBigAsset.test.ts +++ b/integration/ocean/ConsumeBigAsset.test.ts @@ -50,15 +50,13 @@ xdescribe('Consume Asset (Large size)', () => { }) it('should order the asset', async () => { - const accessService = ddo.findServiceByType('access') - try { await consumer.requestTokens( +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) ) } catch {} - agreementId = await ocean.assets.order(ddo.id, accessService.index, consumer) + agreementId = await ocean.assets.order(ddo.id, consumer) assert.isDefined(agreementId) }) diff --git a/integration/utils/ddo-metadata-generator.ts b/integration/utils/ddo-metadata-generator.ts index 2c20efa..71aad12 100644 --- a/integration/utils/ddo-metadata-generator.ts +++ b/integration/utils/ddo-metadata-generator.ts @@ -1,6 +1,6 @@ import { MetaData } from '../../src' // @oceanprotocol/squid import { ServiceType } from '../../src/ddo/Service' -import ddoCompute from '../../test/testdata/ddo-compute.json' +import ddoExample from '../../test/testdata/ddo.json' const metadata: Partial = { main: { @@ -83,7 +83,7 @@ export const getMetadata = (price?: number, type?: 'dataset' | 'algorithm') => generateMetadata('TestAsset', type, price) export const getComputeServiceExample = () => { - const computeService = ddoCompute.service.find(service => service.type === 'compute') + const computeService = ddoExample.service.find(service => service.type === 'compute') const { index, serviceEndpoint, templateId, attributes } = computeService return { diff --git a/src/ddo/Service.ts b/src/ddo/Service.ts index 48f36ac..d5a1102 100644 --- a/src/ddo/Service.ts +++ b/src/ddo/Service.ts @@ -34,10 +34,10 @@ export interface ServiceAccess extends ServiceCommon { price: string timeout: number } - serviceAgreementTemplate?: ServiceAgreementTemplate additionalInformation: { description: string } + serviceAgreementTemplate?: ServiceAgreementTemplate } } @@ -51,8 +51,8 @@ export interface ServiceCompute extends ServiceCommon { price: string timeout: number provider?: ServiceComputeProvider - serviceAgreementTemplate?: ServiceAgreementTemplate } + serviceAgreementTemplate?: ServiceAgreementTemplate } } diff --git a/src/ocean/OceanAssets.ts b/src/ocean/OceanAssets.ts index 4ad9107..9109c02 100644 --- a/src/ocean/OceanAssets.ts +++ b/src/ocean/OceanAssets.ts @@ -5,8 +5,9 @@ import { MetaData } from '../ddo/MetaData' import { Service } from '../ddo/Service' import Account from './Account' import DID from './DID' -import { fillConditionsWithDDO, SubscribablePromise, generateId, zeroX } from '../utils' +import { fillConditionsWithDDO, SubscribablePromise } from '../utils' import { Instantiable, InstantiableConfig } from '../Instantiable.abstract' +import { OrderProgressStep } from './utils/ServiceUtils' export enum CreateProgressStep { EncryptingFiles, @@ -19,13 +20,6 @@ export enum CreateProgressStep { DdoStored } -export enum OrderProgressStep { - CreatingAgreement, - AgreementInitialized, - LockingPayment, - LockedPayment -} - /** * Assets submodule of Ocean Protocol. */ @@ -284,95 +278,28 @@ export class OceanAssets extends Instantiable { * Start the purchase/order of an asset's service. Starts by signing the service agreement * then sends the request to the publisher via the service endpoint (Brizo http service). * @param {string} did Decentralized ID. - * @param {number} index Service index. * @param {Account} consumerAccount Consumer account. * @param {string} provider ethereum address of service provider (optional) * @return {Promise} Returns Agreement ID */ public order( did: string, - index: number, consumerAccount: Account, provider?: string ): SubscribablePromise { return new SubscribablePromise(async observer => { - const oceanAgreements = this.ocean.agreements + const { keeper, utils } = this.ocean + const ddo: DDO = await this.resolve(did) + const condition = keeper.conditions.accessSecretStoreCondition - const agreementId = zeroX(generateId()) - const ddo = await this.resolve(did) - - const { keeper } = this.ocean - const templateName = ddo.findServiceByType('access').attributes - .serviceAgreementTemplate.contractName - const template = keeper.getTemplateByName(templateName) - const accessCondition = keeper.conditions.accessSecretStoreCondition - - // eslint-disable-next-line no-async-promise-executor - const paymentFlow = new Promise(async (resolve, reject) => { - await template.getAgreementCreatedEvent(agreementId).once() - - this.logger.log('Agreement initialized') - observer.next(OrderProgressStep.AgreementInitialized) - - const { attributes } = ddo.findServiceByType('metadata') - - this.logger.log('Locking payment') - - const accessGranted = accessCondition - .getConditionFulfilledEvent(agreementId) - .once() - - observer.next(OrderProgressStep.LockingPayment) - const paid = await oceanAgreements.conditions.lockReward( - agreementId, - attributes.main.price, - consumerAccount - ) - observer.next(OrderProgressStep.LockedPayment) - - if (paid) { - this.logger.log('Payment was OK') - } else { - this.logger.error('Payment was KO') - this.logger.error('Agreement ID: ', agreementId) - this.logger.error('DID: ', ddo.id) - reject(new Error('Error on payment')) - } - - await accessGranted - - this.logger.log('Access granted') - resolve() - }) - - observer.next(OrderProgressStep.CreatingAgreement) - this.logger.log('Creating agreement') - - // Get provider from didRegistry if not given in arguments - let _provider = provider - if (!provider) { - const providers = await keeper.didRegistry.getDIDProviders(ddo.shortId()) - if (providers) { - _provider = providers[0] - } - } - - await oceanAgreements.create( - did, - agreementId, - index, - undefined, + const agreementId = await utils.services.order( + 'access', + condition, + observer, consumerAccount, - _provider, - consumerAccount + ddo, + provider ) - this.logger.log('Agreement created') - - try { - await paymentFlow - } catch (e) { - throw new Error('Error paying the asset.') - } return agreementId }) diff --git a/src/ocean/OceanCompute.ts b/src/ocean/OceanCompute.ts index 5fc2437..e5f22f5 100644 --- a/src/ocean/OceanCompute.ts +++ b/src/ocean/OceanCompute.ts @@ -2,8 +2,8 @@ import { Instantiable, InstantiableConfig } from '../Instantiable.abstract' import { MetaData } from '../ddo/MetaData' import Account from './Account' import { DDO } from '../ddo/DDO' -import { SubscribablePromise, generateId, zeroX } from '../utils' -import { OrderProgressStep } from './OceanAssets' +import { SubscribablePromise } from '../utils' +import { OrderProgressStep } from './utils/ServiceUtils' export interface ComputeJobStatus { owner: string @@ -48,80 +48,18 @@ export class OceanCompute extends Instantiable { provider?: string ): SubscribablePromise { return new SubscribablePromise(async observer => { - const { keeper, assets, agreements } = this.ocean - - const agreementId = zeroX(generateId()) + const { assets, keeper, utils } = this.ocean const ddo: DDO = await assets.resolve(datasetDid) - const { index, attributes } = ddo.findServiceByType('compute') + const condition = keeper.conditions.computeExecutionCondition - const templateName = attributes.main.serviceAgreementTemplate.contractName - const template = keeper.getTemplateByName(templateName) - const computeCondition = keeper.conditions.computeExecutionCondition - - // eslint-disable-next-line no-async-promise-executor - const paymentFlow = new Promise(async (resolve, reject) => { - await template.getAgreementCreatedEvent(agreementId).once() - - this.logger.log('Agreement initialized') - observer.next(OrderProgressStep.AgreementInitialized) - - this.logger.log('Locking payment') - - const computeGranted = computeCondition - .getConditionFulfilledEvent(agreementId) - .once() - - observer.next(OrderProgressStep.LockingPayment) - const paid = await agreements.conditions.lockReward( - agreementId, - attributes.main.price, - consumerAccount - ) - observer.next(OrderProgressStep.LockedPayment) - - if (paid) { - this.logger.log('Payment was OK') - } else { - this.logger.error('Payment was KO') - this.logger.error('Agreement ID: ', agreementId) - this.logger.error('DID: ', ddo.id) - reject(new Error('Error on payment')) - } - - await computeGranted - - this.logger.log('Compute granted') - resolve() - }) - - observer.next(OrderProgressStep.CreatingAgreement) - this.logger.log('Creating agreement') - - // Get provider from didRegistry if not given in arguments - let _provider = provider - if (!provider) { - const providers = await keeper.didRegistry.getDIDProviders(ddo.shortId()) - if (providers) { - _provider = providers[0] - } - } - - await agreements.create( - datasetDid, - agreementId, - index, - undefined, + const agreementId = await utils.services.order( + 'compute', + condition, + observer, consumerAccount, - _provider, - consumerAccount + ddo, + provider ) - this.logger.log('Agreement created') - - try { - await paymentFlow - } catch (e) { - throw new Error('Error paying the compute service.') - } return agreementId }) diff --git a/src/ocean/utils/OceanUtils.ts b/src/ocean/utils/OceanUtils.ts index 581398b..5fda842 100644 --- a/src/ocean/utils/OceanUtils.ts +++ b/src/ocean/utils/OceanUtils.ts @@ -1,5 +1,6 @@ import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract' +import { ServiceUtils } from './ServiceUtils' import { ServiceAgreement } from './ServiceAgreement' import { SignatureUtils } from './SignatureUtils' import { WebServiceConnector } from './WebServiceConnector' @@ -21,6 +22,7 @@ export class OceanUtils extends Instantiable { config.logger, config.web3 ) + instance.services = new ServiceUtils(config.ocean, config.logger) instance.signature = new SignatureUtils(config.web3, config.logger) instance.fetch = new WebServiceConnector(config.logger) @@ -33,6 +35,12 @@ export class OceanUtils extends Instantiable { */ public agreements: ServiceAgreement + /** + * Service utils. + * @type {ServiceUtils} + */ + public services: ServiceUtils + /** * Signature utils. * @type {SignatureUtils} diff --git a/src/ocean/utils/ServiceUtils.ts b/src/ocean/utils/ServiceUtils.ts new file mode 100644 index 0000000..b46f1c1 --- /dev/null +++ b/src/ocean/utils/ServiceUtils.ts @@ -0,0 +1,113 @@ +import { DDO } from '../../ddo/DDO' +import Account from '../Account' +import { zeroX, Logger, generateId } from '../../utils' +import { Ocean } from '../../squid' +import { Condition } from '../../keeper/contracts/conditions' +import { ServiceType } from '../../ddo/Service' + +export enum OrderProgressStep { + CreatingAgreement, + AgreementInitialized, + LockingPayment, + LockedPayment +} + +export class ServiceUtils { + private ocean: Ocean + private logger: Logger + + constructor(ocean: Ocean, logger: Logger) { + this.ocean = ocean + this.logger = logger + } + + public async order( + type: ServiceType, + condition: Condition, + observer: any, + consumerAccount: Account, + ddo: DDO, + provider?: string + ): Promise { + const { keeper, agreements } = this.ocean + + const agreementId = zeroX(generateId()) + const { index, attributes } = ddo.findServiceByType(type) + const metadata = ddo.findServiceByType('metadata') + + const templateName = attributes.serviceAgreementTemplate.contractName + const template = keeper.getTemplateByName(templateName) + + // use price from compute service, + // otherwise always take the price from metadata + const price = + type === 'compute' ? attributes.main.price : metadata.attributes.main.price + + // eslint-disable-next-line no-async-promise-executor + const paymentFlow = new Promise(async (resolve, reject) => { + await template.getAgreementCreatedEvent(agreementId).once() + + this.logger.log('Agreement initialized') + observer.next(OrderProgressStep.AgreementInitialized) + + this.logger.log('Locking payment') + + const serviceGranted = condition + .getConditionFulfilledEvent(agreementId) + .once() + + observer.next(OrderProgressStep.LockingPayment) + const paid = await agreements.conditions.lockReward( + agreementId, + price, + consumerAccount + ) + observer.next(OrderProgressStep.LockedPayment) + + if (paid) { + this.logger.log('Payment was OK') + } else { + this.logger.error('Payment was KO') + this.logger.error('Agreement ID: ', agreementId) + this.logger.error('DID: ', ddo.id) + reject(new Error('Error on payment')) + } + + await serviceGranted + + this.logger.log(`Service ${type} granted`) + resolve() + }) + + observer.next(OrderProgressStep.CreatingAgreement) + this.logger.log('Creating agreement') + + // Get provider from didRegistry if not given in arguments + let _provider = provider + if (!provider) { + const providers = await keeper.didRegistry.getDIDProviders(ddo.shortId()) + if (providers) { + _provider = providers[0] + } + } + + await agreements.create( + ddo.id, + agreementId, + index, + undefined, + consumerAccount, + _provider, + consumerAccount + ) + this.logger.log('Agreement created') + + try { + await paymentFlow + } catch (e) { + throw new Error(`Error paying the ${type} service.`) + } + + return agreementId + } +} diff --git a/src/squid.ts b/src/squid.ts index 2709151..b5ff8ef 100644 --- a/src/squid.ts +++ b/src/squid.ts @@ -14,7 +14,8 @@ import * as utils from './utils' export * from './ddo/DDO' export * from './ddo/MetaData' -export { OrderProgressStep, CreateProgressStep } from './ocean/OceanAssets' +export { CreateProgressStep } from './ocean/OceanAssets' +export { OrderProgressStep } from './ocean/utils/ServiceUtils' export { OceanPlatformTechStatus, OceanPlatformTech, diff --git a/test/testdata/ddo-compute.json b/test/testdata/ddo-compute.json deleted file mode 100644 index 1091d1d..0000000 --- a/test/testdata/ddo-compute.json +++ /dev/null @@ -1,248 +0,0 @@ -{ - "@context": "https://w3id.org/future-method/v1", - "authentication": [], - "created": "2019-04-09T19:02:11Z", - "id": "did:op:8d1b4d73e7af4634958f071ab8dfe7ab0df14019755e444090fd392c8ec9c3f4", - "proof": { - "created": "2019-04-09T19:02:11Z", - "creator": "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e", - "signatureValue": "1cd57300733bcbcda0beb59b3e076de6419c0d7674e7befb77820b53c79e3aa8f1776effc64cf088bad8cb694cc4d71ebd74a13b2f75893df5a53f3f318f6cf828", - "type": "DDOIntegritySignature" - }, - "publicKey": [ - { - "id": "did:op:8d1b4d73e7af4634958f071ab8dfe7ab0df14019755e444090fd392c8ec9c3f4", - "owner": "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e", - "type": "EthereumECDSAKey" - } - ], - "service": [ - { - "type": "metadata", - "index": 0, - "serviceEndpoint": "http://myaquarius.org/api/v1/provider/assets/metadata/{did}", - "attributes": { - "main": { - "author": "Met Office", - "dateCreated": "2019-02-08T08:13:49Z", - "files": [ - { - "url": "https://raw.githubusercontent.com/tbertinmahieux/MSongsDB/master/Tasks_Demos/CoverSongs/shs_dataset_test.txt", - "index": 0, - "checksum": "efb2c764274b745f5fc37f97c6b0e764", - "contentLength": "4535431", - "contentType": "text/csv", - "encoding": "UTF-8", - "compression": "zip" - } - ], - "license": "CC-BY", - "name": "UK Weather information 2011", - "price": "1", - "type": "dataset" - }, - "additionalInformation": {} - } - }, - { - "type": "compute", - "index": 1, - "serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/compute", - "templateId": "", - "attributes": { - "main": { - "name": "dataAssetComputingServiceAgreement", - "creator": "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e", - "datePublished": "2019-04-09T19:02:11Z", - "price": "10", - "timeout": 86400, - "provider": { - "type": "Azure", - "description": "", - "environment": { - "cluster": { - "type": "Kubernetes", - "url": "http://10.0.0.17/xxx" - }, - "supportedContainers": [ - { - "image": "tensorflow/tensorflow", - "tag": "latest", - "checksum": "sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc" - }, - { - "image": "tensorflow/tensorflow", - "tag": "latest", - "checksum": "sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc" - } - ], - "supportedServers": [ - { - "serverId": "1", - "serverType": "xlsize", - "price": "50", - "cpu": "16", - "gpu": "0", - "memory": "128gb", - "disk": "160gb", - "maxExecutionTime": 86400 - }, - { - "serverId": "2", - "serverType": "medium", - "price": "10", - "cpu": "2", - "gpu": "0", - "memory": "8gb", - "disk": "80gb", - "maxExecutionTime": 86400 - } - ] - } - } - }, - "additionalInformation": {} - }, - "serviceAgreementTemplate": { - "contractName": "EscrowComputeExecutionTemplate", - "events": [ - { - "name": "AgreementCreated", - "actorType": "consumer", - "handler": { - "moduleName": "serviceExecutionTemplate", - "functionName": "fulfillLockRewardCondition", - "version": "0.1" - } - } - ], - "fulfillmentOrder": [ - "lockReward.fulfill", - "serviceExecution.fulfill", - "escrowReward.fulfill" - ], - "conditionDependency": { - "lockReward": [], - "serviceExecution": [], - "releaseReward": ["lockReward", "serviceExecution"] - }, - "conditions": [ - { - "name": "lockReward", - "timelock": 0, - "timeout": 0, - "contractName": "LockRewardCondition", - "functionName": "fulfill", - "parameters": [ - { - "name": "_rewardAddress", - "type": "address", - "value": "" - }, - { - "name": "_amount", - "type": "uint256", - "value": "" - } - ], - "events": [ - { - "name": "Fulfilled", - "actorType": "publisher", - "handler": { - "moduleName": "lockRewardCondition", - "functionName": "fulfillServiceExecutionCondition", - "version": "0.1" - } - } - ] - }, - { - "name": "serviceExecution", - "timelock": 0, - "timeout": 0, - "contractName": "ComputeExecutionCondition", - "functionName": "fulfill", - "parameters": [ - { - "name": "_documentId", - "type": "bytes32", - "value": "" - }, - { - "name": "_grantee", - "type": "address", - "value": "" - } - ], - "events": [ - { - "name": "Fulfilled", - "actorType": "publisher", - "handler": { - "moduleName": "serviceExecution", - "functionName": "fulfillServiceExecutionCondition", - "version": "0.1" - } - }, - { - "name": "TimedOut", - "actorType": "consumer", - "handler": { - "moduleName": "serviceExec", - "functionName": "fulfillServiceExecutionCondition", - "version": "0.1" - } - } - ] - }, - { - "name": "escrowReward", - "timelock": 0, - "timeout": 0, - "contractName": "EscrowReward", - "functionName": "fulfill", - "parameters": [ - { - "name": "_amount", - "type": "uint256", - "value": "" - }, - { - "name": "_receiver", - "type": "address", - "value": "" - }, - { - "name": "_sender", - "type": "address", - "value": "" - }, - { - "name": "_lockCondition", - "type": "bytes32", - "value": "" - }, - { - "name": "_releaseCondition", - "type": "bytes32", - "value": "" - } - ], - "events": [ - { - "name": "Fulfilled", - "actorType": "publisher", - "handler": { - "moduleName": "escrowRewardCondition", - "functionName": "verifyRewardTokens", - "version": "0.1" - } - } - ] - } - ] - } - } - ] -} diff --git a/test/testdata/ddo.json b/test/testdata/ddo.json index 32404c8..ede9b96 100644 --- a/test/testdata/ddo.json +++ b/test/testdata/ddo.json @@ -147,9 +147,10 @@ "type": "compute", "index": 1, "serviceEndpoint": "http://mybrizo.org/api/v1/brizo/services/compute", - "templateId": "804932804923850985093485039850349850439583409583404534231321131a", + "templateId": "", "attributes": { "main": { + "name": "dataAssetComputingServiceAgreement", "creator": "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e", "datePublished": "2019-04-09T19:02:11Z", "price": "10", @@ -198,6 +199,147 @@ ] } } + }, + "additionalInformation": {}, + "serviceAgreementTemplate": { + "contractName": "EscrowComputeExecutionTemplate", + "events": [ + { + "name": "AgreementCreated", + "actorType": "consumer", + "handler": { + "moduleName": "serviceExecutionTemplate", + "functionName": "fulfillLockRewardCondition", + "version": "0.1" + } + } + ], + "fulfillmentOrder": [ + "lockReward.fulfill", + "serviceExecution.fulfill", + "escrowReward.fulfill" + ], + "conditionDependency": { + "lockReward": [], + "serviceExecution": [], + "releaseReward": ["lockReward", "serviceExecution"] + }, + "conditions": [ + { + "name": "lockReward", + "timelock": 0, + "timeout": 0, + "contractName": "LockRewardCondition", + "functionName": "fulfill", + "parameters": [ + { + "name": "_rewardAddress", + "type": "address", + "value": "" + }, + { + "name": "_amount", + "type": "uint256", + "value": "" + } + ], + "events": [ + { + "name": "Fulfilled", + "actorType": "publisher", + "handler": { + "moduleName": "lockRewardCondition", + "functionName": "fulfillServiceExecutionCondition", + "version": "0.1" + } + } + ] + }, + { + "name": "serviceExecution", + "timelock": 0, + "timeout": 0, + "contractName": "ComputeExecutionCondition", + "functionName": "fulfill", + "parameters": [ + { + "name": "_documentId", + "type": "bytes32", + "value": "" + }, + { + "name": "_grantee", + "type": "address", + "value": "" + } + ], + "events": [ + { + "name": "Fulfilled", + "actorType": "publisher", + "handler": { + "moduleName": "serviceExecution", + "functionName": "fulfillServiceExecutionCondition", + "version": "0.1" + } + }, + { + "name": "TimedOut", + "actorType": "consumer", + "handler": { + "moduleName": "serviceExec", + "functionName": "fulfillServiceExecutionCondition", + "version": "0.1" + } + } + ] + }, + { + "name": "escrowReward", + "timelock": 0, + "timeout": 0, + "contractName": "EscrowReward", + "functionName": "fulfill", + "parameters": [ + { + "name": "_amount", + "type": "uint256", + "value": "" + }, + { + "name": "_receiver", + "type": "address", + "value": "" + }, + { + "name": "_sender", + "type": "address", + "value": "" + }, + { + "name": "_lockCondition", + "type": "bytes32", + "value": "" + }, + { + "name": "_releaseCondition", + "type": "bytes32", + "value": "" + } + ], + "events": [ + { + "name": "Fulfilled", + "actorType": "publisher", + "handler": { + "moduleName": "escrowRewardCondition", + "functionName": "verifyRewardTokens", + "version": "0.1" + } + } + ] + } + ] } } },