Skip to content

Commit

Permalink
finish cocm adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlosQ96 committed Oct 16, 2024
1 parent d0b4b97 commit 56857c3
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 92 deletions.
3 changes: 0 additions & 3 deletions src/adapters/cocmAdapter/cocmMockAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import axios from 'axios';
import {
CocmAdapterInterface,
ProjectsEstimatedMatchings,
} from './cocmAdapterInterface';
import { i18n, translationErrorMessagesKeys } from '../../utils/errorMessages';
import { logger } from '../../utils/logger';

export class CocmMockAdapter implements CocmAdapterInterface {
async fetchEstimatedClusterMatchings(
Expand Down
21 changes: 4 additions & 17 deletions src/entities/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ import { Category } from './category';
import { FeaturedUpdate } from './featuredUpdate';
import { getHtmlTextSummary } from '../utils/utils';
import { QfRound } from './qfRound';
import {
getQfRoundTotalSqrtRootSumSquared,
getProjectDonationsSqrtRootSum,
findActiveQfRound,
} from '../repositories/qfRoundRepository';
import { findActiveQfRound } from '../repositories/qfRoundRepository';
import { EstimatedMatching } from '../types/qfTypes';
import { Campaign } from './campaign';
import { ProjectEstimatedMatchingView } from './ProjectEstimatedMatchingView';
Expand Down Expand Up @@ -501,23 +497,14 @@ export class Project extends BaseEntity {
async estimatedMatching(): Promise<EstimatedMatching | null> {
const activeQfRound = await findActiveQfRound();
if (!activeQfRound) {
// TODO should move it to materialized view
return null;
}
const projectDonationsSqrtRootSum = await getProjectDonationsSqrtRootSum(
this.id,
activeQfRound.id,
);

const allProjectsSum = await getQfRoundTotalSqrtRootSumSquared(
activeQfRound.id,
);

const matchingPool = activeQfRound.allocatedFund;

// Facilitate migration in frontend return empty values for now
return {
projectDonationsSqrtRootSum,
allProjectsSum,
projectDonationsSqrtRootSum: 0,
allProjectsSum: 0,
matchingPool,
};
}
Expand Down
22 changes: 22 additions & 0 deletions src/repositories/donationRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,28 @@ import { ORGANIZATION_LABELS } from '../entities/organization';
import { AppDataSource } from '../orm';
import { getPowerRound } from './powerRoundRepository';

export const exportClusterMatchingDonationsFormat = async (
qfRoundId: number,
) => {
return await Donation.query(
`
SELECT
d."fromWalletAddress" AS voter,
d."toWalletAddress" AS payoutAddress,
d."valueUsd" AS amountUSD,
p."title" AS project_name,
d."qfRoundUserScore" AS score
FROM
donation d
INNER JOIN
project p ON d."projectId" = p."id"
WHERE
d."qfRoundId" = $1
`,
[qfRoundId],
);
};

export const fillQfRoundDonationsUserScores = async (): Promise<void> => {
await Donation.query(`
UPDATE donation
Expand Down
53 changes: 27 additions & 26 deletions src/resolvers/projectResolver.allProject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { InstantPowerBalance } from '../entities/instantPowerBalance';
import { saveOrUpdateInstantPowerBalances } from '../repositories/instantBoostingRepository';
import { updateInstantBoosting } from '../services/instantBoostingServices';
import { QfRound } from '../entities/qfRound';
import { calculateEstimatedMatchingWithParams } from '../utils/qfUtils';
// import { calculateEstimatedMatchingWithParams } from '../utils/qfUtils';
import { refreshProjectEstimatedMatchingView } from '../services/projectViewsService';
import { addOrUpdatePowerSnapshotBalances } from '../repositories/powerBalanceSnapshotRepository';
import { findPowerSnapshots } from '../repositories/powerSnapshotRepository';
Expand Down Expand Up @@ -2195,31 +2195,32 @@ function allProjectsTestCases() {
});

assert.equal(result.data.data.allProjects.projects.length, 2);
const firstProject = result.data.data.allProjects.projects.find(
p => Number(p.id) === project1.id,
);
const secondProject = result.data.data.allProjects.projects.find(
p => Number(p.id) === project2.id,
);

const project1EstimatedMatching =
await calculateEstimatedMatchingWithParams({
matchingPool: firstProject.estimatedMatching.matchingPool,
projectDonationsSqrtRootSum:
firstProject.estimatedMatching.projectDonationsSqrtRootSum,
allProjectsSum: firstProject.estimatedMatching.allProjectsSum,
});

const project2EstimatedMatching =
await calculateEstimatedMatchingWithParams({
matchingPool: secondProject.estimatedMatching.matchingPool,
projectDonationsSqrtRootSum:
secondProject.estimatedMatching.projectDonationsSqrtRootSum,
allProjectsSum: secondProject.estimatedMatching.allProjectsSum,
});

assert.equal(Math.floor(project1EstimatedMatching), 666);
assert.equal(Math.floor(project2EstimatedMatching), 333);
// const firstProject = result.data.data.allProjects.projects.find(
// p => Number(p.id) === project1.id,
// );
// const secondProject = result.data.data.allProjects.projects.find(
// p => Number(p.id) === project2.id,
// );

// New estimated matching wont calculate it here
// const project1EstimatedMatching =
// await calculateEstimatedMatchingWithParams({
// matchingPool: firstProject.estimatedMatching.matchingPool,
// projectDonationsSqrtRootSum:
// firstProject.estimatedMatching.projectDonationsSqrtRootSum,
// allProjectsSum: firstProject.estimatedMatching.allProjectsSum,
// });

// const project2EstimatedMatching =
// await calculateEstimatedMatchingWithParams({
// matchingPool: secondProject.estimatedMatching.matchingPool,
// projectDonationsSqrtRootSum:
// secondProject.estimatedMatching.projectDonationsSqrtRootSum,
// allProjectsSum: secondProject.estimatedMatching.allProjectsSum,
// });

// assert.equal(Math.floor(project1EstimatedMatching), 666);
// assert.equal(Math.floor(project2EstimatedMatching), 333);
qfRound.isActive = false;
await qfRound.save();
});
Expand Down
2 changes: 0 additions & 2 deletions src/server/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ import { ApolloContext } from '../types/ApolloContext';
import { ProjectResolverWorker } from '../workers/projectsResolverWorker';

import { runInstantBoostingUpdateCronJob } from '../services/cronJobs/instantBoostingUpdateJob';
import { refreshProjectEstimatedMatchingView } from '../services/projectViewsService';
import { isTestEnv } from '../utils/utils';
import { runCheckActiveStatusOfQfRounds } from '../services/cronJobs/checkActiveStatusQfRounds';
import { runUpdateProjectCampaignsCacheJob } from '../services/cronJobs/updateProjectCampaignsCacheJob';
import { corsOptions } from './cors';
Expand Down
57 changes: 30 additions & 27 deletions src/services/cronJobs/syncEstimatedClusterMatchingJob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ import { schedule } from 'node-cron';
import { spawn, Worker, Thread } from 'threads';
import config from '../../config';
import { logger } from '../../utils/logger';
import {
findActiveQfRound,
findUsersWithoutMBDScoreInActiveAround,
} from '../../repositories/qfRoundRepository';
import { findUserById } from '../../repositories/userRepository';
import { UserQfRoundModelScore } from '../../entities/userQfRoundModelScore';
import { findActiveQfRound } from '../../repositories/qfRoundRepository';
import { exportClusterMatchingDonationsFormat } from '../../repositories/donationRepository';

const cronJobTime =
(config.get('SYNC_ESTIMATED_CLUSTED_MATCHING_CRONJOB_EXPRESSION') as string) ||
'0 * * * * *';
(config.get(
'SYNC_ESTIMATED_CLUSTER_MATCHING_CRONJOB_EXPRESSION',
) as string) || '0 * * * * *';

export const runSyncEstimatedClusterMatchingCronjob = () => {
logger.debug(
Expand All @@ -24,27 +21,33 @@ export const runSyncEstimatedClusterMatchingCronjob = () => {
};

export const fetchAndUpdateClusterEstimatedMatching = async () => {
const fetchWorker = await spawn(
const matchingWorker = await spawn(
new Worker('../../workers/cocm/fetchEstimatedClusterMtchingWorker'),
);

const updateWorker = await spawn(
new Worker('../../workers/cocm/updateProjectsEstimatedClusterMatchingWorker')
const activeQfRound = await findActiveQfRound();
if (!activeQfRound?.id) return;

const clusterMatchingDonations = await exportClusterMatchingDonationsFormat(
activeQfRound?.id,
);
const activeQfRoundId =
(await findActiveQfRound())?.id;
if (!activeQfRoundId || activeQfRoundId === 0) return;

for (const projectId of []) {
try {

// const userScore = await worker.syncUserScore({
// userWallet: user?.walletAddress,
// });
} catch (e) {
logger.info(`User with Id ${1} did not sync MBD score this batch`);
}
}
await Thread.terminate(fetchWorker);
await Thread.terminate(updateWorker);
if (clusterMatchingDonations?.length === 0) return;

const matchingDataInput = {
votes_data: clusterMatchingDonations,
strategy: 'COCM',
min_donation_threshold_amount: activeQfRound.minimumValidUsdValue,
matching_cap_amount: activeQfRound.maximumReward,
matching_amount: activeQfRound.allocatedFundUSD,
passport_threshold: activeQfRound.minimumPassportScore,
};

const matchingData =
await matchingWorker.fetchEstimatedClusterMatching(matchingDataInput);
await matchingWorker.updateEstimatedClusterMatching(
activeQfRound.id,
matchingData,
);

await Thread.terminate(matchingWorker);
};
55 changes: 55 additions & 0 deletions src/workers/cocm/estimatedClusterMatchingWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// workers/auth.js
import { expose } from 'threads/worker';
import { WorkerModule } from 'threads/dist/types/worker';
import { getClusterMatchingAdapter } from '../../adapters/adaptersFactory';
import { EstimatedClusterMatching } from '../../entities/estimatedClusterMatching';
import { logger } from '../../utils/logger';

type EstimatedClusterMatchingWorkerFunctions =
| 'fetchEstimatedClusterMatching'
| 'updateEstimatedClusterMatching';

export type EstimatedClusterMatchingWorker =
WorkerModule<EstimatedClusterMatchingWorkerFunctions>;

const worker: EstimatedClusterMatchingWorker = {
async fetchEstimatedClusterMatching(matchingDataInput: any) {
return await getClusterMatchingAdapter().fetchEstimatedClusterMatchings(
matchingDataInput,
);
},

async updateEstimatedClusterMatching(qfRoundId: number, matchingData: any) {
try {
// Prepare values for bulk insert
const values = matchingData
.map(
data => `(
(SELECT id FROM project WHERE title = '${data.project_name}'),
${qfRoundId},
${data.matching_amount}
)`,
)
.join(',');

const query = `
INSERT INTO estimated_cluster_matching ("projectId", "qfRoundId", matching)
VALUES ${values}
ON CONFLICT ("projectId", "qfRoundId")
DO UPDATE SET matching = EXCLUDED.matching
RETURNING "projectId", "qfRoundId", matching;
`;

const result = await EstimatedClusterMatching.query(query);
if (result.length === 0) {
throw new Error('No records were inserted or updated.');
}

logger.debug('Matching data processed successfully with raw SQL.');
} catch (error) {
logger.debug('Error processing matching data:', error.message);
}
},
};

expose(worker);
17 changes: 0 additions & 17 deletions src/workers/cocm/fetchEstimatedClusterMatchingWorker.ts

This file was deleted.

Empty file.

0 comments on commit 56857c3

Please sign in to comment.