Skip to content

Commit cb1b040

Browse files
committed
add arg flags for checking remote status.json or local status.json to see if the winners have already been calculated for a draw, or if the draw is finalized and there is no point to calculating winners
1 parent 9340778 commit cb1b040

File tree

3 files changed

+136
-11
lines changed

3 files changed

+136
-11
lines changed

src/commands/utils/compileWinners.ts

Lines changed: 124 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import yn from "yn";
2+
import nodeFetch from "node-fetch";
23
import { readFileSync } from "fs";
34
import { Command, Flags } from "@oclif/core";
45
import {
@@ -13,12 +14,14 @@ import { Address } from "viem";
1314

1415
import { createStatus, updateStatusFailure, updateStatusSuccess } from "../../lib/utils/status.js";
1516
import { getProvider } from "../../lib/utils/getProvider.js";
16-
import { createOutputPath } from "../../lib/utils/createOutputPath.js";
17+
import { createOutputPath, drawPath } from "../../lib/utils/createOutputPath.js";
1718
import { createExitCode } from "../../lib/utils/createExitCode.js";
1819
import { getAllPrizeVaultsAndAccountsWithBalance } from "../../lib/utils/getAllPrizeVaultsAndAccountsWithBalance.js";
1920
import { writeToOutput } from "../../lib/utils/writeOutput.js";
2021
import { Winner } from "../../types.js";
2122

23+
import { Status } from "../../types.js";
24+
2225
const DEFAULT_RETRY_ATTEMPTS = 10;
2326
const DEFAULT_RETRY_INTERVAL = 5;
2427

@@ -66,6 +69,17 @@ export default class CompileWinners extends Command {
6669
description: "Custom address for a Multicall contract",
6770
required: false,
6871
}),
72+
remoteStatusUrl: Flags.string({
73+
char: "r",
74+
description:
75+
"Remote URL where status.json would exist (eg. 'https://raw.githubusercontent.com/GenerationSoftware/pt-v5-winners/refs/heads/main/winners/vaultAccounts')",
76+
required: false,
77+
}),
78+
localFileStatusPath: Flags.string({
79+
char: "l",
80+
description: "Local file path where status.json would exist (eg. './winners/vaultAccounts')",
81+
required: false,
82+
}),
6983
};
7084

7185
static args = [];
@@ -83,7 +97,7 @@ export default class CompileWinners extends Command {
8397
const prizePoolInfo: PrizePoolInfo = await getPrizePoolInfo(readProvider, contracts);
8498
const drawId = prizePoolInfo.drawId;
8599

86-
this.warn("Failed to fetch depositors (" + error + ")");
100+
this.warn("Failed to calculate winners (" + error + ")");
87101
const statusFailure = updateStatusFailure(CompileWinners.statusLoading.createdAt, error);
88102

89103
if (drawId) {
@@ -102,7 +116,16 @@ export default class CompileWinners extends Command {
102116

103117
public async run(): Promise<void> {
104118
const { flags } = await this.parse(CompileWinners);
105-
const { chainId, prizePool, outDir, contractJsonUrl, subgraphUrl, multicallAddress } = flags;
119+
const {
120+
chainId,
121+
prizePool,
122+
outDir,
123+
contractJsonUrl,
124+
subgraphUrl,
125+
multicallAddress,
126+
remoteStatusUrl,
127+
localFileStatusPath,
128+
} = flags;
106129

107130
console.log("");
108131
console.log(`Running "utils:compileWinners"`);
@@ -114,17 +137,24 @@ export default class CompileWinners extends Command {
114137
const drawId = prizePoolInfo.drawId;
115138
const isDrawFinalized = prizePoolInfo.isDrawFinalized;
116139

140+
console.log(`--- ARGS ---`);
117141
console.log(`chainId: ${chainId}`);
118142
console.log(`prizePool: ${prizePool.toLowerCase()}`);
119-
console.log(`drawId: #${drawId ? drawId : ""}`);
120143
console.log(`contractJsonUrl: ${contractJsonUrl}`);
121144
console.log(`subgraphUrl: ${subgraphUrl}`);
122145
console.log(`outDir: ${outDir}`);
146+
console.log(`--- OPTIONAL ARGS ---`);
123147
console.log(`multicallAddress: ${multicallAddress}`);
148+
console.log(`remoteStatusUrl: ${remoteStatusUrl}`);
149+
console.log(`localFileStatusPath: ${localFileStatusPath}`);
124150
console.log(`--- ENV ---`);
125151
console.log(`JSON_RPC_URL: ${process.env.JSON_RPC_URL}`);
126152
console.log(`DEBUG: ${yn(process.env.DEBUG)}`);
127153
console.log(`PRIZE_TIERS_TO_COMPUTE: ${process.env.PRIZE_TIERS_TO_COMPUTE}`);
154+
console.log(`--- STATUS ---`);
155+
console.log(`drawId: #${drawId ? drawId : ""}`);
156+
console.log(`isDrawFinalized: ${isDrawFinalized}`);
157+
console.log(``);
128158

129159
if (!drawId) {
130160
console.log("");
@@ -143,10 +173,32 @@ export default class CompileWinners extends Command {
143173
return;
144174
}
145175

146-
if (status === "success") {
147-
console.log("");
148-
console.warn("Winners have already been calculated for current draw.");
149-
return;
176+
if (remoteStatusUrl) {
177+
const status = await downloadRemoteStatusJson(
178+
remoteStatusUrl,
179+
chainId,
180+
prizePool.toLowerCase(),
181+
drawId.toString()
182+
);
183+
if (status?.status === "SUCCESS") {
184+
console.log("");
185+
console.warn("Winners have already been calculated for current draw.");
186+
return;
187+
}
188+
}
189+
190+
if (localFileStatusPath) {
191+
const status = readLocalFileStatusJson(
192+
localFileStatusPath,
193+
chainId,
194+
prizePool.toLowerCase(),
195+
drawId.toString()
196+
);
197+
if (status?.status === "SUCCESS") {
198+
console.log("");
199+
console.warn("Winners have already been calculated for current draw.");
200+
return;
201+
}
150202
}
151203

152204
/* -------------------------------------------------- */
@@ -303,3 +355,67 @@ export async function tryNTimes<T>({
303355
export function delay(time: number): Promise<void> {
304356
return new Promise<void>((resolve) => setTimeout(resolve, time * 1000));
305357
}
358+
359+
/**
360+
* Downloads the status.json for provided drawId if it exists
361+
*
362+
* @param {remoteStatusUrl} string
363+
*
364+
* @returns {Status} Parsed status.json object
365+
*/
366+
export const downloadRemoteStatusJson = async (
367+
remoteStatusUrl: string,
368+
chainId: string,
369+
prizePoolAddress: string,
370+
drawId: string,
371+
fetch?: any
372+
): Promise<Status> => {
373+
let status;
374+
375+
if (!fetch) {
376+
fetch = nodeFetch;
377+
}
378+
379+
try {
380+
const outputPath = drawPath(chainId, prizePoolAddress, drawId);
381+
const url = `${remoteStatusUrl}/${outputPath}status.json`;
382+
const response = await fetch(url);
383+
if (!response.ok) {
384+
console.warn(response.statusText);
385+
} else {
386+
status = await response.json();
387+
}
388+
} catch (err) {
389+
console.log(err);
390+
}
391+
392+
return status;
393+
};
394+
395+
/**
396+
* Reads the status.json from the local filesystem if it exists for the provided drawId
397+
*
398+
* @param {readLocalFileStatusJson} string
399+
*
400+
* @returns {Status} Parsed status.json object
401+
*/
402+
export const readLocalFileStatusJson = (
403+
localFileStatusPath: string,
404+
chainId: string,
405+
prizePoolAddress: string,
406+
drawId: string
407+
): Status => {
408+
let status;
409+
410+
const path = drawPath(chainId, prizePoolAddress, drawId);
411+
const statusPath = `${localFileStatusPath}/${path}status.json`;
412+
const fileJson = readFileSync(statusPath, "utf8");
413+
414+
if (!fileJson) {
415+
console.warn("no status.json file?");
416+
} else {
417+
status = JSON.parse(fileJson);
418+
}
419+
420+
return status;
421+
};

src/lib/utils/createOutputPath.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1-
export function createOutputPath(outputDir: string, chainId: string, address: string, drawId: string): string {
2-
return `${outputDir}/${chainId}/${address.toLowerCase()}/draw/${drawId}/`
1+
export function createOutputPath(
2+
outputDir: string,
3+
chainId: string,
4+
prizePoolAddress: string,
5+
drawId: string
6+
): string {
7+
return `${outputDir}/${drawPath(chainId, prizePoolAddress, drawId)}`;
8+
}
9+
10+
export function drawPath(chainId: string, prizePoolAddress: string, drawId: string): string {
11+
return `${chainId}/${prizePoolAddress.toLowerCase()}/draw/${drawId}/`;
312
}

src/lib/utils/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { createOutputPath } from "./createOutputPath.js";
1+
export { createOutputPath, drawPath } from "./createOutputPath.js";
22
export { updateStatusFailure, updateStatusSuccess, createStatus } from "./status.js";
33
export { createExitCode } from "./createExitCode.js";
44
export { getAllPrizeVaultsAndAccountsWithBalance } from "./getAllPrizeVaultsAndAccountsWithBalance.js";

0 commit comments

Comments
 (0)