Skip to content

Commit 970ca86

Browse files
Mani BrarMani Brar
authored andcommitted
feat(validator): saveSnapshot in watcher
1 parent a87864d commit 970ca86

File tree

2 files changed

+61
-22
lines changed

2 files changed

+61
-22
lines changed

validator-cli/src/utils/botConfig.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ interface BotPathParams {
1818
* @param defaultPath - default path to use if not specified in the command line arguments
1919
* @returns BotPaths - the bot path (BotPaths)
2020
*/
21-
export function getBotPath({ cliCommand, defaultPath = BotPaths.BOTH }: BotPathParams): number {
21+
export function getBotPath({ cliCommand, defaultPath = BotPaths.BOTH }: BotPathParams): {
22+
path: number;
23+
toSaveSnapshot: boolean;
24+
} {
2225
const args = cliCommand.slice(2);
2326
const pathFlag = args.find((arg) => arg.startsWith("--path="));
2427

@@ -33,8 +36,9 @@ export function getBotPath({ cliCommand, defaultPath = BotPaths.BOTH }: BotPathP
3336
if (path && !(path in pathMapping)) {
3437
throw new InvalidBotPathError();
3538
}
36-
37-
return path ? pathMapping[path] : defaultPath;
39+
const saveSnapshotFlag = args.find((a) => a.startsWith("--saveSnapshot"));
40+
const toSaveSnapshot = saveSnapshotFlag ? true : false;
41+
return path ? { path: pathMapping[path], toSaveSnapshot } : { path: defaultPath, toSaveSnapshot };
3842
}
3943

4044
export interface NetworkConfig {

validator-cli/src/watcher.ts

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { JsonRpcProvider } from "@ethersproject/providers";
22
import { getBridgeConfig, Network } from "./consts/bridgeRoutes";
3-
import { getVeaInbox, getVeaOutbox } from "./utils/ethers";
3+
import { getTransactionHandler, getVeaInbox, getVeaOutbox } from "./utils/ethers";
44
import { getBlockFromEpoch, setEpochRange } from "./utils/epochHandler";
55
import { getClaimValidator, getClaimer } from "./utils/ethers";
66
import { defaultEmitter } from "./utils/emitter";
@@ -12,6 +12,7 @@ import { getClaim } from "./utils/claim";
1212
import { MissingEnvError } from "./utils/errors";
1313
import { CheckAndClaimParams } from "./ArbToEth/claimer";
1414
import { ChallengeAndResolveClaimParams } from "./ArbToEth/validator";
15+
import { saveSnapshot, SaveSnapshotParams } from "./utils/snapshot";
1516

1617
const RPC_BLOCK_LIMIT = 500; // RPC_BLOCK_LIMIT is the limit of blocks that can be queried at once
1718

@@ -31,24 +32,25 @@ export const watch = async (
3132
const privKey = process.env.PRIVATE_KEY;
3233
if (!privKey) throw new MissingEnvError("PRIVATE_KEY");
3334
const cliCommand = process.argv;
34-
const path = getBotPath({ cliCommand });
35+
const { path, toSaveSnapshot } = getBotPath({ cliCommand });
3536
const networkConfigs = getNetworkConfig();
3637
emitter.emit(BotEvents.STARTED, path, networkConfigs[0].networks);
3738
const transactionHandlers: { [epoch: number]: any } = {};
38-
const toWatch: { [key: string]: number[] } = {};
39+
const toWatch: { [key: string]: { count: number; epochs: number[] } } = {};
3940
while (!shutDownSignal.getIsShutdownSignal()) {
4041
for (const networkConfig of networkConfigs) {
41-
await processNetwork(path, networkConfig, transactionHandlers, toWatch, emitter);
42+
await processNetwork(path, toSaveSnapshot, networkConfig, transactionHandlers, toWatch, emitter);
4243
}
4344
await wait(1000 * 10);
4445
}
4546
};
4647

4748
async function processNetwork(
4849
path: number,
50+
toSaveSnapshot: boolean,
4951
networkConfig: NetworkConfig,
5052
transactionHandlers: { [epoch: number]: any },
51-
toWatch: { [key: string]: number[] },
53+
toWatch: { [key: string]: { count: number; epochs: number[] } },
5254
emitter: typeof defaultEmitter
5355
): Promise<void> {
5456
const { chainId, networks } = networkConfig;
@@ -57,27 +59,27 @@ async function processNetwork(
5759
emitter.emit(BotEvents.WATCHING, chainId, network);
5860
const networkKey = `${chainId}_${network}`;
5961
if (!toWatch[networkKey]) {
60-
toWatch[networkKey] = [];
62+
toWatch[networkKey] = { count: -1, epochs: [] };
6163
}
62-
6364
const veaOutboxProvider = new JsonRpcProvider(outboxRPC);
6465
let veaOutboxLatestBlock = await veaOutboxProvider.getBlock("latest");
6566

6667
// If the watcher has already started, only check the latest epoch
6768
if (network == Network.DEVNET) {
68-
toWatch[networkKey] = [Math.floor(veaOutboxLatestBlock.timestamp / routeConfig[network].epochPeriod)];
69-
} else if (toWatch[networkKey].length == 0) {
69+
toWatch[networkKey].epochs = [Math.floor(veaOutboxLatestBlock.timestamp / routeConfig[network].epochPeriod)];
70+
} else if (toWatch[networkKey].epochs.length == 0) {
7071
const epochRange = setEpochRange({
7172
chainId,
7273
currentTimestamp: veaOutboxLatestBlock.timestamp,
7374
epochPeriod: routeConfig[network].epochPeriod,
7475
});
75-
toWatch[networkKey] = epochRange;
76+
toWatch[networkKey].epochs = epochRange;
7677
}
7778

7879
await processEpochsForNetwork({
7980
chainId,
8081
path,
82+
toSaveSnapshot,
8183
networkKey,
8284
network,
8385
routeConfig,
@@ -88,30 +90,33 @@ async function processNetwork(
8890
emitter,
8991
});
9092
const currentLatestBlock = await veaOutboxProvider.getBlock("latest");
91-
const currentLatestEpoch = Math.floor(currentLatestBlock.timestamp / routeConfig[network].epochPeriod);
93+
const currentClaimableEpoch = Math.floor(currentLatestBlock.timestamp / routeConfig[network].epochPeriod) - 1;
94+
9295
const toWatchEpochs = toWatch[networkKey];
93-
const lastEpochInToWatch = toWatchEpochs[toWatchEpochs.length - 1];
94-
if (currentLatestEpoch > lastEpochInToWatch) {
95-
toWatch[networkKey].push(currentLatestEpoch);
96+
const lastEpochInToWatch = toWatchEpochs[toWatchEpochs.epochs.length - 1];
97+
if (currentClaimableEpoch > lastEpochInToWatch) {
98+
toWatch[networkKey].epochs.push(currentClaimableEpoch);
9699
}
97100
}
98101
}
99102

100103
interface ProcessEpochParams {
101104
chainId: number;
102105
path: number;
106+
toSaveSnapshot: boolean;
103107
networkKey: string;
104108
network: Network;
105109
routeConfig: any;
106110
inboxRPC: string;
107111
outboxRPC: string;
108-
toWatch: { [key: string]: number[] };
112+
toWatch: { [key: string]: { count: number; epochs: number[] } };
109113
transactionHandlers: { [epoch: number]: any };
110114
emitter: typeof defaultEmitter;
111115
}
112116
async function processEpochsForNetwork({
113117
chainId,
114118
path,
119+
toSaveSnapshot,
115120
networkKey,
116121
network,
117122
routeConfig,
@@ -126,10 +131,39 @@ async function processEpochsForNetwork({
126131
const veaOutbox = getVeaOutbox(routeConfig[network].veaOutbox.address, privKey, outboxRPC, chainId, network);
127132
const veaInboxProvider = new JsonRpcProvider(inboxRPC);
128133
const veaOutboxProvider = new JsonRpcProvider(outboxRPC);
129-
let i = toWatch[networkKey].length - 1;
130-
const latestEpoch = toWatch[networkKey][i];
134+
let i = toWatch[networkKey].epochs.length - 1;
135+
const latestEpoch = toWatch[networkKey].epochs[i];
136+
const currentEpoch = Math.floor(Date.now() / (1000 * routeConfig[network].epochPeriod));
137+
// Checks and saves the snapshot if needed
138+
if (toSaveSnapshot) {
139+
const TransactionHandler = getTransactionHandler(chainId, network) as any;
140+
const transactionHandler =
141+
transactionHandlers[currentEpoch] ||
142+
new TransactionHandler({
143+
network,
144+
epoch: currentEpoch,
145+
veaInbox,
146+
veaOutbox,
147+
veaInboxProvider,
148+
veaOutboxProvider,
149+
emitter,
150+
});
151+
const { updatedTransactionHandler, latestCount } = await saveSnapshot({
152+
veaInbox,
153+
network,
154+
epochPeriod: routeConfig[network].epochPeriod,
155+
count: toWatch[networkKey].count,
156+
transactionHandler,
157+
} as SaveSnapshotParams);
158+
const count = toWatch[networkKey].count;
159+
if (count == -1 || count != latestCount) {
160+
transactionHandlers[currentEpoch] = updatedTransactionHandler;
161+
toWatch[networkKey].count = latestCount;
162+
}
163+
}
164+
131165
while (i >= 0) {
132-
const epoch = toWatch[networkKey][i];
166+
const epoch = toWatch[networkKey].epochs[i];
133167
const epochBlock = await getBlockFromEpoch(epoch, routeConfig[network].epochPeriod, veaOutboxProvider);
134168
const latestBlock = await veaOutboxProvider.getBlock("latest");
135169
let toBlock: number | string = "latest";
@@ -142,6 +176,7 @@ async function processEpochsForNetwork({
142176
const checkAndChallengeResolve = getClaimValidator(chainId, network);
143177
const checkAndClaim = getClaimer(chainId, network);
144178
let updatedTransactions;
179+
145180
if (path > BotPaths.CLAIMER && claim != null) {
146181
const checkAndChallengeResolveDeps: ChallengeAndResolveClaimParams = {
147182
claim,
@@ -177,7 +212,7 @@ async function processEpochsForNetwork({
177212
transactionHandlers[epoch] = updatedTransactions;
178213
} else if (epoch != latestEpoch) {
179214
delete transactionHandlers[epoch];
180-
toWatch[networkKey].splice(i, 1);
215+
toWatch[networkKey].epochs.splice(i, 1);
181216
}
182217
i--;
183218
}

0 commit comments

Comments
 (0)