@gzeoneth/gov-tracker 0.2.1-beta.e9f73a3 → 0.2.1-beta.f5af747
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -88
- package/dist/abis.d.ts +3 -0
- package/dist/abis.d.ts.map +1 -1
- package/dist/abis.js +30 -2
- package/dist/abis.js.map +1 -1
- package/dist/cli/cli.js +266 -27
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/lib/cli.d.ts +48 -2
- package/dist/cli/lib/cli.d.ts.map +1 -1
- package/dist/cli/lib/cli.js +356 -63
- package/dist/cli/lib/cli.js.map +1 -1
- package/dist/cli/lib/json-state.d.ts +23 -0
- package/dist/cli/lib/json-state.d.ts.map +1 -1
- package/dist/cli/lib/json-state.js +51 -4
- package/dist/cli/lib/json-state.js.map +1 -1
- package/dist/constants.d.ts +9 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +16 -1
- package/dist/constants.js.map +1 -1
- package/dist/data/bundled-cache.json +3720 -1240
- package/dist/deduplication.d.ts +132 -0
- package/dist/deduplication.d.ts.map +1 -0
- package/dist/deduplication.js +270 -0
- package/dist/deduplication.js.map +1 -0
- package/dist/discovery/governor-discovery.d.ts.map +1 -1
- package/dist/discovery/governor-discovery.js +50 -35
- package/dist/discovery/governor-discovery.js.map +1 -1
- package/dist/discovery/timelock-discovery.d.ts +15 -6
- package/dist/discovery/timelock-discovery.d.ts.map +1 -1
- package/dist/discovery/timelock-discovery.js +27 -11
- package/dist/discovery/timelock-discovery.js.map +1 -1
- package/dist/election/contracts.d.ts +8 -0
- package/dist/election/contracts.d.ts.map +1 -0
- package/dist/election/contracts.js +28 -0
- package/dist/election/contracts.js.map +1 -0
- package/dist/election/details.d.ts +5 -0
- package/dist/election/details.d.ts.map +1 -0
- package/dist/election/details.js +95 -0
- package/dist/election/details.js.map +1 -0
- package/dist/election/index.d.ts +11 -0
- package/dist/election/index.d.ts.map +1 -0
- package/dist/election/index.js +45 -0
- package/dist/election/index.js.map +1 -0
- package/dist/election/params.d.ts +13 -0
- package/dist/election/params.d.ts.map +1 -0
- package/dist/election/params.js +93 -0
- package/dist/election/params.js.map +1 -0
- package/dist/election/participants.d.ts +6 -0
- package/dist/election/participants.d.ts.map +1 -0
- package/dist/election/participants.js +102 -0
- package/dist/election/participants.js.map +1 -0
- package/dist/election/prepare.d.ts +10 -0
- package/dist/election/prepare.d.ts.map +1 -0
- package/dist/election/prepare.js +52 -0
- package/dist/election/prepare.js.map +1 -0
- package/dist/election/proposal-ids.d.ts +18 -0
- package/dist/election/proposal-ids.d.ts.map +1 -0
- package/dist/election/proposal-ids.js +77 -0
- package/dist/election/proposal-ids.js.map +1 -0
- package/dist/election/status.d.ts +6 -0
- package/dist/election/status.d.ts.map +1 -0
- package/dist/election/status.js +86 -0
- package/dist/election/status.js.map +1 -0
- package/dist/election/tracking.d.ts +28 -0
- package/dist/election/tracking.d.ts.map +1 -0
- package/dist/election/tracking.js +412 -0
- package/dist/election/tracking.js.map +1 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -7
- package/dist/index.js.map +1 -1
- package/dist/stages/builder.d.ts +4 -0
- package/dist/stages/builder.d.ts.map +1 -1
- package/dist/stages/builder.js +7 -0
- package/dist/stages/builder.js.map +1 -1
- package/dist/stages/l2-to-l1-message.d.ts +3 -1
- package/dist/stages/l2-to-l1-message.d.ts.map +1 -1
- package/dist/stages/l2-to-l1-message.js +6 -6
- package/dist/stages/l2-to-l1-message.js.map +1 -1
- package/dist/stages/proposal-created.d.ts +1 -0
- package/dist/stages/proposal-created.d.ts.map +1 -1
- package/dist/stages/proposal-created.js +1 -0
- package/dist/stages/proposal-created.js.map +1 -1
- package/dist/stages/proposal-queued.d.ts +1 -0
- package/dist/stages/proposal-queued.d.ts.map +1 -1
- package/dist/stages/proposal-queued.js +3 -1
- package/dist/stages/proposal-queued.js.map +1 -1
- package/dist/stages/retryables.js +2 -2
- package/dist/stages/retryables.js.map +1 -1
- package/dist/stages/timelock.d.ts +3 -1
- package/dist/stages/timelock.d.ts.map +1 -1
- package/dist/stages/timelock.js +11 -7
- package/dist/stages/timelock.js.map +1 -1
- package/dist/stages/utils.d.ts +4 -7
- package/dist/stages/utils.d.ts.map +1 -1
- package/dist/stages/utils.js +31 -22
- package/dist/stages/utils.js.map +1 -1
- package/dist/stages/voting.d.ts.map +1 -1
- package/dist/stages/voting.js +5 -4
- package/dist/stages/voting.js.map +1 -1
- package/dist/tracker/cache.d.ts +10 -6
- package/dist/tracker/cache.d.ts.map +1 -1
- package/dist/tracker/cache.js +36 -13
- package/dist/tracker/cache.js.map +1 -1
- package/dist/tracker/checkpoint-helpers.d.ts +63 -0
- package/dist/tracker/checkpoint-helpers.d.ts.map +1 -0
- package/dist/tracker/checkpoint-helpers.js +176 -0
- package/dist/tracker/checkpoint-helpers.js.map +1 -0
- package/dist/tracker/discovery.d.ts +40 -9
- package/dist/tracker/discovery.d.ts.map +1 -1
- package/dist/tracker/discovery.js +152 -15
- package/dist/tracker/discovery.js.map +1 -1
- package/dist/tracker/execute.d.ts.map +1 -1
- package/dist/tracker/execute.js +1 -25
- package/dist/tracker/execute.js.map +1 -1
- package/dist/tracker/pipeline.d.ts.map +1 -1
- package/dist/tracker/pipeline.js +26 -11
- package/dist/tracker/pipeline.js.map +1 -1
- package/dist/tracker/query.d.ts +1 -0
- package/dist/tracker/query.d.ts.map +1 -1
- package/dist/tracker/query.js +14 -61
- package/dist/tracker/query.js.map +1 -1
- package/dist/tracker/state.d.ts +0 -10
- package/dist/tracker/state.d.ts.map +1 -1
- package/dist/tracker/state.js +1 -28
- package/dist/tracker/state.js.map +1 -1
- package/dist/tracker.d.ts +69 -4
- package/dist/tracker.d.ts.map +1 -1
- package/dist/tracker.js +274 -13
- package/dist/tracker.js.map +1 -1
- package/dist/types/config.d.ts +49 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts +4 -2
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/election.d.ts +91 -0
- package/dist/types/election.d.ts.map +1 -1
- package/dist/types/index.d.ts +5 -7
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/stages.d.ts +70 -1
- package/dist/types/stages.d.ts.map +1 -1
- package/dist/types/stages.js.map +1 -1
- package/dist/types/tracking.d.ts +30 -4
- package/dist/types/tracking.d.ts.map +1 -1
- package/dist/utils/block-cache.d.ts +50 -0
- package/dist/utils/block-cache.d.ts.map +1 -0
- package/dist/utils/block-cache.js +80 -0
- package/dist/utils/block-cache.js.map +1 -0
- package/dist/utils/formatters.d.ts +91 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/formatters.js +327 -0
- package/dist/utils/formatters.js.map +1 -0
- package/dist/utils/multicall.d.ts +52 -0
- package/dist/utils/multicall.d.ts.map +1 -0
- package/dist/utils/multicall.js +75 -0
- package/dist/utils/multicall.js.map +1 -0
- package/dist/utils/salt-computation.d.ts.map +1 -1
- package/dist/utils/salt-computation.js +33 -7
- package/dist/utils/salt-computation.js.map +1 -1
- package/dist/utils/stage-metadata.d.ts +0 -20
- package/dist/utils/stage-metadata.d.ts.map +1 -1
- package/dist/utils/stage-metadata.js +29 -44
- package/dist/utils/stage-metadata.js.map +1 -1
- package/dist/utils/timing.d.ts +13 -0
- package/dist/utils/timing.d.ts.map +1 -1
- package/dist/utils/timing.js +37 -1
- package/dist/utils/timing.js.map +1 -1
- package/package.json +3 -2
- package/dist/election.d.ts +0 -172
- package/dist/election.d.ts.map +0 -1
- package/dist/election.js +0 -467
- package/dist/election.js.map +0 -1
- package/dist/types/cross-chain.d.ts +0 -24
- package/dist/types/cross-chain.d.ts.map +0 -1
- package/dist/types/cross-chain.js +0 -6
- package/dist/types/cross-chain.js.map +0 -1
package/dist/cli/lib/cli.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { Command, Option } from "commander";
|
|
14
14
|
import { ethers } from "ethers";
|
|
15
|
-
import { ProposalStageTracker, TrackingResult, TrackingCheckpoint, PreparedTransaction, PrepareResult, isElectionGovernor, DiscoveredProposal, DiscoveredTimelockOp, DiscoveryWatermarks } from "../../index";
|
|
15
|
+
import { ProposalStageTracker, TrackingResult, TrackingCheckpoint, PreparedTransaction, PrepareResult, TrackerStats, isElectionGovernor, DiscoveredProposal, DiscoveredTimelockOp, DiscoveryWatermarks, DiscoveryTargets, ElectionProposalStatus } from "../../index";
|
|
16
16
|
export { isElectionGovernor };
|
|
17
17
|
/** Default block lag to prevent reorg issues */
|
|
18
18
|
export declare const DEFAULT_BLOCK_LAG = 12;
|
|
@@ -67,6 +67,23 @@ export declare const gasOptions: Option[];
|
|
|
67
67
|
*/
|
|
68
68
|
export declare const loopOptions: Option[];
|
|
69
69
|
export declare function addOptions(cmd: Command, opts: Option[]): void;
|
|
70
|
+
interface CommonCliOptions {
|
|
71
|
+
cache?: string;
|
|
72
|
+
noCache?: boolean;
|
|
73
|
+
force?: boolean;
|
|
74
|
+
startBlock?: string;
|
|
75
|
+
prepare?: boolean;
|
|
76
|
+
write?: boolean;
|
|
77
|
+
prepareCompleted?: boolean;
|
|
78
|
+
preparePending?: boolean;
|
|
79
|
+
inspect?: boolean;
|
|
80
|
+
inspectOnly?: boolean;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validate CLI options for contradictions and conflicts.
|
|
84
|
+
* Throws an error if conflicting options are detected.
|
|
85
|
+
*/
|
|
86
|
+
export declare function validateCliOptions(opts: CommonCliOptions, command: "run" | "track"): void;
|
|
70
87
|
/**
|
|
71
88
|
* Parse gas settings from CLI options
|
|
72
89
|
*/
|
|
@@ -112,7 +129,19 @@ export declare function formatDryRun(prepared: PreparedTransaction): string;
|
|
|
112
129
|
*/
|
|
113
130
|
export declare function formatMultiplePreparedTransactions(preparedTransactions: PreparedTransaction[]): string;
|
|
114
131
|
export declare function formatTrackingResult(result: TrackingResult, label?: string): string;
|
|
115
|
-
export declare function formatCacheStatus(checkpoints: Map<string, TrackingCheckpoint>): string;
|
|
132
|
+
export declare function formatCacheStatus(checkpoints: Map<string, TrackingCheckpoint>, elections: Map<number, TrackingCheckpoint>): string;
|
|
133
|
+
/**
|
|
134
|
+
* Format an election status for CLI output
|
|
135
|
+
*/
|
|
136
|
+
export declare function formatElectionResult(election: ElectionProposalStatus): string;
|
|
137
|
+
/**
|
|
138
|
+
* Display a tracking result, automatically switching to election display for election proposals.
|
|
139
|
+
* Handles the election auto-switch logic internally, falling back to formatTrackingResult for non-elections.
|
|
140
|
+
*
|
|
141
|
+
* @param result - Tracking result to display
|
|
142
|
+
* @param label - Optional label prefix
|
|
143
|
+
*/
|
|
144
|
+
export declare function displayTrackingResult(result: TrackingResult, label?: string): void;
|
|
116
145
|
/** Check if shutdown has been requested */
|
|
117
146
|
export declare function isShuttingDown(): boolean;
|
|
118
147
|
export declare function runWithLoop(cycleFn: () => Promise<void>, options: {
|
|
@@ -140,6 +169,12 @@ export interface MonitorRunOptions {
|
|
|
140
169
|
maxAgeDays?: number;
|
|
141
170
|
/** Number of concurrent tracking operations (default: 1 = sequential) */
|
|
142
171
|
concurrency?: number;
|
|
172
|
+
/** Custom discovery targets (default: all enabled via buildDefaultTargets()) */
|
|
173
|
+
targets?: DiscoveryTargets;
|
|
174
|
+
/** Skip discovery and only track elections (faster when only elections needed) */
|
|
175
|
+
electionsOnly?: boolean;
|
|
176
|
+
/** Force re-track all elections, bypassing cache */
|
|
177
|
+
forceElections?: boolean;
|
|
143
178
|
}
|
|
144
179
|
export interface MonitorRunResult {
|
|
145
180
|
tracked: number;
|
|
@@ -147,11 +182,22 @@ export interface MonitorRunResult {
|
|
|
147
182
|
errors: number;
|
|
148
183
|
retracked: number;
|
|
149
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Filter checkpoints to only include those matching enabled discovery targets.
|
|
187
|
+
* Used for JSON output and stats to ensure we only show tracked types.
|
|
188
|
+
*/
|
|
189
|
+
export declare function filterCheckpointsByTargets(checkpoints: Map<string, TrackingCheckpoint>, targets: DiscoveryTargets): Map<string, TrackingCheckpoint>;
|
|
190
|
+
/**
|
|
191
|
+
* Calculate stats filtered by enabled discovery targets.
|
|
192
|
+
* Only counts checkpoints that match the enabled governors/timelocks.
|
|
193
|
+
*/
|
|
194
|
+
export declare function calculateFilteredStats(checkpoints: Map<string, TrackingCheckpoint>, targets: DiscoveryTargets, maxErrorCount?: number): TrackerStats;
|
|
150
195
|
export declare function runMonitorCycle(tracker: ProposalStageTracker, providers: ProviderBundle, options?: MonitorRunOptions): Promise<{
|
|
151
196
|
result: MonitorRunResult;
|
|
152
197
|
proposals: DiscoveredProposal[];
|
|
153
198
|
timelockOps: DiscoveredTimelockOp[];
|
|
154
199
|
watermarks: DiscoveryWatermarks;
|
|
200
|
+
elections: ElectionProposalStatus[];
|
|
155
201
|
}>;
|
|
156
202
|
export declare function trackAndPrepare(tracker: ProposalStageTracker, txHash: string, options: {
|
|
157
203
|
prepare?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EACL,oBAAoB,EAEpB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/lib/cli.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.loopOptions = exports.gasOptions = exports.chunkingOptions = exports.executionOptions = exports.cacheOptions = exports.verboseOption = exports.rpcOptions = exports.HEALTH_CHECK_TIMEOUT_MS = exports.DEFAULT_L2_GAS_SETTINGS = exports.MAX_CONSECUTIVE_ERRORS = exports.DEFAULT_MAX_AGE_DAYS = exports.DEFAULT_BLOCK_LAG = exports.isElectionGovernor = void 0;
|
|
16
16
|
exports.addOptions = addOptions;
|
|
17
|
+
exports.validateCliOptions = validateCliOptions;
|
|
17
18
|
exports.parseGasSettings = parseGasSettings;
|
|
18
19
|
exports.parseChunkingConfig = parseChunkingConfig;
|
|
19
20
|
exports.createProvidersFromOptions = createProvidersFromOptions;
|
|
@@ -24,8 +25,12 @@ exports.formatDryRun = formatDryRun;
|
|
|
24
25
|
exports.formatMultiplePreparedTransactions = formatMultiplePreparedTransactions;
|
|
25
26
|
exports.formatTrackingResult = formatTrackingResult;
|
|
26
27
|
exports.formatCacheStatus = formatCacheStatus;
|
|
28
|
+
exports.formatElectionResult = formatElectionResult;
|
|
29
|
+
exports.displayTrackingResult = displayTrackingResult;
|
|
27
30
|
exports.isShuttingDown = isShuttingDown;
|
|
28
31
|
exports.runWithLoop = runWithLoop;
|
|
32
|
+
exports.filterCheckpointsByTargets = filterCheckpointsByTargets;
|
|
33
|
+
exports.calculateFilteredStats = calculateFilteredStats;
|
|
29
34
|
exports.runMonitorCycle = runMonitorCycle;
|
|
30
35
|
exports.trackAndPrepare = trackAndPrepare;
|
|
31
36
|
const commander_1 = require("commander");
|
|
@@ -114,6 +119,59 @@ exports.loopOptions = [
|
|
|
114
119
|
function addOptions(cmd, opts) {
|
|
115
120
|
opts.forEach((o) => cmd.addOption(o));
|
|
116
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Validate CLI options for contradictions and conflicts.
|
|
124
|
+
* Throws an error if conflicting options are detected.
|
|
125
|
+
*/
|
|
126
|
+
function validateCliOptions(opts, command) {
|
|
127
|
+
const errors = [];
|
|
128
|
+
// Cache conflicts
|
|
129
|
+
if (opts.cache && opts.noCache) {
|
|
130
|
+
errors.push({
|
|
131
|
+
flags: ["--cache", "--no-cache"],
|
|
132
|
+
message: "--cache and --no-cache are mutually exclusive",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// --force overrides --start-block (warn, not error)
|
|
136
|
+
if (opts.force && opts.startBlock) {
|
|
137
|
+
errors.push({
|
|
138
|
+
flags: ["--force", "--start-block"],
|
|
139
|
+
message: "--force resets discovery to block 0, overriding --start-block",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// Track command specific validations
|
|
143
|
+
if (command === "track") {
|
|
144
|
+
// --inspect and --inspect-only are mutually exclusive
|
|
145
|
+
if (opts.inspect && opts.inspectOnly) {
|
|
146
|
+
errors.push({
|
|
147
|
+
flags: ["--inspect", "--inspect-only"],
|
|
148
|
+
message: "--inspect and --inspect-only are mutually exclusive",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// --inspect-only skips tracking, so execution options don't make sense
|
|
152
|
+
if (opts.inspectOnly) {
|
|
153
|
+
const conflictingFlags = [];
|
|
154
|
+
if (opts.prepare)
|
|
155
|
+
conflictingFlags.push("--prepare");
|
|
156
|
+
if (opts.write)
|
|
157
|
+
conflictingFlags.push("--write");
|
|
158
|
+
if (opts.prepareCompleted)
|
|
159
|
+
conflictingFlags.push("--prepare-completed");
|
|
160
|
+
if (opts.preparePending)
|
|
161
|
+
conflictingFlags.push("--prepare-pending");
|
|
162
|
+
if (conflictingFlags.length > 0) {
|
|
163
|
+
errors.push({
|
|
164
|
+
flags: ["--inspect-only", ...conflictingFlags],
|
|
165
|
+
message: `--inspect-only skips tracking; ${conflictingFlags.join(", ")} require tracking`,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (errors.length > 0) {
|
|
171
|
+
const messages = errors.map((e) => ` ${e.flags.join(" + ")}: ${e.message}`);
|
|
172
|
+
throw new Error(`Conflicting options detected:\n${messages.join("\n")}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
117
175
|
/**
|
|
118
176
|
* Parse gas settings from CLI options
|
|
119
177
|
*/
|
|
@@ -340,57 +398,114 @@ function formatTrackingResult(result, label) {
|
|
|
340
398
|
}
|
|
341
399
|
return lines.join("\n").concat("\n");
|
|
342
400
|
}
|
|
343
|
-
function formatCacheStatus(checkpoints) {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
401
|
+
function formatCacheStatus(checkpoints, elections) {
|
|
402
|
+
const stats = (0, index_1.computeCacheStats)(checkpoints, elections, exports.MAX_CONSECUTIVE_ERRORS);
|
|
403
|
+
const lines = [
|
|
404
|
+
`Total cached: ${stats.total}`,
|
|
405
|
+
``,
|
|
406
|
+
`Proposals: ${stats.proposals.total}`,
|
|
407
|
+
` Complete: ${stats.proposals.complete}`,
|
|
408
|
+
` Active: ${stats.proposals.active}`,
|
|
409
|
+
];
|
|
410
|
+
if (stats.proposals.errored > 0)
|
|
411
|
+
lines.push(` Failed: ${stats.proposals.errored}`);
|
|
412
|
+
lines.push(``, `Timelock Ops: ${stats.timelocks.total}`, ` Complete: ${stats.timelocks.complete}`, ` Active: ${stats.timelocks.active}`);
|
|
413
|
+
if (stats.timelocks.errored > 0)
|
|
414
|
+
lines.push(` Failed: ${stats.timelocks.errored}`);
|
|
415
|
+
if (stats.elections.total > 0) {
|
|
416
|
+
const active = stats.elections.total - stats.elections.complete;
|
|
417
|
+
lines.push(``, `Elections: ${stats.elections.total}`, ` Complete: ${stats.elections.complete}`, ` Active: ${active}`);
|
|
418
|
+
}
|
|
419
|
+
return lines.join("\n");
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Format an election status for CLI output
|
|
423
|
+
*/
|
|
424
|
+
function formatElectionResult(election) {
|
|
425
|
+
const lines = [];
|
|
426
|
+
const cohortName = election.cohort === 0 ? "First" : "Second";
|
|
427
|
+
const phaseName = election.phase.replace(/_/g, " ");
|
|
428
|
+
lines.push(`[Election #${election.electionIndex}]`);
|
|
429
|
+
lines.push(`Phase: ${phaseName}`);
|
|
430
|
+
lines.push(`Cohort: ${cohortName}`);
|
|
431
|
+
lines.push(`Complete: ${election.phase === "COMPLETED"}`);
|
|
432
|
+
lines.push(`Stages: ${election.stages?.length ?? 0}`);
|
|
433
|
+
lines.push("");
|
|
434
|
+
if (election.stages && election.stages.length > 0) {
|
|
435
|
+
for (let i = 0; i < election.stages.length; i++) {
|
|
436
|
+
const stage = election.stages[i];
|
|
437
|
+
const statusStr = stage.status;
|
|
438
|
+
const title = (0, index_1.formatStageTitle)(stage.type);
|
|
439
|
+
const eta = (0, index_1.calculateExpectedEta)(election.stages, i);
|
|
440
|
+
let line = ` ${title}: ${statusStr}`;
|
|
441
|
+
if (eta)
|
|
442
|
+
line += ` | ETA: ${new Date(eta * 1000).toISOString()}`;
|
|
443
|
+
lines.push(line);
|
|
444
|
+
for (const tx of stage.transactions) {
|
|
445
|
+
lines.push(` tx: ${tx.hash}`);
|
|
446
|
+
const url = (0, index_1.getStageTransactionUrl)(tx);
|
|
447
|
+
if (url)
|
|
448
|
+
lines.push(` ${url}`);
|
|
358
449
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
// Show timelock operation ID if tracked (useful for cross-referencing)
|
|
453
|
+
if (election.timelockOperationId) {
|
|
454
|
+
lines.push(` Timelock Op: ${election.timelockOperationId}`);
|
|
455
|
+
}
|
|
456
|
+
if (election.canProceedToMemberPhase) {
|
|
457
|
+
lines.push("");
|
|
458
|
+
lines.push(" → Ready to trigger member election");
|
|
459
|
+
}
|
|
460
|
+
if (election.canExecuteMember) {
|
|
461
|
+
lines.push("");
|
|
462
|
+
lines.push(" → Ready to execute member election");
|
|
463
|
+
}
|
|
464
|
+
if (election.canCreateElection) {
|
|
465
|
+
lines.push("");
|
|
466
|
+
lines.push(" → Ready to create election");
|
|
467
|
+
}
|
|
468
|
+
lines.push("");
|
|
469
|
+
return lines.join("\n");
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Display a tracking result, automatically switching to election display for election proposals.
|
|
473
|
+
* Handles the election auto-switch logic internally, falling back to formatTrackingResult for non-elections.
|
|
474
|
+
*
|
|
475
|
+
* @param result - Tracking result to display
|
|
476
|
+
* @param label - Optional label prefix
|
|
477
|
+
*/
|
|
478
|
+
function displayTrackingResult(result, label) {
|
|
479
|
+
if (result.isElection && result.electionStatus) {
|
|
480
|
+
const election = result.electionStatus;
|
|
481
|
+
const cohortName = election.cohort === 0 ? "First" : "Second";
|
|
482
|
+
console.log(`=== Election #${election.electionIndex} ===`);
|
|
483
|
+
console.log(`Phase: ${election.phase}`);
|
|
484
|
+
console.log(`Cohort: ${cohortName} (${election.cohort})`);
|
|
485
|
+
console.log(`Compliant Nominees: ${election.compliantNomineeCount}/${election.targetNomineeCount}`);
|
|
486
|
+
if (election.nomineeProposalId) {
|
|
487
|
+
console.log(`\nElection ID: ${election.nomineeProposalId}`);
|
|
488
|
+
console.log(`\nNominee Phase:`);
|
|
489
|
+
console.log(` State: ${election.nomineeProposalState}`);
|
|
490
|
+
if (election.vettingDeadline) {
|
|
491
|
+
console.log(` Vetting Deadline: block ${election.vettingDeadline}`);
|
|
367
492
|
}
|
|
493
|
+
console.log(` In Vetting Period: ${election.isInVettingPeriod ? "YES" : "NO"}`);
|
|
368
494
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
495
|
+
if (election.memberProposalId) {
|
|
496
|
+
console.log(`\nMember Phase:`);
|
|
497
|
+
console.log(` State: ${election.memberProposalState}`);
|
|
498
|
+
}
|
|
499
|
+
if (election.canProceedToMemberPhase) {
|
|
500
|
+
console.log(`\n→ Ready to trigger member election`);
|
|
501
|
+
}
|
|
502
|
+
if (election.canExecuteMember) {
|
|
503
|
+
console.log(`\n→ Ready to execute member election`);
|
|
377
504
|
}
|
|
505
|
+
console.log("");
|
|
506
|
+
return;
|
|
378
507
|
}
|
|
379
|
-
|
|
380
|
-
`Total cached: ${checkpoints.size}`,
|
|
381
|
-
``,
|
|
382
|
-
`Proposals: ${proposalTotal}`,
|
|
383
|
-
` Complete: ${proposalComplete}`,
|
|
384
|
-
` Active: ${proposalActive}`,
|
|
385
|
-
];
|
|
386
|
-
if (proposalFailed > 0)
|
|
387
|
-
lines.push(` Failed: ${proposalFailed}`);
|
|
388
|
-
lines.push(``, `Timelock Ops: ${timelockTotal}`, ` Complete: ${timelockComplete}`, ` Active: ${timelockActive}`);
|
|
389
|
-
if (timelockFailed > 0)
|
|
390
|
-
lines.push(` Failed: ${timelockFailed}`);
|
|
391
|
-
if (electionTotal > 0)
|
|
392
|
-
lines.push(``, `Elections: ${electionTotal} (${electionComplete} complete)`);
|
|
393
|
-
return lines.join("\n");
|
|
508
|
+
console.log(formatTrackingResult(result, label));
|
|
394
509
|
}
|
|
395
510
|
// ============================================================================
|
|
396
511
|
// Loop Runner
|
|
@@ -549,27 +664,193 @@ function shortScope(key) {
|
|
|
549
664
|
}
|
|
550
665
|
return key;
|
|
551
666
|
}
|
|
667
|
+
/**
|
|
668
|
+
* Check if a checkpoint matches the enabled discovery targets.
|
|
669
|
+
* Used to filter incomplete checkpoints to only re-track types that are enabled.
|
|
670
|
+
*/
|
|
671
|
+
function checkpointMatchesTargets(checkpoint, targets) {
|
|
672
|
+
if (checkpoint.input.type === "governor") {
|
|
673
|
+
const governorAddress = checkpoint.input.governorAddress;
|
|
674
|
+
// Skip election governors - they're handled separately
|
|
675
|
+
if ((0, index_1.isElectionGovernor)(governorAddress))
|
|
676
|
+
return false;
|
|
677
|
+
// Check if constitutional or non-constitutional governor is enabled
|
|
678
|
+
const isCore = (0, index_1.isConstitutional)(governorAddress);
|
|
679
|
+
return isCore ? !!targets.constitutionalGovernor : !!targets.nonConstitutionalGovernor;
|
|
680
|
+
}
|
|
681
|
+
if (checkpoint.input.type === "timelock") {
|
|
682
|
+
// Timelock operations: check if the corresponding timelock target is enabled
|
|
683
|
+
const timelockAddress = checkpoint.input.timelockAddress;
|
|
684
|
+
const isCore = (0, index_1.isConstitutional)(timelockAddress);
|
|
685
|
+
return isCore ? !!targets.l2ConstitutionalTimelock : !!targets.l2NonConstitutionalTimelock;
|
|
686
|
+
}
|
|
687
|
+
if (checkpoint.input.type === "election") {
|
|
688
|
+
return !!targets.electionNomineeGovernor || !!targets.electionMemberGovernor;
|
|
689
|
+
}
|
|
690
|
+
// Discovery checkpoints don't need re-tracking
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Filter checkpoints to only include those matching enabled discovery targets.
|
|
695
|
+
* Used for JSON output and stats to ensure we only show tracked types.
|
|
696
|
+
*/
|
|
697
|
+
function filterCheckpointsByTargets(checkpoints, targets) {
|
|
698
|
+
const filtered = new Map();
|
|
699
|
+
for (const [key, checkpoint] of checkpoints) {
|
|
700
|
+
if (checkpointMatchesTargets(checkpoint, targets)) {
|
|
701
|
+
filtered.set(key, checkpoint);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
return filtered;
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Calculate stats filtered by enabled discovery targets.
|
|
708
|
+
* Only counts checkpoints that match the enabled governors/timelocks.
|
|
709
|
+
*/
|
|
710
|
+
function calculateFilteredStats(checkpoints, targets, maxErrorCount = 5) {
|
|
711
|
+
let proposalTotal = 0, proposalComplete = 0, proposalActive = 0, proposalErrored = 0;
|
|
712
|
+
let timelockTotal = 0, timelockComplete = 0, timelockActive = 0, timelockErrored = 0;
|
|
713
|
+
let electionTotal = 0, electionComplete = 0;
|
|
714
|
+
for (const [, checkpoint] of checkpoints) {
|
|
715
|
+
const complete = (0, index_1.isCheckpointComplete)(checkpoint);
|
|
716
|
+
const errored = (0, index_1.isCheckpointErrored)(checkpoint, maxErrorCount);
|
|
717
|
+
const inputType = checkpoint.input.type;
|
|
718
|
+
if (inputType === "governor") {
|
|
719
|
+
const governorAddress = checkpoint.input.governorAddress;
|
|
720
|
+
if ((0, index_1.isElectionGovernor)(governorAddress))
|
|
721
|
+
continue;
|
|
722
|
+
const isCore = (0, index_1.isConstitutional)(governorAddress);
|
|
723
|
+
const matchesTarget = isCore
|
|
724
|
+
? !!targets.constitutionalGovernor
|
|
725
|
+
: !!targets.nonConstitutionalGovernor;
|
|
726
|
+
if (!matchesTarget)
|
|
727
|
+
continue;
|
|
728
|
+
proposalTotal++;
|
|
729
|
+
if (complete)
|
|
730
|
+
proposalComplete++;
|
|
731
|
+
else if (errored)
|
|
732
|
+
proposalErrored++;
|
|
733
|
+
else
|
|
734
|
+
proposalActive++;
|
|
735
|
+
}
|
|
736
|
+
else if (inputType === "timelock") {
|
|
737
|
+
const timelockAddress = checkpoint.input.timelockAddress;
|
|
738
|
+
const isCore = (0, index_1.isConstitutional)(timelockAddress);
|
|
739
|
+
const matchesTarget = isCore
|
|
740
|
+
? !!targets.l2ConstitutionalTimelock
|
|
741
|
+
: !!targets.l2NonConstitutionalTimelock;
|
|
742
|
+
if (!matchesTarget)
|
|
743
|
+
continue;
|
|
744
|
+
timelockTotal++;
|
|
745
|
+
if (complete)
|
|
746
|
+
timelockComplete++;
|
|
747
|
+
else if (errored)
|
|
748
|
+
timelockErrored++;
|
|
749
|
+
else
|
|
750
|
+
timelockActive++;
|
|
751
|
+
}
|
|
752
|
+
else if (inputType === "election") {
|
|
753
|
+
// Only count elections if election tracking is enabled
|
|
754
|
+
if (!targets.electionNomineeGovernor && !targets.electionMemberGovernor)
|
|
755
|
+
continue;
|
|
756
|
+
electionTotal++;
|
|
757
|
+
if (complete)
|
|
758
|
+
electionComplete++;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return {
|
|
762
|
+
total: proposalTotal + timelockTotal + electionTotal,
|
|
763
|
+
proposals: {
|
|
764
|
+
total: proposalTotal,
|
|
765
|
+
complete: proposalComplete,
|
|
766
|
+
active: proposalActive,
|
|
767
|
+
errored: proposalErrored,
|
|
768
|
+
},
|
|
769
|
+
timelocks: {
|
|
770
|
+
total: timelockTotal,
|
|
771
|
+
complete: timelockComplete,
|
|
772
|
+
active: timelockActive,
|
|
773
|
+
errored: timelockErrored,
|
|
774
|
+
},
|
|
775
|
+
elections: { total: electionTotal, complete: electionComplete },
|
|
776
|
+
};
|
|
777
|
+
}
|
|
552
778
|
async function runMonitorCycle(tracker, providers, options = {}) {
|
|
779
|
+
const result = { tracked: 0, prepared: 0, errors: 0, retracked: 0 };
|
|
780
|
+
// Fast path: elections-only mode skips discovery entirely
|
|
781
|
+
if (options.electionsOnly) {
|
|
782
|
+
const elections = [];
|
|
783
|
+
if (!isShuttingDown()) {
|
|
784
|
+
try {
|
|
785
|
+
// Use tracker's cached method - completed elections use cache (0 RPC calls)
|
|
786
|
+
// Use forceElections to bypass cache when --force is specified
|
|
787
|
+
const allElections = await tracker.trackAllElections({ force: options.forceElections });
|
|
788
|
+
for (const electionStatus of allElections) {
|
|
789
|
+
elections.push(electionStatus);
|
|
790
|
+
// Print each election
|
|
791
|
+
console.log(formatElectionResult(electionStatus));
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
catch (err) {
|
|
795
|
+
console.error("Election tracking failed:", err);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return {
|
|
799
|
+
result,
|
|
800
|
+
proposals: [],
|
|
801
|
+
timelockOps: [],
|
|
802
|
+
watermarks: {},
|
|
803
|
+
elections,
|
|
804
|
+
};
|
|
805
|
+
}
|
|
553
806
|
const l2Provider = providers.l2Provider;
|
|
554
807
|
const tipBlock = await l2Provider.getBlockNumber();
|
|
555
808
|
const blockLag = options.blockLag ?? exports.DEFAULT_BLOCK_LAG;
|
|
556
809
|
const currentBlock = Math.max(0, tipBlock - blockLag);
|
|
557
810
|
const concurrency = options.concurrency ?? 1;
|
|
558
811
|
const limit = (0, concurrency_1.pLimit)(concurrency);
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
812
|
+
const maxAgeDays = options.maxAgeDays ?? exports.DEFAULT_MAX_AGE_DAYS;
|
|
813
|
+
// Calculate startBlock based on maxAgeDays if not explicitly provided
|
|
814
|
+
// ~7200 blocks per day on Arbitrum (12s block time on L1, ~250ms on L2)
|
|
815
|
+
const BLOCKS_PER_DAY = 86400 / 0.25; // ~345,600 blocks/day on Arbitrum One
|
|
816
|
+
let startBlockWatermarks;
|
|
817
|
+
// Load existing watermarks to determine scan range
|
|
818
|
+
const loadedWatermarks = await tracker.loadWatermarks();
|
|
819
|
+
const hasWatermarks = Object.values(loadedWatermarks.watermarks).some((v) => v !== undefined);
|
|
820
|
+
if (options.startBlock !== undefined) {
|
|
821
|
+
// Explicit startBlock override (watermarks are exclusive, so subtract 1)
|
|
822
|
+
startBlockWatermarks = {
|
|
562
823
|
constitutionalGovernor: options.startBlock - 1,
|
|
563
824
|
nonConstitutionalGovernor: options.startBlock - 1,
|
|
564
825
|
electionNomineeGovernor: options.startBlock - 1,
|
|
565
826
|
electionMemberGovernor: options.startBlock - 1,
|
|
566
827
|
l2ConstitutionalTimelock: options.startBlock - 1,
|
|
567
828
|
l2NonConstitutionalTimelock: options.startBlock - 1,
|
|
568
|
-
}
|
|
569
|
-
:
|
|
570
|
-
|
|
829
|
+
};
|
|
830
|
+
console.log(`Discovery: blocks ${options.startBlock} → ${currentBlock}`);
|
|
831
|
+
}
|
|
832
|
+
else if (!hasWatermarks) {
|
|
833
|
+
// No cache - calculate start block from maxAgeDays
|
|
834
|
+
const defaultStartBlock = Math.max(0, currentBlock - Math.floor(maxAgeDays * BLOCKS_PER_DAY));
|
|
835
|
+
startBlockWatermarks = {
|
|
836
|
+
constitutionalGovernor: defaultStartBlock,
|
|
837
|
+
nonConstitutionalGovernor: defaultStartBlock,
|
|
838
|
+
electionNomineeGovernor: defaultStartBlock,
|
|
839
|
+
electionMemberGovernor: defaultStartBlock,
|
|
840
|
+
l2ConstitutionalTimelock: defaultStartBlock,
|
|
841
|
+
l2NonConstitutionalTimelock: defaultStartBlock,
|
|
842
|
+
};
|
|
843
|
+
console.log(`No cached watermarks. Discovery: blocks ${defaultStartBlock} → ${currentBlock} (~${maxAgeDays} days)`);
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
// Cached watermarks exist - calculate effective range from min watermark
|
|
847
|
+
const watermarkBlocks = Object.values(loadedWatermarks.watermarks).filter((v) => v !== undefined);
|
|
848
|
+
const minWatermark = Math.min(...watermarkBlocks);
|
|
849
|
+
const blockRange = currentBlock - minWatermark;
|
|
850
|
+
console.log(`Discovery: blocks ${minWatermark} → ${currentBlock} (${blockRange.toLocaleString()} blocks)`);
|
|
851
|
+
}
|
|
852
|
+
const targets = options.targets ?? (0, index_1.buildDefaultTargets)();
|
|
571
853
|
const discoveryResult = await tracker.discoverAll(targets, currentBlock, startBlockWatermarks);
|
|
572
|
-
const result = { tracked: 0, prepared: 0, errors: 0, retracked: 0 };
|
|
573
854
|
const trackedKeys = new Set();
|
|
574
855
|
const trackedOperationIds = new Set();
|
|
575
856
|
async function track(key, trackFn) {
|
|
@@ -623,7 +904,6 @@ async function runMonitorCycle(tracker, providers, options = {}) {
|
|
|
623
904
|
});
|
|
624
905
|
}
|
|
625
906
|
// Query incomplete checkpoints first to avoid duplicate tracking
|
|
626
|
-
const maxAgeDays = options.maxAgeDays ?? exports.DEFAULT_MAX_AGE_DAYS;
|
|
627
907
|
const incompleteCheckpoints = await tracker.queryIncompleteCheckpoints({
|
|
628
908
|
maxAgeDays,
|
|
629
909
|
maxErrorCount: exports.MAX_CONSECUTIVE_ERRORS,
|
|
@@ -654,14 +934,10 @@ async function runMonitorCycle(tracker, providers, options = {}) {
|
|
|
654
934
|
},
|
|
655
935
|
});
|
|
656
936
|
}
|
|
657
|
-
// 1b. Incomplete
|
|
658
|
-
const
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
return true;
|
|
662
|
-
});
|
|
663
|
-
result.retracked = nonElectionCheckpoints.length;
|
|
664
|
-
for (const { key, checkpoint } of nonElectionCheckpoints) {
|
|
937
|
+
// 1b. Incomplete checkpoints to re-track (filtered by enabled targets)
|
|
938
|
+
const targetMatchingCheckpoints = incompleteCheckpoints.filter(({ checkpoint }) => checkpointMatchesTargets(checkpoint, targets));
|
|
939
|
+
result.retracked = targetMatchingCheckpoints.length;
|
|
940
|
+
for (const { key, checkpoint } of targetMatchingCheckpoints) {
|
|
665
941
|
if (checkpoint.input.type === "governor") {
|
|
666
942
|
proposalTasks.push({
|
|
667
943
|
key,
|
|
@@ -699,7 +975,7 @@ async function runMonitorCycle(tracker, providers, options = {}) {
|
|
|
699
975
|
});
|
|
700
976
|
}
|
|
701
977
|
// 2b. Incomplete timelock checkpoints to re-track
|
|
702
|
-
for (const { key, checkpoint } of
|
|
978
|
+
for (const { key, checkpoint } of targetMatchingCheckpoints) {
|
|
703
979
|
if (checkpoint.input.type === "timelock") {
|
|
704
980
|
const operationId = checkpoint.input.operationId;
|
|
705
981
|
// Skip if already tracked via proposal
|
|
@@ -715,11 +991,28 @@ async function runMonitorCycle(tracker, providers, options = {}) {
|
|
|
715
991
|
}
|
|
716
992
|
// Run timelock tasks
|
|
717
993
|
await Promise.all(timelockTasks.map((task) => limit(() => track(task.key, task.fn))));
|
|
994
|
+
// Phase 3: Track elections (only if election targets are enabled)
|
|
995
|
+
const elections = [];
|
|
996
|
+
const shouldTrackElections = targets.electionNomineeGovernor || targets.electionMemberGovernor;
|
|
997
|
+
if (shouldTrackElections && !isShuttingDown()) {
|
|
998
|
+
try {
|
|
999
|
+
// Use tracker's cached method - completed elections use cache (0 RPC calls)
|
|
1000
|
+
const allElections = await tracker.trackAllElections({ force: options.forceElections });
|
|
1001
|
+
for (const electionStatus of allElections) {
|
|
1002
|
+
elections.push(electionStatus);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
catch (err) {
|
|
1006
|
+
// Election tracking is non-critical, log and continue
|
|
1007
|
+
console.error("Election tracking failed:", err);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
718
1010
|
return {
|
|
719
1011
|
result,
|
|
720
1012
|
proposals: discoveryResult.proposals,
|
|
721
1013
|
timelockOps: discoveryResult.timelockOps,
|
|
722
1014
|
watermarks: discoveryResult.watermarks,
|
|
1015
|
+
elections,
|
|
723
1016
|
};
|
|
724
1017
|
}
|
|
725
1018
|
// ============================================================================
|