Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 4.0 - Includes breaking changes for C2D V2 (also free compute) #1891

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f6057f3
add datasets on ComputeAsset, new start compute fn
paulo-ocean Oct 31, 2024
9e6ec4d
fix type mismatch new c2d v2
paulo-ocean Oct 31, 2024
50e3ed8
fix tests
paulo-ocean Oct 31, 2024
0f0ad3e
fix tests, keep backwards compatibility due to tests running with exi…
paulo-ocean Oct 31, 2024
a9a099d
support for starting a free env compute job
paulo-ocean Nov 4, 2024
2107197
minor fix
paulo-ocean Nov 5, 2024
583db8e
add file object types
paulo-ocean Nov 6, 2024
7df390a
enforce asset files object type
paulo-ocean Nov 7, 2024
e312ec7
support for consumer signature on initialize compute
paulo-ocean Nov 12, 2024
88ee8d3
update docs and tests, pass signer account, not signer address
paulo-ocean Nov 12, 2024
c31c0c3
Release 4.0.0-next.0
paulo-ocean Nov 12, 2024
2c631d4
Release 4.0.0-next.1
paulo-ocean Nov 12, 2024
1030ee5
remove noZerox usage on compute routes query string/params
paulo-ocean Jan 7, 2025
c1b8546
fix conflicts
paulo-ocean Jan 7, 2025
c7a5ffd
merge main, fix conflicts
paulo-ocean Jan 14, 2025
a9e5614
fix conflict
paulo-ocean Jan 14, 2025
309b781
fix conflict
paulo-ocean Jan 14, 2025
bfceb46
rm node 18 image ref
paulo-ocean Jan 14, 2025
bd56020
put back change, was 18 not 16, 18 is ok
paulo-ocean Jan 14, 2025
fcebea0
try fix build ci
paulo-ocean Jan 20, 2025
ac61d94
try skip the delete part (images were not built before?)
paulo-ocean Jan 20, 2025
7f604f6
add the delete images part back
paulo-ocean Jan 20, 2025
cdc1ec6
add -f flag on ci, removal of docker images, avoid fail if img not pr…
paulo-ocean Jan 22, 2025
cca8092
merge main & fix conflicts
paulo-ocean Feb 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ComputeExamples.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ Let's have 5 minute of compute access
computeEnv.id,
computeValidUntil,
providerUrl,
await consumerAccount.getAddress()
consumerAccount
)
```
<!--
Expand Down Expand Up @@ -655,7 +655,7 @@ Let's have 5 minute of compute access
providerUrl,
consumerAccount,
computeEnv.id,
assets[0],
assets,
algo
)

Expand Down
2 changes: 1 addition & 1 deletion docs/classes/Provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ Initializes the provider for a compute request.
| `computeEnv` | `string` | The compute environment. |
| `validUntil` | `number` | The job expiration date. |
| `providerUri` | `string` | The provider URI. |
| `accountId` | `string` | caller address |
| `signer` | `Signer` | caller account |
| `signal?` | `AbortSignal` | abort signal |

#### Returns
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@oceanprotocol/lib",
"source": "./src/index.ts",
"version": "3.4.6",
"version": "4.0.0-next.1",
"description": "JavaScript client library for Ocean Protocol",
"main": "./dist/lib.js",
"umd:main": "dist/lib.umd.js",
Expand Down
37 changes: 37 additions & 0 deletions src/@types/Compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
storageExpiry: number
maxJobDuration: number
lastSeen: number
free: boolean
}

export interface ComputeResult {
Expand Down Expand Up @@ -59,14 +60,50 @@
whitelist?: string[]
}

export enum FileObjectType {
URL = 'url',

Check warning on line 64 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'URL' is defined but never used

Check warning on line 64 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'URL' is defined but never used
IPFS = 'ipfs',

Check warning on line 65 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'IPFS' is defined but never used

Check warning on line 65 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'IPFS' is defined but never used
ARWEAVE = 'arweave'

Check warning on line 66 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'ARWEAVE' is defined but never used

Check warning on line 66 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'ARWEAVE' is defined but never used
}

export enum EncryptMethod {
AES = 'AES',

Check warning on line 70 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'AES' is defined but never used

Check warning on line 70 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'AES' is defined but never used
ECIES = 'ECIES'

Check warning on line 71 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'ECIES' is defined but never used

Check warning on line 71 in src/@types/Compute.ts

View workflow job for this annotation

GitHub Actions / lint

'ECIES' is defined but never used
}

export interface HeadersObject {
[key: string]: string
}

export interface BaseFileObject {
type: string
encryptedBy?: string
encryptMethod?: EncryptMethod
}

export interface UrlFileObject extends BaseFileObject {
url: string
method: string
headers?: [HeadersObject]
}

export interface IpfsFileObject extends BaseFileObject {
hash: string
}

export interface ArweaveFileObject extends BaseFileObject {
transactionId: string
}
export interface ComputeAsset {
fileObject?: BaseFileObject // C2D v2
documentId: string
serviceId: string
transferTxId?: string
userdata?: { [key: string]: any }
}

export interface ComputeAlgorithm {
fileObject?: BaseFileObject // C2D v2
documentId?: string
serviceId?: string
meta?: MetadataAlgorithm
Expand Down
193 changes: 187 additions & 6 deletions src/services/Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ export class Provider {
* @param {AbortSignal} signal abort signal
* @return {Promise<ProviderComputeInitialize>} ProviderComputeInitialize data
*/
public async initializeCompute(
public async initializeComputeV1(
assets: ComputeAsset[],
algorithm: ComputeAlgorithm,
computeEnv: string,
Expand Down Expand Up @@ -470,6 +470,90 @@ export class Provider {
throw new Error(JSON.stringify(resolvedResponse))
}

/** Initializes the provider for a compute request.
* @param {ComputeAsset[]} assets The datasets array to initialize compute request.
* @param {ComputeAlgorithmber} algorithm The algorithm to use.
* @param {string} computeEnv The compute environment.
* @param {number} validUntil The job expiration date.
* @param {string} providerUri The provider URI.
* @param {Signer} signer caller address
* @param {AbortSignal} signal abort signal
* @return {Promise<ProviderComputeInitialize>} ProviderComputeInitialize data
*/
public async initializeCompute(
assets: ComputeAsset[],
algorithm: ComputeAlgorithm,
computeEnv: string,
validUntil: number,
providerUri: string,
signer: Signer,
signal?: AbortSignal
): Promise<ProviderComputeInitializeResults> {
const providerEndpoints = await this.getEndpoints(providerUri)
const serviceEndpoints = await this.getServiceEndpoints(
providerUri,
providerEndpoints
)

// Diff from V1. We might need a signature to get the files object, specially if dealing with confidential evm and template 4
// otherwise it can be ignored
const consumerAddress = await signer.getAddress()
const nonce = (
(await this.getNonce(
providerUri,
consumerAddress,
signal,
providerEndpoints,
serviceEndpoints
)) + 1
).toString()

// same signed message as for start compute (consumer address + did[0] + nonce)
let signatureMessage = consumerAddress
signatureMessage += assets[0].documentId
signatureMessage += nonce
const signature = await this.signProviderRequest(signer, signatureMessage)

const providerData = {
datasets: assets,
algorithm,
compute: { env: computeEnv, validUntil },
consumerAddress,
signature
}
const initializeUrl = this.getEndpointURL(serviceEndpoints, 'initializeCompute')
? this.getEndpointURL(serviceEndpoints, 'initializeCompute').urlPath
: null
if (!initializeUrl) return null

let response
try {
response = await fetch(initializeUrl, {
method: 'POST',
body: JSON.stringify(providerData),
headers: { 'Content-Type': 'application/json' },
signal
})
} catch (e) {
LoggerInstance.error('Initialize compute failed: ')
LoggerInstance.error(e)
throw new Error('ComputeJob cannot be initialized')
}
if (response?.ok) {
const params = await response.json()
return params
}
const resolvedResponse = await response.json()
LoggerInstance.error(
'Initialize compute failed: ',
response.status,
response.statusText,
resolvedResponse
)
LoggerInstance.error('Payload was:', providerData)
throw new Error(JSON.stringify(resolvedResponse))
}

/**
* Gets the download URL.
* @param {string} did - The DID.
Expand Down Expand Up @@ -524,7 +608,7 @@ export class Provider {
return consumeUrl
}

/** Instruct the provider to start a compute job
/** Instruct the provider to start a compute job (Old C2D V1) Kept for now, for backwards compatibility
* @param {string} providerUri The provider URI.
* @param {Signer} signer The consumer signer object.
* @param {string} computeEnv The compute environment.
Expand All @@ -535,7 +619,7 @@ export class Provider {
* @param {ComputeOutput} output The compute job output settings.
* @return {Promise<ComputeJob | ComputeJob[]>} The compute job or jobs.
*/
public async computeStart(
public async computeStartV1(
providerUri: string,
consumer: Signer,
computeEnv: string,
Expand Down Expand Up @@ -607,6 +691,103 @@ export class Provider {
return null
}

/** Instruct the provider to start a compute job (new C2D V2)
* @param {string} providerUri The provider URI.
* @param {Signer} signer The consumer signer object.
* @param {string} computeEnv The compute environment.
* @param {ComputeAsset} datasets The dataset to start compute on + additionalDatasets (the additional datasets if that is the case)
* @param {ComputeAlgorithm} algorithm The algorithm to start compute with.
* @param {AbortSignal} signal abort signal
* @param {ComputeOutput} output The compute job output settings.
* @param {boolean} freeEnvironment is it a free environment? uses different route
* @return {Promise<ComputeJob | ComputeJob[]>} The compute job or jobs.
*/
public async computeStart(
providerUri: string,
consumer: Signer,
computeEnv: string,
datasets: ComputeAsset[],
algorithm: ComputeAlgorithm,
signal?: AbortSignal,
output?: ComputeOutput,
freeEnvironment?: boolean
): Promise<ComputeJob | ComputeJob[]> {
console.log('called new compute start method...')
console.log('datasets: ', datasets)
console.log('algorithm: ', algorithm)
const providerEndpoints = await this.getEndpoints(providerUri)
const serviceEndpoints = await this.getServiceEndpoints(
providerUri,
providerEndpoints
)
let computeStartUrl = null

if (freeEnvironment) {
computeStartUrl = this.getEndpointURL(serviceEndpoints, 'freeCompute')
? this.getEndpointURL(serviceEndpoints, 'freeCompute').urlPath
: null
} else {
computeStartUrl = this.getEndpointURL(serviceEndpoints, 'computeStart')
? this.getEndpointURL(serviceEndpoints, 'computeStart').urlPath
: null
}

const consumerAddress = await consumer.getAddress()
const nonce = (
(await this.getNonce(
providerUri,
consumerAddress,
signal,
providerEndpoints,
serviceEndpoints
)) + 1
).toString()

let signatureMessage = consumerAddress
signatureMessage += datasets[0].documentId
signatureMessage += nonce
const signature = await this.signProviderRequest(consumer, signatureMessage)
const payload = Object()
payload.consumerAddress = consumerAddress
payload.signature = signature
payload.nonce = nonce
payload.environment = computeEnv
// kept for backwards compatibility (tests running against existing provider)
payload.dataset = datasets[0]
// new field for C2D v2
payload.datasets = datasets
payload.algorithm = algorithm
// if (additionalDatasets) payload.additionalDatasets = additionalDatasets
if (output) payload.output = output
if (!computeStartUrl) return null
let response
try {
response = await fetch(computeStartUrl, {
method: 'POST',
body: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' },
signal
})
} catch (e) {
LoggerInstance.error('Compute start failed:')
LoggerInstance.error(e)
LoggerInstance.error('Payload was:', payload)
throw new Error('HTTP request failed calling Provider')
}
if (response?.ok) {
const params = await response.json()
return params
}
LoggerInstance.error(
'Compute start failed: ',
response.status,
response.statusText,
await response.json()
)
LoggerInstance.error('Payload was:', payload)
return null
}

/** Instruct the provider to Stop the execution of a to stop a compute job.
* @param {string} did the asset did
* @param {string} consumerAddress The consumer address.
Expand Down Expand Up @@ -655,7 +836,7 @@ export class Provider {
const signature = await this.signProviderRequest(signer, signatureMessage)
const payload = Object()
payload.signature = signature
payload.agreementId = this.noZeroX(agreementId)
payload.agreementId = agreementId // this.noZeroX(agreementId) #https://github.com/oceanprotocol/ocean.js/issues/1892
payload.consumerAddress = consumerAddress
payload.nonce = nonce
if (jobId) payload.jobId = jobId
Expand Down Expand Up @@ -716,7 +897,7 @@ export class Provider {
: null

let url = `?consumerAddress=${consumerAddress}`
url += (agreementId && `&agreementId=${this.noZeroX(agreementId)}`) || ''
url += (agreementId && `&agreementId=${agreementId}`) || '' // ${this.noZeroX(agreementId)} #https://github.com/oceanprotocol/ocean.js/issues/1892
url += (jobId && `&jobId=${jobId}`) || ''

if (!computeStatusUrl) return null
Expand Down Expand Up @@ -841,7 +1022,7 @@ export class Provider {
signatureMessage += nonce
const signature = await this.signProviderRequest(consumer, signatureMessage)
const payload = Object()
payload.documentId = this.noZeroX(did)
payload.documentId = did // this.noZeroX(did) #https://github.com/oceanprotocol/ocean.js/issues/1892
payload.consumerAddress = await consumer.getAddress()
payload.jobId = jobId
if (signature) payload.signature = signature
Expand Down
10 changes: 10 additions & 0 deletions src/utils/Assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ProviderInstance } from '../services/Provider'
import AccessListFactory from '@oceanprotocol/contracts/artifacts/contracts/accesslists/AccessListFactory.sol/AccessListFactory.json'
import ERC20Template4 from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template4.sol/ERC20Template4.json'
import { calculateActiveTemplateIndex } from './Adresses'
import { FileObjectType } from '../@types'

// import * as hre from 'hardhat'

Expand Down Expand Up @@ -113,6 +114,15 @@ export async function createAsset(
mpFeeAddress: ZERO_ADDRESS
}

if (
!assetUrl.type ||
![FileObjectType.ARWEAVE, FileObjectType.IPFS, FileObjectType.URL].includes(
assetUrl.type.toLowerCase()
)
) {
console.log('Missing or invalid files object type, defaulting to "url"')
assetUrl.type = FileObjectType.URL
}
// include fileObject in the DT constructor
if (config.sdk === 'oasis') {
datatokenParams.filesObject = assetUrl
Expand Down
Loading
Loading