@gzeoneth/gov-tracker 0.1.0
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/LICENSE +191 -0
- package/README.md +201 -0
- package/dist/abis.d.ts +79 -0
- package/dist/abis.d.ts.map +1 -0
- package/dist/abis.js +159 -0
- package/dist/abis.js.map +1 -0
- package/dist/cli/lib/cli.d.ts +92 -0
- package/dist/cli/lib/cli.d.ts.map +1 -0
- package/dist/cli/lib/cli.js +562 -0
- package/dist/cli/lib/cli.js.map +1 -0
- package/dist/cli/lib/election-check.d.ts +46 -0
- package/dist/cli/lib/election-check.d.ts.map +1 -0
- package/dist/cli/lib/election-check.js +136 -0
- package/dist/cli/lib/election-check.js.map +1 -0
- package/dist/cli/lib/json-state.d.ts +100 -0
- package/dist/cli/lib/json-state.d.ts.map +1 -0
- package/dist/cli/lib/json-state.js +225 -0
- package/dist/cli/lib/json-state.js.map +1 -0
- package/dist/cli/monitor.d.ts +3 -0
- package/dist/cli/monitor.d.ts.map +1 -0
- package/dist/cli/monitor.js +442 -0
- package/dist/cli/monitor.js.map +1 -0
- package/dist/constants.d.ts +235 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +293 -0
- package/dist/constants.js.map +1 -0
- package/dist/discovery/governor-discovery.d.ts +84 -0
- package/dist/discovery/governor-discovery.d.ts.map +1 -0
- package/dist/discovery/governor-discovery.js +310 -0
- package/dist/discovery/governor-discovery.js.map +1 -0
- package/dist/discovery/security-council.d.ts +68 -0
- package/dist/discovery/security-council.d.ts.map +1 -0
- package/dist/discovery/security-council.js +181 -0
- package/dist/discovery/security-council.js.map +1 -0
- package/dist/discovery/timelock-discovery.d.ts +99 -0
- package/dist/discovery/timelock-discovery.d.ts.map +1 -0
- package/dist/discovery/timelock-discovery.js +322 -0
- package/dist/discovery/timelock-discovery.js.map +1 -0
- package/dist/election.d.ts +172 -0
- package/dist/election.d.ts.map +1 -0
- package/dist/election.js +464 -0
- package/dist/election.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +164 -0
- package/dist/index.js.map +1 -0
- package/dist/stages/base.d.ts +127 -0
- package/dist/stages/base.d.ts.map +1 -0
- package/dist/stages/base.js +280 -0
- package/dist/stages/base.js.map +1 -0
- package/dist/stages/l2-to-l1-message.d.ts +108 -0
- package/dist/stages/l2-to-l1-message.d.ts.map +1 -0
- package/dist/stages/l2-to-l1-message.js +422 -0
- package/dist/stages/l2-to-l1-message.js.map +1 -0
- package/dist/stages/proposal-created.d.ts +20 -0
- package/dist/stages/proposal-created.d.ts.map +1 -0
- package/dist/stages/proposal-created.js +62 -0
- package/dist/stages/proposal-created.js.map +1 -0
- package/dist/stages/proposal-queued.d.ts +39 -0
- package/dist/stages/proposal-queued.d.ts.map +1 -0
- package/dist/stages/proposal-queued.js +131 -0
- package/dist/stages/proposal-queued.js.map +1 -0
- package/dist/stages/retryables.d.ts +79 -0
- package/dist/stages/retryables.d.ts.map +1 -0
- package/dist/stages/retryables.js +307 -0
- package/dist/stages/retryables.js.map +1 -0
- package/dist/stages/stage-builder.d.ts +46 -0
- package/dist/stages/stage-builder.d.ts.map +1 -0
- package/dist/stages/stage-builder.js +87 -0
- package/dist/stages/stage-builder.js.map +1 -0
- package/dist/stages/timelock.d.ts +100 -0
- package/dist/stages/timelock.d.ts.map +1 -0
- package/dist/stages/timelock.js +552 -0
- package/dist/stages/timelock.js.map +1 -0
- package/dist/stages/voting.d.ts +18 -0
- package/dist/stages/voting.d.ts.map +1 -0
- package/dist/stages/voting.js +109 -0
- package/dist/stages/voting.js.map +1 -0
- package/dist/tracker/context.d.ts +111 -0
- package/dist/tracker/context.d.ts.map +1 -0
- package/dist/tracker/context.js +264 -0
- package/dist/tracker/context.js.map +1 -0
- package/dist/tracker/discovery.d.ts +89 -0
- package/dist/tracker/discovery.d.ts.map +1 -0
- package/dist/tracker/discovery.js +228 -0
- package/dist/tracker/discovery.js.map +1 -0
- package/dist/tracker/execute.d.ts +44 -0
- package/dist/tracker/execute.d.ts.map +1 -0
- package/dist/tracker/execute.js +126 -0
- package/dist/tracker/execute.js.map +1 -0
- package/dist/tracker/index.d.ts +18 -0
- package/dist/tracker/index.d.ts.map +1 -0
- package/dist/tracker/index.js +70 -0
- package/dist/tracker/index.js.map +1 -0
- package/dist/tracker/pipeline.d.ts +47 -0
- package/dist/tracker/pipeline.d.ts.map +1 -0
- package/dist/tracker/pipeline.js +299 -0
- package/dist/tracker/pipeline.js.map +1 -0
- package/dist/tracker/query.d.ts +45 -0
- package/dist/tracker/query.d.ts.map +1 -0
- package/dist/tracker/query.js +159 -0
- package/dist/tracker/query.js.map +1 -0
- package/dist/tracker/state.d.ts +104 -0
- package/dist/tracker/state.d.ts.map +1 -0
- package/dist/tracker/state.js +287 -0
- package/dist/tracker/state.js.map +1 -0
- package/dist/tracker.d.ts +261 -0
- package/dist/tracker.d.ts.map +1 -0
- package/dist/tracker.js +556 -0
- package/dist/tracker.js.map +1 -0
- package/dist/types/config.d.ts +81 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +6 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/core.d.ts +51 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +6 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/cross-chain.d.ts +80 -0
- package/dist/types/cross-chain.d.ts.map +1 -0
- package/dist/types/cross-chain.js +6 -0
- package/dist/types/cross-chain.js.map +1 -0
- package/dist/types/election.d.ts +59 -0
- package/dist/types/election.d.ts.map +1 -0
- package/dist/types/election.js +6 -0
- package/dist/types/election.js.map +1 -0
- package/dist/types/governor.d.ts +71 -0
- package/dist/types/governor.d.ts.map +1 -0
- package/dist/types/governor.js +6 -0
- package/dist/types/governor.js.map +1 -0
- package/dist/types/index.d.ts +22 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/stages.d.ts +189 -0
- package/dist/types/stages.d.ts.map +1 -0
- package/dist/types/stages.js +23 -0
- package/dist/types/stages.js.map +1 -0
- package/dist/types/timelock.d.ts +108 -0
- package/dist/types/timelock.d.ts.map +1 -0
- package/dist/types/timelock.js +6 -0
- package/dist/types/timelock.js.map +1 -0
- package/dist/types/tracking.d.ts +180 -0
- package/dist/types/tracking.d.ts.map +1 -0
- package/dist/types/tracking.js +6 -0
- package/dist/types/tracking.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/chain.d.ts +18 -0
- package/dist/utils/chain.d.ts.map +1 -0
- package/dist/utils/chain.js +34 -0
- package/dist/utils/chain.js.map +1 -0
- package/dist/utils/log-filters.d.ts +67 -0
- package/dist/utils/log-filters.d.ts.map +1 -0
- package/dist/utils/log-filters.js +116 -0
- package/dist/utils/log-filters.js.map +1 -0
- package/dist/utils/log-search.d.ts +76 -0
- package/dist/utils/log-search.d.ts.map +1 -0
- package/dist/utils/log-search.js +142 -0
- package/dist/utils/log-search.js.map +1 -0
- package/dist/utils/logger.d.ts +41 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/operation-id.d.ts +48 -0
- package/dist/utils/operation-id.d.ts.map +1 -0
- package/dist/utils/operation-id.js +102 -0
- package/dist/utils/operation-id.js.map +1 -0
- package/dist/utils/rpc-utils.d.ts +30 -0
- package/dist/utils/rpc-utils.d.ts.map +1 -0
- package/dist/utils/rpc-utils.js +99 -0
- package/dist/utils/rpc-utils.js.map +1 -0
- package/dist/utils/salt-computation.d.ts +78 -0
- package/dist/utils/salt-computation.d.ts.map +1 -0
- package/dist/utils/salt-computation.js +132 -0
- package/dist/utils/salt-computation.js.map +1 -0
- package/dist/utils/salt-resolver.d.ts +63 -0
- package/dist/utils/salt-resolver.d.ts.map +1 -0
- package/dist/utils/salt-resolver.js +144 -0
- package/dist/utils/salt-resolver.js.map +1 -0
- package/dist/utils/scoped-logger.d.ts +43 -0
- package/dist/utils/scoped-logger.d.ts.map +1 -0
- package/dist/utils/scoped-logger.js +72 -0
- package/dist/utils/scoped-logger.js.map +1 -0
- package/dist/utils/stage-helpers.d.ts +51 -0
- package/dist/utils/stage-helpers.d.ts.map +1 -0
- package/dist/utils/stage-helpers.js +143 -0
- package/dist/utils/stage-helpers.js.map +1 -0
- package/dist/utils/stage-metadata.d.ts +62 -0
- package/dist/utils/stage-metadata.d.ts.map +1 -0
- package/dist/utils/stage-metadata.js +140 -0
- package/dist/utils/stage-metadata.js.map +1 -0
- package/dist/utils/timing.d.ts +115 -0
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/timing.js +303 -0
- package/dist/utils/timing.js.map +1 -0
- package/dist/utils/urls.d.ts +20 -0
- package/dist/utils/urls.d.ts.map +1 -0
- package/dist/utils/urls.js +51 -0
- package/dist/utils/urls.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chunked log search with early exit optimization
|
|
3
|
+
*
|
|
4
|
+
* Critical performance pattern: 10-40x faster than naive log search
|
|
5
|
+
*/
|
|
6
|
+
import { ethers } from "ethers";
|
|
7
|
+
/**
|
|
8
|
+
* Log filter parameters
|
|
9
|
+
*/
|
|
10
|
+
export interface LogFilter {
|
|
11
|
+
address?: string | string[];
|
|
12
|
+
topics?: (string | string[] | null)[];
|
|
13
|
+
fromBlock: number;
|
|
14
|
+
toBlock: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Search result with metadata
|
|
18
|
+
*/
|
|
19
|
+
export interface LogSearchResult {
|
|
20
|
+
logs: ethers.providers.Log[];
|
|
21
|
+
searchedBlocks: number;
|
|
22
|
+
chunksProcessed: number;
|
|
23
|
+
earlyExit: boolean;
|
|
24
|
+
/** The log that triggered early exit (if earlyExitCheck returned one) */
|
|
25
|
+
matchedLog?: ethers.providers.Log;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Options for log search
|
|
29
|
+
*/
|
|
30
|
+
export interface LogSearchOptions {
|
|
31
|
+
chunkSize?: number;
|
|
32
|
+
delayBetweenChunks?: number;
|
|
33
|
+
earlyExitCheck?: (logs: ethers.providers.Log[]) => ethers.providers.Log | undefined;
|
|
34
|
+
maxChunks?: number;
|
|
35
|
+
reverseDirection?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Search for logs in chunks with early exit optimization
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* // Search for CallExecuted events, stop when found
|
|
43
|
+
* const result = await searchLogsInChunks(
|
|
44
|
+
* l2Provider,
|
|
45
|
+
* {
|
|
46
|
+
* address: timelockAddress,
|
|
47
|
+
* topics: [EVENT_TOPICS.CALL_EXECUTED, operationId],
|
|
48
|
+
* fromBlock: queueBlock,
|
|
49
|
+
* toBlock: currentBlock
|
|
50
|
+
* },
|
|
51
|
+
* {
|
|
52
|
+
* chunkSize: 10_000_000,
|
|
53
|
+
* earlyExitCheck: (logs) => logs.find(l => l.topics[1] === operationId) ?? null
|
|
54
|
+
* }
|
|
55
|
+
* );
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function searchLogsInChunks(provider: ethers.providers.Provider, filter: LogFilter, options?: LogSearchOptions): Promise<LogSearchResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Search for a single log matching a predicate
|
|
61
|
+
* Returns immediately when found (early exit optimization)
|
|
62
|
+
*/
|
|
63
|
+
export declare function findLog(provider: ethers.providers.Provider, filter: LogFilter, predicate: (log: ethers.providers.Log) => boolean, options?: Omit<LogSearchOptions, "earlyExitCheck">): Promise<ethers.providers.Log | undefined>;
|
|
64
|
+
/**
|
|
65
|
+
* Generic find and parse event - consolidates the common pattern:
|
|
66
|
+
* getSearchDefaults → findLog → parse → null check
|
|
67
|
+
*
|
|
68
|
+
* Reduces boilerplate in timelock-discovery.ts and similar modules.
|
|
69
|
+
*/
|
|
70
|
+
export declare function findAndParseEvent<T>(provider: ethers.providers.Provider, filter: LogFilter, predicate: (log: ethers.providers.Log) => boolean, parser: (log: ethers.providers.Log) => T | null, options?: Omit<LogSearchOptions, "earlyExitCheck">): Promise<T | null>;
|
|
71
|
+
/**
|
|
72
|
+
* Create a predicate that matches operationId in topics[1]
|
|
73
|
+
* Common pattern for timelock event filtering
|
|
74
|
+
*/
|
|
75
|
+
export declare function createOperationIdPredicate(operationId: string, addressEquals: (a: string, b: string) => boolean): (log: ethers.providers.Log) => boolean;
|
|
76
|
+
//# sourceMappingURL=log-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-search.d.ts","sourceRoot":"","sources":["../../src/utils/log-search.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAOhC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,MAAM,CAAC,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAoH1B;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,OAAO,EACjD,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAM,GACrD,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,GAAG,SAAS,CAAC,CAQ3C;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EACnC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,OAAO,EACjD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,EAC/C,OAAO,GAAE,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAM,GACrD,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAInB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,GAC/C,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,OAAO,CAExC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Chunked log search with early exit optimization
|
|
4
|
+
*
|
|
5
|
+
* Critical performance pattern: 10-40x faster than naive log search
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.searchLogsInChunks = searchLogsInChunks;
|
|
9
|
+
exports.findLog = findLog;
|
|
10
|
+
exports.findAndParseEvent = findAndParseEvent;
|
|
11
|
+
exports.createOperationIdPredicate = createOperationIdPredicate;
|
|
12
|
+
const constants_1 = require("../constants");
|
|
13
|
+
const rpc_utils_1 = require("./rpc-utils");
|
|
14
|
+
const logger_1 = require("./logger");
|
|
15
|
+
const log = logger_1.loggers.rpc;
|
|
16
|
+
/**
|
|
17
|
+
* Search for logs in chunks with early exit optimization
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Search for CallExecuted events, stop when found
|
|
22
|
+
* const result = await searchLogsInChunks(
|
|
23
|
+
* l2Provider,
|
|
24
|
+
* {
|
|
25
|
+
* address: timelockAddress,
|
|
26
|
+
* topics: [EVENT_TOPICS.CALL_EXECUTED, operationId],
|
|
27
|
+
* fromBlock: queueBlock,
|
|
28
|
+
* toBlock: currentBlock
|
|
29
|
+
* },
|
|
30
|
+
* {
|
|
31
|
+
* chunkSize: 10_000_000,
|
|
32
|
+
* earlyExitCheck: (logs) => logs.find(l => l.topics[1] === operationId) ?? null
|
|
33
|
+
* }
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
async function searchLogsInChunks(provider, filter, options = {}) {
|
|
38
|
+
const { chunkSize = constants_1.DEFAULT_CHUNKING_CONFIG.l2ChunkSize, delayBetweenChunks = constants_1.DEFAULT_CHUNKING_CONFIG.delayBetweenChunks, earlyExitCheck, maxChunks, reverseDirection = false, } = options;
|
|
39
|
+
const allLogs = [];
|
|
40
|
+
let chunksProcessed = 0;
|
|
41
|
+
let earlyExit = false;
|
|
42
|
+
let matchedLog;
|
|
43
|
+
const { fromBlock, toBlock } = filter;
|
|
44
|
+
const totalBlocks = toBlock - fromBlock + 1;
|
|
45
|
+
const searchStart = Date.now();
|
|
46
|
+
const addressStr = Array.isArray(filter.address)
|
|
47
|
+
? `[${filter.address.length} addrs]`
|
|
48
|
+
: filter.address;
|
|
49
|
+
log("searchLogsInChunks: %s blocks=%d-%d (%d blocks, ~%d chunks)", addressStr, fromBlock, toBlock, totalBlocks, Math.ceil(totalBlocks / chunkSize));
|
|
50
|
+
if (totalBlocks <= 0) {
|
|
51
|
+
return { logs: [], searchedBlocks: 0, chunksProcessed: 0, earlyExit: false };
|
|
52
|
+
}
|
|
53
|
+
// Generate chunk ranges
|
|
54
|
+
const chunks = [];
|
|
55
|
+
if (reverseDirection) {
|
|
56
|
+
// Search backwards (useful for finding most recent events)
|
|
57
|
+
for (let end = toBlock; end >= fromBlock; end -= chunkSize) {
|
|
58
|
+
const start = Math.max(end - chunkSize + 1, fromBlock);
|
|
59
|
+
chunks.push({ start, end });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Search forwards (default)
|
|
64
|
+
for (let start = fromBlock; start <= toBlock; start += chunkSize) {
|
|
65
|
+
const end = Math.min(start + chunkSize - 1, toBlock);
|
|
66
|
+
chunks.push({ start, end });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Process chunks and track actual blocks searched
|
|
70
|
+
let actualBlocksSearched = 0;
|
|
71
|
+
for (const { start, end } of chunks) {
|
|
72
|
+
if (maxChunks && chunksProcessed >= maxChunks) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
const chunkStart = Date.now();
|
|
76
|
+
const logs = await (0, rpc_utils_1.queryWithRetry)(() => provider.getLogs({
|
|
77
|
+
address: filter.address,
|
|
78
|
+
topics: filter.topics,
|
|
79
|
+
fromBlock: start,
|
|
80
|
+
toBlock: end,
|
|
81
|
+
}));
|
|
82
|
+
const chunkMs = Date.now() - chunkStart;
|
|
83
|
+
log(" chunk %d: blocks=%d-%d found=%d logs (%dms)", chunksProcessed + 1, start, end, logs.length, chunkMs);
|
|
84
|
+
allLogs.push(...logs);
|
|
85
|
+
chunksProcessed++;
|
|
86
|
+
actualBlocksSearched += end - start + 1;
|
|
87
|
+
// Early exit check - critical optimization
|
|
88
|
+
if (earlyExitCheck && logs.length > 0) {
|
|
89
|
+
const match = earlyExitCheck(logs);
|
|
90
|
+
if (match) {
|
|
91
|
+
earlyExit = true;
|
|
92
|
+
matchedLog = match;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Rate limiting between chunks
|
|
97
|
+
if (end < toBlock && delayBetweenChunks > 0) {
|
|
98
|
+
await (0, rpc_utils_1.delay)(delayBetweenChunks);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const totalMs = Date.now() - searchStart;
|
|
102
|
+
log("searchLogsInChunks done: %d logs, %d chunks, %dms%s", allLogs.length, chunksProcessed, totalMs, earlyExit ? " (early exit)" : "");
|
|
103
|
+
return {
|
|
104
|
+
logs: allLogs,
|
|
105
|
+
searchedBlocks: actualBlocksSearched,
|
|
106
|
+
chunksProcessed,
|
|
107
|
+
earlyExit,
|
|
108
|
+
matchedLog,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Search for a single log matching a predicate
|
|
113
|
+
* Returns immediately when found (early exit optimization)
|
|
114
|
+
*/
|
|
115
|
+
async function findLog(provider, filter, predicate, options = {}) {
|
|
116
|
+
const result = await searchLogsInChunks(provider, filter, {
|
|
117
|
+
...options,
|
|
118
|
+
earlyExitCheck: (logs) => logs.find(predicate),
|
|
119
|
+
});
|
|
120
|
+
// Use matchedLog from early exit to avoid double-searching
|
|
121
|
+
return result.matchedLog;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Generic find and parse event - consolidates the common pattern:
|
|
125
|
+
* getSearchDefaults → findLog → parse → null check
|
|
126
|
+
*
|
|
127
|
+
* Reduces boilerplate in timelock-discovery.ts and similar modules.
|
|
128
|
+
*/
|
|
129
|
+
async function findAndParseEvent(provider, filter, predicate, parser, options = {}) {
|
|
130
|
+
const log = await findLog(provider, filter, predicate, options);
|
|
131
|
+
if (!log)
|
|
132
|
+
return null;
|
|
133
|
+
return parser(log);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create a predicate that matches operationId in topics[1]
|
|
137
|
+
* Common pattern for timelock event filtering
|
|
138
|
+
*/
|
|
139
|
+
function createOperationIdPredicate(operationId, addressEquals) {
|
|
140
|
+
return (log) => (log.topics[1] ? addressEquals(log.topics[1], operationId) : false);
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=log-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-search.js","sourceRoot":"","sources":["../../src/utils/log-search.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AA+DH,gDAwHC;AAMD,0BAaC;AAQD,8CAUC;AAMD,gEAKC;AApOD,4CAAuD;AACvD,2CAAoD;AACpD,qCAAmC;AAEnC,MAAM,GAAG,GAAG,gBAAO,CAAC,GAAG,CAAC;AAmCxB;;;;;;;;;;;;;;;;;;;;GAoBG;AACI,KAAK,UAAU,kBAAkB,CACtC,QAAmC,EACnC,MAAiB,EACjB,UAA4B,EAAE;IAE9B,MAAM,EACJ,SAAS,GAAG,mCAAuB,CAAC,WAAW,EAC/C,kBAAkB,GAAG,mCAAuB,CAAC,kBAAkB,EAC/D,cAAc,EACd,SAAS,EACT,gBAAgB,GAAG,KAAK,GACzB,GAAG,OAAO,CAAC;IAEZ,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,UAA4C,CAAC;IAEjD,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IACtC,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE/B,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;QAC9C,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,SAAS;QACpC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IACnB,GAAG,CACD,6DAA6D,EAC7D,UAAU,EACV,SAAS,EACT,OAAO,EACP,WAAW,EACX,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC,CACnC,CAAC;IAEF,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC/E,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAA0C,EAAE,CAAC;IAEzD,IAAI,gBAAgB,EAAE,CAAC;QACrB,2DAA2D;QAC3D,KAAK,IAAI,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,SAAS,EAAE,GAAG,IAAI,SAAS,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,SAAS,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC;YACvD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,4BAA4B;QAC5B,KAAK,IAAI,KAAK,GAAG,SAAS,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,CAAC;YACjE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,SAAS,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAE7B,KAAK,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,MAAM,EAAE,CAAC;QACpC,IAAI,SAAS,IAAI,eAAe,IAAI,SAAS,EAAE,CAAC;YAC9C,MAAM;QACR,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,IAAA,0BAAc,EAAC,GAAG,EAAE,CACrC,QAAQ,CAAC,OAAO,CAAC;YACf,OAAO,EAAE,MAAM,CAAC,OAA6B;YAC7C,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,GAAG;SACb,CAAC,CACH,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC;QAExC,GAAG,CACD,+CAA+C,EAC/C,eAAe,GAAG,CAAC,EACnB,KAAK,EACL,GAAG,EACH,IAAI,CAAC,MAAM,EACX,OAAO,CACR,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACtB,eAAe,EAAE,CAAC;QAClB,oBAAoB,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;QAExC,2CAA2C;QAC3C,IAAI,cAAc,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,KAAK,EAAE,CAAC;gBACV,SAAS,GAAG,IAAI,CAAC;gBACjB,UAAU,GAAG,KAAK,CAAC;gBACnB,MAAM;YACR,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,IAAI,GAAG,GAAG,OAAO,IAAI,kBAAkB,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAA,iBAAK,EAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;IAEzC,GAAG,CACD,qDAAqD,EACrD,OAAO,CAAC,MAAM,EACd,eAAe,EACf,OAAO,EACP,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CACjC,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,OAAO;QACb,cAAc,EAAE,oBAAoB;QACpC,eAAe;QACf,SAAS;QACT,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,OAAO,CAC3B,QAAmC,EACnC,MAAiB,EACjB,SAAiD,EACjD,UAAoD,EAAE;IAEtD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE;QACxD,GAAG,OAAO;QACV,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;KAC/C,CAAC,CAAC;IAEH,2DAA2D;IAC3D,OAAO,MAAM,CAAC,UAAU,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,iBAAiB,CACrC,QAAmC,EACnC,MAAiB,EACjB,SAAiD,EACjD,MAA+C,EAC/C,UAAoD,EAAE;IAEtD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAChE,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CACxC,WAAmB,EACnB,aAAgD;IAEhD,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized debug loggers for the SDK
|
|
3
|
+
*
|
|
4
|
+
* Two types of loggers:
|
|
5
|
+
* 1. Regular loggers - for code that runs sequentially
|
|
6
|
+
* 2. Scoped loggers - for code that runs concurrently (auto-prefix with scope)
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { loggers } from "../utils/logger";
|
|
10
|
+
* import { withScope } from "../utils/scoped-logger";
|
|
11
|
+
*
|
|
12
|
+
* // Regular logging
|
|
13
|
+
* loggers.tracker("message %s", value);
|
|
14
|
+
*
|
|
15
|
+
* // Scoped logging (for concurrent operations)
|
|
16
|
+
* await withScope("core-gov", async () => {
|
|
17
|
+
* loggers.discovery("discovering..."); // [core-gov] discovering...
|
|
18
|
+
* });
|
|
19
|
+
*/
|
|
20
|
+
export { withScope, getCurrentScope, scopedLog } from "./scoped-logger";
|
|
21
|
+
/**
|
|
22
|
+
* Pre-configured debug loggers for common namespaces.
|
|
23
|
+
*
|
|
24
|
+
* Scoped loggers (discovery, pipeline, stage.*) automatically include
|
|
25
|
+
* the current scope prefix when used within withScope().
|
|
26
|
+
*/
|
|
27
|
+
export declare const loggers: {
|
|
28
|
+
readonly tracker: (fmt: string, ...args: unknown[]) => void;
|
|
29
|
+
readonly execution: (fmt: string, ...args: unknown[]) => void;
|
|
30
|
+
readonly election: (fmt: string, ...args: unknown[]) => void;
|
|
31
|
+
readonly rpc: (fmt: string, ...args: unknown[]) => void;
|
|
32
|
+
readonly retryables: (fmt: string, ...args: unknown[]) => void;
|
|
33
|
+
readonly discovery: (fmt: string, ...args: unknown[]) => void;
|
|
34
|
+
readonly pipeline: (fmt: string, ...args: unknown[]) => void;
|
|
35
|
+
readonly stage: {
|
|
36
|
+
readonly timelock: (fmt: string, ...args: unknown[]) => void;
|
|
37
|
+
readonly l2ToL1: (fmt: string, ...args: unknown[]) => void;
|
|
38
|
+
readonly proposalQueued: (fmt: string, ...args: unknown[]) => void;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAExE;;;;;GAKG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;CAcV,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Centralized debug loggers for the SDK
|
|
4
|
+
*
|
|
5
|
+
* Two types of loggers:
|
|
6
|
+
* 1. Regular loggers - for code that runs sequentially
|
|
7
|
+
* 2. Scoped loggers - for code that runs concurrently (auto-prefix with scope)
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { loggers } from "../utils/logger";
|
|
11
|
+
* import { withScope } from "../utils/scoped-logger";
|
|
12
|
+
*
|
|
13
|
+
* // Regular logging
|
|
14
|
+
* loggers.tracker("message %s", value);
|
|
15
|
+
*
|
|
16
|
+
* // Scoped logging (for concurrent operations)
|
|
17
|
+
* await withScope("core-gov", async () => {
|
|
18
|
+
* loggers.discovery("discovering..."); // [core-gov] discovering...
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.loggers = exports.scopedLog = exports.getCurrentScope = exports.withScope = void 0;
|
|
23
|
+
const scoped_logger_1 = require("./scoped-logger");
|
|
24
|
+
// Re-export scoped logging utilities
|
|
25
|
+
var scoped_logger_2 = require("./scoped-logger");
|
|
26
|
+
Object.defineProperty(exports, "withScope", { enumerable: true, get: function () { return scoped_logger_2.withScope; } });
|
|
27
|
+
Object.defineProperty(exports, "getCurrentScope", { enumerable: true, get: function () { return scoped_logger_2.getCurrentScope; } });
|
|
28
|
+
Object.defineProperty(exports, "scopedLog", { enumerable: true, get: function () { return scoped_logger_2.scopedLog; } });
|
|
29
|
+
/**
|
|
30
|
+
* Pre-configured debug loggers for common namespaces.
|
|
31
|
+
*
|
|
32
|
+
* Scoped loggers (discovery, pipeline, stage.*) automatically include
|
|
33
|
+
* the current scope prefix when used within withScope().
|
|
34
|
+
*/
|
|
35
|
+
exports.loggers = {
|
|
36
|
+
// Scoped loggers - auto-prefix with current scope (tracker ID, governor name, etc.)
|
|
37
|
+
tracker: (0, scoped_logger_1.scopedLog)("gov-tracker:tracker"),
|
|
38
|
+
execution: (0, scoped_logger_1.scopedLog)("gov-tracker:execution"),
|
|
39
|
+
election: (0, scoped_logger_1.scopedLog)("gov-tracker:election"),
|
|
40
|
+
rpc: (0, scoped_logger_1.scopedLog)("gov-tracker:rpc"),
|
|
41
|
+
retryables: (0, scoped_logger_1.scopedLog)("gov-tracker:retryables"),
|
|
42
|
+
discovery: (0, scoped_logger_1.scopedLog)("gov-tracker:discovery"),
|
|
43
|
+
pipeline: (0, scoped_logger_1.scopedLog)("gov-tracker:pipeline"),
|
|
44
|
+
stage: {
|
|
45
|
+
timelock: (0, scoped_logger_1.scopedLog)("gov-tracker:stage:timelock"),
|
|
46
|
+
l2ToL1: (0, scoped_logger_1.scopedLog)("gov-tracker:stage:l2-to-l1-message"),
|
|
47
|
+
proposalQueued: (0, scoped_logger_1.scopedLog)("gov-tracker:stage:proposal-queued"),
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,mDAA4C;AAE5C,qCAAqC;AACrC,iDAAwE;AAA/D,0GAAA,SAAS,OAAA;AAAE,gHAAA,eAAe,OAAA;AAAE,0GAAA,SAAS,OAAA;AAE9C;;;;;GAKG;AACU,QAAA,OAAO,GAAG;IACrB,oFAAoF;IACpF,OAAO,EAAE,IAAA,yBAAS,EAAC,qBAAqB,CAAC;IACzC,SAAS,EAAE,IAAA,yBAAS,EAAC,uBAAuB,CAAC;IAC7C,QAAQ,EAAE,IAAA,yBAAS,EAAC,sBAAsB,CAAC;IAC3C,GAAG,EAAE,IAAA,yBAAS,EAAC,iBAAiB,CAAC;IACjC,UAAU,EAAE,IAAA,yBAAS,EAAC,wBAAwB,CAAC;IAC/C,SAAS,EAAE,IAAA,yBAAS,EAAC,uBAAuB,CAAC;IAC7C,QAAQ,EAAE,IAAA,yBAAS,EAAC,sBAAsB,CAAC;IAC3C,KAAK,EAAE;QACL,QAAQ,EAAE,IAAA,yBAAS,EAAC,4BAA4B,CAAC;QACjD,MAAM,EAAE,IAAA,yBAAS,EAAC,oCAAoC,CAAC;QACvD,cAAc,EAAE,IAAA,yBAAS,EAAC,mCAAmC,CAAC;KAC/D;CACO,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operation ID utilities
|
|
3
|
+
*
|
|
4
|
+
* Uses on-chain timelock contract calls for operation ID computation
|
|
5
|
+
* to ensure consistency with the actual contract behavior.
|
|
6
|
+
*/
|
|
7
|
+
import { ethers } from "ethers";
|
|
8
|
+
import { TimelockBatchParams, TimelockParams } from "../types";
|
|
9
|
+
/**
|
|
10
|
+
* Compute operation ID using on-chain timelock contract
|
|
11
|
+
*/
|
|
12
|
+
export declare function hashOperation(timelockAddress: string, params: TimelockParams, provider: ethers.providers.Provider): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Compute batch operation ID using on-chain timelock contract
|
|
15
|
+
*/
|
|
16
|
+
export declare function hashOperationBatch(timelockAddress: string, params: TimelockBatchParams, provider: ethers.providers.Provider): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Validate that a salt produces the expected operation ID
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateSalt(timelockAddress: string, expectedOperationId: string, params: TimelockParams, provider: ethers.providers.Provider): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Validate that a salt produces the expected operation ID for a batch
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateSaltBatch(timelockAddress: string, expectedOperationId: string, params: TimelockBatchParams, provider: ethers.providers.Provider): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Try salt candidates to find matching salt for an operation
|
|
27
|
+
*
|
|
28
|
+
* Supports both single and batch operations.
|
|
29
|
+
*/
|
|
30
|
+
export declare function tryFindSalt(timelockAddress: string, expectedOperationId: string, baseParams: Omit<TimelockParams, "salt"> | Omit<TimelockBatchParams, "salt">, candidates: string[], provider: ethers.providers.Provider): Promise<string | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Validate operation parameters and return computed hash with validation status.
|
|
33
|
+
*
|
|
34
|
+
* This is useful for debugging when you want to see the computed hash
|
|
35
|
+
* and whether it matches the expected operation ID.
|
|
36
|
+
*
|
|
37
|
+
* @param timelockAddress - Address of the timelock contract
|
|
38
|
+
* @param expectedOperationId - Expected operation ID to validate against
|
|
39
|
+
* @param params - Operation parameters (single or batch)
|
|
40
|
+
* @param provider - Provider for RPC calls
|
|
41
|
+
* @returns Computed hash and whether it matches expected
|
|
42
|
+
*/
|
|
43
|
+
export declare function computeAndValidateOperationHash(timelockAddress: string, expectedOperationId: string, params: TimelockParams | TimelockBatchParams, provider: ethers.providers.Provider): Promise<{
|
|
44
|
+
computedHash: string;
|
|
45
|
+
isValid: boolean;
|
|
46
|
+
error?: string;
|
|
47
|
+
}>;
|
|
48
|
+
//# sourceMappingURL=operation-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-id.d.ts","sourceRoot":"","sources":["../../src/utils/operation-id.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/D;;GAEG;AACH,wBAAsB,aAAa,CACjC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,UAAU,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,EAC5E,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,+BAA+B,CACnD,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,MAAM,EAC3B,MAAM,EAAE,cAAc,GAAG,mBAAmB,EAC5C,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,GAClC,OAAO,CAAC;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBrE"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Operation ID utilities
|
|
4
|
+
*
|
|
5
|
+
* Uses on-chain timelock contract calls for operation ID computation
|
|
6
|
+
* to ensure consistency with the actual contract behavior.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.hashOperation = hashOperation;
|
|
10
|
+
exports.hashOperationBatch = hashOperationBatch;
|
|
11
|
+
exports.validateSalt = validateSalt;
|
|
12
|
+
exports.validateSaltBatch = validateSaltBatch;
|
|
13
|
+
exports.tryFindSalt = tryFindSalt;
|
|
14
|
+
exports.computeAndValidateOperationHash = computeAndValidateOperationHash;
|
|
15
|
+
const ethers_1 = require("ethers");
|
|
16
|
+
const rpc_utils_1 = require("./rpc-utils");
|
|
17
|
+
const abis_1 = require("../abis");
|
|
18
|
+
const chain_1 = require("./chain");
|
|
19
|
+
/**
|
|
20
|
+
* Compute operation ID using on-chain timelock contract
|
|
21
|
+
*/
|
|
22
|
+
async function hashOperation(timelockAddress, params, provider) {
|
|
23
|
+
const timelock = new ethers_1.ethers.Contract(timelockAddress, abis_1.TIMELOCK_ABI, provider);
|
|
24
|
+
const { target, value, data, predecessor, salt } = params;
|
|
25
|
+
return (0, rpc_utils_1.queryWithRetry)(() => timelock.hashOperation(target, value, data, predecessor, salt));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Compute batch operation ID using on-chain timelock contract
|
|
29
|
+
*/
|
|
30
|
+
async function hashOperationBatch(timelockAddress, params, provider) {
|
|
31
|
+
const timelock = new ethers_1.ethers.Contract(timelockAddress, abis_1.TIMELOCK_ABI, provider);
|
|
32
|
+
const { targets, values, payloads, predecessor, salt } = params;
|
|
33
|
+
return (0, rpc_utils_1.queryWithRetry)(() => timelock.hashOperationBatch(targets, values, payloads, predecessor, salt));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validate that a salt produces the expected operation ID
|
|
37
|
+
*/
|
|
38
|
+
async function validateSalt(timelockAddress, expectedOperationId, params, provider) {
|
|
39
|
+
const computed = await hashOperation(timelockAddress, params, provider);
|
|
40
|
+
return (0, chain_1.addressEquals)(computed, expectedOperationId);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validate that a salt produces the expected operation ID for a batch
|
|
44
|
+
*/
|
|
45
|
+
async function validateSaltBatch(timelockAddress, expectedOperationId, params, provider) {
|
|
46
|
+
const computed = await hashOperationBatch(timelockAddress, params, provider);
|
|
47
|
+
return (0, chain_1.addressEquals)(computed, expectedOperationId);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Try salt candidates to find matching salt for an operation
|
|
51
|
+
*
|
|
52
|
+
* Supports both single and batch operations.
|
|
53
|
+
*/
|
|
54
|
+
async function tryFindSalt(timelockAddress, expectedOperationId, baseParams, candidates, provider) {
|
|
55
|
+
const isBatch = "targets" in baseParams;
|
|
56
|
+
for (const salt of candidates) {
|
|
57
|
+
const fullParams = { ...baseParams, salt };
|
|
58
|
+
const isValid = isBatch
|
|
59
|
+
? await validateSaltBatch(timelockAddress, expectedOperationId, fullParams, provider)
|
|
60
|
+
: await validateSalt(timelockAddress, expectedOperationId, fullParams, provider);
|
|
61
|
+
if (isValid) {
|
|
62
|
+
return salt;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Validate operation parameters and return computed hash with validation status.
|
|
69
|
+
*
|
|
70
|
+
* This is useful for debugging when you want to see the computed hash
|
|
71
|
+
* and whether it matches the expected operation ID.
|
|
72
|
+
*
|
|
73
|
+
* @param timelockAddress - Address of the timelock contract
|
|
74
|
+
* @param expectedOperationId - Expected operation ID to validate against
|
|
75
|
+
* @param params - Operation parameters (single or batch)
|
|
76
|
+
* @param provider - Provider for RPC calls
|
|
77
|
+
* @returns Computed hash and whether it matches expected
|
|
78
|
+
*/
|
|
79
|
+
async function computeAndValidateOperationHash(timelockAddress, expectedOperationId, params, provider) {
|
|
80
|
+
try {
|
|
81
|
+
const isBatch = "targets" in params;
|
|
82
|
+
const computed = isBatch
|
|
83
|
+
? await hashOperationBatch(timelockAddress, params, provider)
|
|
84
|
+
: await hashOperation(timelockAddress, params, provider);
|
|
85
|
+
const isValid = (0, chain_1.addressEquals)(computed, expectedOperationId);
|
|
86
|
+
return {
|
|
87
|
+
computedHash: computed,
|
|
88
|
+
isValid,
|
|
89
|
+
error: isValid
|
|
90
|
+
? undefined
|
|
91
|
+
: `Operation hash mismatch: computed ${computed} but expected ${expectedOperationId}. This may indicate incorrect salt or operation parameters.`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
return {
|
|
96
|
+
computedHash: "",
|
|
97
|
+
isValid: false,
|
|
98
|
+
error: `Failed to compute operation hash: ${err instanceof Error ? err.message : String(err)}`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=operation-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-id.js","sourceRoot":"","sources":["../../src/utils/operation-id.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC utilities with retry logic and rate limiting
|
|
3
|
+
*/
|
|
4
|
+
import { RetryConfig } from "../types";
|
|
5
|
+
/**
|
|
6
|
+
* Delay for specified milliseconds
|
|
7
|
+
*/
|
|
8
|
+
export declare function delay(ms: number): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Error type for RPC failures
|
|
11
|
+
*/
|
|
12
|
+
export declare class RpcError extends Error {
|
|
13
|
+
readonly code?: string | undefined;
|
|
14
|
+
readonly cause?: Error | undefined;
|
|
15
|
+
constructor(message: string, code?: string | undefined, cause?: Error | undefined);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if an error is retryable
|
|
19
|
+
*/
|
|
20
|
+
export declare function isRetryableError(error: unknown): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Query with retry and exponential backoff
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const result = await queryWithRetry(() => provider.getBlockNumber());
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function queryWithRetry<T>(queryFn: () => Promise<T>, config?: RetryConfig): Promise<T>;
|
|
30
|
+
//# sourceMappingURL=rpc-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-utils.d.ts","sourceRoot":"","sources":["../../src/utils/rpc-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAMvC;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAGf,IAAI,CAAC,EAAE,MAAM;aACb,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,KAAK,CAAC,EAAE,KAAK,YAAA;CAKhC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAyCxD;AAED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,MAAM,GAAE,WAAkC,GACzC,OAAO,CAAC,CAAC,CAAC,CAsCZ"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RPC utilities with retry logic and rate limiting
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RpcError = void 0;
|
|
7
|
+
exports.delay = delay;
|
|
8
|
+
exports.isRetryableError = isRetryableError;
|
|
9
|
+
exports.queryWithRetry = queryWithRetry;
|
|
10
|
+
const constants_1 = require("../constants");
|
|
11
|
+
const logger_1 = require("./logger");
|
|
12
|
+
const log = logger_1.loggers.rpc;
|
|
13
|
+
/**
|
|
14
|
+
* Delay for specified milliseconds
|
|
15
|
+
*/
|
|
16
|
+
function delay(ms) {
|
|
17
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error type for RPC failures
|
|
21
|
+
*/
|
|
22
|
+
class RpcError extends Error {
|
|
23
|
+
constructor(message, code, cause) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.code = code;
|
|
26
|
+
this.cause = cause;
|
|
27
|
+
this.name = "RpcError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.RpcError = RpcError;
|
|
31
|
+
/**
|
|
32
|
+
* Check if an error is retryable
|
|
33
|
+
*/
|
|
34
|
+
function isRetryableError(error) {
|
|
35
|
+
if (error instanceof Error) {
|
|
36
|
+
const message = error.message.toLowerCase();
|
|
37
|
+
// Rate limiting errors
|
|
38
|
+
if (message.includes("rate limit") ||
|
|
39
|
+
message.includes("too many requests") ||
|
|
40
|
+
message.includes("429")) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// Server errors
|
|
44
|
+
if (message.includes("server error") ||
|
|
45
|
+
message.includes("502") ||
|
|
46
|
+
message.includes("503") ||
|
|
47
|
+
message.includes("504")) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
// Connection errors
|
|
51
|
+
if (message.includes("econnreset") ||
|
|
52
|
+
message.includes("econnrefused") ||
|
|
53
|
+
message.includes("etimedout") ||
|
|
54
|
+
message.includes("network error") ||
|
|
55
|
+
message.includes("timeout")) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// Provider-specific errors
|
|
59
|
+
if (message.includes("missing response") || message.includes("request failed")) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Query with retry and exponential backoff
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const result = await queryWithRetry(() => provider.getBlockNumber());
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
async function queryWithRetry(queryFn, config = constants_1.DEFAULT_RETRY_CONFIG) {
|
|
74
|
+
let retryDelay = config.initialDelay;
|
|
75
|
+
let lastError;
|
|
76
|
+
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
77
|
+
try {
|
|
78
|
+
return await queryFn();
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
82
|
+
// Don't retry non-retryable errors
|
|
83
|
+
if (!isRetryableError(error)) {
|
|
84
|
+
const code = error?.code?.toString();
|
|
85
|
+
log("query failed (non-retryable): %s", lastError.message);
|
|
86
|
+
throw new RpcError(`RPC query failed: ${lastError.message}`, code, lastError);
|
|
87
|
+
}
|
|
88
|
+
// Don't retry on last attempt
|
|
89
|
+
if (attempt < config.maxRetries) {
|
|
90
|
+
log("retry attempt %d/%d after %dms: %s", attempt + 1, config.maxRetries, retryDelay, lastError.message);
|
|
91
|
+
await delay(retryDelay);
|
|
92
|
+
retryDelay = Math.min(retryDelay * config.backoffMultiplier, config.maxDelay);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
log("all %d retries exhausted: %s", config.maxRetries + 1, lastError?.message);
|
|
97
|
+
throw new RpcError(`All ${config.maxRetries + 1} retry attempts failed: ${lastError?.message ?? "Unknown error"}`, undefined, lastError);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=rpc-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-utils.js","sourceRoot":"","sources":["../../src/utils/rpc-utils.ts"],"names":[],"mappings":"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"}
|