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

Check if ddo state is active before executing node's commands. #542

Merged
merged 6 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions src/@types/Asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,8 @@ export interface Asset extends DDO {
*/
purgatory: Purgatory
}

export interface OrdableAssetResponse {
isOrdable: boolean
reason?: string
}
3 changes: 3 additions & 0 deletions src/@types/DDO/DDO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Service } from './Service'
import { Metadata } from './Metadata'
import { Credentials } from './Credentials'
import { Event } from './Event'
import { Nft } from './Nft'

/**
* DID Descriptor Object.
Expand Down Expand Up @@ -64,4 +65,6 @@ export interface DDO {
* @type {Event}
*/
event?: Event

nft?: Nft
}
9 changes: 9 additions & 0 deletions src/@types/DDO/Nft.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface Nft {
state: number
address: string
name?: string
symbol?: string
tokenURI?: string
owner?: string
created?: string
}
12 changes: 12 additions & 0 deletions src/components/core/compute/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { isAddress } from 'ethers'
import { getConfiguration } from '../../../utils/index.js'
import { sanitizeServiceFiles } from '../../../utils/util.js'
import { FindDdoHandler } from '../handler/ddoHandler.js'
import { isOrderingAllowedForAsset } from '../handler/downloadHandler.js'
export class ComputeInitializeHandler extends Handler {
validate(command: ComputeInitializeCommand): ValidateParams {
const validation = validateCommandParameters(command, [
Expand Down Expand Up @@ -81,6 +82,17 @@ export class ComputeInitializeHandler extends Handler {
}
}
}
const isOrdable = isOrderingAllowedForAsset(ddo)
if (!isOrdable.isOrdable) {
CORE_LOGGER.error(isOrdable.reason)
return {
stream: null,
status: {
httpStatus: 500,
error: isOrdable.reason
}
}
}
const service = AssetUtils.getServiceById(ddo, elem.serviceId)
if (!service) {
const error = `Cannot find service ${elem.serviceId} in DDO ${elem.documentId}`
Expand Down
12 changes: 12 additions & 0 deletions src/components/core/compute/startCompute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { sanitizeServiceFiles } from '../../../utils/util.js'
import { FindDdoHandler } from '../handler/ddoHandler.js'
import { ProviderFeeValidation } from '../../../@types/Fees.js'
import { getAlgoChecksums, validateAlgoForDataset } from '../../c2d/index.js'
import { isOrderingAllowedForAsset } from '../handler/downloadHandler.js'
export class ComputeStartHandler extends Handler {
validate(command: ComputeStartCommand): ValidateParams {
const commandValidation = validateCommandParameters(command, [
Expand Down Expand Up @@ -102,6 +103,17 @@ export class ComputeStartHandler extends Handler {
}
}
}
const isOrdable = isOrderingAllowedForAsset(ddo)
if (!isOrdable.isOrdable) {
CORE_LOGGER.error(isOrdable.reason)
return {
stream: null,
status: {
httpStatus: 500,
error: isOrdable.reason
}
}
}
const service = AssetUtils.getServiceById(ddo, elem.serviceId)
if (!service) {
const error = `Cannot find service ${elem.serviceId} in DDO ${elem.documentId}`
Expand Down
42 changes: 41 additions & 1 deletion src/components/core/handler/downloadHandler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Handler } from './handler.js'
import { checkNonce, NonceResponse } from '../utils/nonceHandler.js'
import { ENVIRONMENT_VARIABLES, PROTOCOL_COMMANDS } from '../../../utils/constants.js'
import {
ENVIRONMENT_VARIABLES,
MetadataStates,
PROTOCOL_COMMANDS
} from '../../../utils/constants.js'
import { P2PCommandResponse } from '../../../@types/OceanNode.js'
import { verifyProviderFees } from '../utils/feesHandler.js'
import { decrypt } from '../../../utils/crypt.js'
Expand Down Expand Up @@ -29,8 +33,32 @@ import {
} from '../../httpRoutes/validateCommands.js'
import { DDO } from '../../../@types/DDO/DDO.js'
import { sanitizeServiceFiles } from '../../../utils/util.js'
import { OrdableAssetResponse } from '../../../@types/Asset.js'
export const FILE_ENCRYPTION_ALGORITHM = 'aes-256-cbc'

export function isOrderingAllowedForAsset(asset: DDO): OrdableAssetResponse {
if (!asset) {
return {
isOrdable: false,
reason: `Asset provided is either null, either undefined ${asset}`
}
} else if (
asset.nft &&
!(asset.nft.state in [MetadataStates.ACTIVE, MetadataStates.UNLISTED])
) {
return {
isOrdable: false,
reason:
'Nft not present in the asset or the state is different than ACTIVE or UNLISTED.'
}
}

return {
isOrdable: true,
reason: ''
}
}

export async function handleDownloadUrlCommand(
node: OceanNode,
task: DownloadURLCommand
Expand Down Expand Up @@ -214,6 +242,18 @@ export class DownloadHandler extends Handler {
}
}

const isOrdable = isOrderingAllowedForAsset(ddo)
if (!isOrdable.isOrdable) {
CORE_LOGGER.error(isOrdable.reason)
return {
stream: null,
status: {
httpStatus: 500,
error: isOrdable.reason
}
}
}

// 2. Validate ddo and credentials
if (!ddo.chainId || !ddo.nftAddress || !ddo.metadata) {
CORE_LOGGER.logMessage('Error: DDO malformed or disabled', true)
Expand Down
21 changes: 17 additions & 4 deletions src/components/core/handler/feesHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { isAddress } from 'ethers'
import { ProviderInitialize } from '../../../@types/Fees.js'
import { getNonce } from '../utils/nonceHandler.js'
import { streamToString } from '../../../utils/util.js'
import { isOrderingAllowedForAsset } from './downloadHandler.js'

export class FeesHandler extends Handler {
validate(command: GetFeesCommand): ValidateParams {
Expand Down Expand Up @@ -46,6 +47,18 @@ export class FeesHandler extends Handler {
errorMsg = 'Cannot resolve DID'
}

const isOrdable = isOrderingAllowedForAsset(ddo)
if (!isOrdable.isOrdable) {
PROVIDER_LOGGER.error(isOrdable.reason)
return {
stream: null,
status: {
httpStatus: 500,
error: isOrdable.reason
}
}
}

const service = ddo.services.find((what: any) => what.id === task.serviceId)
if (!service) {
errorMsg = 'Invalid serviceId'
Expand All @@ -64,10 +77,6 @@ export class FeesHandler extends Handler {
validUntil = task.validUntil
}

const nonceDB = this.getOceanNode().getDatabase().nonce
const nonceHandlerResponse = await getNonce(nonceDB, task.consumerAddress)
const nonce = await streamToString(nonceHandlerResponse.stream as Readable)

if (errorMsg) {
PROVIDER_LOGGER.logMessageWithEmoji(
errorMsg,
Expand All @@ -84,6 +93,10 @@ export class FeesHandler extends Handler {
}
}

const nonceDB = this.getOceanNode().getDatabase().nonce
const nonceHandlerResponse = await getNonce(nonceDB, task.consumerAddress)
const nonce = await streamToString(nonceHandlerResponse.stream as Readable)

try {
const providerFee = await createProviderFee(ddo, service, validUntil, null, null)
if (providerFee) {
Expand Down
7 changes: 7 additions & 0 deletions src/utils/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { AssetUtils } from './asset.js'
import { decrypt } from './crypt.js'
import { CORE_LOGGER } from './logging/common.js'
import { sanitizeServiceFiles } from './util.js'
import { isOrderingAllowedForAsset } from '../components/core/handler/downloadHandler.js'

export async function getFile(
didOrDdo: string | DDO,
Expand All @@ -25,6 +26,12 @@ export async function getFile(
? await new FindDdoHandler(node).findAndFormatDdo(didOrDdo)
: didOrDdo

const isOrdable = isOrderingAllowedForAsset(ddo)
if (!isOrdable.isOrdable) {
CORE_LOGGER.error(isOrdable.reason)
throw new Error(isOrdable.reason)
}

// 2. Get the service
const service: Service = AssetUtils.getServiceById(ddo, serviceId)
if (!service) {
Expand Down
Loading