diff --git a/package-lock.json b/package-lock.json index c986388c..2b603169 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29865,4 +29865,4 @@ "dev": true } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 61587381..d32ee244 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "test:unit:cover": "nyc --report-dir coverage/unit npm run test:unit", "test:integration": "npm run mocha -- 'test/integration/**/*.test.ts'", "test:provider": "npm run mocha -- 'test/integration/Provider.test.ts'", + "test:compute": "npm run mocha -- 'test/integration/ComputeFlow.test.ts'", "test:integration:cover": "nyc --report-dir coverage/integration --no-clean npm run test:integration" }, "repository": { diff --git a/src/@types/Compute.ts b/src/@types/Compute.ts index c175b115..39b8edf1 100644 --- a/src/@types/Compute.ts +++ b/src/@types/Compute.ts @@ -1,6 +1,10 @@ import { Metadata, MetadataAlgorithm } from './DDO/Metadata' -export type ComputeResultType = 'algorithmLog' | 'output' +export type ComputeResultType = + | 'algorithmLog' + | 'output' + | 'configrationLog' + | 'publishLog' export interface ComputeEnvironment { id: string diff --git a/src/provider/Provider.ts b/src/provider/Provider.ts index fd4ff118..f2116541 100644 --- a/src/provider/Provider.ts +++ b/src/provider/Provider.ts @@ -1,5 +1,5 @@ import Web3 from 'web3' -import { LoggerInstance, getData, downloadFile, downloadFileBrowser } from '../utils' +import { LoggerInstance, getData } from '../utils' import { FileMetadata, ComputeJob, @@ -11,7 +11,6 @@ import { } from '../@types/' import { noZeroX } from '../utils/ConversionTypeHelper' import fetch from 'cross-fetch' -import { DownloadResponse } from '../@types/DownloadResponse' export interface HttpCallback { (httpMethod: string, url: string, body: string, header: any): Promise } @@ -66,7 +65,7 @@ export class Provider { return serviceEndpoints } - /** Encrypt DDO using the Provider's own symmetric key + /** Gets current nonce * @param {string} providerUri provider uri address * @param {string} consumerAddress Publisher address * @param {AbortSignal} signal abort signal @@ -142,12 +141,11 @@ export class Provider { const path = this.getEndpointURL(serviceEndpoints, 'encrypt') ? this.getEndpointURL(serviceEndpoints, 'encrypt').urlPath : null - if (!path) return null try { const response = await fetch(path, { method: 'POST', - body: decodeURI(JSON.stringify(data)), + body: JSON.stringify(data), headers: { 'Content-Type': 'application/octet-stream' }, @@ -437,7 +435,7 @@ export class Provider { const params = await response.json() return params } - console.error('Compute start failed:', response.status, response.statusText) + LoggerInstance.error('Compute start failed: ', response.status, response.statusText) LoggerInstance.error('Payload was:', payload) return null } catch (e) { @@ -577,23 +575,21 @@ export class Provider { } } - /** Get status for a specific jobId/documentId/owner. - * @param {string} jobId - * @param {number} index - * @param {string} providerUri - * @param {string} destination - * @param {Web3} web3 - * @param {AbortSignal} signal abort signal - * @return {Promise} + /** Get compute result url + * @param {string} providerUri The URI of the provider we want to query + * @param {Web3} web3 Web3 instance + * @param {string} consumerAddress The consumer ethereum address + * @param {string} jobId The ID of a compute job. + * @param {number} index Result index + * @return {Promise} */ - public async computeResult( - jobId: string, - index: number, - accountId: string, + public async getComputeResultUrl( providerUri: string, web3: Web3, - signal?: AbortSignal - ): Promise { + consumerAddress: string, + jobId: string, + index: number + ): Promise { const providerEndpoints = await this.getEndpoints(providerUri) const serviceEndpoints = await this.getServiceEndpoints( providerUri, @@ -603,38 +599,24 @@ export class Provider { ? this.getEndpointURL(serviceEndpoints, 'computeResult').urlPath : null - const nonce = await this.getNonce( - providerUri, - accountId, - signal, - providerEndpoints, - serviceEndpoints - ) - - let signatureMessage = accountId + const nonce = Date.now() + let signatureMessage = consumerAddress signatureMessage += jobId signatureMessage += index.toString() signatureMessage += nonce - const signature = await this.signProviderRequest(web3, accountId, signatureMessage) - - let consumeUrl = computeResultUrl - consumeUrl += `?consumerAddress=${accountId}` - consumeUrl += `&jobId=${jobId}` - consumeUrl += `&index=${String(index)}` - consumeUrl += (signature && `&signature=${signature}`) || '' - + const signature = await this.signProviderRequest( + web3, + consumerAddress, + signatureMessage + ) if (!computeResultUrl) return null - try { - if (document) { - await downloadFileBrowser(consumeUrl) - } else { - return await downloadFile(consumeUrl, index) - } - } catch (e) { - LoggerInstance.error('Error getting job result') - LoggerInstance.error(e) - throw e - } + let resultUrl = computeResultUrl + resultUrl += `?consumerAddress=${consumerAddress}` + resultUrl += `&jobId=${jobId}` + resultUrl += `&index=${index.toString()}` + resultUrl += `&nonce=${nonce}` + resultUrl += (signature && `&signature=${signature}`) || '' + return resultUrl } /** Deletes a compute job. diff --git a/src/utils/DdoHelpers.ts b/src/utils/DdoHelpers.ts index 23b9406f..a2bb88e4 100644 --- a/src/utils/DdoHelpers.ts +++ b/src/utils/DdoHelpers.ts @@ -1,5 +1,6 @@ import sha256 from 'crypto-js/sha256' import Web3 from 'web3' +import LoggerInstance from './Logger' export function generateDid(erc721Address: string, chainId: number): string { erc721Address = Web3.utils.toChecksumAddress(erc721Address) @@ -8,5 +9,9 @@ export function generateDid(erc721Address: string, chainId: number): string { } export function getHash(data: any): string { - return sha256(data).toString() + try { + return sha256(data).toString() + } catch (e) { + LoggerInstance.error('getHash error: ', e.message) + } } diff --git a/test/integration/ComputeFlow.test.ts b/test/integration/ComputeFlow.test.ts index e5e0e661..3a231035 100644 --- a/test/integration/ComputeFlow.test.ts +++ b/test/integration/ComputeFlow.test.ts @@ -1,6 +1,5 @@ import { assert } from 'chai' import { SHA256 } from 'crypto-js' -import console from 'console' import { web3, getTestConfig, getAddresses } from '../config' import { Config, @@ -10,9 +9,10 @@ import { NftCreateData, Datatoken, getHash, - Nft + Nft, + sleep } from '../../src' -import { ProviderFees, Erc20CreateParams } from '../../src/@types' +import { ProviderFees, Erc20CreateParams, ComputeJob, Asset } from '../../src/@types' const assetUrl = [ { @@ -110,12 +110,15 @@ const algoDdo = { } ] } +let providerUrl: string +let consumerAccount: string +let computeJobId: string +let resolvedDDOAsset: Asset describe('Simple compute tests', async () => { let config: Config let addresses: any let aquarius: Aquarius - let providerUrl: any before(async () => { config = await getTestConfig(web3) @@ -130,7 +133,7 @@ describe('Simple compute tests', async () => { const Factory = new NftFactory(addresses.ERC721Factory, web3) const accounts = await web3.eth.getAccounts() const publisherAccount = accounts[0] - const consumerAccount = accounts[1] + consumerAccount = accounts[1] const chain = await web3.eth.getChainId() const nftParamsAsset: NftCreateData = { name: 'testNFT', @@ -234,7 +237,7 @@ describe('Simple compute tests', async () => { ) // let's wait - const resolvedDDOAsset = await aquarius.waitForAqua(ddo.id) + resolvedDDOAsset = await aquarius.waitForAqua(ddo.id) assert(resolvedDDOAsset, 'Cannot fetch DDO from Aquarius') const resolvedDDOAlgo = await aquarius.waitForAqua(algoDdo.id) assert(resolvedDDOAlgo, 'Cannot fetch DDO from Aquarius') @@ -246,7 +249,6 @@ describe('Simple compute tests', async () => { const computeEnvs = await ProviderInstance.getComputeEnvironments(providerUrl) assert(computeEnvs, 'No Compute environments found') // we choose the first env - console.log(computeEnvs) const computeEnv = computeEnvs[0].id const computeConsumerAddress = computeEnvs[0].consumerAddress // let's have 10 minutesof compute access @@ -265,7 +267,6 @@ describe('Simple compute tests', async () => { computeEnv, computeValidUntil ) - console.log(initializeDataAlgo) const providerAlgoFees: ProviderFees = { providerFeeAddress: initializeDataAlgo.providerFee.providerFeeAddress, providerFeeToken: initializeDataAlgo.providerFee.providerFeeToken, @@ -302,7 +303,6 @@ describe('Simple compute tests', async () => { computeEnv, computeValidUntil ) - console.log(initializeData) const providerDatasetFees: ProviderFees = { providerFeeAddress: initializeData.providerFee.providerFeeAddress, providerFeeToken: initializeData.providerFee.providerFeeToken, @@ -340,12 +340,28 @@ describe('Simple compute tests', async () => { } ) assert(computeJobs, 'Cannot start compute job') - const jobStatus = await ProviderInstance.computeStatus( + computeJobId = computeJobs[0].jobId + }) + + it('Check compute status', async () => { + const jobStatus = (await ProviderInstance.computeStatus( providerUrl, consumerAccount, - computeJobs[0].jobId, + computeJobId, resolvedDDOAsset.id + )) as ComputeJob + assert(jobStatus, 'Cannot retrieve compute status!') + }) + + it('Get download compute results url', async () => { + sleep(10000) + const downloadURL = await ProviderInstance.getComputeResultUrl( + providerUrl, + web3, + consumerAccount, + computeJobId, + 0 ) - assert(jobStatus) + assert(downloadURL, 'Provider getComputeResultUrl failed!') }) })