@aztec/sequencer-client 0.0.1-commit.179ed20 → 0.0.1-commit.189eedb3
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 +281 -21
- package/dest/client/sequencer-client.d.ts +19 -9
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +65 -32
- package/dest/config.d.ts +28 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +76 -37
- package/dest/global_variable_builder/fee_predictor.d.ts +37 -0
- package/dest/global_variable_builder/fee_predictor.d.ts.map +1 -0
- package/dest/global_variable_builder/fee_predictor.js +128 -0
- package/dest/global_variable_builder/fee_provider.d.ts +21 -0
- package/dest/global_variable_builder/fee_provider.d.ts.map +1 -0
- package/dest/global_variable_builder/fee_provider.js +58 -0
- package/dest/global_variable_builder/global_builder.d.ts +14 -16
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +16 -50
- package/dest/global_variable_builder/index.d.ts +4 -2
- package/dest/global_variable_builder/index.d.ts.map +1 -1
- package/dest/global_variable_builder/index.js +2 -0
- package/dest/index.d.ts +2 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/publisher/config.d.ts +47 -17
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +121 -42
- package/dest/publisher/index.d.ts +2 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
- package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +58 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/index.js +2 -0
- package/dest/publisher/sequencer-bundle-simulator.d.ts +96 -0
- package/dest/publisher/sequencer-bundle-simulator.d.ts.map +1 -0
- package/dest/publisher/sequencer-bundle-simulator.js +198 -0
- package/dest/publisher/sequencer-publisher-factory.d.ts +11 -5
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +27 -3
- package/dest/publisher/sequencer-publisher.d.ts +94 -67
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +442 -378
- package/dest/sequencer/automine/automine_factory.d.ts +54 -0
- package/dest/sequencer/automine/automine_factory.d.ts.map +1 -0
- package/dest/sequencer/automine/automine_factory.js +84 -0
- package/dest/sequencer/automine/automine_sequencer.d.ts +151 -0
- package/dest/sequencer/automine/automine_sequencer.d.ts.map +1 -0
- package/dest/sequencer/automine/automine_sequencer.js +509 -0
- package/dest/sequencer/chain_state_overrides.d.ts +61 -0
- package/dest/sequencer/chain_state_overrides.d.ts.map +1 -0
- package/dest/sequencer/chain_state_overrides.js +98 -0
- package/dest/sequencer/checkpoint_proposal_job.d.ts +65 -11
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +850 -249
- package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts +34 -0
- package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts.map +1 -0
- package/dest/sequencer/checkpoint_proposal_job_metrics.js +72 -0
- package/dest/sequencer/checkpoint_voter.d.ts +1 -2
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_voter.js +2 -5
- package/dest/sequencer/events.d.ts +48 -2
- package/dest/sequencer/events.d.ts.map +1 -1
- package/dest/sequencer/index.d.ts +3 -1
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +2 -0
- package/dest/sequencer/metrics.d.ts +23 -8
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +117 -21
- package/dest/sequencer/sequencer.d.ts +85 -22
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +380 -137
- package/dest/sequencer/timetable.d.ts +14 -6
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +47 -46
- package/dest/sequencer/types.d.ts +2 -2
- package/dest/sequencer/types.d.ts.map +1 -1
- package/dest/test/index.d.ts +3 -5
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +11 -11
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.js +45 -34
- package/dest/test/utils.d.ts +3 -3
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +10 -8
- package/package.json +27 -28
- package/src/client/sequencer-client.ts +91 -35
- package/src/config.ts +98 -46
- package/src/global_variable_builder/README.md +44 -0
- package/src/global_variable_builder/fee_predictor.ts +172 -0
- package/src/global_variable_builder/fee_provider.ts +75 -0
- package/src/global_variable_builder/global_builder.ts +26 -63
- package/src/global_variable_builder/index.ts +3 -1
- package/src/index.ts +10 -1
- package/src/publisher/config.ts +157 -45
- package/src/publisher/index.ts +3 -0
- package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
- package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +57 -0
- package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
- package/src/publisher/l1_tx_failed_store/index.ts +3 -0
- package/src/publisher/sequencer-bundle-simulator.ts +254 -0
- package/src/publisher/sequencer-publisher-factory.ts +38 -9
- package/src/publisher/sequencer-publisher.ts +535 -469
- package/src/sequencer/README.md +162 -450
- package/src/sequencer/automine/README.md +46 -0
- package/src/sequencer/automine/automine_factory.ts +145 -0
- package/src/sequencer/automine/automine_sequencer.ts +595 -0
- package/src/sequencer/chain_state_overrides.ts +162 -0
- package/src/sequencer/checkpoint_proposal_job.ts +1027 -268
- package/src/sequencer/checkpoint_proposal_job_metrics.ts +128 -0
- package/src/sequencer/checkpoint_voter.ts +1 -12
- package/src/sequencer/events.ts +51 -2
- package/src/sequencer/index.ts +2 -0
- package/src/sequencer/metrics.ts +132 -25
- package/src/sequencer/sequencer.ts +470 -156
- package/src/sequencer/timetable.ts +62 -56
- package/src/sequencer/types.ts +1 -1
- package/src/test/index.ts +2 -4
- package/src/test/mock_checkpoint_builder.ts +63 -49
- package/src/test/utils.ts +31 -10
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
function _ts_add_disposable_resource(env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() {
|
|
16
|
+
try {
|
|
17
|
+
inner.call(this);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return Promise.reject(e);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
env.stack.push({
|
|
23
|
+
value: value,
|
|
24
|
+
dispose: dispose,
|
|
25
|
+
async: async
|
|
26
|
+
});
|
|
27
|
+
} else if (async) {
|
|
28
|
+
env.stack.push({
|
|
29
|
+
async: true
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
function _ts_dispose_resources(env) {
|
|
35
|
+
var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
|
|
36
|
+
var e = new Error(message);
|
|
37
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
38
|
+
};
|
|
39
|
+
return (_ts_dispose_resources = function _ts_dispose_resources(env) {
|
|
40
|
+
function fail(e) {
|
|
41
|
+
env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
42
|
+
env.hasError = true;
|
|
43
|
+
}
|
|
44
|
+
var r, s = 0;
|
|
45
|
+
function next() {
|
|
46
|
+
while(r = env.stack.pop()){
|
|
47
|
+
try {
|
|
48
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
49
|
+
if (r.dispose) {
|
|
50
|
+
var result = r.dispose.call(r.value);
|
|
51
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) {
|
|
52
|
+
fail(e);
|
|
53
|
+
return next();
|
|
54
|
+
});
|
|
55
|
+
} else s |= 1;
|
|
56
|
+
} catch (e) {
|
|
57
|
+
fail(e);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
61
|
+
if (env.hasError) throw env.error;
|
|
62
|
+
}
|
|
63
|
+
return next();
|
|
64
|
+
})(env);
|
|
65
|
+
}
|
|
66
|
+
import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
67
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
68
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
69
|
+
import { SerialQueue } from '@aztec/foundation/queue';
|
|
70
|
+
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
71
|
+
import { isErrorClass } from '@aztec/foundation/types';
|
|
72
|
+
import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
73
|
+
import { getPreviousCheckpointOutHashes } from '@aztec/stdlib/checkpoint';
|
|
74
|
+
import { getEpochAtSlot, getSlotAtTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
75
|
+
import { InsufficientValidTxsError } from '@aztec/stdlib/interfaces/server';
|
|
76
|
+
/**
|
|
77
|
+
* Minimal, deterministic, queue-driven sequencer for e2e tests that don't exercise
|
|
78
|
+
* block-building or consensus (e.g. e2e_token, e2e_amm, e2e_authwit).
|
|
79
|
+
*
|
|
80
|
+
* Differences from the production `Sequencer`:
|
|
81
|
+
* - No proposer-turn check (single sequencer).
|
|
82
|
+
* - No sync check, no pipelining, no validator orchestration, no attestations,
|
|
83
|
+
* no slashing, no votes, no P2P proposal gossip, no timetable enforcement.
|
|
84
|
+
* - No event emission — consumers (archiver, world-state, `EpochTestSettler`) observe
|
|
85
|
+
* L1 and the archiver tip rather than sequencer events.
|
|
86
|
+
* - All test-driven time control (warp / mine empty block) goes through a single
|
|
87
|
+
* serial queue alongside mempool-driven builds; the three never interleave.
|
|
88
|
+
*
|
|
89
|
+
* Requires `aztecTargetCommitteeSize == 0` on the deployed rollup so that the
|
|
90
|
+
* L1 `verifyProposer` / `verifyAttestations` short-circuits accept an empty
|
|
91
|
+
* `CommitteeAttestationsAndSigners` (see
|
|
92
|
+
* `l1-contracts/src/core/libraries/rollup/ValidatorSelectionLib.sol:244`).
|
|
93
|
+
*/ export class AutomineSequencer {
|
|
94
|
+
log;
|
|
95
|
+
queue;
|
|
96
|
+
pollIntervalMs;
|
|
97
|
+
deps;
|
|
98
|
+
running = false;
|
|
99
|
+
stopped = false;
|
|
100
|
+
paused = false;
|
|
101
|
+
mempoolPoller;
|
|
102
|
+
publisher;
|
|
103
|
+
attestorAddress;
|
|
104
|
+
/** Set while a mempool-driven build is queued but not yet run; used to coalesce. */ buildQueued = undefined;
|
|
105
|
+
/** Last L2 slot we published a checkpoint for (-1 means none yet). */ lastBuiltSlot = -1;
|
|
106
|
+
constructor(deps){
|
|
107
|
+
this.deps = deps;
|
|
108
|
+
this.log = deps.log ?? createLogger('sequencer:automine');
|
|
109
|
+
this.queue = new SerialQueue();
|
|
110
|
+
this.pollIntervalMs = deps.pollIntervalMs ?? 50;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Starts the sequencer. Switches anvil into automine mode (no interval mining),
|
|
114
|
+
* acquires a publisher, and begins polling the mempool for pending txs.
|
|
115
|
+
*/ async start() {
|
|
116
|
+
if (this.running) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.running = true;
|
|
120
|
+
await this.deps.ethCheatCodes.setIntervalMining(0, {
|
|
121
|
+
silent: true
|
|
122
|
+
});
|
|
123
|
+
await this.deps.ethCheatCodes.setAutomine(true, {
|
|
124
|
+
silent: true
|
|
125
|
+
});
|
|
126
|
+
const { publisher, attestorAddress } = await this.deps.publisherFactory.create();
|
|
127
|
+
this.publisher = publisher;
|
|
128
|
+
this.attestorAddress = attestorAddress;
|
|
129
|
+
this.log.info(`AutomineSequencer started`, {
|
|
130
|
+
publisher: this.publisher.getSenderAddress().toString(),
|
|
131
|
+
attestor: this.attestorAddress.toString()
|
|
132
|
+
});
|
|
133
|
+
this.queue.start();
|
|
134
|
+
// Fallback poller that triggers a build if we discover pending txs without an explicit
|
|
135
|
+
// notification. Tests can also call `buildIfPending()` directly to skip the poll wait.
|
|
136
|
+
this.mempoolPoller = new RunningPromise(()=>this.maybeEnqueueBuild(), this.log, this.pollIntervalMs);
|
|
137
|
+
this.mempoolPoller.start();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Stops the sequencer. Drains the queue, unsubscribes the mempool poller, and runs any
|
|
141
|
+
* registered {@link AutomineSequencerDeps.stopExtras} hook (e.g. the PublisherManager's
|
|
142
|
+
* funding loop). Idempotent: subsequent calls return without re-running cleanup.
|
|
143
|
+
*/ async stop() {
|
|
144
|
+
if (this.stopped) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
this.stopped = true;
|
|
148
|
+
this.running = false;
|
|
149
|
+
await this.mempoolPoller?.stop();
|
|
150
|
+
await this.queue.end();
|
|
151
|
+
await this.deps.stopExtras?.();
|
|
152
|
+
this.log.info('AutomineSequencer stopped');
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Enqueues a mempool-driven build. Coalesces consecutive calls so a burst of new txs
|
|
156
|
+
* collapses into one build job. Returns the built block (or undefined if nothing was built
|
|
157
|
+
* or the sequencer is paused).
|
|
158
|
+
*/ buildIfPending() {
|
|
159
|
+
if (!this.running || this.paused) {
|
|
160
|
+
return Promise.resolve(undefined);
|
|
161
|
+
}
|
|
162
|
+
if (this.buildQueued) {
|
|
163
|
+
// A build is already queued; coalesce. The pending build will pick up the new txs.
|
|
164
|
+
return this.buildQueued;
|
|
165
|
+
}
|
|
166
|
+
this.buildQueued = this.queue.put(async ()=>{
|
|
167
|
+
try {
|
|
168
|
+
return await this.runBuild({
|
|
169
|
+
allowEmpty: false
|
|
170
|
+
});
|
|
171
|
+
} finally{
|
|
172
|
+
this.buildQueued = undefined;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
return this.buildQueued;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Pauses mempool-driven block production. Pending txs accumulate in the pool without being
|
|
179
|
+
* mined. Explicit test-harness operations (`buildEmptyBlock`, `warpTo`, `revertToCheckpoint`)
|
|
180
|
+
* continue to work; this only gates the mempool poller and `buildIfPending`.
|
|
181
|
+
*/ pause() {
|
|
182
|
+
if (this.paused) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.paused = true;
|
|
186
|
+
this.log.info('AutomineSequencer paused');
|
|
187
|
+
}
|
|
188
|
+
/** Resumes mempool-driven block production after a previous {@link pause}. */ resume() {
|
|
189
|
+
if (!this.paused) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
this.paused = false;
|
|
193
|
+
this.log.info('AutomineSequencer resumed');
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Updates the in-memory sequencer config. Mirrors {@link SequencerClient.updateConfig} so that
|
|
197
|
+
* `AztecNode.setConfig` (e.g. tests bumping `minTxsPerBlock` to bundle multiple txs into one
|
|
198
|
+
* block) propagates to the AutomineSequencer's gating logic in {@link runBuild}.
|
|
199
|
+
*/ updateConfig(config) {
|
|
200
|
+
Object.assign(this.deps.config, config);
|
|
201
|
+
}
|
|
202
|
+
/** Returns a snapshot of the current sequencer config (used by pause/resume bookkeeping). */ getConfig() {
|
|
203
|
+
return this.deps.config;
|
|
204
|
+
}
|
|
205
|
+
/** Enqueues an empty-block build. Resolves to the built block. */ buildEmptyBlock() {
|
|
206
|
+
return this.queue.put(async ()=>{
|
|
207
|
+
const block = await this.runBuild({
|
|
208
|
+
allowEmpty: true
|
|
209
|
+
});
|
|
210
|
+
if (!block) {
|
|
211
|
+
throw new Error('buildEmptyBlock: runBuild returned undefined');
|
|
212
|
+
}
|
|
213
|
+
return block;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Warps L1 timestamp to `targetTimestampSec`. Rounded up to the next aztec-slot
|
|
218
|
+
* boundary so the next build lands on a fresh slot. Atomic with respect to builds —
|
|
219
|
+
* the queue ensures no build is in flight while the warp executes.
|
|
220
|
+
*/ warpTo(targetTimestampSec) {
|
|
221
|
+
return this.queue.put(()=>this.runWarp(targetTimestampSec));
|
|
222
|
+
}
|
|
223
|
+
/** Warps L1 timestamp forward by `deltaSec` seconds from the current L1 time. */ warpBy(deltaSec) {
|
|
224
|
+
return this.queue.put(async ()=>{
|
|
225
|
+
const current = await this.deps.ethCheatCodes.lastBlockTimestamp();
|
|
226
|
+
await this.runWarp(current + deltaSec);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Reorgs L1 so that every L1 block strictly after the one that published
|
|
231
|
+
* `targetCheckpoint` is removed. The archiver, world-state, and date provider
|
|
232
|
+
* are all brought back in sync before the promise resolves.
|
|
233
|
+
*
|
|
234
|
+
* Runs inside the serial queue so it never interleaves with a build or warp.
|
|
235
|
+
*/ revertToCheckpoint(targetCheckpoint) {
|
|
236
|
+
return this.queue.put(()=>this.runRevert(targetCheckpoint));
|
|
237
|
+
}
|
|
238
|
+
/** Awaits the queue draining to a fully idle state. */ syncPoint() {
|
|
239
|
+
return this.queue.syncPoint();
|
|
240
|
+
}
|
|
241
|
+
/** Called from the mempool poller. Enqueues a build if there are pending txs. */ async maybeEnqueueBuild() {
|
|
242
|
+
if (!this.running || this.paused || this.buildQueued) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
const pending = await this.deps.p2pClient.getPendingTxCount();
|
|
247
|
+
if (pending > 0) {
|
|
248
|
+
// Fire-and-forget; the build result is delivered via `buildIfPending()` callers,
|
|
249
|
+
// not via the poller.
|
|
250
|
+
void this.buildIfPending().catch((err)=>{
|
|
251
|
+
this.log.error('Mempool-driven build failed', err);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
} catch (err) {
|
|
255
|
+
this.log.warn('Failed to poll mempool', {
|
|
256
|
+
err: err instanceof Error ? err.message : String(err)
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/** Builds one checkpoint with a single block, publishes it, syncs the date provider. */ async runBuild({ allowEmpty }) {
|
|
261
|
+
const env = {
|
|
262
|
+
stack: [],
|
|
263
|
+
error: void 0,
|
|
264
|
+
hasError: false
|
|
265
|
+
};
|
|
266
|
+
try {
|
|
267
|
+
if (!this.running || !this.publisher || !this.attestorAddress) {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
const txCount = await this.deps.p2pClient.getPendingTxCount();
|
|
271
|
+
// For mempool-driven builds, wait for at least `minTxsPerBlock` pending txs (or 1 if not set)
|
|
272
|
+
// before building. This mirrors the production sequencer's `waitForMinTxs` behavior, and is
|
|
273
|
+
// required for tests that bundle multiple txs into one block via `setConfig({ minTxsPerBlock })`.
|
|
274
|
+
// Explicit empty-block / warp paths pass `allowEmpty: true` and bypass this gate.
|
|
275
|
+
const minRequired = allowEmpty ? 0 : Math.max(this.deps.config.minTxsPerBlock ?? 1, 1);
|
|
276
|
+
if (txCount < minRequired) {
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
// Decide target slot from the pending block's timestamp — picks up any prior
|
|
280
|
+
// `setNextBlockTimestamp` call (e.g. queued by runWarp) instead of assuming +1 over
|
|
281
|
+
// the last mined block.
|
|
282
|
+
const pendingBlockTs = await this.deps.ethCheatCodes.nextBlockTimestamp();
|
|
283
|
+
let targetSlot = Number(getSlotAtTimestamp(BigInt(pendingBlockTs), this.deps.l1Constants));
|
|
284
|
+
if (targetSlot <= this.lastBuiltSlot) {
|
|
285
|
+
// Pending block doesn't reach a new slot yet; advance to the next slot we own.
|
|
286
|
+
targetSlot = this.lastBuiltSlot + 1;
|
|
287
|
+
}
|
|
288
|
+
const slotBoundaryTs = Number(getTimestampForSlot(SlotNumber(targetSlot), this.deps.l1Constants));
|
|
289
|
+
// Pre-set anvil's next block timestamp only if the slot boundary is past what's already
|
|
290
|
+
// scheduled. setNextBlockTimestamp rejects values not strictly greater than the last block's
|
|
291
|
+
// timestamp, and pendingBlockTs is always > lastBlockTimestamp, so this guard is sufficient.
|
|
292
|
+
if (slotBoundaryTs > pendingBlockTs) {
|
|
293
|
+
await this.deps.ethCheatCodes.setNextBlockTimestamp(slotBoundaryTs);
|
|
294
|
+
}
|
|
295
|
+
const tips = await this.deps.l2BlockSource.getL2Tips();
|
|
296
|
+
const syncedToBlockNumber = tips.proposed.number;
|
|
297
|
+
// Ensure world state has processed the archiver's tip before forking. Without this,
|
|
298
|
+
// world state may still be at the previous block (since it syncs asynchronously from
|
|
299
|
+
// the archiver), and `fork(syncedToBlockNumber)` would fail with
|
|
300
|
+
// "Unable to initialize from future block".
|
|
301
|
+
await this.deps.worldState.syncImmediate(BlockNumber(syncedToBlockNumber));
|
|
302
|
+
const nextBlockNumber = BlockNumber(syncedToBlockNumber + 1);
|
|
303
|
+
const checkpointNumber = CheckpointNumber(tips.proposedCheckpoint.checkpoint.number + 1);
|
|
304
|
+
const targetEpoch = getEpochAtSlot(SlotNumber(targetSlot), this.deps.l1Constants);
|
|
305
|
+
this.log.verbose(`Building automine checkpoint`, {
|
|
306
|
+
checkpointNumber,
|
|
307
|
+
blockNumber: nextBlockNumber,
|
|
308
|
+
slot: targetSlot,
|
|
309
|
+
slotTimestamp: slotBoundaryTs,
|
|
310
|
+
txCount,
|
|
311
|
+
allowEmpty
|
|
312
|
+
});
|
|
313
|
+
const checkpointGlobals = await this.deps.globalsBuilder.buildCheckpointGlobalVariables(this.deps.coinbase, this.deps.feeRecipient, SlotNumber(targetSlot));
|
|
314
|
+
const l1ToL2Messages = await this.deps.l1ToL2MessageSource.getL1ToL2Messages(checkpointNumber);
|
|
315
|
+
const previousCheckpointOutHashes = await getPreviousCheckpointOutHashes({
|
|
316
|
+
blockSource: this.deps.l2BlockSource,
|
|
317
|
+
epoch: targetEpoch,
|
|
318
|
+
checkpointNumber,
|
|
319
|
+
l1Constants: this.deps.l1Constants,
|
|
320
|
+
pipeliningEnabled: false,
|
|
321
|
+
log: this.log
|
|
322
|
+
});
|
|
323
|
+
const feeAssetPriceModifier = await this.publisher.getFeeAssetPriceModifier();
|
|
324
|
+
const fork = _ts_add_disposable_resource(env, await this.deps.worldState.fork(syncedToBlockNumber, {
|
|
325
|
+
closeDelayMs: 0
|
|
326
|
+
}), true);
|
|
327
|
+
const checkpointBuilder = await this.deps.checkpointsBuilder.startCheckpoint(checkpointNumber, checkpointGlobals, feeAssetPriceModifier, l1ToL2Messages, previousCheckpointOutHashes, fork, this.log.getBindings());
|
|
328
|
+
const pendingTxs = this.deps.p2pClient.iterateEligiblePendingTxs();
|
|
329
|
+
const buildResult = await this.tryBuildBlock(checkpointBuilder, pendingTxs, nextBlockNumber, checkpointGlobals.timestamp, allowEmpty, checkpointNumber);
|
|
330
|
+
if (!buildResult) {
|
|
331
|
+
return undefined;
|
|
332
|
+
}
|
|
333
|
+
const checkpoint = await checkpointBuilder.completeCheckpoint();
|
|
334
|
+
// Empty CommitteeAttestationsAndSigners is accepted on-chain when committee size is 0.
|
|
335
|
+
const emptyAttestations = CommitteeAttestationsAndSigners.empty(this.deps.signatureContext);
|
|
336
|
+
const emptyAttestationsSignature = Signature.empty();
|
|
337
|
+
// Push the block and proposed checkpoint into the archiver locally BEFORE publishing to L1.
|
|
338
|
+
// This avoids racing the archiver's L1 polling: if the L1 publish happened first, polling
|
|
339
|
+
// could surface the checkpoint and reject our subsequent local push as duplicate. Pushing
|
|
340
|
+
// first means the archiver already has the proposed entry when L1 polling fires; the L1
|
|
341
|
+
// sync path then promotes the existing proposed checkpoint via promoteProposedToCheckpointed
|
|
342
|
+
// rather than re-adding it.
|
|
343
|
+
await this.deps.archiver.addBlock(buildResult.block);
|
|
344
|
+
await this.deps.archiver.addProposedCheckpoint({
|
|
345
|
+
header: checkpoint.header,
|
|
346
|
+
checkpointNumber,
|
|
347
|
+
startBlock: BlockNumber(buildResult.block.number),
|
|
348
|
+
blockCount: 1,
|
|
349
|
+
totalManaUsed: checkpoint.header.totalManaUsed.toBigInt(),
|
|
350
|
+
feeAssetPriceModifier
|
|
351
|
+
});
|
|
352
|
+
await this.publisher.enqueueProposeCheckpoint(checkpoint, emptyAttestations, emptyAttestationsSignature);
|
|
353
|
+
// Automine publishes synchronously in the current slot via `sendRequests`. It must NOT use the
|
|
354
|
+
// production `sendRequestsAt` (or `canProposeAt`), which always apply the one-slot pipelining
|
|
355
|
+
// offset — automine is the deliberate non-pipelined exception and builds/publishes in place.
|
|
356
|
+
const result = await this.publisher.sendRequests(SlotNumber(targetSlot));
|
|
357
|
+
const successful = result?.successfulActions?.find((a)=>a === 'propose');
|
|
358
|
+
if (!successful) {
|
|
359
|
+
this.log.error('Propose action did not succeed under automine', {
|
|
360
|
+
slot: targetSlot,
|
|
361
|
+
checkpointNumber,
|
|
362
|
+
successful: result?.successfulActions,
|
|
363
|
+
failed: result?.failedActions
|
|
364
|
+
});
|
|
365
|
+
throw new Error(`AutomineSequencer: propose did not succeed for slot ${targetSlot}`);
|
|
366
|
+
}
|
|
367
|
+
// Force one full L1-sync cycle synchronously. The local addBlock/addProposedCheckpoint
|
|
368
|
+
// above advances the proposed tip, but tips.checkpointed and the L1->L2 inbox tree state
|
|
369
|
+
// only advance when the archiver observes the L1-confirmed checkpoint via its sync loop.
|
|
370
|
+
await this.deps.archiver.syncImmediate();
|
|
371
|
+
// Sync the date provider to the L1 block timestamp we just mined.
|
|
372
|
+
const newL1Ts = await this.deps.ethCheatCodes.lastBlockTimestamp();
|
|
373
|
+
this.deps.dateProvider.setTime(newL1Ts * 1000);
|
|
374
|
+
this.lastBuiltSlot = targetSlot;
|
|
375
|
+
this.log.verbose(`Automine checkpoint published`, {
|
|
376
|
+
checkpointNumber,
|
|
377
|
+
blockNumber: nextBlockNumber,
|
|
378
|
+
slot: targetSlot,
|
|
379
|
+
l1Timestamp: newL1Ts,
|
|
380
|
+
txCount: buildResult.numTxs
|
|
381
|
+
});
|
|
382
|
+
return buildResult.block;
|
|
383
|
+
} catch (e) {
|
|
384
|
+
env.error = e;
|
|
385
|
+
env.hasError = true;
|
|
386
|
+
} finally{
|
|
387
|
+
const result = _ts_dispose_resources(env);
|
|
388
|
+
if (result) await result;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Warps L1 timestamp to (or past) `targetTimestampSec`, rounded up to the next aztec-slot
|
|
393
|
+
* boundary, by queuing an empty-checkpoint build at that slot. Mines exactly one L1 block
|
|
394
|
+
* (the propose tx auto-mined under anvil's automine mode), with the timestamp pre-set so
|
|
395
|
+
* the mined block lands on the slot boundary.
|
|
396
|
+
*/ async runWarp(targetTimestampSec) {
|
|
397
|
+
const currentL1Ts = await this.deps.ethCheatCodes.lastBlockTimestamp();
|
|
398
|
+
if (targetTimestampSec <= currentL1Ts) {
|
|
399
|
+
this.log.debug(`Warp target ${targetTimestampSec} is not in the future of current L1 ts ${currentL1Ts}`);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
// Round up to the next aztec-slot boundary so the next build naturally lands on a new slot.
|
|
403
|
+
const targetSlot = Number(getSlotAtTimestamp(BigInt(targetTimestampSec), this.deps.l1Constants));
|
|
404
|
+
const slotBoundaryTs = Number(getTimestampForSlot(SlotNumber(targetSlot + 1), this.deps.l1Constants));
|
|
405
|
+
// Queue the next L1 block at the slot boundary timestamp, then build (and publish) an
|
|
406
|
+
// empty L2 checkpoint. The propose tx auto-mines a single L1 block at slotBoundaryTs,
|
|
407
|
+
// and `runBuild` syncs the date provider to the new L1 timestamp.
|
|
408
|
+
await this.deps.ethCheatCodes.setNextBlockTimestamp(slotBoundaryTs);
|
|
409
|
+
await this.runBuild({
|
|
410
|
+
allowEmpty: true
|
|
411
|
+
});
|
|
412
|
+
this.log.verbose(`Warped L1 to slot boundary`, {
|
|
413
|
+
slot: targetSlot + 1,
|
|
414
|
+
timestamp: slotBoundaryTs
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Rolls L1 back to the block that published `targetCheckpoint`, drops the archiver's
|
|
419
|
+
* in-memory state to match, and resets internal slot bookkeeping.
|
|
420
|
+
*/ async runRevert(targetCheckpoint) {
|
|
421
|
+
const checkpointData = await this.deps.l2BlockSource.getCheckpointData({
|
|
422
|
+
number: CheckpointNumber(targetCheckpoint)
|
|
423
|
+
});
|
|
424
|
+
if (!checkpointData) {
|
|
425
|
+
throw new Error(`AutomineSequencer: checkpoint ${targetCheckpoint} not found in archiver`);
|
|
426
|
+
}
|
|
427
|
+
const targetL1Block = Number(checkpointData.l1.blockNumber);
|
|
428
|
+
this.log.verbose(`Reverting to checkpoint ${targetCheckpoint}`, {
|
|
429
|
+
targetCheckpoint,
|
|
430
|
+
targetL1Block,
|
|
431
|
+
checkpointSlot: checkpointData.header.slotNumber
|
|
432
|
+
});
|
|
433
|
+
// Roll the archiver back to the last block of targetCheckpoint before the L1 reorg,
|
|
434
|
+
// since the archiver needs to fetch the target checkpoint's L1 block hash during rollback.
|
|
435
|
+
const lastBlockInCheckpoint = BlockNumber(checkpointData.startBlock + checkpointData.blockCount - 1);
|
|
436
|
+
await this.deps.archiver.rollbackTo(lastBlockInCheckpoint);
|
|
437
|
+
// Force the P2P block stream to run one cycle immediately so it processes the
|
|
438
|
+
// chain-pruned event triggered by the archiver rollback above. Without this, the
|
|
439
|
+
// P2P pool may not have restored rolled-back txs to pending by the time the next
|
|
440
|
+
// build runs.
|
|
441
|
+
await this.deps.p2pClient.sync();
|
|
442
|
+
// Force world-state to process the archiver's prune event immediately, so the next build
|
|
443
|
+
// doesn't try to insert nullifiers that were already in the pruned checkpoints.
|
|
444
|
+
await this.deps.worldState.syncImmediate();
|
|
445
|
+
// Remove all L1 blocks strictly after the target checkpoint's publish block so that
|
|
446
|
+
// the propose txs for later checkpoints are gone from L1. We use reorg(depth) directly
|
|
447
|
+
// to keep targetL1Block itself as the new chain tip.
|
|
448
|
+
const currentL1Block = await this.deps.ethCheatCodes.publicClient.getBlockNumber();
|
|
449
|
+
const depth = Number(currentL1Block) - targetL1Block;
|
|
450
|
+
if (depth > 0) {
|
|
451
|
+
await this.deps.ethCheatCodes.reorg(depth);
|
|
452
|
+
}
|
|
453
|
+
// anvil_rollback re-queues the rolled-back txs into the mempool. Clear them so they
|
|
454
|
+
// don't get re-mined, then reset the publisher nonce tracker so the next propose tx
|
|
455
|
+
// uses the correct nonce for the post-reorg chain state.
|
|
456
|
+
await this.deps.ethCheatCodes.rpcCall('anvil_dropAllTransactions', []);
|
|
457
|
+
this.deps.l1TxUtils.forEach((utils)=>utils.resetNonce());
|
|
458
|
+
// Reset slot bookkeeping so the next build picks up at the correct slot.
|
|
459
|
+
this.lastBuiltSlot = Number(checkpointData.header.slotNumber);
|
|
460
|
+
this.log.verbose(`Reverted to checkpoint ${targetCheckpoint}`, {
|
|
461
|
+
targetCheckpoint,
|
|
462
|
+
targetL1Block
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Wraps `checkpointBuilder.buildBlock` with the failed-tx handling shared by both error
|
|
467
|
+
* and success paths: drops the failed txs from the P2P mempool, and returns `undefined`
|
|
468
|
+
* when `InsufficientValidTxsError` aborts the build (so the caller skips publishing).
|
|
469
|
+
*/ async tryBuildBlock(checkpointBuilder, pendingTxs, nextBlockNumber, timestamp, allowEmpty, checkpointNumber) {
|
|
470
|
+
let buildResult;
|
|
471
|
+
try {
|
|
472
|
+
buildResult = await checkpointBuilder.buildBlock(pendingTxs, nextBlockNumber, timestamp, {
|
|
473
|
+
maxTransactions: this.deps.config.maxTxsPerBlock,
|
|
474
|
+
// Allow empty for explicit-empty builds; require at least 1 valid tx otherwise.
|
|
475
|
+
minValidTxs: allowEmpty ? 0 : 1,
|
|
476
|
+
isBuildingProposal: true,
|
|
477
|
+
maxBlocksPerCheckpoint: 1,
|
|
478
|
+
perBlockAllocationMultiplier: 1
|
|
479
|
+
});
|
|
480
|
+
} catch (err) {
|
|
481
|
+
// Mirrors production's checkpoint_proposal_job: if every pending tx failed execution and
|
|
482
|
+
// we didn't reach minValidTxs, drop the failed txs from the mempool so they don't block
|
|
483
|
+
// the poller forever, then abort this build with no checkpoint published.
|
|
484
|
+
if (isErrorClass(err, InsufficientValidTxsError)) {
|
|
485
|
+
await this.dropFailedTxsFromP2P(err.failedTxs);
|
|
486
|
+
this.log.verbose(`AutomineSequencer: insufficient valid txs, skipping build`, {
|
|
487
|
+
checkpointNumber,
|
|
488
|
+
processedCount: err.processedCount,
|
|
489
|
+
minRequired: err.minRequired,
|
|
490
|
+
failedCount: err.failedTxs.length
|
|
491
|
+
});
|
|
492
|
+
return undefined;
|
|
493
|
+
}
|
|
494
|
+
throw err;
|
|
495
|
+
}
|
|
496
|
+
// Drop any txs that failed execution but didn't trigger InsufficientValidTxsError, so we
|
|
497
|
+
// don't re-pick them up on the next build.
|
|
498
|
+
await this.dropFailedTxsFromP2P(buildResult.failedTxs);
|
|
499
|
+
return buildResult;
|
|
500
|
+
}
|
|
501
|
+
/** Removes txs that failed execution from the P2P mempool so they don't get retried. */ async dropFailedTxsFromP2P(failedTxs) {
|
|
502
|
+
if (failedTxs.length === 0) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
const failedTxHashes = failedTxs.map((fail)=>fail.tx.getTxHash());
|
|
506
|
+
this.log.verbose(`Dropping failed txs ${failedTxHashes.join(', ')}`);
|
|
507
|
+
await this.deps.p2pClient.handleFailedExecution(failedTxHashes);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { RollupContract, type SimulationOverridesPlan } from '@aztec/ethereum/contracts';
|
|
2
|
+
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import type { Logger } from '@aztec/foundation/log';
|
|
4
|
+
import { type ProposedCheckpointData } from '@aztec/stdlib/checkpoint';
|
|
5
|
+
import type { CoordinationSignatureContext } from '@aztec/stdlib/p2p';
|
|
6
|
+
type CheckpointSimulationOverridesPlanInput = {
|
|
7
|
+
/** Target rollup contract. */
|
|
8
|
+
rollup: RollupContract;
|
|
9
|
+
/** Checkpoint number to be proposed. */
|
|
10
|
+
checkpointNumber: CheckpointNumber;
|
|
11
|
+
/** Logger instance. */
|
|
12
|
+
log: Logger;
|
|
13
|
+
/**
|
|
14
|
+
* The proposed parent checkpoint when pipelining. Its `checkpointNumber` must equal
|
|
15
|
+
* `checkpointNumber - 1`; the helper enforces this. Mutually exclusive with
|
|
16
|
+
* `invalidateToPendingCheckpointNumber`.
|
|
17
|
+
*/
|
|
18
|
+
proposedCheckpointData?: ProposedCheckpointData;
|
|
19
|
+
/**
|
|
20
|
+
* The pending checkpoint number we'll end up at after invalidation lands. Mutually exclusive
|
|
21
|
+
* with `proposedCheckpointData`.
|
|
22
|
+
*/
|
|
23
|
+
invalidateToPendingCheckpointNumber?: CheckpointNumber;
|
|
24
|
+
/**
|
|
25
|
+
* The real on-chain pending checkpoint number (typically `syncedTo.checkpointedCheckpointNumber`).
|
|
26
|
+
* Used as the snapshot we pin both `pending` and `proven` to avoid prunes in simulation.
|
|
27
|
+
*/
|
|
28
|
+
checkpointedCheckpointNumber: CheckpointNumber;
|
|
29
|
+
/**
|
|
30
|
+
* Chain-level consensus signature context. Used to recompute the parent's `payloadDigest` for the
|
|
31
|
+
* pipelined simulation override so it matches what `propose` will write into `tempCheckpointLogs[parent]`
|
|
32
|
+
* once the parent lands.
|
|
33
|
+
*/
|
|
34
|
+
signatureContext: CoordinationSignatureContext;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Builds the SimulationOverridesPlan describing the simulated L1 rollup state for a checkpoint's
|
|
38
|
+
* enqueue-time simulations: `canProposeAt` (in Sequencer.doWork) and the propose-related sims
|
|
39
|
+
* (validateBlockHeader, simulateProposeTx). The plan reflects "as if our pipelined parent
|
|
40
|
+
* checkpoint has landed and any required invalidation has executed" — the gap that needs to be
|
|
41
|
+
* bridged at enqueue time.
|
|
42
|
+
*
|
|
43
|
+
* Pipelining (`proposedCheckpointData`) and invalidation (`invalidateToPendingCheckpointNumber`)
|
|
44
|
+
* are mutually exclusive; passing both throws.
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildCheckpointSimulationOverridesPlan(input: CheckpointSimulationOverridesPlanInput): Promise<SimulationOverridesPlan | undefined>;
|
|
47
|
+
type PipelinedParentFeeHeaderInput = {
|
|
48
|
+
checkpointNumber: CheckpointNumber;
|
|
49
|
+
proposedCheckpointData: ProposedCheckpointData;
|
|
50
|
+
rollup: RollupContract;
|
|
51
|
+
log: Logger;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Derives the pending parent fee header used during pipelined proposal simulation. Returns
|
|
55
|
+
* `undefined` only when no grandparent exists (i.e. the proposed parent is the genesis
|
|
56
|
+
* checkpoint); all other failure modes (missing grandparent state, missing fee header, RPC
|
|
57
|
+
* errors) throw so callers don't silently desync the fee-header override.
|
|
58
|
+
*/
|
|
59
|
+
export declare function computePipelinedParentFeeHeader(input: PipelinedParentFeeHeaderInput): Promise<import("@aztec/ethereum/contracts").FeeHeader | undefined>;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhaW5fc3RhdGVfb3ZlcnJpZGVzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL2NoYWluX3N0YXRlX292ZXJyaWRlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUE4QixLQUFLLHVCQUF1QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssc0JBQXNCLEVBQWtDLE1BQU0sMEJBQTBCLENBQUM7QUFDdkcsT0FBTyxLQUFLLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUV0RSxLQUFLLHNDQUFzQyxHQUFHO0lBQzVDLDhCQUE4QjtJQUM5QixNQUFNLEVBQUUsY0FBYyxDQUFDO0lBQ3ZCLHdDQUF3QztJQUN4QyxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztJQUNuQyx1QkFBdUI7SUFDdkIsR0FBRyxFQUFFLE1BQU0sQ0FBQztJQUNaOzs7O09BSUc7SUFDSCxzQkFBc0IsQ0FBQyxFQUFFLHNCQUFzQixDQUFDO0lBQ2hEOzs7T0FHRztJQUNILG1DQUFtQyxDQUFDLEVBQUUsZ0JBQWdCLENBQUM7SUFDdkQ7OztPQUdHO0lBQ0gsNEJBQTRCLEVBQUUsZ0JBQWdCLENBQUM7SUFDL0M7Ozs7T0FJRztJQUNILGdCQUFnQixFQUFFLDRCQUE0QixDQUFDO0NBQ2hELENBQUM7QUFFRjs7Ozs7Ozs7O0dBU0c7QUFDSCx3QkFBc0Isc0NBQXNDLENBQzFELEtBQUssRUFBRSxzQ0FBc0MsR0FDNUMsT0FBTyxDQUFDLHVCQUF1QixHQUFHLFNBQVMsQ0FBQyxDQXNEOUM7QUFxQkQsS0FBSyw2QkFBNkIsR0FBRztJQUNuQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztJQUNuQyxzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQztJQUMvQyxNQUFNLEVBQUUsY0FBYyxDQUFDO0lBQ3ZCLEdBQUcsRUFBRSxNQUFNLENBQUM7Q0FDYixDQUFDO0FBRUY7Ozs7O0dBS0c7QUFDSCx3QkFBc0IsK0JBQStCLENBQUMsS0FBSyxFQUFFLDZCQUE2QixzRUF3QnpGIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain_state_overrides.d.ts","sourceRoot":"","sources":["../../src/sequencer/chain_state_overrides.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,KAAK,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACrH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,KAAK,sBAAsB,EAAkC,MAAM,0BAA0B,CAAC;AACvG,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEtE,KAAK,sCAAsC,GAAG;IAC5C,8BAA8B;IAC9B,MAAM,EAAE,cAAc,CAAC;IACvB,wCAAwC;IACxC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD;;;OAGG;IACH,mCAAmC,CAAC,EAAE,gBAAgB,CAAC;IACvD;;;OAGG;IACH,4BAA4B,EAAE,gBAAgB,CAAC;IAC/C;;;;OAIG;IACH,gBAAgB,EAAE,4BAA4B,CAAC;CAChD,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAsB,sCAAsC,CAC1D,KAAK,EAAE,sCAAsC,GAC5C,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAsD9C;AAqBD,KAAK,6BAA6B,GAAG;IACnC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,MAAM,EAAE,cAAc,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,+BAA+B,CAAC,KAAK,EAAE,6BAA6B,sEAwBzF"}
|