Skip to content

Commit a8b4d37

Browse files
authored
Validate algorithm for dataset in intializeCompute. (#1012)
* Validate algorithm for dataset in intialize. * Update samples. * Add sample with compute asset without access. * Fix import. * Update compute test. * Fix variable. * Uodate status code. * Authorize. * Fix samples w credentials. * Add new URL for storage. * Revert URL.
1 parent f6d424a commit a8b4d37

File tree

3 files changed

+231
-104
lines changed

3 files changed

+231
-104
lines changed

src/components/core/compute/initialize.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { C2DEngineDocker, getAlgorithmImage } from '../../c2d/compute_engine_doc
3333
import { Credentials, DDOManager } from '@oceanprotocol/ddo-js'
3434
import { areKnownCredentialTypes, checkCredentials } from '../../../utils/credentials.js'
3535
import { PolicyServer } from '../../policyServer/index.js'
36+
import { getAlgoChecksums, validateAlgoForDataset } from './utils.js'
3637

3738
export class ComputeInitializeHandler extends CommandHandler {
3839
validate(command: ComputeInitializeCommand): ValidateParams {
@@ -88,6 +89,28 @@ export class ComputeInitializeHandler extends CommandHandler {
8889
}
8990
}
9091
}
92+
93+
const algoChecksums = await getAlgoChecksums(
94+
task.algorithm.documentId,
95+
task.algorithm.serviceId,
96+
node
97+
)
98+
99+
const isRawCodeAlgorithm = task.algorithm.meta?.rawcode
100+
const hasValidChecksums = algoChecksums.container && algoChecksums.files
101+
102+
if (!isRawCodeAlgorithm && !hasValidChecksums) {
103+
const errorMessage =
104+
'Failed to retrieve algorithm checksums. Both container and files checksums are required.'
105+
CORE_LOGGER.error(errorMessage)
106+
return {
107+
stream: null,
108+
status: {
109+
httpStatus: 500,
110+
error: errorMessage
111+
}
112+
}
113+
}
91114
if (engine === null) {
92115
return {
93116
stream: null,
@@ -201,7 +224,8 @@ export class ComputeInitializeHandler extends CommandHandler {
201224
const {
202225
chainId: ddoChainId,
203226
nftAddress,
204-
credentials
227+
credentials,
228+
metadata
205229
} = ddoInstance.getDDOFields()
206230
const isOrdable = isOrderingAllowedForAsset(ddo)
207231
if (!isOrdable.isOrdable) {
@@ -214,6 +238,30 @@ export class ComputeInitializeHandler extends CommandHandler {
214238
}
215239
}
216240
}
241+
if (metadata.type !== 'algorithm') {
242+
const index = task.datasets.findIndex(
243+
(d) => d.documentId === ddoInstance.getDid()
244+
)
245+
const safeIndex = index === -1 ? 0 : index
246+
const validAlgoForDataset = await validateAlgoForDataset(
247+
task.algorithm.documentId,
248+
algoChecksums,
249+
ddoInstance,
250+
task.datasets[safeIndex].serviceId,
251+
node
252+
)
253+
if (!validAlgoForDataset) {
254+
return {
255+
stream: null,
256+
status: {
257+
httpStatus: 400,
258+
error: `Algorithm ${
259+
task.algorithm.documentId
260+
} not allowed to run on the dataset: ${ddoInstance.getDid()}`
261+
}
262+
}
263+
}
264+
}
217265
// check credentials (DDO level)
218266
let accessGrantedDDOLevel: boolean
219267
if (credentials) {

src/test/data/assets.ts

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,14 @@ export const computeAssetWithCredentials = {
190190
compute: {
191191
allowRawAlgorithm: false,
192192
allowNetworkAccess: true,
193-
publisherTrustedAlgorithmPublishers: [] as any,
194-
publisherTrustedAlgorithms: [] as any
193+
publisherTrustedAlgorithmPublishers: ['*'] as any,
194+
publisherTrustedAlgorithms: [
195+
{
196+
did: '*',
197+
filesChecksum: '*',
198+
containerSectionChecksum: '*'
199+
}
200+
] as any
195201
}
196202
}
197203
],
@@ -287,6 +293,78 @@ export const algoAssetWithCredentials = {
287293
}
288294

289295
export const computeAsset = {
296+
'@context': ['https://w3id.org/did/v1'],
297+
id: '',
298+
nftAddress: '',
299+
version: '4.1.0',
300+
chainId: 8996,
301+
metadata: {
302+
created: '2021-12-20T14:35:20Z',
303+
updated: '2021-12-20T14:35:20Z',
304+
type: 'dataset',
305+
name: 'cli fixed asset',
306+
description: 'asset published using ocean.js cli tool',
307+
tags: ['test'],
308+
author: 'oceanprotocol',
309+
license: 'https://market.oceanprotocol.com/terms',
310+
additionalInformation: {
311+
termsAndConditions: true
312+
}
313+
},
314+
services: [
315+
{
316+
id: '1155995dda741e93afe4b1c6ced2d01734a6ec69865cc0997daf1f4db7259a36',
317+
type: 'compute',
318+
files: {
319+
files: [
320+
{
321+
type: 'url',
322+
url: 'https://raw.githubusercontent.com/oceanprotocol/testdatasets/main/shs_dataset_test.txt',
323+
method: 'GET'
324+
}
325+
]
326+
},
327+
datatokenAddress: '',
328+
serviceEndpoint: 'https://v4.provider.oceanprotocol.com',
329+
timeout: 86400,
330+
compute: {
331+
allowRawAlgorithm: false,
332+
allowNetworkAccess: true,
333+
publisherTrustedAlgorithmPublishers: ['*'] as any,
334+
publisherTrustedAlgorithms: [
335+
{
336+
did: '*',
337+
filesChecksum: '*',
338+
containerSectionChecksum: '*'
339+
}
340+
] as any
341+
}
342+
}
343+
],
344+
event: {},
345+
nft: {
346+
address: '',
347+
name: 'Ocean Data NFT',
348+
symbol: 'OCEAN-NFT',
349+
state: 5,
350+
tokenURI: '',
351+
owner: '',
352+
created: ''
353+
},
354+
purgatory: {
355+
state: false
356+
},
357+
datatokens: [] as any,
358+
stats: {
359+
allocated: 0,
360+
orders: 0,
361+
price: {
362+
value: '0'
363+
}
364+
}
365+
}
366+
367+
export const computeAssetWithNoAccess = {
290368
'@context': ['https://w3id.org/did/v1'],
291369
id: '',
292370
nftAddress: '',

0 commit comments

Comments
 (0)