@aztec/sequencer-client 0.8.9 → 0.8.11

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.
Files changed (41) hide show
  1. package/dest/block_builder/solo_block_builder.d.ts.map +1 -1
  2. package/dest/block_builder/solo_block_builder.js +3 -4
  3. package/dest/client/sequencer-client.d.ts +6 -1
  4. package/dest/client/sequencer-client.d.ts.map +1 -1
  5. package/dest/client/sequencer-client.js +8 -1
  6. package/dest/config.d.ts +9 -1
  7. package/dest/config.d.ts.map +1 -1
  8. package/dest/config.js +7 -6
  9. package/dest/publisher/index.d.ts +0 -27
  10. package/dest/publisher/index.d.ts.map +1 -1
  11. package/dest/publisher/index.js +1 -1
  12. package/dest/publisher/l1-publisher.d.ts +1 -1
  13. package/dest/publisher/l1-publisher.d.ts.map +1 -1
  14. package/dest/publisher/l1-publisher.js +5 -5
  15. package/dest/sequencer/config.d.ts +0 -8
  16. package/dest/sequencer/config.d.ts.map +1 -1
  17. package/dest/sequencer/sequencer.d.ts +7 -2
  18. package/dest/sequencer/sequencer.d.ts.map +1 -1
  19. package/dest/sequencer/sequencer.js +42 -22
  20. package/dest/simulator/public_executor.d.ts +1 -1
  21. package/dest/simulator/public_executor.d.ts.map +1 -1
  22. package/dest/simulator/public_executor.js +5 -5
  23. package/dest/simulator/public_kernel.d.ts.map +1 -1
  24. package/dest/simulator/public_kernel.js +5 -5
  25. package/dest/simulator/rollup.d.ts.map +1 -1
  26. package/dest/simulator/rollup.js +7 -7
  27. package/dest/utils.d.ts +3 -3
  28. package/dest/utils.d.ts.map +1 -1
  29. package/dest/utils.js +5 -5
  30. package/package.json +10 -10
  31. package/src/block_builder/solo_block_builder.ts +8 -3
  32. package/src/client/sequencer-client.ts +9 -1
  33. package/src/config.ts +21 -9
  34. package/src/publisher/index.ts +0 -28
  35. package/src/publisher/l1-publisher.ts +5 -5
  36. package/src/sequencer/config.ts +0 -10
  37. package/src/sequencer/sequencer.ts +49 -24
  38. package/src/simulator/public_executor.ts +5 -4
  39. package/src/simulator/public_kernel.ts +7 -6
  40. package/src/simulator/rollup.ts +10 -9
  41. package/src/utils.ts +4 -4
@@ -5,34 +5,6 @@ import { ViemTxSender } from './viem-tx-sender.js';
5
5
  export { L1Publisher } from './l1-publisher.js';
6
6
  export { PublisherConfig } from './config.js';
7
7
 
8
- /** Stats logged for each L1 rollup publish tx.*/
9
- export type L1PublishStats = {
10
- /** Name of the event for metrics purposes */
11
- eventName: 'rollup-published-to-l1';
12
- /** Effective gas price of the tx. */
13
- gasPrice: bigint;
14
- /** Effective gas used in the tx. */
15
- gasUsed: bigint;
16
- /** Hash of the L1 tx. */
17
- transactionHash: string;
18
- /** Gas cost of the calldata. */
19
- calldataGas: number;
20
- /** Size in bytes of the calldata. */
21
- calldataSize: number;
22
- /** Number of txs in the L2 block. */
23
- txCount: number;
24
- /** Number of the L2 block. */
25
- blockNumber: number;
26
- /** Number of encrypted logs. */
27
- encryptedLogCount?: number;
28
- /** Number of unencrypted logs. */
29
- unencryptedLogCount?: number;
30
- /** Serialised size of encrypted logs. */
31
- encryptedLogSize?: number;
32
- /** Serialised size of unencrypted logs. */
33
- unencryptedLogSize?: number;
34
- };
35
-
36
8
  /**
37
9
  * Returns a new instance of the L1Publisher.
38
10
  * @param config - Configuration to initialize the new instance.
@@ -1,12 +1,12 @@
1
1
  import { createDebugLogger } from '@aztec/foundation/log';
2
- import { InterruptableSleep } from '@aztec/foundation/sleep';
2
+ import { InterruptibleSleep } from '@aztec/foundation/sleep';
3
3
  import { ExtendedContractData, L2Block } from '@aztec/types';
4
+ import { L1PublishStats } from '@aztec/types/stats';
4
5
 
5
6
  import pick from 'lodash.pick';
6
7
 
7
8
  import { L2BlockReceiver } from '../receiver.js';
8
9
  import { PublisherConfig } from './config.js';
9
- import { L1PublishStats } from './index.js';
10
10
 
11
11
  /**
12
12
  * Stats for a sent transaction.
@@ -108,7 +108,7 @@ function isNotUndefined<T>(item: T | undefined): item is T {
108
108
  * Adapted from https://github.com/AztecProtocol/aztec2-internal/blob/master/falafel/src/rollup_publisher.ts.
109
109
  */
110
110
  export class L1Publisher implements L2BlockReceiver {
111
- private interruptableSleep = new InterruptableSleep();
111
+ private interruptibleSleep = new InterruptibleSleep();
112
112
  private sleepTimeMs: number;
113
113
  private interrupted = false;
114
114
  private log = createDebugLogger('aztec:sequencer:publisher');
@@ -217,7 +217,7 @@ export class L1Publisher implements L2BlockReceiver {
217
217
  */
218
218
  public interrupt() {
219
219
  this.interrupted = true;
220
- this.interruptableSleep.interrupt();
220
+ this.interruptibleSleep.interrupt();
221
221
  }
222
222
 
223
223
  /** Restarts the publisher after calling `interrupt`. */
@@ -276,6 +276,6 @@ export class L1Publisher implements L2BlockReceiver {
276
276
  }
277
277
 
278
278
  protected async sleepOrInterrupted() {
279
- await this.interruptableSleep.sleep(this.sleepTimeMs);
279
+ await this.interruptibleSleep.sleep(this.sleepTimeMs);
280
280
  }
281
281
  }
@@ -14,14 +14,4 @@ export interface SequencerConfig {
14
14
  * The minimum number of txs to include in a block.
15
15
  */
16
16
  minTxsPerBlock?: number;
17
-
18
- /**
19
- * The chain id of the ethereum host.
20
- */
21
- chainId: number;
22
-
23
- /**
24
- * The version of the rollup.
25
- */
26
- version: number;
27
17
  }
@@ -2,8 +2,10 @@ import { GlobalVariables } from '@aztec/circuits.js';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
3
  import { createDebugLogger } from '@aztec/foundation/log';
4
4
  import { RunningPromise } from '@aztec/foundation/running-promise';
5
+ import { Timer, elapsed } from '@aztec/foundation/timer';
5
6
  import { P2P } from '@aztec/p2p';
6
7
  import { ContractDataSource, L1ToL2MessageSource, L2Block, L2BlockSource, MerkleTreeId, Tx } from '@aztec/types';
8
+ import { L2BlockBuiltStats } from '@aztec/types/stats';
7
9
  import { WorldStateStatus, WorldStateSynchronizer } from '@aztec/world-state';
8
10
 
9
11
  import times from 'lodash.times';
@@ -27,7 +29,7 @@ import { PublicProcessorFactory } from './public_processor.js';
27
29
  */
28
30
  export class Sequencer {
29
31
  private runningPromise?: RunningPromise;
30
- private pollingIntervalMs: number;
32
+ private pollingIntervalMs: number = 1000;
31
33
  private maxTxsPerBlock = 32;
32
34
  private minTxsPerBLock = 1;
33
35
  private lastPublishedBlock = 0;
@@ -43,19 +45,23 @@ export class Sequencer {
43
45
  private l1ToL2MessageSource: L1ToL2MessageSource,
44
46
  private contractDataSource: ContractDataSource,
45
47
  private publicProcessorFactory: PublicProcessorFactory,
46
- config: SequencerConfig,
48
+ config: SequencerConfig = {},
47
49
  private log = createDebugLogger('aztec:sequencer'),
48
50
  ) {
49
- this.pollingIntervalMs = config.transactionPollingIntervalMS ?? 1_000;
50
- if (config.maxTxsPerBlock) {
51
- this.maxTxsPerBlock = config.maxTxsPerBlock;
52
- }
53
- if (config.minTxsPerBlock) {
54
- this.minTxsPerBLock = config.minTxsPerBlock;
55
- }
51
+ this.updateConfig(config);
56
52
  this.log(`Initialized sequencer with ${this.minTxsPerBLock}-${this.maxTxsPerBlock} txs per block.`);
57
53
  }
58
54
 
55
+ /**
56
+ * Updates sequencer config.
57
+ * @param config - New parameters.
58
+ */
59
+ public updateConfig(config: SequencerConfig) {
60
+ if (config.transactionPollingIntervalMS) this.pollingIntervalMs = config.transactionPollingIntervalMS;
61
+ if (config.maxTxsPerBlock) this.maxTxsPerBlock = config.maxTxsPerBlock;
62
+ if (config.minTxsPerBlock) this.minTxsPerBLock = config.minTxsPerBlock;
63
+ }
64
+
59
65
  /**
60
66
  * Starts the sequencer and moves to IDLE state. Blocks until the initial sync is complete.
61
67
  */
@@ -97,7 +103,7 @@ export class Sequencer {
97
103
  }
98
104
 
99
105
  protected async initialSync() {
100
- // TODO: Should we wait for worldstate to be ready, or is the caller expected to run await start?
106
+ // TODO: Should we wait for world state to be ready, or is the caller expected to run await start?
101
107
  this.lastPublishedBlock = await this.worldState.status().then((s: WorldStateStatus) => s.syncedToL2Block);
102
108
  }
103
109
 
@@ -116,6 +122,7 @@ export class Sequencer {
116
122
  // Do not go forward with new block if the previous one has not been mined and processed
117
123
  if (!prevBlockSynced) return;
118
124
 
125
+ const workTimer = new Timer();
119
126
  this.state = SequencerState.WAITING_FOR_TXS;
120
127
 
121
128
  // Get txs to build the new block
@@ -123,23 +130,23 @@ export class Sequencer {
123
130
  if (pendingTxs.length < this.minTxsPerBLock) return;
124
131
  this.log.info(`Retrieved ${pendingTxs.length} txs from P2P pool`);
125
132
 
133
+ const blockNumber = (await this.l2BlockSource.getBlockNumber()) + 1;
134
+ const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(new Fr(blockNumber));
135
+
126
136
  // Filter out invalid txs
127
137
  // TODO: It should be responsibility of the P2P layer to validate txs before passing them on here
128
- const validTxs = await this.takeValidTxs(pendingTxs);
138
+ const validTxs = await this.takeValidTxs(pendingTxs, newGlobalVariables);
129
139
  if (validTxs.length < this.minTxsPerBLock) return;
130
140
 
131
- const blockNumber = (await this.l2BlockSource.getBlockNumber()) + 1;
132
-
133
141
  this.log.info(`Building block ${blockNumber} with ${validTxs.length} transactions`);
134
142
  this.state = SequencerState.CREATING_BLOCK;
135
143
 
136
- const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(new Fr(blockNumber));
137
- const prevGlobalVariables = (await this.l2BlockSource.getL2Block(-1))?.globalVariables ?? GlobalVariables.empty();
144
+ const prevGlobalVariables = (await this.l2BlockSource.getBlock(-1))?.globalVariables ?? GlobalVariables.empty();
138
145
 
139
146
  // Process txs and drop the ones that fail processing
140
147
  // We create a fresh processor each time to reset any cached state (eg storage writes)
141
148
  const processor = await this.publicProcessorFactory.create(prevGlobalVariables, newGlobalVariables);
142
- const [processedTxs, failedTxs] = await processor.process(validTxs);
149
+ const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() => processor.process(validTxs));
143
150
  if (failedTxs.length > 0) {
144
151
  const failedTxData = failedTxs.map(fail => fail.tx);
145
152
  this.log(`Dropping failed txs ${(await Tx.getHashes(failedTxData)).join(', ')}`);
@@ -150,7 +157,7 @@ export class Sequencer {
150
157
  // public functions emitting nullifiers would pass earlier check but fail here.
151
158
  // Note that we're checking all nullifiers generated in the private execution twice,
152
159
  // we could store the ones already checked and skip them here as an optimisation.
153
- const processedValidTxs = await this.takeValidTxs(processedTxs);
160
+ const processedValidTxs = await this.takeValidTxs(processedTxs, newGlobalVariables);
154
161
 
155
162
  if (processedValidTxs.length === 0) {
156
163
  this.log('No txs processed correctly to build block. Exiting');
@@ -166,8 +173,17 @@ export class Sequencer {
166
173
  this.log(`Assembling block with txs ${processedValidTxs.map(tx => tx.hash).join(', ')}`);
167
174
 
168
175
  const emptyTx = await processor.makeEmptyProcessedTx();
169
- const block = await this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables);
170
- this.log(`Assembled block ${block.number}`);
176
+ const [rollupCircuitsDuration, block] = await elapsed(() =>
177
+ this.buildBlock(processedValidTxs, l1ToL2Messages, emptyTx, newGlobalVariables),
178
+ );
179
+
180
+ this.log(`Assembled block ${block.number}`, {
181
+ eventName: 'l2-block-built',
182
+ duration: workTimer.ms(),
183
+ publicProcessDuration: publicProcessorDuration,
184
+ rollupCircuitsDuration: rollupCircuitsDuration,
185
+ ...block.getStats(),
186
+ } satisfies L2BlockBuiltStats);
171
187
 
172
188
  await this.publishExtendedContractData(validTxs, block);
173
189
 
@@ -224,16 +240,25 @@ export class Sequencer {
224
240
  }
225
241
  }
226
242
 
227
- protected async takeValidTxs<T extends Tx | ProcessedTx>(txs: T[]): Promise<T[]> {
243
+ protected async takeValidTxs<T extends Tx | ProcessedTx>(txs: T[], globalVariables: GlobalVariables): Promise<T[]> {
228
244
  const validTxs: T[] = [];
229
- const doubleSpendTxs = [];
245
+ const txsToDelete = [];
230
246
  const thisBlockNullifiers: Set<bigint> = new Set();
231
247
 
232
248
  // Process txs until we get to maxTxsPerBlock, rejecting double spends in the process
233
249
  for (const tx of txs) {
250
+ if (tx.data.constants.txContext.chainId.value !== globalVariables.chainId.value) {
251
+ this.log(
252
+ `Deleting tx for incorrect chain ${tx.data.constants.txContext.chainId.toString()}, tx hash ${await Tx.getHash(
253
+ tx,
254
+ )}`,
255
+ );
256
+ txsToDelete.push(tx);
257
+ continue;
258
+ }
234
259
  if (await this.isTxDoubleSpend(tx)) {
235
260
  this.log(`Deleting double spend tx ${await Tx.getHash(tx)}`);
236
- doubleSpendTxs.push(tx);
261
+ txsToDelete.push(tx);
237
262
  continue;
238
263
  } else if (this.isTxDoubleSpendSameBlock(tx, thisBlockNullifiers)) {
239
264
  // We don't drop these txs from the p2p pool immediately since they become valid
@@ -248,8 +273,8 @@ export class Sequencer {
248
273
  }
249
274
 
250
275
  // Make sure we remove these from the tx pool so we do not consider it again
251
- if (doubleSpendTxs.length > 0) {
252
- await this.p2pClient.deleteTxs(await Tx.getHashes([...doubleSpendTxs]));
276
+ if (txsToDelete.length > 0) {
277
+ await this.p2pClient.deleteTxs(await Tx.getHashes([...txsToDelete]));
253
278
  }
254
279
 
255
280
  return validTxs;
@@ -6,8 +6,9 @@ import {
6
6
  PublicStateDB,
7
7
  } from '@aztec/acir-simulator';
8
8
  import { AztecAddress, CircuitsWasm, EthAddress, Fr, FunctionSelector, HistoricBlockData } from '@aztec/circuits.js';
9
+ import { computePublicDataTreeIndex } from '@aztec/circuits.js/abis';
9
10
  import { ContractDataSource, ExtendedContractData, L1ToL2MessageSource, MerkleTreeId, Tx } from '@aztec/types';
10
- import { MerkleTreeOperations, computePublicDataTreeLeafIndex } from '@aztec/world-state';
11
+ import { MerkleTreeOperations } from '@aztec/world-state';
11
12
 
12
13
  /**
13
14
  * Returns a new PublicExecutor simulator backed by the supplied merkle tree db and contract data source.
@@ -31,7 +32,7 @@ export function getPublicExecutor(
31
32
 
32
33
  /**
33
34
  * Implements the PublicContractsDB using a ContractDataSource.
34
- * Progresively records contracts in transaction as they are processed in a block.
35
+ * Progressively records contracts in transaction as they are processed in a block.
35
36
  */
36
37
  export class ContractsDataSourcePublicDB implements PublicContractsDB {
37
38
  cache = new Map<string, ExtendedContractData>();
@@ -106,7 +107,7 @@ class WorldStatePublicDB implements PublicStateDB {
106
107
  * @returns The current value in the storage slot.
107
108
  */
108
109
  public async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
109
- const index = computePublicDataTreeLeafIndex(contract, slot, await CircuitsWasm.get());
110
+ const index = computePublicDataTreeIndex(await CircuitsWasm.get(), contract, slot).value;
110
111
  const cached = this.writeCache.get(index);
111
112
  if (cached !== undefined) return cached;
112
113
  const value = await this.db.getLeafValue(MerkleTreeId.PUBLIC_DATA_TREE, index);
@@ -120,7 +121,7 @@ class WorldStatePublicDB implements PublicStateDB {
120
121
  * @param newValue - The new value to store.
121
122
  */
122
123
  public async storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<void> {
123
- const index = computePublicDataTreeLeafIndex(contract, slot, await CircuitsWasm.get());
124
+ const index = computePublicDataTreeIndex(await CircuitsWasm.get(), contract, slot).value;
124
125
  this.writeCache.set(index, newValue);
125
126
  }
126
127
  }
@@ -1,6 +1,7 @@
1
1
  import { PublicKernelInputs, PublicKernelPublicInputs, simulatePublicKernelCircuit } from '@aztec/circuits.js';
2
2
  import { createDebugLogger } from '@aztec/foundation/log';
3
3
  import { elapsed } from '@aztec/foundation/timer';
4
+ import { CircuitSimulationStats } from '@aztec/types/stats';
4
5
 
5
6
  import { PublicKernelCircuitSimulator } from './index.js';
6
7
 
@@ -17,14 +18,14 @@ export class WasmPublicKernelCircuitSimulator implements PublicKernelCircuitSimu
17
18
  */
18
19
  public async publicKernelCircuitPrivateInput(input: PublicKernelInputs): Promise<PublicKernelPublicInputs> {
19
20
  if (!input.previousKernel.publicInputs.isPrivate) throw new Error(`Expected private kernel previous inputs`);
20
- const [time, result] = await elapsed(() => simulatePublicKernelCircuit(input));
21
+ const [duration, result] = await elapsed(() => simulatePublicKernelCircuit(input));
21
22
  this.log(`Simulated public kernel circuit with private input`, {
22
23
  eventName: 'circuit-simulation',
23
24
  circuitName: 'public-kernel-private-input',
24
- duration: time.ms(),
25
+ duration,
25
26
  inputSize: input.toBuffer().length,
26
27
  outputSize: result.toBuffer().length,
27
- });
28
+ } satisfies CircuitSimulationStats);
28
29
  return result;
29
30
  }
30
31
 
@@ -35,14 +36,14 @@ export class WasmPublicKernelCircuitSimulator implements PublicKernelCircuitSimu
35
36
  */
36
37
  public async publicKernelCircuitNonFirstIteration(input: PublicKernelInputs): Promise<PublicKernelPublicInputs> {
37
38
  if (input.previousKernel.publicInputs.isPrivate) throw new Error(`Expected public kernel previous inputs`);
38
- const [time, result] = await elapsed(() => simulatePublicKernelCircuit(input));
39
+ const [duration, result] = await elapsed(() => simulatePublicKernelCircuit(input));
39
40
  this.log(`Simulated public kernel circuit non-first iteration`, {
40
41
  eventName: 'circuit-simulation',
41
42
  circuitName: 'public-kernel-non-first-iteration',
42
- duration: time.ms(),
43
+ duration,
43
44
  inputSize: input.toBuffer().length,
44
45
  outputSize: result.toBuffer().length,
45
- });
46
+ } satisfies CircuitSimulationStats);
46
47
  return result;
47
48
  }
48
49
  }
@@ -12,6 +12,7 @@ import {
12
12
  } from '@aztec/circuits.js';
13
13
  import { createDebugLogger } from '@aztec/foundation/log';
14
14
  import { elapsed } from '@aztec/foundation/timer';
15
+ import { CircuitSimulationStats } from '@aztec/types/stats';
15
16
 
16
17
  import { RollupSimulator } from './index.js';
17
18
 
@@ -28,7 +29,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
28
29
  */
29
30
  public async baseRollupCircuit(input: BaseRollupInputs): Promise<BaseOrMergeRollupPublicInputs> {
30
31
  const wasm = await CircuitsWasm.get();
31
- const [time, result] = await elapsed(() => baseRollupSim(wasm, input));
32
+ const [duration, result] = await elapsed(() => baseRollupSim(wasm, input));
32
33
  if (result instanceof CircuitError) {
33
34
  throw new CircuitError(result.code, result.message);
34
35
  }
@@ -36,10 +37,10 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
36
37
  this.log(`Simulated base rollup circuit`, {
37
38
  eventName: 'circuit-simulation',
38
39
  circuitName: 'base-rollup',
39
- duration: time.ms(),
40
+ duration,
40
41
  inputSize: input.toBuffer().length,
41
42
  outputSize: result.toBuffer().length,
42
- });
43
+ } satisfies CircuitSimulationStats);
43
44
 
44
45
  return Promise.resolve(result);
45
46
  }
@@ -50,7 +51,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
50
51
  */
51
52
  public async mergeRollupCircuit(input: MergeRollupInputs): Promise<BaseOrMergeRollupPublicInputs> {
52
53
  const wasm = await CircuitsWasm.get();
53
- const [time, result] = await elapsed(() => mergeRollupSim(wasm, input));
54
+ const [duration, result] = await elapsed(() => mergeRollupSim(wasm, input));
54
55
  if (result instanceof CircuitError) {
55
56
  throw new CircuitError(result.code, result.message);
56
57
  }
@@ -58,10 +59,10 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
58
59
  this.log(`Simulated merge rollup circuit`, {
59
60
  eventName: 'circuit-simulation',
60
61
  circuitName: 'merge-rollup',
61
- duration: time.ms(),
62
+ duration,
62
63
  inputSize: input.toBuffer().length,
63
64
  outputSize: result.toBuffer().length,
64
- });
65
+ } satisfies CircuitSimulationStats);
65
66
 
66
67
  return result;
67
68
  }
@@ -73,7 +74,7 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
73
74
  */
74
75
  public async rootRollupCircuit(input: RootRollupInputs): Promise<RootRollupPublicInputs> {
75
76
  const wasm = await CircuitsWasm.get();
76
- const [time, result] = await elapsed(() => rootRollupSim(wasm, input));
77
+ const [duration, result] = await elapsed(() => rootRollupSim(wasm, input));
77
78
  if (result instanceof CircuitError) {
78
79
  throw new CircuitError(result.code, result.message);
79
80
  }
@@ -81,10 +82,10 @@ export class WasmRollupCircuitSimulator implements RollupSimulator {
81
82
  this.log(`Simulated root rollup circuit`, {
82
83
  eventName: 'circuit-simulation',
83
84
  circuitName: 'root-rollup',
84
- duration: time.ms(),
85
+ duration,
85
86
  inputSize: input.toBuffer().length,
86
87
  outputSize: result.toBuffer().length,
87
- });
88
+ } satisfies CircuitSimulationStats);
88
89
 
89
90
  return result;
90
91
  }
package/src/utils.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Returns a promise that resolves after ms milliseconds, returning retval.
2
+ * Returns a promise that resolves after ms milliseconds, returning "returnValue".
3
3
  * @param ms - How many milliseconds to sleep.
4
- * @param retval - The return value of the promise.
4
+ * @param returnValue - The return value of the promise.
5
5
  */
6
- export function sleep<T>(ms: number, retval: T): Promise<T> {
7
- return new Promise(resolve => setTimeout(() => resolve(retval), ms));
6
+ export function sleep<T>(ms: number, returnValue: T): Promise<T> {
7
+ return new Promise(resolve => setTimeout(() => resolve(returnValue), ms));
8
8
  }
9
9
 
10
10
  /**