mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
wip: compute module, compute tests, create compute service.
This commit is contained in:
parent
76af744726
commit
dad7a56c1e
@ -40,9 +40,9 @@ export class DataTokens {
|
|||||||
*/
|
*/
|
||||||
public async create(metaDataStoreURI: string, account: Account): Promise<string> {
|
public async create(metaDataStoreURI: string, account: Account): Promise<string> {
|
||||||
// Create factory contract object
|
// Create factory contract object
|
||||||
const factory = new this.web3.eth.Contract(this.factoryABI, this.factoryAddress, {
|
const factory = new this.web3.eth.Contract(
|
||||||
from: account
|
this.factoryABI, this.factoryAddress, {from: account}
|
||||||
})
|
)
|
||||||
const estGas = await factory.methods
|
const estGas = await factory.methods
|
||||||
.createToken(metaDataStoreURI)
|
.createToken(metaDataStoreURI)
|
||||||
.estimateGas(function (err, estGas) {
|
.estimateGas(function (err, estGas) {
|
||||||
|
@ -33,7 +33,7 @@ export interface ServiceComputeAttributes extends ServiceCommonAttributes {
|
|||||||
main: {
|
main: {
|
||||||
creator: string
|
creator: string
|
||||||
datePublished: string
|
datePublished: string
|
||||||
price: string
|
cost: string
|
||||||
timeout: number
|
timeout: number
|
||||||
provider?: ServiceComputeProvider
|
provider?: ServiceComputeProvider
|
||||||
name: string
|
name: string
|
||||||
@ -57,7 +57,7 @@ export interface ServiceComputeProvider {
|
|||||||
supportedServers: {
|
supportedServers: {
|
||||||
serverId: string
|
serverId: string
|
||||||
serverType: string
|
serverType: string
|
||||||
price: string
|
cost: string
|
||||||
cpu: string
|
cpu: string
|
||||||
gpu: string
|
gpu: string
|
||||||
memory: string
|
memory: string
|
||||||
@ -74,13 +74,11 @@ export interface ServiceMetadata extends ServiceCommon {
|
|||||||
|
|
||||||
export interface ServiceAccess extends ServiceCommon {
|
export interface ServiceAccess extends ServiceCommon {
|
||||||
type: 'access'
|
type: 'access'
|
||||||
templateId?: string
|
|
||||||
attributes: ServiceAccessAttributes
|
attributes: ServiceAccessAttributes
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServiceCompute extends ServiceCommon {
|
export interface ServiceCompute extends ServiceCommon {
|
||||||
type: 'compute'
|
type: 'compute'
|
||||||
templateId?: string
|
|
||||||
attributes: ServiceComputeAttributes
|
attributes: ServiceComputeAttributes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,20 +33,6 @@ export enum OrderProgressStep {
|
|||||||
TransferDataToken
|
TransferDataToken
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ComputeJobStatus = Object.freeze({
|
|
||||||
Started: 10,
|
|
||||||
ConfiguringVolumes: 20,
|
|
||||||
ProvisioningSuccess: 30,
|
|
||||||
DataProvisioningFailed: 31,
|
|
||||||
AlgorithmProvisioningFailed: 32,
|
|
||||||
RunningAlgorithm: 40,
|
|
||||||
FilteringResults: 50,
|
|
||||||
PublishingResult: 60,
|
|
||||||
Completed: 70,
|
|
||||||
Stopped: 80,
|
|
||||||
Deleted: 90
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assets submodule of Ocean Protocol.
|
* Assets submodule of Ocean Protocol.
|
||||||
*/
|
*/
|
||||||
@ -458,205 +444,4 @@ export class Assets extends Instantiable {
|
|||||||
|
|
||||||
return serviceEndpoint
|
return serviceEndpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the execution of a compute job.
|
|
||||||
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
|
||||||
* @param {string} did Decentralized identifer for the asset
|
|
||||||
* @param {string} algorithmDid The DID of the algorithm asset (of type `algorithm`) to run on the asset.
|
|
||||||
* @param {MetaData} algorithmMeta Metadata about the algorithm being run if `algorithm` is being used. This is ignored when `algorithmDid` is specified.
|
|
||||||
* @param {Output} output Define algorithm output publishing. Publishing the result of a compute job is turned off by default.
|
|
||||||
* @return {Promise<ComputeJob>} Returns compute job ID under status.jobId
|
|
||||||
*/
|
|
||||||
public async start(
|
|
||||||
consumerAccount: Account,
|
|
||||||
did: string,
|
|
||||||
algorithmDid?: string,
|
|
||||||
algorithmMeta?: MetadataAlgorithm,
|
|
||||||
output?: Output
|
|
||||||
): Promise<ComputeJob> {
|
|
||||||
output = this.checkOutput(consumerAccount, output)
|
|
||||||
if (did) {
|
|
||||||
const computeJobsList = await this.ocean.provider.compute(
|
|
||||||
'post',
|
|
||||||
did,
|
|
||||||
consumerAccount,
|
|
||||||
algorithmDid,
|
|
||||||
algorithmMeta,
|
|
||||||
undefined,
|
|
||||||
output
|
|
||||||
)
|
|
||||||
return computeJobsList[0] as ComputeJob
|
|
||||||
} else return null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends a running compute job.
|
|
||||||
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
|
||||||
* @param {string} did Decentralized identifier.
|
|
||||||
* @param {string} jobId The ID of the compute job to be stopped
|
|
||||||
* @return {Promise<ComputeJob>} Returns the new status of a job
|
|
||||||
*/
|
|
||||||
public async stop(
|
|
||||||
consumerAccount: Account,
|
|
||||||
did: string,
|
|
||||||
jobId: string
|
|
||||||
): Promise<ComputeJob> {
|
|
||||||
const computeJobsList = await this.ocean.provider.compute(
|
|
||||||
'put',
|
|
||||||
did,
|
|
||||||
consumerAccount,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
jobId
|
|
||||||
)
|
|
||||||
|
|
||||||
return computeJobsList[0] as ComputeJob
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a compute job and all resources associated with the job. If job is running it will be stopped first.
|
|
||||||
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
|
||||||
* @param {string} did Decentralized identifier.
|
|
||||||
* @param {string} jobId The ID of the compute job to be stopped
|
|
||||||
* @return {Promise<ComputeJob>} Returns the new status of a job
|
|
||||||
*/
|
|
||||||
public async delete(
|
|
||||||
consumerAccount: Account,
|
|
||||||
did: string,
|
|
||||||
jobId: string
|
|
||||||
): Promise<ComputeJob> {
|
|
||||||
const computeJobsList = await this.ocean.provider.compute(
|
|
||||||
'delete',
|
|
||||||
did,
|
|
||||||
consumerAccount,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
jobId
|
|
||||||
)
|
|
||||||
|
|
||||||
return computeJobsList[0] as ComputeJob
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends a running compute job and starts it again.
|
|
||||||
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
|
||||||
* @param {string} did Decentralized identifier.
|
|
||||||
* @param {string} jobId The ID of the compute job to be stopped
|
|
||||||
* @return {Promise<ComputeJob>} Returns the new status of a job
|
|
||||||
*/
|
|
||||||
public async restart(
|
|
||||||
consumerAccount: Account,
|
|
||||||
did: string,
|
|
||||||
jobId: string
|
|
||||||
): Promise<ComputeJob> {
|
|
||||||
await this.stop(consumerAccount, did, jobId)
|
|
||||||
const result = await this.start(consumerAccount, did, jobId)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns information about the status of all compute jobs, or a single compute job.
|
|
||||||
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
|
||||||
* @param {string} did Decentralized identifier.
|
|
||||||
* @param {string} jobId The ID of the compute job to be stopped
|
|
||||||
* @return {Promise<ComputeJob[]>} Returns the status
|
|
||||||
*/
|
|
||||||
public async status(
|
|
||||||
consumerAccount: Account,
|
|
||||||
did?: string,
|
|
||||||
jobId?: string
|
|
||||||
): Promise<ComputeJob[]> {
|
|
||||||
const computeJobsList = await this.ocean.provider.compute(
|
|
||||||
'get',
|
|
||||||
did,
|
|
||||||
consumerAccount,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
jobId
|
|
||||||
)
|
|
||||||
|
|
||||||
return computeJobsList as ComputeJob[]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the final result of a specific compute job published as an asset.
|
|
||||||
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
|
||||||
* @param {string} did Decentralized identifier.
|
|
||||||
* @param {string} jobId The ID of the compute job to be stopped.
|
|
||||||
* @return {Promise<ComputeJob>} Returns the DDO of the result asset.
|
|
||||||
*/
|
|
||||||
public async result(
|
|
||||||
consumerAccount: Account,
|
|
||||||
did: string,
|
|
||||||
jobId: string
|
|
||||||
): Promise<ComputeJob> {
|
|
||||||
const computeJobsList = await this.ocean.provider.compute(
|
|
||||||
'get',
|
|
||||||
did,
|
|
||||||
consumerAccount,
|
|
||||||
undefined,
|
|
||||||
undefined,
|
|
||||||
jobId
|
|
||||||
)
|
|
||||||
|
|
||||||
return computeJobsList[0] as ComputeJob
|
|
||||||
}
|
|
||||||
|
|
||||||
public async createComputeServiceAttributes(
|
|
||||||
consumerAccount: Account,
|
|
||||||
price: string,
|
|
||||||
datePublished: string,
|
|
||||||
computePrivacy?: ServiceComputePrivacy,
|
|
||||||
timeout?: number
|
|
||||||
): Promise<ServiceCompute> {
|
|
||||||
const name = 'dataAssetComputingService'
|
|
||||||
if (!timeout) timeout = 3600
|
|
||||||
// TODO
|
|
||||||
const service = {
|
|
||||||
type: 'compute',
|
|
||||||
index: 3,
|
|
||||||
serviceEndpoint: this.ocean.provider.getComputeEndpoint(),
|
|
||||||
attributes: {
|
|
||||||
main: {
|
|
||||||
creator: consumerAccount.getId(),
|
|
||||||
datePublished,
|
|
||||||
price,
|
|
||||||
privacy: {},
|
|
||||||
timeout: timeout,
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (computePrivacy) service.attributes.main.privacy = computePrivacy
|
|
||||||
return service as ServiceCompute
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the output object and add default properties if needed
|
|
||||||
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
|
||||||
* @param {Output} output Output section used for publishing the result.
|
|
||||||
* @return {Promise<Output>} Returns output object
|
|
||||||
*/
|
|
||||||
private checkOutput(consumerAccount: Account, output?: Output): Output {
|
|
||||||
const isDefault =
|
|
||||||
!output || (!output.publishAlgorithmLog && !output.publishOutput)
|
|
||||||
|
|
||||||
if (isDefault) {
|
|
||||||
return {
|
|
||||||
publishAlgorithmLog: false,
|
|
||||||
publishOutput: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
publishAlgorithmLog: output.publishAlgorithmLog,
|
|
||||||
publishOutput: output.publishOutput,
|
|
||||||
providerAddress: output.providerAddress || this.config.providerAddress,
|
|
||||||
providerUri: output.providerUri || this.config.providerUri,
|
|
||||||
metadataUri: output.metadataUri || this.config.metadataStoreUri,
|
|
||||||
nodeUri: output.nodeUri || this.config.nodeUri,
|
|
||||||
owner: output.owner || consumerAccount.getId()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
309
src/ocean/Compute.ts
Normal file
309
src/ocean/Compute.ts
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
import { SearchQuery } from '../metadatastore/MetadataStore'
|
||||||
|
import { DDO } from '../ddo/DDO'
|
||||||
|
import { Metadata } from '../ddo/interfaces/Metadata'
|
||||||
|
import { MetadataAlgorithm } from '../ddo/interfaces/MetadataAlgorithm'
|
||||||
|
import {
|
||||||
|
Service,
|
||||||
|
ServiceComputePrivacy,
|
||||||
|
ServiceCompute
|
||||||
|
} from '../ddo/interfaces/Service'
|
||||||
|
import { EditableMetadata } from '../ddo/interfaces/EditableMetadata'
|
||||||
|
import Account from './Account'
|
||||||
|
import DID from './DID'
|
||||||
|
import { SubscribablePromise } from '../utils'
|
||||||
|
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
||||||
|
import {Output} from "./interfaces/ComputeOutput";
|
||||||
|
import {ComputeJob} from "./interfaces/ComputeJob";
|
||||||
|
// import { WebServiceConnector } from './utils/WebServiceConnector'
|
||||||
|
// import { Output } from './interfaces/ComputeOutput'
|
||||||
|
// import { ComputeJob } from './interfaces/ComputeJob'
|
||||||
|
|
||||||
|
export enum OrderProgressStep {
|
||||||
|
TransferDataToken
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ComputeJobStatus = Object.freeze({
|
||||||
|
Started: 10,
|
||||||
|
ConfiguringVolumes: 20,
|
||||||
|
ProvisioningSuccess: 30,
|
||||||
|
DataProvisioningFailed: 31,
|
||||||
|
AlgorithmProvisioningFailed: 32,
|
||||||
|
RunningAlgorithm: 40,
|
||||||
|
FilteringResults: 50,
|
||||||
|
PublishingResult: 60,
|
||||||
|
Completed: 70,
|
||||||
|
Stopped: 80,
|
||||||
|
Deleted: 90
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute submodule of Ocean Protocol.
|
||||||
|
*/
|
||||||
|
export class Compute extends Instantiable {
|
||||||
|
/**
|
||||||
|
* Returns the instance of Compute.
|
||||||
|
* @return {Promise<Assets>}
|
||||||
|
*/
|
||||||
|
public static async getInstance(config: InstantiableConfig): Promise<Compute> {
|
||||||
|
const instance = new Compute()
|
||||||
|
instance.setInstanceConfig(config)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the execution of a compute job.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} did Decentralized identifer for the asset
|
||||||
|
* @param {string} algorithmDid The DID of the algorithm asset (of type `algorithm`) to run on the asset.
|
||||||
|
* @param {MetaData} algorithmMeta Metadata about the algorithm being run if `algorithm` is being used. This is ignored when `algorithmDid` is specified.
|
||||||
|
* @param {Output} output Define algorithm output publishing. Publishing the result of a compute job is turned off by default.
|
||||||
|
* @return {Promise<ComputeJob>} Returns compute job ID under status.jobId
|
||||||
|
*/
|
||||||
|
public async start(
|
||||||
|
consumerAccount: Account,
|
||||||
|
did: string,
|
||||||
|
algorithmDid?: string,
|
||||||
|
algorithmMeta?: MetadataAlgorithm,
|
||||||
|
output?: Output
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
output = this.checkOutput(consumerAccount, output)
|
||||||
|
if (did) {
|
||||||
|
const computeJobsList = await this.ocean.provider.compute(
|
||||||
|
'post',
|
||||||
|
did,
|
||||||
|
consumerAccount,
|
||||||
|
algorithmDid,
|
||||||
|
algorithmMeta,
|
||||||
|
undefined,
|
||||||
|
output
|
||||||
|
)
|
||||||
|
return computeJobsList[0] as ComputeJob
|
||||||
|
} else return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends a running compute job.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} did Decentralized identifier.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped
|
||||||
|
* @return {Promise<ComputeJob>} Returns the new status of a job
|
||||||
|
*/
|
||||||
|
public async stop(
|
||||||
|
consumerAccount: Account,
|
||||||
|
did: string,
|
||||||
|
jobId: string
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
const computeJobsList = await this.ocean.provider.compute(
|
||||||
|
'put',
|
||||||
|
did,
|
||||||
|
consumerAccount,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
jobId
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList[0] as ComputeJob
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about the status of all compute jobs, or a single compute job.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} did Decentralized identifier.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped
|
||||||
|
* @return {Promise<ComputeJob[]>} Returns the status
|
||||||
|
*/
|
||||||
|
public async status(
|
||||||
|
consumerAccount: Account,
|
||||||
|
did?: string,
|
||||||
|
jobId?: string
|
||||||
|
): Promise<ComputeJob[]> {
|
||||||
|
const computeJobsList = await this.ocean.provider.compute(
|
||||||
|
'get',
|
||||||
|
did,
|
||||||
|
consumerAccount,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
jobId
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList as ComputeJob[]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the final result of a specific compute job published as an asset.
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {string} did Decentralized identifier.
|
||||||
|
* @param {string} jobId The ID of the compute job to be stopped.
|
||||||
|
* @return {Promise<ComputeJob>} Returns the DDO of the result asset.
|
||||||
|
*/
|
||||||
|
public async result(
|
||||||
|
consumerAccount: Account,
|
||||||
|
did: string,
|
||||||
|
jobId: string
|
||||||
|
): Promise<ComputeJob> {
|
||||||
|
const computeJobsList = await this.ocean.provider.compute(
|
||||||
|
'get',
|
||||||
|
did,
|
||||||
|
consumerAccount,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
jobId
|
||||||
|
)
|
||||||
|
|
||||||
|
return computeJobsList[0] as ComputeJob
|
||||||
|
}
|
||||||
|
|
||||||
|
public createServerAttributes(
|
||||||
|
serverId: string, serverType: string, cost: string,
|
||||||
|
cpu: string, gpu: string, memory: string,
|
||||||
|
disk: string, maxExecutionTime: number
|
||||||
|
): object {
|
||||||
|
return {
|
||||||
|
serverId, serverType, cost, cpu, gpu, memory, disk, maxExecutionTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public createContainerAttributes(image: string, tag: string, checksum: string): object {
|
||||||
|
return {image, tag, checksum}
|
||||||
|
}
|
||||||
|
|
||||||
|
public createClusterAttributes(type: string, url: string): object {
|
||||||
|
return {type, url}
|
||||||
|
}
|
||||||
|
|
||||||
|
public createProviderAttributes(
|
||||||
|
type: string, description: string, cluster: object, containers: object[], servers: object[]
|
||||||
|
): object {
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
description,
|
||||||
|
environment: {
|
||||||
|
cluster: cluster,
|
||||||
|
supportedServers: containers,
|
||||||
|
supportedContainers: servers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public createComputeService(
|
||||||
|
consumerAccount: Account,
|
||||||
|
cost: string,
|
||||||
|
datePublished: string,
|
||||||
|
providerAttributes: object,
|
||||||
|
computePrivacy?: ServiceComputePrivacy,
|
||||||
|
timeout?: number,
|
||||||
|
): ServiceCompute {
|
||||||
|
const name = 'dataAssetComputingService'
|
||||||
|
if (!timeout) timeout = 3600
|
||||||
|
|
||||||
|
const service = {
|
||||||
|
type: 'compute',
|
||||||
|
index: 3,
|
||||||
|
serviceEndpoint: this.ocean.provider.getComputeEndpoint(),
|
||||||
|
attributes: {
|
||||||
|
main: {
|
||||||
|
name,
|
||||||
|
creator: consumerAccount.getId(),
|
||||||
|
datePublished,
|
||||||
|
cost,
|
||||||
|
timeout: timeout,
|
||||||
|
provider: providerAttributes,
|
||||||
|
privacy: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (computePrivacy)
|
||||||
|
service.attributes.main.privacy = computePrivacy
|
||||||
|
|
||||||
|
return service as ServiceCompute
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the output object and add default properties if needed
|
||||||
|
* @param {Account} consumerAccount The account of the consumer ordering the service.
|
||||||
|
* @param {Output} output Output section used for publishing the result.
|
||||||
|
* @return {Promise<Output>} Returns output object
|
||||||
|
*/
|
||||||
|
private checkOutput(consumerAccount: Account, output?: Output): Output {
|
||||||
|
const isDefault =
|
||||||
|
!output || (!output.publishAlgorithmLog && !output.publishOutput)
|
||||||
|
|
||||||
|
if (isDefault) {
|
||||||
|
return {
|
||||||
|
publishAlgorithmLog: false,
|
||||||
|
publishOutput: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 'signature': signature,
|
||||||
|
// 'documentId': did,
|
||||||
|
// 'serviceId': sa.index,
|
||||||
|
// 'serviceType': sa.type,
|
||||||
|
// 'consumerAddress': cons_acc.address,
|
||||||
|
// 'transferTxId': Web3.toHex(tx_id),
|
||||||
|
// 'dataToken': data_token,
|
||||||
|
// 'output': build_stage_output_dict(dict(), dataset_ddo_w_compute_service, cons_acc.address, pub_acc),
|
||||||
|
// 'algorithmDid': alg_ddo.did,
|
||||||
|
// 'algorithmMeta': {},
|
||||||
|
// 'algorithmDataToken': alg_data_token
|
||||||
|
|
||||||
|
return {
|
||||||
|
publishAlgorithmLog: output.publishAlgorithmLog,
|
||||||
|
publishOutput: output.publishOutput,
|
||||||
|
providerAddress: output.providerAddress || this.config.providerAddress,
|
||||||
|
providerUri: output.providerUri || this.config.providerUri,
|
||||||
|
metadataUri: output.metadataUri || this.config.metadataStoreUri,
|
||||||
|
nodeUri: output.nodeUri || this.config.nodeUri,
|
||||||
|
owner: output.owner || consumerAccount.getId()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// "creator": "0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e",
|
||||||
|
// "datePublished": "2019-04-09T19:02:11Z",
|
||||||
|
// "cost": "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",
|
||||||
|
// "cost": "50",
|
||||||
|
// "cpu": "16",
|
||||||
|
// "gpu": "0",
|
||||||
|
// "memory": "128gb",
|
||||||
|
// "disk": "160gb",
|
||||||
|
// "maxExecutionTime": 86400
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "serverId": "2",
|
||||||
|
// "serverType": "medium",
|
||||||
|
// "cost": "10",
|
||||||
|
// "cpu": "2",
|
||||||
|
// "gpu": "0",
|
||||||
|
// "memory": "8gb",
|
||||||
|
// "disk": "80gb",
|
||||||
|
// "maxExecutionTime": 86400
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
@ -17,6 +17,7 @@ import {
|
|||||||
Instantiable,
|
Instantiable,
|
||||||
generateIntantiableConfigFromConfig
|
generateIntantiableConfigFromConfig
|
||||||
} from '../Instantiable.abstract'
|
} from '../Instantiable.abstract'
|
||||||
|
import {Compute} from "./Compute";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main interface for Ocean Protocol.
|
* Main interface for Ocean Protocol.
|
||||||
@ -47,7 +48,7 @@ export class Ocean extends Instantiable {
|
|||||||
instance.accounts = await Accounts.getInstance(instanceConfig)
|
instance.accounts = await Accounts.getInstance(instanceConfig)
|
||||||
// instance.auth = await Auth.getInstance(instanceConfig)
|
// instance.auth = await Auth.getInstance(instanceConfig)
|
||||||
instance.assets = await Assets.getInstance(instanceConfig)
|
instance.assets = await Assets.getInstance(instanceConfig)
|
||||||
// instance.compute = await Compute.getInstance(instanceConfig)
|
instance.compute = await Compute.getInstance(instanceConfig)
|
||||||
instance.datatokens = new DataTokens(
|
instance.datatokens = new DataTokens(
|
||||||
instanceConfig.config.factoryAddress,
|
instanceConfig.config.factoryAddress,
|
||||||
instanceConfig.config.factoryABI,
|
instanceConfig.config.factoryABI,
|
||||||
@ -105,9 +106,8 @@ export class Ocean extends Instantiable {
|
|||||||
/**
|
/**
|
||||||
* Ocean compute submodule
|
* Ocean compute submodule
|
||||||
* @type {Compute}
|
* @type {Compute}
|
||||||
|
*/
|
||||||
public compute: Compute
|
public compute: Compute
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ocean secretStore submodule
|
* Ocean secretStore submodule
|
||||||
|
@ -174,6 +174,17 @@ export class Provider extends Instantiable {
|
|||||||
url += `&serviceType=${serviceType}` || ''
|
url += `&serviceType=${serviceType}` || ''
|
||||||
url += `&dataToken=${tokenAddress}` || ''
|
url += `&dataToken=${tokenAddress}` || ''
|
||||||
url += `&consumerAddress=${consumerAccount.getId()}` || ''
|
url += `&consumerAddress=${consumerAccount.getId()}` || ''
|
||||||
|
// 'signature': signature,
|
||||||
|
// 'documentId': did,
|
||||||
|
// 'serviceId': sa.index,
|
||||||
|
// 'serviceType': sa.type,
|
||||||
|
// 'consumerAddress': cons_acc.address,
|
||||||
|
// 'transferTxId': Web3.toHex(tx_id),
|
||||||
|
// 'dataToken': data_token,
|
||||||
|
// 'output': build_stage_output_dict(dict(), dataset_ddo_w_compute_service, cons_acc.address, pub_acc),
|
||||||
|
// 'algorithmDid': alg_ddo.did,
|
||||||
|
// 'algorithmMeta': {},
|
||||||
|
// 'algorithmDataToken': alg_data_token
|
||||||
|
|
||||||
// switch fetch method
|
// switch fetch method
|
||||||
let fetch
|
let fetch
|
||||||
|
@ -22,9 +22,10 @@ describe('Marketplace flow', () => {
|
|||||||
let service1
|
let service1
|
||||||
let price
|
let price
|
||||||
let ocean
|
let ocean
|
||||||
let accessService
|
let computeService
|
||||||
let data
|
let data
|
||||||
let blob
|
let blob
|
||||||
|
const dateCreated = new Date(Date.now()).toISOString().split('.')[0] + 'Z' // remove milliseconds
|
||||||
|
|
||||||
const marketplaceAllowance = 20
|
const marketplaceAllowance = 20
|
||||||
const tokenAmount = 100
|
const tokenAmount = 100
|
||||||
@ -60,13 +61,75 @@ describe('Marketplace flow', () => {
|
|||||||
assert(tokenAddress != null)
|
assert(tokenAddress != null)
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('Alice publishes dataset with a compute service', async () => {})
|
it('Generates metadata', async () => {
|
||||||
|
asset = {
|
||||||
|
main: {
|
||||||
|
type: 'dataset',
|
||||||
|
name: 'UK Weather information 2011',
|
||||||
|
dateCreated: dateCreated,
|
||||||
|
author: 'Met Office',
|
||||||
|
license: 'CC-BY',
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
url:'https://raw.githubusercontent.com/tbertinmahieux/MSongsDB/master/Tasks_Demos/CoverSongs/shs_dataset_test.txt',
|
||||||
|
checksum: 'efb2c764274b745f5fc37f97c6b0e764',
|
||||||
|
contentLength: '4535431',
|
||||||
|
contentType: 'text/csv',
|
||||||
|
encoding: 'UTF-8',
|
||||||
|
compression: 'zip'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// it('Alice mints 100 DTs and tranfers them to the compute marketplace', async () => {})
|
it('Alice publishes dataset with a compute service', async () => {
|
||||||
|
price = 10 // in datatoken
|
||||||
|
const timeout = 86400
|
||||||
|
const cluster = ocean.compute.createClusterAttributes('Kubernetes', 'http://10.0.0.17/xxx')
|
||||||
|
const servers = [
|
||||||
|
ocean.compute.createServerAttributes('1', 'xlsize', '50', '16', '0', '128gb', '160gb', timeout)
|
||||||
|
]
|
||||||
|
const containers = [
|
||||||
|
ocean.compute.createContainerAttributes(
|
||||||
|
'tensorflow/tensorflow',
|
||||||
|
'latest',
|
||||||
|
'sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc'
|
||||||
|
)
|
||||||
|
]
|
||||||
|
const provider = ocean.compute.createProviderAttributes(
|
||||||
|
'Azure',
|
||||||
|
'Compute service with 16gb ram for each node.',
|
||||||
|
cluster,
|
||||||
|
containers,
|
||||||
|
servers
|
||||||
|
)
|
||||||
|
const computeService = ocean.compute.createComputeService(
|
||||||
|
alice, price, dateCreated, provider
|
||||||
|
)
|
||||||
|
ddo = await ocean.assets.create(asset, alice, [computeService], tokenAddress)
|
||||||
|
assert(ddo.dataToken === tokenAddress)
|
||||||
|
|
||||||
// it('Markeplace post compute service for sale', async () => {})
|
})
|
||||||
|
|
||||||
// it('Bob buys datatokens from open market and order a compute service', async () => {})
|
it('Alice mints 100 DTs and tranfers them to the compute marketplace', async () => {
|
||||||
|
await datatoken.mint(tokenAddress, alice.getId(), tokenAmount)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Marketplace posts compute service for sale', async () => {
|
||||||
|
computeService = await ocean.assets.getServiceByType(ddo.id, 'compute')
|
||||||
|
assert(computeService.attributes.main.cost === price)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Bob buys datatokens from open market and order a compute service', async () => {
|
||||||
|
const dTamount = 20
|
||||||
|
await datatoken
|
||||||
|
.transfer(tokenAddress, bob.getId(), dTamount, alice.getId())
|
||||||
|
.then(async () => {
|
||||||
|
const balance = await datatoken.balance(tokenAddress, bob.getId())
|
||||||
|
assert(balance.toString() === dTamount.toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// it('Bob starts compute job', async () => {})
|
// it('Bob starts compute job', async () => {})
|
||||||
|
|
||||||
|
188
test/integration/Computeflow.test.ts
Normal file
188
test/integration/Computeflow.test.ts
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
import { TestContractHandler } from '../TestContractHandler'
|
||||||
|
import { DataTokens } from '../../src/datatokens/Datatokens'
|
||||||
|
import { Ocean } from '../../src/ocean/Ocean'
|
||||||
|
import config from './config'
|
||||||
|
import { assert } from 'console'
|
||||||
|
|
||||||
|
const Web3 = require('web3')
|
||||||
|
const web3 = new Web3('http://127.0.0.1:8545')
|
||||||
|
const factory = require('@oceanprotocol/contracts/artifacts/development/Factory.json')
|
||||||
|
const datatokensTemplate = require('@oceanprotocol/contracts/artifacts/development/DataTokenTemplate.json')
|
||||||
|
|
||||||
|
describe('Compute-2-Data flow', () => {
|
||||||
|
let owner
|
||||||
|
let bob
|
||||||
|
let ddo
|
||||||
|
let alice
|
||||||
|
let asset
|
||||||
|
let marketplace
|
||||||
|
let contracts
|
||||||
|
let datatoken
|
||||||
|
let tokenAddress
|
||||||
|
let service1
|
||||||
|
let price
|
||||||
|
let ocean
|
||||||
|
let accessService
|
||||||
|
let data
|
||||||
|
let blob
|
||||||
|
|
||||||
|
const marketplaceAllowance = 20
|
||||||
|
const tokenAmount = 100
|
||||||
|
|
||||||
|
describe('#test', () => {
|
||||||
|
it('Initialize Ocean contracts v3', async () => {
|
||||||
|
contracts = new TestContractHandler(
|
||||||
|
factory.abi,
|
||||||
|
datatokensTemplate.abi,
|
||||||
|
datatokensTemplate.bytecode,
|
||||||
|
factory.bytecode,
|
||||||
|
web3
|
||||||
|
)
|
||||||
|
|
||||||
|
ocean = await Ocean.getInstance(config)
|
||||||
|
owner = (await ocean.accounts.list())[0]
|
||||||
|
alice = (await ocean.accounts.list())[1]
|
||||||
|
bob = (await ocean.accounts.list())[2]
|
||||||
|
marketplace = (await ocean.accounts.list())[3]
|
||||||
|
data = { t: 1, url: ocean.config.metadataStoreUri }
|
||||||
|
blob = JSON.stringify(data)
|
||||||
|
await contracts.deployContracts(owner.getId())
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Alice publishes a datatoken contract', async () => {
|
||||||
|
datatoken = new DataTokens(
|
||||||
|
contracts.factoryAddress,
|
||||||
|
factory.abi,
|
||||||
|
datatokensTemplate.abi,
|
||||||
|
web3
|
||||||
|
)
|
||||||
|
tokenAddress = await datatoken.create(blob, alice.getId())
|
||||||
|
assert(tokenAddress != null)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Generates metadata', async () => {
|
||||||
|
asset = {
|
||||||
|
main: {
|
||||||
|
type: 'dataset',
|
||||||
|
name: 'UK Weather information 2011',
|
||||||
|
dateCreated: new Date(Date.now()).toISOString().split('.')[0] + 'Z', // remove milliseconds
|
||||||
|
author: 'Met Office',
|
||||||
|
license: 'CC-BY',
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
url:'https://raw.githubusercontent.com/tbertinmahieux/MSongsDB/master/Tasks_Demos/CoverSongs/shs_dataset_test.txt',
|
||||||
|
checksum: 'efb2c764274b745f5fc37f97c6b0e764',
|
||||||
|
contentLength: '4535431',
|
||||||
|
contentType: 'text/csv',
|
||||||
|
encoding: 'UTF-8',
|
||||||
|
compression: 'zip'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Alice publishes a dataset', async () => {
|
||||||
|
price = 10 // in datatoken
|
||||||
|
const publishedDate = new Date(Date.now()).toISOString().split('.')[0] + 'Z'
|
||||||
|
const timeout = 0
|
||||||
|
service1 = await ocean.assets.createAccessServiceAttributes(
|
||||||
|
alice,
|
||||||
|
price,
|
||||||
|
publishedDate,
|
||||||
|
timeout
|
||||||
|
)
|
||||||
|
ddo = await ocean.assets.create(asset, alice, [service1], tokenAddress)
|
||||||
|
assert(ddo.dataToken === tokenAddress)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Alice mints 100 tokens', async () => {
|
||||||
|
await datatoken.mint(tokenAddress, alice.getId(), tokenAmount)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Alice allows marketplace to sell her datatokens', async () => {
|
||||||
|
await datatoken
|
||||||
|
.approve(
|
||||||
|
tokenAddress,
|
||||||
|
marketplace.getId(),
|
||||||
|
marketplaceAllowance,
|
||||||
|
alice.getId()
|
||||||
|
)
|
||||||
|
.then(async () => {
|
||||||
|
const allowance = await datatoken.allowance(
|
||||||
|
tokenAddress,
|
||||||
|
alice.getId(),
|
||||||
|
marketplace.getId()
|
||||||
|
)
|
||||||
|
assert(allowance.toString() === marketplaceAllowance.toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Marketplace withdraw Alice tokens from allowance', async () => {
|
||||||
|
const allowance = await datatoken.allowance(
|
||||||
|
tokenAddress,
|
||||||
|
alice.getId(),
|
||||||
|
marketplace.getId()
|
||||||
|
)
|
||||||
|
await datatoken
|
||||||
|
.transferFrom(tokenAddress, alice.getId(), allowance, marketplace.getId())
|
||||||
|
.then(async () => {
|
||||||
|
const marketplaceBalance = await datatoken.balance(
|
||||||
|
tokenAddress,
|
||||||
|
marketplace.getId()
|
||||||
|
)
|
||||||
|
assert(
|
||||||
|
marketplaceBalance.toString() === marketplaceAllowance.toString()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
it('Marketplace should resolve asset using DID', async () => {
|
||||||
|
await ocean.assets.resolve(ddo.id).then((newDDO) => {
|
||||||
|
assert(newDDO.id === ddo.id)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Marketplace posts asset for sale', async () => {
|
||||||
|
accessService = await ocean.assets.getServiceByType(ddo.id, 'access')
|
||||||
|
price = 20
|
||||||
|
assert(accessService.attributes.main.cost * price === 200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Bob gets datatokens', async () => {
|
||||||
|
const dTamount = 20
|
||||||
|
await datatoken
|
||||||
|
.transfer(tokenAddress, bob.getId(), dTamount, alice.getId())
|
||||||
|
.then(async () => {
|
||||||
|
const balance = await datatoken.balance(tokenAddress, bob.getId())
|
||||||
|
assert(balance.toString() === dTamount.toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Bob consumes asset 1', async () => {
|
||||||
|
await ocean.assets
|
||||||
|
.order(ddo.id, accessService.type, bob.getId())
|
||||||
|
.then(async (res: string) => {
|
||||||
|
res = JSON.parse(res)
|
||||||
|
return await datatoken.transfer(
|
||||||
|
res['dataToken'],
|
||||||
|
res['to'],
|
||||||
|
res['numTokens'],
|
||||||
|
res['from']
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.then(async (tx) => {
|
||||||
|
await ocean.assets.download(
|
||||||
|
ddo.id,
|
||||||
|
tx.transactionHash,
|
||||||
|
tokenAddress,
|
||||||
|
bob,
|
||||||
|
'./node_modules/my-datasets'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
it('owner can list there assets', async () => {
|
||||||
|
const assets = await ocean.assets.ownerAssets(alice.getId())
|
||||||
|
assert(assets.length > 0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user