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

[V8] Adapt publish API for v8 SDK #3425

Merged
merged 2 commits into from
Nov 25, 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
22 changes: 0 additions & 22 deletions src/commands/common/validate-asset-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,6 @@ class ValidateAssetCommand extends Command {
cachedData.public.assertion,
);

if (cachedData.private?.assertionId && cachedData.private?.assertion) {
this.logger.info(
`Validating asset's private assertion with id: ${cachedData.private.assertionId} ual: ${ual}`,
);

try {
await this.validationService.validateAssertionId(
cachedData.private.assertion,
cachedData.private.assertionId,
);
} catch (error) {
await this.handleError(
operationId,
blockchain,
error.message,
this.errorType,
true,
);
return Command.empty();
}
}

let paranetId;
if (storeType === LOCAL_STORE_TYPES.TRIPLE_PARANET) {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import ValidateAssetCommand from '../../../common/validate-asset-command.js';
import Command from '../../../command.js';
import {
OPERATION_ID_STATUS,
LOCAL_STORE_TYPES,
ZERO_BYTES32,
} from '../../../../constants/constants.js';

class PublishValidateAssetBlockchainCommand extends ValidateAssetCommand {
constructor(ctx) {
super(ctx);
this.operationService = ctx.publishService;
}

async handleError(operationId, blockchain, errorMessage, errorType) {
await this.operationService.markOperationAsFailed(
operationId,
blockchain,
errorMessage,
errorType,
);
}

/**
* Executes command and produces one or more events
* @param command
*/
async execute(command) {
const {
operationId,
blockchain,
contract,
tokenId,
storeType = LOCAL_STORE_TYPES.TRIPLE,
} = command.data;

await this.operationIdService.updateOperationIdStatus(
operationId,
blockchain,
OPERATION_ID_STATUS.VALIDATE_ASSET_BLOCKCHAIN_START,
);

let blockchainAssertionId;
if (
storeType === LOCAL_STORE_TYPES.TRIPLE ||
storeType === LOCAL_STORE_TYPES.TRIPLE_PARANET
) {
blockchainAssertionId = await this.blockchainModuleManager.getLatestAssertionId(
blockchain,
contract,
tokenId,
);
} else {
blockchainAssertionId = await this.blockchainModuleManager.getUnfinalizedAssertionId(
blockchain,
tokenId,
);
}
if (!blockchainAssertionId || blockchainAssertionId === ZERO_BYTES32) {
return Command.retry();
}

const cachedData = await this.operationIdService.getCachedOperationIdData(operationId);
const ual = this.ualService.deriveUAL(blockchain, contract, tokenId);
this.logger.info(
`Validating asset's public assertion with id: ${cachedData.public.assertionId} ual: ${ual}`,
);

if (blockchainAssertionId !== cachedData.public.assertionId) {
await this.handleError(
operationId,
blockchain,
`Invalid assertion id for asset ${ual}. Received value from blockchain: ${blockchainAssertionId}, received value from request: ${cachedData.public.assertionId}`,
this.errorType,
true,
);
return Command.empty();
}

await this.validationService.validateAssertion(
cachedData.public.assertionId,
blockchain,
cachedData.public.assertion,
);

await this.operationIdService.updateOperationIdStatus(
operationId,
blockchain,
OPERATION_ID_STATUS.VALIDATE_ASSET_BLOCKCHAIN_END,
);
return this.continueSequence(
{ ...command.data, retry: undefined, period: undefined },
command.sequence,
);
}

/**
* Builds default PublishValidateAssetBlockchainCommand
* @param map
* @returns {{add, data: *, delay: *, deadline: *}}
*/
default(map) {
const command = {
name: 'publishValidateAssetBlockchainCommand',
delay: 0,
transactional: false,
};
Object.assign(command, map);
return command;
}
}

export default PublishValidateAssetBlockchainCommand;
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import ValidateAssetCommand from '../../../common/validate-asset-command.js';
import Command from '../../../command.js';
import {
OPERATION_ID_STATUS,
LOCAL_STORE_TYPES,
PARANET_ACCESS_POLICY,
} from '../../../../constants/constants.js';

class PublishValidateAssetCommand extends ValidateAssetCommand {
constructor(ctx) {
Expand All @@ -15,6 +21,115 @@ class PublishValidateAssetCommand extends ValidateAssetCommand {
);
}

/**
* Executes command and produces one or more events
* @param command
*/
async execute(command) {
const {
operationId,
blockchain,
storeType = LOCAL_STORE_TYPES.TRIPLE,
paranetUAL,
} = command.data;

await this.operationIdService.updateOperationIdStatus(
operationId,
blockchain,
OPERATION_ID_STATUS.VALIDATE_ASSET_START,
);

const cachedData = await this.operationIdService.getCachedOperationIdData(operationId);

const isValidAssertion = await this.validationService.validateAssertionId(
cachedData.public.assertion,
cachedData.public.assertionId,
);

if (!isValidAssertion) {
await this.handleError(
operationId,
blockchain,
`Invalid dastaset root for asset ???. Received value , received value from request: ${cachedData.public.datasetRoot}`,
this.errorType,
);
return Command.empty();
}

let paranetId;
if (storeType === LOCAL_STORE_TYPES.TRIPLE_PARANET) {
try {
const {
blockchain: paranetBlockchain,
contract: paranetContract,
tokenId: paranetTokenId,
} = this.ualService.resolveUAL(paranetUAL);

paranetId = this.paranetService.constructParanetId(
paranetBlockchain,
paranetContract,
paranetTokenId,
);
const paranetExists = await this.blockchainModuleManager.paranetExists(
paranetBlockchain,
paranetId,
);
if (!paranetExists) {
await this.handleError(
operationId,
blockchain,
`Paranet: ${paranetId} doesn't exist.`,
this.errorType,
);
return Command.empty();
}

const nodesAccessPolicy = await this.blockchainModuleManager.getNodesAccessPolicy(
blockchain,
paranetId,
);
if (nodesAccessPolicy === PARANET_ACCESS_POLICY.CURATED) {
const identityId = await this.blockchainModuleManager.getIdentityId(blockchain);
const isCuratedNode = await this.blockchainModuleManager.isCuratedNode(
blockchain,
paranetId,
identityId,
);
if (!isCuratedNode) {
await this.handleError(
operationId,
blockchain,
`Node is not part of curated paranet ${paranetId} because node with id ${identityId} is not a curated node.`,
this.errorType,
);
return Command.empty();
}
} else {
await this.handleError(
operationId,
blockchain,
`Paranet ${paranetId} is not curated paranet.`,
this.errorType,
);
return Command.empty();
}
} catch (error) {
await this.handleError(operationId, blockchain, error.message, this.errorType);
return Command.empty();
}
}

await this.operationIdService.updateOperationIdStatus(
operationId,
blockchain,
OPERATION_ID_STATUS.VALIDATE_ASSET_END,
);
return this.continueSequence(
{ ...command.data, paranetId, retry: undefined, period: undefined },
command.sequence,
);
}

/**
* Builds default publishValidateAssetCommand
* @param map
Expand Down
2 changes: 2 additions & 0 deletions src/constants/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ export const OPERATION_ID_STATUS = {
DIAL_PROTOCOL_END: 'DIAL_PROTOCOL_END',
VALIDATE_ASSET_START: 'VALIDATE_ASSET_START',
VALIDATE_ASSET_END: 'VALIDATE_ASSET_END',
VALIDATE_ASSET_BLOCKCHAIN_START: 'VALIDATE_ASSET_BLOCKCHAIN_START',
VALIDATE_ASSET_BLOCKCHAIN_END: 'VALIDATE_ASSET_BLOCKCHAIN_END',
VALIDATE_ASSET_REMOTE_START: 'VALIDATE_ASSET_REMOTE_START',
VALIDATE_ASSET_REMOTE_END: 'VALIDATE_ASSET_REMOTE_END',
PUBLISH: {
Expand Down
12 changes: 3 additions & 9 deletions src/controllers/http-api/v0/publish-http-api-controller-v0.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ class PublishController extends BaseController {
}

async handleRequest(req, res) {
const { assertion, assertionId, blockchain, contract, tokenId } = req.body;
const { assertion, assertionId, blockchain } = req.body;
const hashFunctionId = req.body.hashFunctionId ?? CONTENT_ASSET_HASH_FUNCTION_ID;

this.logger.info(
`Received asset with assertion id: ${assertionId}, blockchain: ${blockchain}, hub contract: ${contract}, token id: ${tokenId}`,
`Received asset with assertion id: ${assertionId}, blockchain: ${blockchain}`,
);

const operationId = await this.operationIdService.generateOperationId(
Expand Down Expand Up @@ -59,16 +59,12 @@ class PublishController extends BaseController {
assertionId,
},
blockchain,
contract,
tokenId,
});

const commandSequence = ['publishValidateAssetCommand'];

// Backwards compatibility check - true for older clients
if (req.body.localStore) {
commandSequence.push('localStoreCommand');
}
commandSequence.push('localStoreCommand');

commandSequence.push('networkPublishCommand');

Expand All @@ -81,8 +77,6 @@ class PublishController extends BaseController {
data: {
assertionId,
blockchain,
contract,
tokenId,
hashFunctionId,
operationId,
storeType: LOCAL_STORE_TYPES.TRIPLE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@ export default (argumentsObject) => ({
blockchain: {
enum: argumentsObject.blockchainImplementationNames,
},
contract: {
type: 'string',
minLength: 42,
maxLength: 42,
},
tokenId: {
type: 'number',
minimum: 0,
},
hashFunctionId: {
type: 'number',
minimum: 1,
Expand Down
2 changes: 2 additions & 0 deletions src/service/validation-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class ValidationService {
`Invalid assertion id. Received value: ${assertionId}, calculated: ${calculatedAssertionId}`,
);
}

return assertionId === calculatedAssertionId;
}
}

Expand Down
Loading