@gzeoneth/gov-tracker 0.3.0 → 0.4.0-beta.18db0de
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 +0 -1
- package/dist/calldata/decoder.d.ts.map +1 -1
- package/dist/calldata/decoder.js +10 -56
- package/dist/calldata/decoder.js.map +1 -1
- package/dist/calldata/parameter-decoder.d.ts +21 -1
- package/dist/calldata/parameter-decoder.d.ts.map +1 -1
- package/dist/calldata/parameter-decoder.js +30 -0
- package/dist/calldata/parameter-decoder.js.map +1 -1
- package/dist/cli/lib/cli.d.ts.map +1 -1
- package/dist/cli/lib/cli.js +30 -42
- package/dist/cli/lib/cli.js.map +1 -1
- package/dist/cli/tui/utils/index.d.ts +1 -1
- package/dist/cli/tui/utils/index.d.ts.map +1 -1
- package/dist/cli/tui/utils/index.js +1 -2
- package/dist/cli/tui/utils/index.js.map +1 -1
- package/dist/cli/tui/utils/stage-formatter.d.ts +1 -1
- package/dist/cli/tui/utils/stage-formatter.d.ts.map +1 -1
- package/dist/cli/tui/utils/stage-formatter.js +1 -2
- package/dist/cli/tui/utils/stage-formatter.js.map +1 -1
- package/dist/cli/tui/views/ElectionView.d.ts.map +1 -1
- package/dist/cli/tui/views/ElectionView.js +3 -3
- package/dist/cli/tui/views/ElectionView.js.map +1 -1
- package/dist/cli/tui/views/StageView.d.ts.map +1 -1
- package/dist/cli/tui/views/StageView.js +1 -1
- package/dist/cli/tui/views/StageView.js.map +1 -1
- package/dist/data/bundled-cache.json +21513 -22619
- package/dist/discovery/governor-discovery.d.ts.map +1 -1
- package/dist/discovery/governor-discovery.js +43 -48
- package/dist/discovery/governor-discovery.js.map +1 -1
- package/dist/discovery/security-council.d.ts +15 -0
- package/dist/discovery/security-council.d.ts.map +1 -1
- package/dist/discovery/security-council.js +42 -19
- package/dist/discovery/security-council.js.map +1 -1
- package/dist/discovery/timelock-discovery.d.ts.map +1 -1
- package/dist/discovery/timelock-discovery.js +34 -54
- package/dist/discovery/timelock-discovery.js.map +1 -1
- package/dist/election/details.d.ts.map +1 -1
- package/dist/election/details.js +28 -30
- package/dist/election/details.js.map +1 -1
- package/dist/election/index.d.ts +3 -6
- package/dist/election/index.d.ts.map +1 -1
- package/dist/election/index.js +7 -14
- package/dist/election/index.js.map +1 -1
- package/dist/election/params.d.ts +8 -1
- package/dist/election/params.d.ts.map +1 -1
- package/dist/election/params.js +45 -1
- package/dist/election/params.js.map +1 -1
- package/dist/election/participants.d.ts.map +1 -1
- package/dist/election/participants.js +21 -24
- package/dist/election/participants.js.map +1 -1
- package/dist/election/proposal-ids.d.ts +10 -0
- package/dist/election/proposal-ids.d.ts.map +1 -1
- package/dist/election/proposal-ids.js +45 -5
- package/dist/election/proposal-ids.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -8
- package/dist/index.js.map +1 -1
- package/dist/simulation/simulation-data.js +2 -2
- package/dist/simulation/simulation-data.js.map +1 -1
- package/dist/stages/builder.js +1 -1
- package/dist/stages/builder.js.map +1 -1
- package/dist/stages/l2-to-l1-message.d.ts.map +1 -1
- package/dist/stages/l2-to-l1-message.js +2 -8
- package/dist/stages/l2-to-l1-message.js.map +1 -1
- package/dist/stages/proposal-queued.d.ts.map +1 -1
- package/dist/stages/proposal-queued.js +4 -1
- package/dist/stages/proposal-queued.js.map +1 -1
- package/dist/stages/retryables.d.ts +4 -3
- package/dist/stages/retryables.d.ts.map +1 -1
- package/dist/stages/retryables.js +25 -48
- package/dist/stages/retryables.js.map +1 -1
- package/dist/stages/timelock.d.ts +1 -0
- package/dist/stages/timelock.d.ts.map +1 -1
- package/dist/stages/timelock.js +44 -58
- package/dist/stages/timelock.js.map +1 -1
- package/dist/stages/utils.d.ts +39 -5
- package/dist/stages/utils.d.ts.map +1 -1
- package/dist/stages/utils.js +102 -40
- package/dist/stages/utils.js.map +1 -1
- package/dist/tracker/discovery.d.ts.map +1 -1
- package/dist/tracker/discovery.js +4 -9
- package/dist/tracker/discovery.js.map +1 -1
- package/dist/tracker/pipeline.d.ts +25 -6
- package/dist/tracker/pipeline.d.ts.map +1 -1
- package/dist/tracker/pipeline.js +428 -211
- package/dist/tracker/pipeline.js.map +1 -1
- package/dist/tracker/query.d.ts +20 -0
- package/dist/tracker/query.d.ts.map +1 -1
- package/dist/tracker/query.js +86 -1
- package/dist/tracker/query.js.map +1 -1
- package/dist/tracker/stage-runner.d.ts +62 -0
- package/dist/tracker/stage-runner.d.ts.map +1 -0
- package/dist/tracker/stage-runner.js +80 -0
- package/dist/tracker/stage-runner.js.map +1 -0
- package/dist/tracker/state.d.ts +64 -0
- package/dist/tracker/state.d.ts.map +1 -1
- package/dist/tracker/state.js +191 -12
- package/dist/tracker/state.js.map +1 -1
- package/dist/tracker.d.ts +30 -1
- package/dist/tracker.d.ts.map +1 -1
- package/dist/tracker.js +220 -167
- package/dist/tracker.js.map +1 -1
- package/dist/types/core.d.ts +3 -2
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/core.js +3 -2
- package/dist/types/core.js.map +1 -1
- package/dist/types/tracking.d.ts +11 -0
- package/dist/types/tracking.d.ts.map +1 -1
- package/dist/utils/log-filters.d.ts.map +1 -1
- package/dist/utils/log-filters.js +4 -8
- package/dist/utils/log-filters.js.map +1 -1
- package/dist/utils/timing.d.ts +10 -3
- package/dist/utils/timing.d.ts.map +1 -1
- package/dist/utils/timing.js +39 -13
- package/dist/utils/timing.js.map +1 -1
- package/package.json +7 -6
- package/dist/election/prepare.d.ts +0 -10
- package/dist/election/prepare.d.ts.map +0 -1
- package/dist/election/prepare.js +0 -52
- package/dist/election/prepare.js.map +0 -1
- package/dist/election/tracking.d.ts +0 -28
- package/dist/election/tracking.d.ts.map +0 -1
- package/dist/election/tracking.js +0 -412
- package/dist/election/tracking.js.map +0 -1
package/dist/tracker/pipeline.js
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Pipeline Stage
|
|
3
|
+
* Pipeline Stage Tracking
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* Each
|
|
5
|
+
* Declarative pipelines for tracking governance proposals and elections.
|
|
6
|
+
* Each stage is a config object with type and track function.
|
|
7
|
+
* The stage runner handles caching automatically.
|
|
8
|
+
*
|
|
9
|
+
* Three tracking paths:
|
|
10
|
+
* - Governor: PROPOSAL_CREATED → VOTING_ACTIVE → PROPOSAL_QUEUED → timelock
|
|
11
|
+
* - Timelock: L2_TIMELOCK → L2_TO_L1_MESSAGE → L1_TIMELOCK → RETRYABLE_EXECUTED
|
|
12
|
+
* - Election: CREATE_ELECTION → NOMINEE_ELECTION → NOMINEE_VETTING → MEMBER_ELECTION → timelock
|
|
7
13
|
*/
|
|
8
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.getElectionContext = getElectionContext;
|
|
16
|
+
exports.proposalStateToStageStatus = proposalStateToStageStatus;
|
|
9
17
|
exports.trackGovernorPipeline = trackGovernorPipeline;
|
|
10
18
|
exports.trackTimelockPipeline = trackTimelockPipeline;
|
|
19
|
+
exports.trackElectionPipeline = trackElectionPipeline;
|
|
20
|
+
const ethers_1 = require("ethers");
|
|
11
21
|
const logger_1 = require("../utils/logger");
|
|
12
22
|
const state_1 = require("./state");
|
|
23
|
+
const stage_runner_1 = require("./stage-runner");
|
|
13
24
|
const utils_1 = require("../stages/utils");
|
|
14
25
|
const proposal_created_1 = require("../stages/proposal-created");
|
|
15
26
|
const voting_1 = require("../stages/voting");
|
|
@@ -20,171 +31,148 @@ const l2_to_l1_message_1 = require("../stages/l2-to-l1-message");
|
|
|
20
31
|
const retryables_1 = require("../stages/retryables");
|
|
21
32
|
const constants_1 = require("../constants");
|
|
22
33
|
const timing_2 = require("../utils/timing");
|
|
23
|
-
|
|
34
|
+
const builder_1 = require("../stages/builder");
|
|
35
|
+
const rpc_utils_1 = require("../utils/rpc-utils");
|
|
36
|
+
const multicall_1 = require("../utils/multicall");
|
|
37
|
+
const abis_1 = require("../abis");
|
|
38
|
+
const contracts_1 = require("../election/contracts");
|
|
39
|
+
const proposal_ids_1 = require("../election/proposal-ids");
|
|
40
|
+
const timelock_discovery_1 = require("../discovery/timelock-discovery");
|
|
41
|
+
const governor_discovery_1 = require("../discovery/governor-discovery");
|
|
42
|
+
const log_search_1 = require("../utils/log-search");
|
|
24
43
|
const { pipeline: log, tracker: logTracker } = logger_1.loggers;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
type,
|
|
33
|
-
status,
|
|
34
|
-
chain: L1_STAGES.has(type) ? "ethereum" : "arb1",
|
|
35
|
-
chainId: L1_STAGES.has(type) ? 1 : 42161,
|
|
36
|
-
transactions: [],
|
|
37
|
-
data: { reason },
|
|
38
|
-
});
|
|
39
|
-
// Helper: track with cache check
|
|
40
|
-
async function withCache(state, stageType, key, onCached, onTrack) {
|
|
41
|
-
const cached = (0, state_1.getCompletedStage)(state, stageType);
|
|
42
|
-
if (cached) {
|
|
43
|
-
log("%s: using cached stage", stageType);
|
|
44
|
-
return { state: await (0, state_1.addStage)(state, cached), [key]: onCached(cached) };
|
|
45
|
-
}
|
|
46
|
-
return onTrack();
|
|
44
|
+
/** Guard for election stages - returns election index and nominee proposal ID if available */
|
|
45
|
+
function getElectionContext(state) {
|
|
46
|
+
const electionIndex = (0, state_1.getElectionIndex)(state);
|
|
47
|
+
const nomineeProposalId = (0, state_1.getNomineeProposalId)(state);
|
|
48
|
+
return electionIndex !== undefined && nomineeProposalId
|
|
49
|
+
? { electionIndex, nomineeProposalId }
|
|
50
|
+
: null;
|
|
47
51
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return { state: await (0, state_1.addStage)(state, stage), [key]: result };
|
|
52
|
+
/** Map proposal state string to stage status */
|
|
53
|
+
function proposalStateToStageStatus(proposalState) {
|
|
54
|
+
if (proposalState === "Active" || proposalState === "Pending") {
|
|
55
|
+
return { status: "PENDING", complete: false };
|
|
53
56
|
}
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
if (proposalState === "Defeated" || proposalState === "Canceled") {
|
|
58
|
+
return { status: "FAILED", complete: false };
|
|
56
59
|
}
|
|
60
|
+
return { status: "COMPLETED", complete: true };
|
|
57
61
|
}
|
|
58
|
-
//
|
|
59
|
-
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// Governor Stage Trackers
|
|
64
|
+
// ============================================================================
|
|
65
|
+
async function trackProposalCreatedStage(state) {
|
|
60
66
|
const governorAddress = (0, state_1.getGovernorAddress)(state);
|
|
61
67
|
const proposalId = (0, state_1.getProposalId)(state);
|
|
62
68
|
if (!governorAddress || !proposalId)
|
|
63
|
-
return { state,
|
|
69
|
+
return { state, continue: false };
|
|
64
70
|
if ((0, state_1.getIsElection)(state))
|
|
65
|
-
return { state,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
creationTxHash,
|
|
72
|
-
chunkSize: state.chunkingConfig.l2ChunkSize,
|
|
73
|
-
});
|
|
74
|
-
return { stage: r.stage, result: r.proposalData !== null };
|
|
75
|
-
});
|
|
71
|
+
return { state, continue: false };
|
|
72
|
+
log("PROPOSAL_CREATED: tracking");
|
|
73
|
+
const creationTxHash = state.input.type === "governor" ? state.input.creationTxHash : undefined;
|
|
74
|
+
const result = await (0, proposal_created_1.trackProposalCreated)(governorAddress, proposalId, state.providers.l2, {
|
|
75
|
+
creationTxHash,
|
|
76
|
+
chunkSize: state.chunkingConfig.l2ChunkSize,
|
|
76
77
|
});
|
|
78
|
+
return {
|
|
79
|
+
state: await (0, state_1.addStage)(state, result.stage),
|
|
80
|
+
continue: result.proposalData !== null,
|
|
81
|
+
};
|
|
77
82
|
}
|
|
78
|
-
async function
|
|
83
|
+
async function trackVotingStage_(state) {
|
|
79
84
|
const governorAddress = (0, state_1.getGovernorAddress)(state);
|
|
80
85
|
const proposalId = (0, state_1.getProposalId)(state);
|
|
81
86
|
const proposalData = (0, state_1.getProposalData)(state);
|
|
82
87
|
if (!governorAddress || !proposalId || !proposalData)
|
|
83
|
-
return { state,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
88
|
+
return { state, continue: false };
|
|
89
|
+
log("VOTING_ACTIVE: tracking");
|
|
90
|
+
const result = await (0, voting_1.trackVotingStage)(governorAddress, proposalId, proposalData, state.providers.l2);
|
|
91
|
+
return {
|
|
92
|
+
state: await (0, state_1.addStage)(state, result.stage),
|
|
93
|
+
continue: result.stage.status === "COMPLETED",
|
|
94
|
+
};
|
|
91
95
|
}
|
|
92
|
-
async function
|
|
96
|
+
async function trackProposalQueuedStage(state) {
|
|
93
97
|
const governorAddress = (0, state_1.getGovernorAddress)(state);
|
|
94
98
|
const proposalId = (0, state_1.getProposalId)(state);
|
|
95
99
|
const proposalData = (0, state_1.getProposalData)(state);
|
|
96
100
|
if (!governorAddress || !proposalId)
|
|
97
|
-
return { state,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
votingEndBlock = await (0, timing_1.getFirstL2BlockForL1Block)(state.providers.l2, votingDeadlineL1, {
|
|
110
|
-
minL2Block: creationBlock,
|
|
111
|
-
maxL2Block,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
const r = await (0, proposal_queued_1.trackProposalQueued)(governorAddress, proposalId, state.providers.l2, proposalData?.creationBlock ?? 0, { votingEndBlock, chunkSize: state.chunkingConfig.l2ChunkSize });
|
|
115
|
-
let stage = r.stage;
|
|
116
|
-
if (stage.type === "PROPOSAL_QUEUED" && stage.status === "READY" && proposalData) {
|
|
117
|
-
// Enrich stage data with proposal info for READY state
|
|
118
|
-
stage = {
|
|
119
|
-
...stage,
|
|
120
|
-
data: {
|
|
121
|
-
...stage.data,
|
|
122
|
-
targets: proposalData.targets,
|
|
123
|
-
values: Array.from(proposalData.values).map((v) => v.toString()),
|
|
124
|
-
calldatas: proposalData.calldatas,
|
|
125
|
-
description: proposalData.description,
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
return { stage, result: r.operationId !== null && r.timelockAddress !== null };
|
|
101
|
+
return { state, continue: false };
|
|
102
|
+
log("PROPOSAL_QUEUED: tracking");
|
|
103
|
+
// Convert L1 voting deadline to L2 block for searching
|
|
104
|
+
const votingDeadlineL1 = (0, state_1.getVotingEndBlock)(state);
|
|
105
|
+
let votingEndBlock;
|
|
106
|
+
if (votingDeadlineL1) {
|
|
107
|
+
const creationBlock = proposalData?.creationBlock ?? 0;
|
|
108
|
+
const { blockNumber: currentL2Block } = await (0, timing_2.getCurrentBlockInfo)(state.providers.l2);
|
|
109
|
+
const maxL2Block = Math.min(creationBlock + 7000000, currentL2Block);
|
|
110
|
+
votingEndBlock = await (0, timing_1.getFirstL2BlockForL1Block)(state.providers.l2, votingDeadlineL1, {
|
|
111
|
+
minL2Block: creationBlock,
|
|
112
|
+
maxL2Block,
|
|
130
113
|
});
|
|
131
|
-
}
|
|
114
|
+
}
|
|
115
|
+
const result = await (0, proposal_queued_1.trackProposalQueued)(governorAddress, proposalId, state.providers.l2, proposalData?.creationBlock ?? 0, { votingEndBlock, chunkSize: state.chunkingConfig.l2ChunkSize });
|
|
116
|
+
let stage = result.stage;
|
|
117
|
+
// Enrich stage data with proposal info for READY state
|
|
118
|
+
if (stage.type === "PROPOSAL_QUEUED" && stage.status === "READY" && proposalData) {
|
|
119
|
+
stage = {
|
|
120
|
+
...stage,
|
|
121
|
+
data: {
|
|
122
|
+
...stage.data,
|
|
123
|
+
targets: proposalData.targets,
|
|
124
|
+
values: Array.from(proposalData.values).map((v) => v.toString()),
|
|
125
|
+
calldatas: proposalData.calldatas,
|
|
126
|
+
description: proposalData.description,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
state: await (0, state_1.addStage)(state, stage),
|
|
132
|
+
continue: result.operationId !== null && result.timelockAddress !== null,
|
|
133
|
+
};
|
|
132
134
|
}
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
+
// ============================================================================
|
|
136
|
+
// Timelock Stage Trackers
|
|
137
|
+
// ============================================================================
|
|
138
|
+
async function trackL2TimelockStage(state) {
|
|
135
139
|
const timelockAddress = (0, state_1.getTimelockAddress)(state);
|
|
136
140
|
const operationId = (0, state_1.getOperationId)(state);
|
|
137
|
-
|
|
141
|
+
const firstCallScheduledData = (0, state_1.getFirstCallScheduledData)(state);
|
|
138
142
|
if (!timelockAddress || !operationId)
|
|
139
|
-
return { state,
|
|
140
|
-
// Check for completed cached stage first (zero-RPC resume path)
|
|
141
|
-
const cached = (0, state_1.getCompletedStage)(state, "L2_TIMELOCK");
|
|
142
|
-
if (cached) {
|
|
143
|
-
log("L2_TIMELOCK: using cached stage");
|
|
144
|
-
return { state: await (0, state_1.addStage)(state, cached), executed: cached.status === "COMPLETED" };
|
|
145
|
-
}
|
|
143
|
+
return { state, continue: false };
|
|
146
144
|
// Fresh tracking requires callScheduledData
|
|
147
|
-
const firstCallScheduledData = (0, state_1.getFirstCallScheduledData)(state);
|
|
148
145
|
if (!firstCallScheduledData) {
|
|
149
146
|
log("L2_TIMELOCK: missing callScheduledData for fresh tracking");
|
|
150
|
-
return { state,
|
|
147
|
+
return { state, continue: false };
|
|
151
148
|
}
|
|
152
149
|
log("L2_TIMELOCK: tracking");
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
});
|
|
159
|
-
return { stage: r.stage, result: r.executionTxHash !== null };
|
|
150
|
+
const result = await (0, timelock_1.trackL2Timelock)(timelockAddress, operationId, state.providers.l2, (0, state_1.getQueueBlockNumber)(state) ?? 0, firstCallScheduledData, {
|
|
151
|
+
cachedExecutionTxHash: (0, state_1.getL2ExecutionTxHash)(state),
|
|
152
|
+
allStages: state.stages,
|
|
153
|
+
proposalType: (0, state_1.getProposalType)(state),
|
|
154
|
+
chunkSize: state.chunkingConfig.l2ChunkSize,
|
|
160
155
|
});
|
|
156
|
+
return {
|
|
157
|
+
state: await (0, state_1.addStage)(state, result.stage),
|
|
158
|
+
continue: result.executionTxHash !== null,
|
|
159
|
+
};
|
|
161
160
|
}
|
|
162
|
-
// L2→L1 Message Stage (5) - Unified
|
|
163
161
|
const L1_ROUNDTRIP_STAGES = ["L2_TO_L1_MESSAGE", "L1_TIMELOCK", "RETRYABLE_EXECUTED"];
|
|
164
|
-
async function
|
|
165
|
-
let s = state;
|
|
166
|
-
for (const type of L1_ROUNDTRIP_STAGES)
|
|
167
|
-
s = await (0, state_1.addStage)(s, placeholder(type, "SKIPPED", "L2-only path"));
|
|
168
|
-
return s;
|
|
169
|
-
}
|
|
170
|
-
async function pipelineTrackL2ToL1Message(state) {
|
|
162
|
+
async function trackL2ToL1MessageStage(state) {
|
|
171
163
|
const l2ExecutionTxHash = (0, state_1.getL2ExecutionTxHash)(state);
|
|
172
164
|
const addressForPath = (0, state_1.getGovernorAddress)(state) ?? (0, state_1.getTimelockAddress)(state);
|
|
173
165
|
const needsL1 = addressForPath ? (0, utils_1.isConstitutional)(addressForPath) : true;
|
|
166
|
+
// L2-only path: skip all L1 stages
|
|
174
167
|
if (!needsL1) {
|
|
175
168
|
log("L2_TO_L1_MESSAGE: L2-only path, skipping L1 stages");
|
|
176
|
-
|
|
169
|
+
const newState = await (0, stage_runner_1.addPlaceholders)(state, L1_ROUNDTRIP_STAGES, "SKIPPED", "L2-only path");
|
|
170
|
+
return { state: newState, continue: false };
|
|
177
171
|
}
|
|
178
172
|
if (!l2ExecutionTxHash)
|
|
179
|
-
return { state,
|
|
180
|
-
// Check completed cache
|
|
181
|
-
const cached = (0, state_1.getCompletedStage)(state, "L2_TO_L1_MESSAGE");
|
|
182
|
-
if (cached) {
|
|
183
|
-
log("L2_TO_L1_MESSAGE: using cached stage");
|
|
184
|
-
return { state: await (0, state_1.addStage)(state, cached), executed: true, needsL1: true };
|
|
185
|
-
}
|
|
173
|
+
return { state, continue: false };
|
|
186
174
|
// Fast-path for pending (still in challenge period)
|
|
187
|
-
const pending = (0,
|
|
175
|
+
const pending = (0, stage_runner_1.getCachedStage)(state, "L2_TO_L1_MESSAGE");
|
|
188
176
|
if (pending?.type === "L2_TO_L1_MESSAGE" && pending.status === "PENDING") {
|
|
189
177
|
const firstExec = pending.data.firstExecutableBlock;
|
|
190
178
|
if (firstExec) {
|
|
@@ -200,112 +188,341 @@ async function pipelineTrackL2ToL1Message(state) {
|
|
|
200
188
|
delaySeconds: remainingSeconds,
|
|
201
189
|
},
|
|
202
190
|
};
|
|
203
|
-
return { state: await (0, state_1.addStage)(state, updated),
|
|
191
|
+
return { state: await (0, state_1.addStage)(state, updated), continue: false };
|
|
204
192
|
}
|
|
205
193
|
}
|
|
206
194
|
}
|
|
207
195
|
// Full tracking
|
|
208
196
|
log("L2_TO_L1_MESSAGE: tracking");
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
215
|
-
return { state: newState, executed, needsL1: true };
|
|
197
|
+
const result = await (0, l2_to_l1_message_1.trackL2ToL1Message)(l2ExecutionTxHash, state.providers.l2, state.providers.l1, { chunkSize: state.chunkingConfig.l1ChunkSize });
|
|
198
|
+
return {
|
|
199
|
+
state: await (0, state_1.addStage)(state, result.stage),
|
|
200
|
+
continue: result.isExecuted,
|
|
201
|
+
};
|
|
216
202
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
fromBlock: (0, state_1.getFirstExecutableBlock)(state),
|
|
225
|
-
allStages: state.stages,
|
|
226
|
-
chunkSize: state.chunkingConfig.l1ChunkSize,
|
|
227
|
-
});
|
|
228
|
-
return { stage: r.stage, result: r.executionTxHash !== null };
|
|
229
|
-
});
|
|
203
|
+
async function trackL1TimelockStage(state) {
|
|
204
|
+
log("L1_TIMELOCK: tracking");
|
|
205
|
+
const result = await (0, timelock_1.trackL1Timelock)(state.providers.l1, {
|
|
206
|
+
outboxExecutionTx: (0, state_1.getOutboxExecutionTx)(state),
|
|
207
|
+
fromBlock: (0, state_1.getFirstExecutableBlock)(state),
|
|
208
|
+
allStages: state.stages,
|
|
209
|
+
chunkSize: state.chunkingConfig.l1ChunkSize,
|
|
230
210
|
});
|
|
211
|
+
return {
|
|
212
|
+
state: await (0, state_1.addStage)(state, result.stage),
|
|
213
|
+
continue: result.executionTxHash !== null,
|
|
214
|
+
};
|
|
231
215
|
}
|
|
232
|
-
|
|
233
|
-
async function pipelineTrackRetryables(state) {
|
|
216
|
+
async function trackRetryablesStage(state) {
|
|
234
217
|
const l1ExecutionTxHash = (0, state_1.getL1ExecutionTxHash)(state);
|
|
235
218
|
if (!l1ExecutionTxHash)
|
|
236
|
-
return { state,
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
l2Provider: state.providers.l2,
|
|
242
|
-
novaProvider: state.providers.nova,
|
|
243
|
-
});
|
|
244
|
-
return { stage: r.stage, result: r.stage.status === "COMPLETED" };
|
|
245
|
-
});
|
|
219
|
+
return { state, continue: false };
|
|
220
|
+
log("RETRYABLE_EXECUTED: tracking");
|
|
221
|
+
const result = await (0, retryables_1.trackRetryables)(l1ExecutionTxHash, state.providers.l1, {
|
|
222
|
+
l2Provider: state.providers.l2,
|
|
223
|
+
novaProvider: state.providers.nova,
|
|
246
224
|
});
|
|
225
|
+
return {
|
|
226
|
+
state: await (0, state_1.addStage)(state, result.stage),
|
|
227
|
+
continue: result.stage.status === "COMPLETED",
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// ============================================================================
|
|
231
|
+
// Election Stage Trackers
|
|
232
|
+
// ============================================================================
|
|
233
|
+
async function findElectionExecuteTxHash(proposalId, governorAddress, provider, l2ChunkSize = 100000) {
|
|
234
|
+
const governor = (0, contracts_1.getNomineeGovernor)(governorAddress, provider);
|
|
235
|
+
const topic = abis_1.proposalExecutedInterface.getEventTopic("ProposalExecuted");
|
|
236
|
+
const snapshotL1 = await (0, rpc_utils_1.queryWithRetry)(() => governor.proposalSnapshot(proposalId));
|
|
237
|
+
const snapshotL2 = await (0, timing_1.getFirstL2BlockForL1Block)(provider, snapshotL1.toNumber());
|
|
238
|
+
if (!snapshotL2)
|
|
239
|
+
return null;
|
|
240
|
+
const currentBlock = await (0, rpc_utils_1.queryWithRetry)(() => provider.getBlockNumber());
|
|
241
|
+
const matchingLog = await (0, log_search_1.findLog)(provider, { address: governorAddress, topics: [topic], fromBlock: snapshotL2, toBlock: currentBlock }, (eventLog) => {
|
|
242
|
+
try {
|
|
243
|
+
const parsed = abis_1.proposalExecutedInterface.parseLog(eventLog);
|
|
244
|
+
return parsed.args.proposalId.toString() === proposalId;
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}, { chunkSize: l2ChunkSize });
|
|
250
|
+
return matchingLog
|
|
251
|
+
? { txHash: matchingLog.transactionHash, blockNumber: matchingLog.blockNumber }
|
|
252
|
+
: null;
|
|
247
253
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
+
async function trackCreateElectionStage(state) {
|
|
255
|
+
const electionIndex = (0, state_1.getElectionIndex)(state);
|
|
256
|
+
if (electionIndex === undefined)
|
|
257
|
+
return { state, continue: false };
|
|
258
|
+
log("CREATE_ELECTION: tracking election %d", electionIndex);
|
|
259
|
+
const nomineeGovernorAddress = constants_1.ADDRESSES.ELECTION_NOMINEE_GOVERNOR;
|
|
260
|
+
const nomineeGovernor = (0, contracts_1.getNomineeGovernor)(nomineeGovernorAddress, state.providers.l2);
|
|
261
|
+
const cohort = (await (0, rpc_utils_1.queryWithRetry)(() => nomineeGovernor.electionIndexToCohort(electionIndex)));
|
|
262
|
+
const nomineeProposalId = await (0, proposal_ids_1.getElectionProposalId)(electionIndex, state.providers.l2, nomineeGovernorAddress);
|
|
263
|
+
if (!nomineeProposalId) {
|
|
264
|
+
const notStartedStage = new builder_1.StageBuilder("CREATE_ELECTION", "arb1")
|
|
265
|
+
.status("NOT_STARTED")
|
|
266
|
+
.data({ electionIndex, cohort, startTimestamp: 0, reason: "Election not yet created" })
|
|
267
|
+
.build();
|
|
268
|
+
return { state: await (0, state_1.addStage)(state, notStartedStage), continue: false };
|
|
269
|
+
}
|
|
270
|
+
const stageBuilder = new builder_1.StageBuilder("CREATE_ELECTION", "arb1")
|
|
271
|
+
.status("COMPLETED")
|
|
272
|
+
.data({ electionIndex, cohort, startTimestamp: 0, nomineeProposalId });
|
|
273
|
+
// Find creation tx hash for the election proposal
|
|
274
|
+
try {
|
|
275
|
+
const creationEvent = await (0, governor_discovery_1.findProposalCreatedEvent)(nomineeGovernorAddress, nomineeProposalId, state.providers.l2);
|
|
276
|
+
if (creationEvent) {
|
|
277
|
+
stageBuilder.tx(creationEvent.creationTxHash, creationEvent.creationBlock, "arb1", 42161);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
// Creation tx discovery failed silently - stage still valid
|
|
282
|
+
}
|
|
283
|
+
return { state: await (0, state_1.addStage)(state, stageBuilder.build()), continue: true };
|
|
254
284
|
}
|
|
255
|
-
|
|
285
|
+
async function trackNomineeElectionStage(state) {
|
|
286
|
+
const ctx = getElectionContext(state);
|
|
287
|
+
if (!ctx)
|
|
288
|
+
return { state, continue: false };
|
|
289
|
+
log("NOMINEE_ELECTION: tracking");
|
|
290
|
+
const nomineeGovernorAddress = constants_1.ADDRESSES.ELECTION_NOMINEE_GOVERNOR;
|
|
291
|
+
const nomineeResults = await (0, multicall_1.multicall)(state.providers.l2, [
|
|
292
|
+
(0, multicall_1.buildCallInput)(nomineeGovernorAddress, abis_1.nomineeElectionGovernorInterface, "state", [
|
|
293
|
+
ctx.nomineeProposalId,
|
|
294
|
+
]),
|
|
295
|
+
(0, multicall_1.buildCallInput)(nomineeGovernorAddress, abis_1.nomineeElectionGovernorInterface, "compliantNomineeCount", [ctx.nomineeProposalId]),
|
|
296
|
+
]);
|
|
297
|
+
const nomineeState = nomineeResults[0];
|
|
298
|
+
const nomineeProposalState = (0, constants_1.proposalStateToString)(nomineeState);
|
|
299
|
+
const compliantNomineeCount = (nomineeResults[1] ?? ethers_1.BigNumber.from(0)).toNumber();
|
|
300
|
+
const { status, complete } = proposalStateToStageStatus(nomineeProposalState);
|
|
301
|
+
const stageBuilder = new builder_1.StageBuilder("NOMINEE_ELECTION", "arb1").status(status).data({
|
|
302
|
+
nomineeProposalId: ctx.nomineeProposalId,
|
|
303
|
+
proposalState: nomineeProposalState,
|
|
304
|
+
contenderCount: 0,
|
|
305
|
+
compliantNomineeCount,
|
|
306
|
+
targetNomineeCount: constants_1.TIMING.SECURITY_COUNCIL_TARGET_NOMINEES,
|
|
307
|
+
});
|
|
308
|
+
return { state: await (0, state_1.addStage)(state, stageBuilder.build()), continue: complete };
|
|
309
|
+
}
|
|
310
|
+
async function trackNomineeVettingStage(state) {
|
|
311
|
+
const ctx = getElectionContext(state);
|
|
312
|
+
if (!ctx)
|
|
313
|
+
return { state, continue: false };
|
|
314
|
+
log("NOMINEE_VETTING: tracking");
|
|
315
|
+
const nomineeGovernorAddress = constants_1.ADDRESSES.ELECTION_NOMINEE_GOVERNOR;
|
|
316
|
+
const memberGovernorAddress = constants_1.ADDRESSES.ELECTION_MEMBER_GOVERNOR;
|
|
317
|
+
const memberGovernor = (0, contracts_1.getMemberGovernor)(memberGovernorAddress, state.providers.l2);
|
|
318
|
+
const [vettingResults, currentL1Block] = await Promise.all([
|
|
319
|
+
(0, multicall_1.multicall)(state.providers.l2, [
|
|
320
|
+
(0, multicall_1.buildCallInput)(nomineeGovernorAddress, abis_1.nomineeElectionGovernorInterface, "proposalVettingDeadline", [ctx.nomineeProposalId]),
|
|
321
|
+
(0, multicall_1.buildCallInput)(nomineeGovernorAddress, abis_1.nomineeElectionGovernorInterface, "compliantNomineeCount", [ctx.nomineeProposalId]),
|
|
322
|
+
(0, multicall_1.buildCallInput)(nomineeGovernorAddress, abis_1.nomineeElectionGovernorInterface, "state", [
|
|
323
|
+
ctx.nomineeProposalId,
|
|
324
|
+
]),
|
|
325
|
+
]),
|
|
326
|
+
(0, timing_1.getL1BlockNumberFromL2)(state.providers.l2),
|
|
327
|
+
]);
|
|
328
|
+
const vettingDeadlineBN = vettingResults[0] ?? ethers_1.BigNumber.from(0);
|
|
329
|
+
const vettingDeadline = vettingDeadlineBN.toNumber();
|
|
330
|
+
const compliantNomineeCount = (vettingResults[1] ?? ethers_1.BigNumber.from(0)).toNumber();
|
|
331
|
+
const nomineeState = vettingResults[2];
|
|
332
|
+
const nomineeProposalState = (0, constants_1.proposalStateToString)(nomineeState);
|
|
333
|
+
const isInVettingPeriod = nomineeProposalState === "Succeeded" && currentL1Block.lte(vettingDeadlineBN);
|
|
334
|
+
// Check if member proposal exists
|
|
335
|
+
let memberProposalId = null;
|
|
336
|
+
const computedMemberProposalId = await (0, proposal_ids_1.computeElectionProposalId)(ctx.electionIndex, memberGovernor);
|
|
337
|
+
try {
|
|
338
|
+
await (0, rpc_utils_1.queryWithRetry)(() => memberGovernor.state(computedMemberProposalId));
|
|
339
|
+
memberProposalId = computedMemberProposalId;
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
// Member election not yet created
|
|
343
|
+
}
|
|
344
|
+
const stageBuilder = new builder_1.StageBuilder("NOMINEE_VETTING", "arb1").data({
|
|
345
|
+
nomineeProposalId: ctx.nomineeProposalId,
|
|
346
|
+
vettingDeadline,
|
|
347
|
+
currentL1Block: currentL1Block.toNumber(),
|
|
348
|
+
compliantNomineeCount,
|
|
349
|
+
memberProposalId: memberProposalId ?? undefined,
|
|
350
|
+
});
|
|
351
|
+
const canProceedToMemberPhase = nomineeProposalState === "Succeeded" &&
|
|
352
|
+
!isInVettingPeriod &&
|
|
353
|
+
compliantNomineeCount >= constants_1.TIMING.SECURITY_COUNCIL_TARGET_NOMINEES &&
|
|
354
|
+
!memberProposalId;
|
|
355
|
+
let complete = false;
|
|
356
|
+
if (nomineeProposalState === "Executed" || memberProposalId) {
|
|
357
|
+
stageBuilder.status("COMPLETED");
|
|
358
|
+
complete = true;
|
|
359
|
+
try {
|
|
360
|
+
const executeEvent = await findElectionExecuteTxHash(ctx.nomineeProposalId, nomineeGovernorAddress, state.providers.l2, state.chunkingConfig.l2ChunkSize);
|
|
361
|
+
if (executeEvent) {
|
|
362
|
+
stageBuilder.tx(executeEvent.txHash, executeEvent.blockNumber, "arb1", 42161);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
// TX hash discovery failed
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
else if (canProceedToMemberPhase) {
|
|
370
|
+
stageBuilder.status("READY").executable(true);
|
|
371
|
+
}
|
|
372
|
+
else if (isInVettingPeriod) {
|
|
373
|
+
stageBuilder.status("PENDING");
|
|
374
|
+
}
|
|
375
|
+
else if (compliantNomineeCount < constants_1.TIMING.SECURITY_COUNCIL_TARGET_NOMINEES) {
|
|
376
|
+
stageBuilder.status("FAILED");
|
|
377
|
+
}
|
|
378
|
+
return {
|
|
379
|
+
state: await (0, state_1.addStage)(state, stageBuilder.build()),
|
|
380
|
+
continue: complete && memberProposalId !== null,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
async function trackMemberElectionStage(state) {
|
|
384
|
+
const electionIndex = (0, state_1.getElectionIndex)(state);
|
|
385
|
+
const memberProposalId = (0, state_1.getMemberProposalId)(state);
|
|
386
|
+
if (electionIndex === undefined || !memberProposalId)
|
|
387
|
+
return { state, continue: false };
|
|
388
|
+
log("MEMBER_ELECTION: tracking");
|
|
389
|
+
const memberGovernorAddress = constants_1.ADDRESSES.ELECTION_MEMBER_GOVERNOR;
|
|
390
|
+
const memberGovernor = (0, contracts_1.getMemberGovernor)(memberGovernorAddress, state.providers.l2);
|
|
391
|
+
const memberState = await (0, rpc_utils_1.queryWithRetry)(() => memberGovernor.state(memberProposalId));
|
|
392
|
+
const memberProposalState = (0, constants_1.proposalStateToString)(memberState);
|
|
393
|
+
const stageBuilder = new builder_1.StageBuilder("MEMBER_ELECTION", "arb1").data({
|
|
394
|
+
memberProposalId,
|
|
395
|
+
proposalState: memberProposalState,
|
|
396
|
+
winnersCount: 0,
|
|
397
|
+
});
|
|
398
|
+
let executed = false;
|
|
399
|
+
let newState = state;
|
|
400
|
+
if (memberProposalState === "Active" || memberProposalState === "Pending") {
|
|
401
|
+
stageBuilder.status("PENDING");
|
|
402
|
+
}
|
|
403
|
+
else if (memberProposalState === "Succeeded") {
|
|
404
|
+
stageBuilder.status("READY").executable(true);
|
|
405
|
+
}
|
|
406
|
+
else if (memberProposalState === "Executed") {
|
|
407
|
+
stageBuilder.status("COMPLETED");
|
|
408
|
+
executed = true;
|
|
409
|
+
try {
|
|
410
|
+
const executeEvent = await findElectionExecuteTxHash(memberProposalId, memberGovernorAddress, state.providers.l2, state.chunkingConfig.l2ChunkSize);
|
|
411
|
+
if (executeEvent) {
|
|
412
|
+
stageBuilder.tx(executeEvent.txHash, executeEvent.blockNumber, "arb1", 42161, {
|
|
413
|
+
description: "executed",
|
|
414
|
+
});
|
|
415
|
+
// Find CallScheduled events and inject into state for timelock pipeline
|
|
416
|
+
const callScheduledEvents = await (0, timelock_discovery_1.findCallScheduledByTxHash)(executeEvent.txHash, state.providers.l2);
|
|
417
|
+
if (callScheduledEvents?.length) {
|
|
418
|
+
const firstEvent = callScheduledEvents[0];
|
|
419
|
+
stageBuilder.data({
|
|
420
|
+
memberProposalId,
|
|
421
|
+
proposalState: memberProposalState,
|
|
422
|
+
winnersCount: 0,
|
|
423
|
+
operationId: firstEvent.operationId,
|
|
424
|
+
timelockAddress: firstEvent.timelockAddress,
|
|
425
|
+
});
|
|
426
|
+
// Inject callScheduledData for timelock pipeline
|
|
427
|
+
newState = { ...state, callScheduledData: callScheduledEvents };
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
// TX hash discovery failed
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
else if (memberProposalState === "Defeated" || memberProposalState === "Canceled") {
|
|
436
|
+
stageBuilder.status("FAILED");
|
|
437
|
+
}
|
|
438
|
+
return {
|
|
439
|
+
state: await (0, state_1.addStage)(newState, stageBuilder.build()),
|
|
440
|
+
continue: executed,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
// ============================================================================
|
|
444
|
+
// Stage Configurations
|
|
445
|
+
// ============================================================================
|
|
446
|
+
const GOVERNOR_STAGES = [
|
|
447
|
+
{ type: "PROPOSAL_CREATED", track: trackProposalCreatedStage },
|
|
448
|
+
{ type: "VOTING_ACTIVE", track: trackVotingStage_ },
|
|
449
|
+
{ type: "PROPOSAL_QUEUED", track: trackProposalQueuedStage },
|
|
450
|
+
];
|
|
451
|
+
const TIMELOCK_STAGES = [
|
|
452
|
+
{
|
|
453
|
+
type: "L2_TIMELOCK",
|
|
454
|
+
track: trackL2TimelockStage,
|
|
455
|
+
// Custom cache: also check if we have callScheduledData
|
|
456
|
+
checkCache: async (state) => {
|
|
457
|
+
const timelockAddress = (0, state_1.getTimelockAddress)(state);
|
|
458
|
+
const operationId = (0, state_1.getOperationId)(state);
|
|
459
|
+
if (!timelockAddress || !operationId)
|
|
460
|
+
return { state, continue: false };
|
|
461
|
+
const cached = (0, stage_runner_1.getCachedStage)(state, "L2_TIMELOCK");
|
|
462
|
+
if (cached && (0, utils_1.isStageSuccess)(cached.status)) {
|
|
463
|
+
log("L2_TIMELOCK: cached");
|
|
464
|
+
return { state: await (0, state_1.addStage)(state, cached), continue: true };
|
|
465
|
+
}
|
|
466
|
+
return undefined; // Fall through to track
|
|
467
|
+
},
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
type: "L2_TO_L1_MESSAGE",
|
|
471
|
+
track: trackL2ToL1MessageStage,
|
|
472
|
+
// Custom cache: handle pending fast-path in track function
|
|
473
|
+
checkCache: async (state) => {
|
|
474
|
+
const cached = (0, stage_runner_1.getCachedStage)(state, "L2_TO_L1_MESSAGE");
|
|
475
|
+
if (cached && (0, utils_1.isStageSuccess)(cached.status)) {
|
|
476
|
+
log("L2_TO_L1_MESSAGE: cached");
|
|
477
|
+
return { state: await (0, state_1.addStage)(state, cached), continue: true };
|
|
478
|
+
}
|
|
479
|
+
return undefined;
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
{ type: "L1_TIMELOCK", track: trackL1TimelockStage },
|
|
483
|
+
{ type: "RETRYABLE_EXECUTED", track: trackRetryablesStage },
|
|
484
|
+
];
|
|
485
|
+
const ELECTION_STAGES = [
|
|
486
|
+
{ type: "CREATE_ELECTION", track: trackCreateElectionStage },
|
|
487
|
+
{ type: "NOMINEE_ELECTION", track: trackNomineeElectionStage },
|
|
488
|
+
{ type: "NOMINEE_VETTING", track: trackNomineeVettingStage },
|
|
489
|
+
{ type: "MEMBER_ELECTION", track: trackMemberElectionStage },
|
|
490
|
+
];
|
|
491
|
+
// ============================================================================
|
|
492
|
+
// Pipeline Exports
|
|
493
|
+
// ============================================================================
|
|
256
494
|
/**
|
|
257
|
-
* Track
|
|
258
|
-
* Returns final state after tracking all stages.
|
|
495
|
+
* Track governor proposal pipeline (stages 1-7).
|
|
259
496
|
*/
|
|
260
497
|
async function trackGovernorPipeline(state) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
// Stage 2: Voting
|
|
268
|
-
const { state: state2, complete: votingComplete } = await pipelineTrackVoting(state1);
|
|
269
|
-
if (!votingComplete) {
|
|
270
|
-
logTracker("voting not complete, stopping");
|
|
271
|
-
return state2;
|
|
498
|
+
logTracker("running governor pipeline");
|
|
499
|
+
state = await (0, stage_runner_1.runPipeline)(state, GOVERNOR_STAGES);
|
|
500
|
+
// Continue with timelock if proposal was queued
|
|
501
|
+
const queued = state.stages.find((s) => s.type === "PROPOSAL_QUEUED");
|
|
502
|
+
if (queued?.status === "COMPLETED") {
|
|
503
|
+
return (0, stage_runner_1.runPipeline)(state, TIMELOCK_STAGES);
|
|
272
504
|
}
|
|
273
|
-
|
|
274
|
-
const { state: state3, queued } = await pipelineTrackProposalQueued(state2);
|
|
275
|
-
if (!queued) {
|
|
276
|
-
logTracker("proposal not queued, stopping");
|
|
277
|
-
return state3;
|
|
278
|
-
}
|
|
279
|
-
// Continue with timelock pipeline
|
|
280
|
-
return trackTimelockPipeline(state3);
|
|
505
|
+
return state;
|
|
281
506
|
}
|
|
282
507
|
/**
|
|
283
508
|
* Track timelock pipeline (stages 4-7).
|
|
284
|
-
* Used by governor pipeline and direct timelock tracking.
|
|
509
|
+
* Used by governor pipeline, election pipeline, and direct timelock tracking.
|
|
285
510
|
*/
|
|
286
511
|
async function trackTimelockPipeline(state) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return
|
|
300
|
-
}
|
|
301
|
-
// Stage 6: L1 Timelock (unified)
|
|
302
|
-
const { state: state3, executed: l1Executed } = await pipelineTrackL1Timelock(state2);
|
|
303
|
-
if (!l1Executed) {
|
|
304
|
-
logTracker("L1 timelock not executed, stopping");
|
|
305
|
-
return addPlaceholders(state3, RETRYABLE_STAGES, "L1 timelock not executed");
|
|
512
|
+
logTracker("running timelock pipeline");
|
|
513
|
+
return (0, stage_runner_1.runPipeline)(state, TIMELOCK_STAGES);
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Track election pipeline (stages 1-8).
|
|
517
|
+
*/
|
|
518
|
+
async function trackElectionPipeline(state) {
|
|
519
|
+
logTracker("running election pipeline");
|
|
520
|
+
state = await (0, stage_runner_1.runPipeline)(state, ELECTION_STAGES);
|
|
521
|
+
// Continue with timelock if member election was executed
|
|
522
|
+
const memberStage = state.stages.find((s) => s.type === "MEMBER_ELECTION");
|
|
523
|
+
if (memberStage?.status === "COMPLETED") {
|
|
524
|
+
return (0, stage_runner_1.runPipeline)(state, TIMELOCK_STAGES);
|
|
306
525
|
}
|
|
307
|
-
|
|
308
|
-
const { state: finalState } = await pipelineTrackRetryables(state3);
|
|
309
|
-
return finalState;
|
|
526
|
+
return state;
|
|
310
527
|
}
|
|
311
528
|
//# sourceMappingURL=pipeline.js.map
|