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

[P1] GET operation and update finalization bugfix #2674

Closed
wants to merge 3 commits into from
Closed
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
2,180 changes: 1,667 additions & 513 deletions postman/DKGv6.postman_collection.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/commands/local-store/local-store-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ class LocalStoreCommand extends Command {
name: 'deletePendingStateCommand',
sequence: [],
delay: updateCommitWindowDuration * 1000,
data: { ...command.data, repository: PENDING_STORAGE_REPOSITORIES.PRIVATE },
data: {
...command.data,
repository: PENDING_STORAGE_REPOSITORIES.PRIVATE,
assertionId: cachedData.public.assertionId,
},
transactional: false,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,24 @@ class HandleGetInitCommand extends HandleProtocolMessageCommand {
blockchain,
contract,
tokenId,
assertionId,
);
}

for (const repository of [
TRIPLE_STORE_REPOSITORIES.PUBLIC_CURRENT,
TRIPLE_STORE_REPOSITORIES.PUBLIC_HISTORY,
]) {
if (assertionExists) {
break;
if (!assertionExists) {
for (const repository of [
TRIPLE_STORE_REPOSITORIES.PUBLIC_CURRENT,
TRIPLE_STORE_REPOSITORIES.PUBLIC_HISTORY,
]) {
// eslint-disable-next-line no-await-in-loop
assertionExists = await this.tripleStoreService.assertionExists(
repository,
assertionId,
);
if (assertionExists) {
break;
}
}

// eslint-disable-next-line no-await-in-loop
assertionExists = await this.tripleStoreService.assertionExists(
repository,
assertionId,
);
}

await this.operationIdService.updateOperationIdStatus(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class HandleGetRequestCommand extends HandleProtocolMessageCommand {
OPERATION_ID_STATUS.GET.GET_REMOTE_START,
);

let nquads;
if (
state !== GET_STATES.FINALIZED &&
blockchain != null &&
Expand All @@ -37,26 +38,24 @@ class HandleGetRequestCommand extends HandleProtocolMessageCommand {
blockchain,
contract,
tokenId,
assertionId,
operationId,
);
if (cachedAssertion?.public?.assertion?.length) {
return {
messageType: NETWORK_MESSAGE_TYPES.RESPONSES.ACK,
messageData: { nquads: cachedAssertion.public.assertion },
};
nquads = cachedAssertion.public.assertion;
}
}

let nquads;
for (const repository of [
TRIPLE_STORE_REPOSITORIES.PUBLIC_CURRENT,
TRIPLE_STORE_REPOSITORIES.PUBLIC_HISTORY,
]) {
// eslint-disable-next-line no-await-in-loop
nquads = await this.tripleStoreService.getAssertion(repository, assertionId);

if (nquads.length) {
break;
if (!nquads.length) {
for (const repository of [
TRIPLE_STORE_REPOSITORIES.PUBLIC_CURRENT,
TRIPLE_STORE_REPOSITORIES.PUBLIC_HISTORY,
]) {
// eslint-disable-next-line no-await-in-loop
nquads = await this.tripleStoreService.getAssertion(repository, assertionId);
if (nquads.length) {
break;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ class GetAssertionIdCommand extends Command {
}
}

return this.continueSequence(
{ ...command.data, state: assertionId, assertionId },
command.sequence,
);
return this.continueSequence({ ...command.data, state, assertionId }, command.sequence);
}

async handleError(operationId, errorMessage, errorType) {
Expand Down
58 changes: 35 additions & 23 deletions src/commands/protocols/get/sender/local-get-command.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Command from '../../../command.js';
import {
OPERATION_ID_STATUS,
ERROR_TYPE,
GET_STATES,
TRIPLE_STORE_REPOSITORIES,
PENDING_STORAGE_REPOSITORIES,
} from '../../../../constants/constants.js';
Expand All @@ -24,42 +25,50 @@ class LocalGetCommand extends Command {
* @param command
*/
async execute(command) {
const { operationId, blockchain, contract, tokenId, state } = command.data;
const { operationId, blockchain, contract, tokenId, assertionId, state } = command.data;
await this.operationIdService.updateOperationIdStatus(
operationId,
OPERATION_ID_STATUS.GET.GET_LOCAL_START,
);

const response = {};
for (const repository of [
PENDING_STORAGE_REPOSITORIES.PRIVATE,
PENDING_STORAGE_REPOSITORIES.PUBLIC,
]) {
// eslint-disable-next-line no-await-in-loop
const stateIsPending = await this.pendingStorageService.assetHasPendingState(
repository,
blockchain,
contract,
tokenId,
state,
);

if (stateIsPending) {
if (
state !== GET_STATES.FINALIZED &&
blockchain != null &&
contract != null &&
tokenId != null
) {
for (const repository of [
PENDING_STORAGE_REPOSITORIES.PRIVATE,
PENDING_STORAGE_REPOSITORIES.PUBLIC,
]) {
// eslint-disable-next-line no-await-in-loop
const cachedAssertion = await this.pendingStorageService.getCachedAssertion(
const stateIsPending = await this.pendingStorageService.assetHasPendingState(
repository,
blockchain,
contract,
tokenId,
operationId,
assertionId,
);

if (cachedAssertion?.public?.assertion?.length) {
response.assertion = cachedAssertion.public.assertion;
if (cachedAssertion?.private?.assertion?.length) {
response.privateAssertion = cachedAssertion.private.assertion;
if (stateIsPending) {
// eslint-disable-next-line no-await-in-loop
const cachedAssertion = await this.pendingStorageService.getCachedAssertion(
repository,
blockchain,
contract,
tokenId,
assertionId,
operationId,
);

if (cachedAssertion?.public?.assertion?.length) {
response.assertion = cachedAssertion.public.assertion;
if (cachedAssertion?.private?.assertion?.length) {
response.privateAssertion = cachedAssertion.private.assertion;
}
break;
}
break;
}
}
}
Expand All @@ -72,7 +81,10 @@ class LocalGetCommand extends Command {
TRIPLE_STORE_REPOSITORIES.PUBLIC_HISTORY,
]) {
// eslint-disable-next-line no-await-in-loop
response.assertion = await this.tripleStoreService.getAssertion(repository, state);
response.assertion = await this.tripleStoreService.getAssertion(
repository,
assertionId,
);
if (response?.assertion?.length) break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ class DeletePendingStateCommand extends Command {
}

async execute(command) {
const { blockchain, contract, tokenId, operationId, repository } = command.data;
const { repository, blockchain, contract, tokenId, assertionId, operationId } =
command.data;

await this.pendingStorageService.removeCachedAssertion(
repository,
blockchain,
contract,
tokenId,
assertionId,
operationId,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ class HandleUpdateRequestCommand extends HandleProtocolMessageCommand {
name: 'deletePendingStateCommand',
sequence: [],
delay: updateCommitWindowDuration * 1000,
data: { ...commandData, repository: PENDING_STORAGE_REPOSITORIES.PUBLIC },
data: {
...commandData,
repository: PENDING_STORAGE_REPOSITORIES.PUBLIC,
assertionId: cachedData.assertionId,
},
transactional: false,
}),
);
Expand Down
2 changes: 2 additions & 0 deletions src/service/blockchain-event-listener-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ class BlockchainEventListenerService {
blockchain,
contract,
tokenId,
assertionId,
);

const storePromises = [];
Expand Down Expand Up @@ -564,6 +565,7 @@ class BlockchainEventListenerService {
blockchain,
contract,
tokenId,
assertionId,
);
}
}
Expand Down
15 changes: 6 additions & 9 deletions src/service/file-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class FileService {
}

async removeFolder(folderPath) {
// this.logger.trace(`Removing folder at path: ${folderPath}`);
this.logger.trace(`Removing folder at path: ${folderPath}`);

try {
await rm(folderPath, { recursive: true });
Expand Down Expand Up @@ -146,19 +146,16 @@ class FileService {
tokenId,
);

let pendingStorageFileName;
if (assertionId === undefined) {
[pendingStorageFileName] = await this.readDirectory(pendingStorageFolder);
} else {
pendingStorageFileName = assertionId;
}

return path.join(pendingStorageFolder, pendingStorageFileName);
return path.join(pendingStorageFolder, assertionId);
}

getArchiveFolderPath(subFolder) {
return path.join(this.getDataFolderPath(), ARCHIVE_FOLDER_NAME, subFolder);
}

getParentDirectory(filePath) {
return path.dirname(filePath);
}
}

export default FileService;
31 changes: 25 additions & 6 deletions src/service/pending-storage-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,61 @@ class PendingStorageService {
);
}

async getCachedAssertion(repository, blockchain, contract, tokenId, operationId) {
async getCachedAssertion(repository, blockchain, contract, tokenId, assertionId, operationId) {
const ual = this.ualService.deriveUAL(blockchain, contract, tokenId);

this.logger.debug(
`Reading cached assertion for ual: ${ual}, operation id: ${operationId} from file in ${repository} pending storage`,
`Reading cached assertion for ual: ${ual}, assertion id: ${assertionId}, operation id: ${operationId} from file in ${repository} pending storage`,
);
try {
const documentPath = await this.fileService.getPendingStorageDocumentPath(
repository,
blockchain,
contract,
tokenId,
assertionId,
);

const data = await this.fileService.readFile(documentPath, true);
return data;
} catch (error) {
this.logger.debug('Assertion not found in pending storage');
this.logger.debug(
`Assertion not found in pending storage. Error message: ${error.message}, ${error.stackTrace}`,
);
return null;
}
}

async removeCachedAssertion(repository, blockchain, contract, tokenId, operationId) {
async removeCachedAssertion(
repository,
blockchain,
contract,
tokenId,
assertionId,
operationId,
) {
const ual = this.ualService.deriveUAL(blockchain, contract, tokenId);

this.logger.debug(
`Removing cached assertion for ual: ${ual} operation id: ${operationId} from file in ${repository} pending storage`,
);

const pendingStorageFolderPath = this.fileService.getPendingStorageFolderPath(
const pendingAssertionPath = this.fileService.getPendingStorageDocumentPath(
repository,
blockchain,
contract,
tokenId,
assertionId,
);
await this.fileService.removeFolder(pendingStorageFolderPath);
await this.fileService.removeFile(pendingAssertionPath);

const pendingStorageFolderPath = this.fileService.getParentDirectory(pendingAssertionPath);
const otherPendingAssertions = await this.fileService.readDirectory(
pendingStorageFolderPath,
);
if (otherPendingAssertions.length === 0) {
await this.fileService.removeFolder(pendingStorageFolderPath);
}
}

async assetHasPendingState(repository, blockchain, contract, tokenId, assertionId) {
Expand Down
Loading