Skip to content

Commit

Permalink
feat: create organization working
Browse files Browse the repository at this point in the history
fix: bugs
  • Loading branch information
wwills2 committed Dec 16, 2024
1 parent 477bafa commit 273aac7
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 63 deletions.
11 changes: 6 additions & 5 deletions src/controllers/organization.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,15 @@ export const resyncOrganization = async (req, res) => {
try {
await assertIfReadOnlyMode();
await assertWalletIsSynced();
await assertHomeOrgExists();

const orgUid = req.body.orgUid;
transaction = await sequelize.transaction();

await Organization.update(
{ registryHash: '0' },
{ where: { orgUid: req?.body?.orgUid } },
);
const organization = await Organization.findOne({ where: { orgUid } });

await Organization.reconcileOrganization(organization);

await Organization.update({ registryHash: '0' }, { where: { orgUid } });

await Promise.all([
...Object.keys(ModelKeys).map(
Expand Down
15 changes: 8 additions & 7 deletions src/datalayer/persistance.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ const getStoreData = async (storeId, rootHash) => {
return false;
};

const getRoot = async (storeId, ignoreEmptyStore = false) => {
const getRoot = async (storeId) => {
const url = `${CONFIG.DATALAYER_URL}/get_root`;
const { cert, key, timeout } = getBaseOptions();

Expand All @@ -394,21 +394,22 @@ const getRoot = async (storeId, ignoreEmptyStore = false) => {
.timeout(timeout)
.send({ id: storeId });

const { confirmed, hash } = response.body;
logger.debug(
`the current root data for store ${storeId} is ${JSON.stringify(response.body)}`,
);

if (confirmed && (ignoreEmptyStore || !hash.includes('0x00000000000'))) {
return response.body;
const { success, error, traceback } = response.body;

if (!success || error || traceback) {
throw new Error(`${error}, ${traceback}`);
}

return false;
return response.body;
} catch (error) {
logger.error(
`failed to get root for store ${storeId}. error: ${error.message}`,
`could not get root data for store ${storeId}. this could be due to the store being in the process of confirming. error: ${error.message}`,
);
return false;
return {};
}
};

Expand Down
8 changes: 5 additions & 3 deletions src/datalayer/syncService.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ const getSubscribedStoreData = async (storeId) => {
logger.debug(
`syncService getSubscribedData() checking that data is available for ${storeId}.`,
);
const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId, true);
if (!storeExistAndIsConfirmed) {
const { confirmed } = await dataLayer.getRoot(storeId);
if (!confirmed) {
throw new Error(`Store not found in DataLayer: ${storeId}.`);
} else {
logger.debug(
Expand Down Expand Up @@ -192,7 +192,9 @@ const getStoreIfUpdated = async (storeId, lastRootHash, callback, onFail) => {
);
}
} catch (error) {
logger.error(error.message);
logger.error(
`getStoreIfUpdated() failed to get updated store data. Error: ${error.message}`,
);
onFail(error.message);
}
};
Expand Down
18 changes: 9 additions & 9 deletions src/datalayer/writeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const createDataLayerStore = async () => {
logger.info(
`Created storeId: ${storeId}, waiting for this to be confirmed on the blockchain.`,
);
await waitForStoreToBeConfirmed(storeId);
await waitForNewStoreToBeConfirmed(storeId);
await wallet.waitForAllTransactionsToConfirm();

// Default AUTO_MIRROR_EXTERNAL_STORES to true if it is null or undefined
Expand All @@ -42,23 +42,23 @@ const addMirror = async (storeId, url, force = false) => {
return dataLayer.addMirror(storeId, url, force);
};

const waitForStoreToBeConfirmed = async (storeId, retry = 0) => {
const waitForNewStoreToBeConfirmed = async (storeId, retry = 0) => {
if (retry > 120) {
throw new Error(
`Creating storeId: ${storeId} timed out. Its possible the transaction is stuck.`,
);
}

const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId);
const { confirmed } = await dataLayer.getRoot(storeId, true);

if (!storeExistAndIsConfirmed) {
if (!confirmed) {
logger.info(`Still waiting for ${storeId} to confirm`);
await new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 30000);
});
return waitForStoreToBeConfirmed(storeId, retry + 1);
return waitForNewStoreToBeConfirmed(storeId, retry + 1);
}
logger.info(`StoreId: ${storeId} has been confirmed. Congrats!`);
};
Expand Down Expand Up @@ -109,7 +109,7 @@ const retry = (storeId, changeList, failedCallback, retryAttempts) => {
logger.info(`Retrying pushing to store ${storeId}: ${retryAttempts}`);
if (retryAttempts >= 60) {
logger.info(
'Could not push changelist to datalayer after retrying 10 times',
'Could not push changelist to datalayer after retrying 60 times',
);
failedCallback();
return;
Expand Down Expand Up @@ -137,9 +137,9 @@ export const pushChangesWhenStoreIsAvailable = async (
const hasUnconfirmedTransactions =
await wallet.hasUnconfirmedTransactions();

const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId);
const { confirmed } = await dataLayer.getRoot(storeId);

if (!hasUnconfirmedTransactions && storeExistAndIsConfirmed) {
if (!hasUnconfirmedTransactions && confirmed) {
logger.info(`pushing to datalayer ${storeId}`);

const success = await dataLayer.pushChangeListToDataLayer(
Expand All @@ -148,7 +148,7 @@ export const pushChangesWhenStoreIsAvailable = async (
);

if (!success) {
logger.info(
logger.error(
`RPC failed when pushing to store ${storeId}, attempting retry.`,
);
retry(storeId, changeList, failedCallback, retryAttempts);
Expand Down
68 changes: 48 additions & 20 deletions src/models/organizations/organizations.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class Organization extends Model {
'registryId',
'registryHash',
'sync_remaining',
'dataModelVersionStoreId',
'dataModelVersionStoreHash',
],
});

Expand Down Expand Up @@ -118,18 +120,18 @@ class Organization extends Model {
icon: '',
});

logger.debug('createHomeOrg() is creating organization (orgUid) store');
logger.verbose('createHomeOrg() is creating organization (orgUid) store');
const newOrganizationId = USE_SIMULATOR
? 'f1c54511-865e-4611-976c-7c3c1f704662'
: await datalayer.createDataLayerStore();

logger.debug('createHomeOrg() is creating registryId store');
logger.verbose('createHomeOrg() is creating registryId store');
const registryStoreId = await datalayer.createDataLayerStore();

logger.debug('createHomeOrg() is creating dataModelVersionId store');
logger.verbose('createHomeOrg() is creating dataModelVersionId store');
const dataModelVersionStoreId = await datalayer.createDataLayerStore();

logger.debug('createHomeOrg() is creating file store');
logger.verbose('createHomeOrg() is creating file store');
const fileStoreId = await datalayer.createDataLayerStore();

const revertOrganizationIfFailed = async () => {
Expand All @@ -150,7 +152,7 @@ class Organization extends Model {
await datalayer.waitForAllTransactionsToConfirm();
}

logger.debug(
logger.verbose(
`the blockchain reported new organization stores orgUid: ${newOrganizationId}, ` +
`dataModelVersionStore: ${dataModelVersionStoreId}, registryId: ${registryStoreId} have confirmed. `,
);
Expand All @@ -161,7 +163,7 @@ class Organization extends Model {
await datalayer.syncDataLayer(
newOrganizationId,
{
registryId: registryStoreId,
registryId: dataModelVersionStoreId, // registryId is the key named here, but this the DATA MODEL VERSION store id
fileStoreId,
name,
icon,
Expand All @@ -181,9 +183,9 @@ class Organization extends Model {
`commiting registry data model version data to data model version store ${dataModelVersionStoreId}`,
);
await datalayer.syncDataLayer(
registryStoreId,
dataModelVersionStoreId,
{
[dataVersion]: dataModelVersionStoreId,
[dataVersion]: registryStoreId,
},
revertOrganizationIfFailed,
);
Expand Down Expand Up @@ -220,8 +222,8 @@ class Organization extends Model {

if (!USE_SIMULATOR) {
logger.info('Waiting for New Organization to be confirmed');
datalayer.getStoreData(
registryStoreId,
await datalayer.getStoreData(
newOrganizationId,
onConfirm,
revertOrganizationIfFailed,
);
Expand Down Expand Up @@ -329,7 +331,7 @@ class Organization extends Model {
}
}

const updatedOrganizationData = { subscribed: true };
const updatedOrganizationData = {};

if (dataModelVersionStoreId !== datalayerDataModelVersionStoreId) {
const message =
Expand Down Expand Up @@ -358,21 +360,44 @@ class Organization extends Model {
const dataModelVersionStoreSyncStatus = await getSyncStatus(
datalayerDataModelVersionStoreId,
);

if (isDlSynced(dataModelVersionStoreSyncStatus)) {
const { hash } = await getRoot(datalayerDataModelVersionStoreId);
if (hash !== organization.dataModelVersionStoreHash) {
const { confirmed, hash } = await getRoot(
datalayerDataModelVersionStoreId,
);
if (confirmed && hash !== organization.dataModelVersionStoreHash) {
logger.info(
`updating data model version store ${datalayerDataModelVersionStoreId} root hash to ${hash} from ${organization.dataModelVersionStoreHash}`,
`data model version store ${datalayerDataModelVersionStoreId} root hash needs to be updated ${hash} ` +
`from ${organization.dataModelVersionStoreHash} to ${hash}`,
);
updatedOrganizationData.dataModelVersionStoreHash = hash;
} else if (!confirmed) {
logger.warn(
`data model version store ${datalayerDataModelVersionStoreId} has not been confirmed yet. cannot validate or update hash.`,
);
}
}

try {
await Organization.update(updatedOrganizationData, { where: { orgUid } });
} catch {
throw new Error(
'failed to write updated organization data to organization table',
if (!organization.subscribed) {
updatedOrganizationData.subscribed = true;
}

if (!_.isEmpty(updatedOrganizationData)) {
logger.info(
`reconcile organization task is updating organization ${organization.orgUid} with the following data ${JSON.stringify(updatedOrganizationData)}`,
);
try {
await Organization.update(updatedOrganizationData, {
where: { orgUid },
});
} catch {
throw new Error(
'failed to write updated organization data to organization table',
);
}
} else {
logger.info(
`reconcile organization task found organization ${organization.orgUid} required no updates or corrections`,
);
}
}
Expand Down Expand Up @@ -650,7 +675,10 @@ class Organization extends Model {

await Organization.update(
{
..._.omit(updateData, ['registryId']),
..._.omit(updateData, [
'registryId',
'dataModelVersionStoreId',
]),
prefix: updateData.prefix || '0',
metadata: JSON.stringify(metadata),
},
Expand Down
2 changes: 1 addition & 1 deletion src/tasks/clean-up-failed-org.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const job = new SimpleIntervalJob(
runImmediately: true,
},
task,
{ id: 'clean-up failed-org', preventOverrun: true },
{ id: 'clean-up-failed-org', preventOverrun: true },
);

export default job;
19 changes: 1 addition & 18 deletions src/tasks/mirror-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ import { logger } from '../config/logger.js';
import { getConfig } from '../utils/config-loader';
import { getMirrorUrl } from '../utils/datalayer-utils';
import dotenv from 'dotenv';
import datalayer from '../datalayer';

const APP_CONFIG = getConfig().APP;
const GOVERNANCE_CONFIG = getConfig().GOVERNANCE;
dotenv.config();

// This task checks if there are any mirrors that have not been properly mirrored and then mirrors them if not
Expand Down Expand Up @@ -82,29 +80,14 @@ const runMirrorCheck = async () => {
mirrorUrl,
true,
);
} else if (GOVERNANCE_CONFIG?.GOVERNANCE_BODY_ID) {
const governanceStoreValue = await datalayer.getSubscribedStoreData(
GOVERNANCE_CONFIG.GOVERNANCE_BODY_ID,
);

if (governanceStoreValue?.v1) {
// add governance mirrors if non-governance instance
await Organization.addMirror(
GOVERNANCE_CONFIG.GOVERNANCE_BODY_ID,
mirrorUrl,
true,
);
await Organization.addMirror(governanceStoreValue.v1, mirrorUrl, true);
} else {
logger.warn('error adding governance mirrors');
}
}

const organizations = await Organization.getOrgsMap();
const orgs = Object.keys(organizations);
for (const org of orgs) {
const orgData = organizations[org];
await Organization.addMirror(orgData.orgUid, mirrorUrl, true);
await Organization.addMirror(orgData.dataModelVersionStoreId, true);
await Organization.addMirror(orgData.registryId, mirrorUrl, true);
}
};
Expand Down

0 comments on commit 273aac7

Please sign in to comment.