@aztec/prover-node 0.0.0-test.0 → 0.0.1-commit.03f7ef2

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 (82) hide show
  1. package/dest/actions/download-epoch-proving-job.d.ts +18 -0
  2. package/dest/actions/download-epoch-proving-job.d.ts.map +1 -0
  3. package/dest/actions/download-epoch-proving-job.js +37 -0
  4. package/dest/actions/index.d.ts +3 -0
  5. package/dest/actions/index.d.ts.map +1 -0
  6. package/dest/actions/index.js +2 -0
  7. package/dest/actions/rerun-epoch-proving-job.d.ts +11 -0
  8. package/dest/actions/rerun-epoch-proving-job.d.ts.map +1 -0
  9. package/dest/actions/rerun-epoch-proving-job.js +40 -0
  10. package/dest/actions/upload-epoch-proof-failure.d.ts +15 -0
  11. package/dest/actions/upload-epoch-proof-failure.d.ts.map +1 -0
  12. package/dest/actions/upload-epoch-proof-failure.js +78 -0
  13. package/dest/bin/run-failed-epoch.d.ts +2 -0
  14. package/dest/bin/run-failed-epoch.d.ts.map +1 -0
  15. package/dest/bin/run-failed-epoch.js +67 -0
  16. package/dest/config.d.ts +15 -11
  17. package/dest/config.d.ts.map +1 -1
  18. package/dest/config.js +83 -15
  19. package/dest/factory.d.ts +16 -12
  20. package/dest/factory.d.ts.map +1 -1
  21. package/dest/factory.js +100 -32
  22. package/dest/index.d.ts +2 -2
  23. package/dest/index.d.ts.map +1 -1
  24. package/dest/index.js +1 -1
  25. package/dest/job/epoch-proving-job-data.d.ts +18 -0
  26. package/dest/job/epoch-proving-job-data.d.ts.map +1 -0
  27. package/dest/job/epoch-proving-job-data.js +59 -0
  28. package/dest/job/epoch-proving-job.d.ts +26 -18
  29. package/dest/job/epoch-proving-job.d.ts.map +1 -1
  30. package/dest/job/epoch-proving-job.js +193 -84
  31. package/dest/metrics.d.ts +30 -5
  32. package/dest/metrics.d.ts.map +1 -1
  33. package/dest/metrics.js +147 -35
  34. package/dest/monitors/epoch-monitor.d.ts +5 -2
  35. package/dest/monitors/epoch-monitor.d.ts.map +1 -1
  36. package/dest/monitors/epoch-monitor.js +17 -3
  37. package/dest/monitors/index.d.ts +1 -1
  38. package/dest/prover-node-publisher.d.ts +14 -15
  39. package/dest/prover-node-publisher.d.ts.map +1 -1
  40. package/dest/prover-node-publisher.js +86 -81
  41. package/dest/prover-node.d.ts +49 -44
  42. package/dest/prover-node.d.ts.map +1 -1
  43. package/dest/prover-node.js +186 -112
  44. package/dest/prover-publisher-factory.d.ts +23 -0
  45. package/dest/prover-publisher-factory.d.ts.map +1 -0
  46. package/dest/prover-publisher-factory.js +26 -0
  47. package/dest/test/index.d.ts +5 -3
  48. package/dest/test/index.d.ts.map +1 -1
  49. package/dest/test/index.js +1 -3
  50. package/package.json +39 -33
  51. package/src/actions/download-epoch-proving-job.ts +44 -0
  52. package/src/actions/index.ts +2 -0
  53. package/src/actions/rerun-epoch-proving-job.ts +61 -0
  54. package/src/actions/upload-epoch-proof-failure.ts +88 -0
  55. package/src/bin/run-failed-epoch.ts +77 -0
  56. package/src/config.ts +111 -25
  57. package/src/factory.ts +167 -44
  58. package/src/index.ts +1 -1
  59. package/src/job/epoch-proving-job-data.ts +82 -0
  60. package/src/job/epoch-proving-job.ts +255 -83
  61. package/src/metrics.ts +147 -37
  62. package/src/monitors/epoch-monitor.ts +19 -7
  63. package/src/prover-node-publisher.ts +132 -115
  64. package/src/prover-node.ts +223 -142
  65. package/src/prover-publisher-factory.ts +39 -0
  66. package/src/test/index.ts +7 -4
  67. package/dest/http.d.ts +0 -8
  68. package/dest/http.d.ts.map +0 -1
  69. package/dest/http.js +0 -9
  70. package/dest/prover-coordination/config.d.ts +0 -7
  71. package/dest/prover-coordination/config.d.ts.map +0 -1
  72. package/dest/prover-coordination/config.js +0 -11
  73. package/dest/prover-coordination/factory.d.ts +0 -22
  74. package/dest/prover-coordination/factory.d.ts.map +0 -1
  75. package/dest/prover-coordination/factory.js +0 -42
  76. package/dest/prover-coordination/index.d.ts +0 -3
  77. package/dest/prover-coordination/index.d.ts.map +0 -1
  78. package/dest/prover-coordination/index.js +0 -2
  79. package/src/http.ts +0 -13
  80. package/src/prover-coordination/config.ts +0 -17
  81. package/src/prover-coordination/factory.ts +0 -72
  82. package/src/prover-coordination/index.ts +0 -2
package/dest/metrics.js CHANGED
@@ -1,83 +1,193 @@
1
1
  import { createLogger } from '@aztec/foundation/log';
2
2
  import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
3
- import { formatEther } from 'viem';
4
- export class ProverNodeMetrics {
5
- client;
3
+ import { formatEther, formatUnits } from 'viem';
4
+ export class ProverNodeJobMetrics {
5
+ meter;
6
+ tracer;
6
7
  logger;
7
8
  proverEpochExecutionDuration;
8
9
  provingJobDuration;
10
+ provingJobCheckpoints;
9
11
  provingJobBlocks;
10
12
  provingJobTransactions;
11
- gasPrice;
12
- txCount;
13
- txDuration;
14
- txGas;
15
- txCalldataSize;
16
- txCalldataGas;
17
- txBlobDataGasUsed;
18
- txBlobDataGasCost;
19
- senderBalance;
20
- constructor(client, name = 'ProverNode', logger = createLogger('prover-node:publisher:metrics')){
21
- this.client = client;
13
+ constructor(meter, tracer, logger = createLogger('prover-node:publisher:metrics')){
14
+ this.meter = meter;
15
+ this.tracer = tracer;
22
16
  this.logger = logger;
23
- const meter = client.getMeter(name);
24
- this.proverEpochExecutionDuration = meter.createHistogram(Metrics.PROVER_NODE_EXECUTION_DURATION, {
17
+ this.proverEpochExecutionDuration = this.meter.createHistogram(Metrics.PROVER_NODE_EXECUTION_DURATION, {
25
18
  description: 'Duration of execution of an epoch by the prover',
26
19
  unit: 'ms',
27
20
  valueType: ValueType.INT
28
21
  });
29
- this.provingJobDuration = meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
22
+ this.provingJobDuration = this.meter.createHistogram(Metrics.PROVER_NODE_JOB_DURATION, {
30
23
  description: 'Duration of proving job',
31
24
  unit: 's',
32
25
  valueType: ValueType.DOUBLE
33
26
  });
34
- this.provingJobBlocks = meter.createGauge(Metrics.PROVER_NODE_JOB_BLOCKS, {
27
+ this.provingJobCheckpoints = this.meter.createGauge(Metrics.PROVER_NODE_JOB_CHECKPOINTS, {
28
+ description: 'Number of checkpoints in a proven epoch',
29
+ valueType: ValueType.INT
30
+ });
31
+ this.provingJobBlocks = this.meter.createGauge(Metrics.PROVER_NODE_JOB_BLOCKS, {
35
32
  description: 'Number of blocks in a proven epoch',
36
33
  valueType: ValueType.INT
37
34
  });
38
- this.provingJobTransactions = meter.createGauge(Metrics.PROVER_NODE_JOB_TRANSACTIONS, {
35
+ this.provingJobTransactions = this.meter.createGauge(Metrics.PROVER_NODE_JOB_TRANSACTIONS, {
39
36
  description: 'Number of transactions in a proven epoch',
40
37
  valueType: ValueType.INT
41
38
  });
42
- this.gasPrice = meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE, {
39
+ }
40
+ recordProvingJob(executionTimeMs, totalTimeMs, numCheckpoints, numBlocks, numTxs) {
41
+ this.proverEpochExecutionDuration.record(Math.ceil(executionTimeMs));
42
+ this.provingJobDuration.record(totalTimeMs / 1000);
43
+ this.provingJobCheckpoints.record(Math.floor(numCheckpoints));
44
+ this.provingJobBlocks.record(Math.floor(numBlocks));
45
+ this.provingJobTransactions.record(Math.floor(numTxs));
46
+ }
47
+ }
48
+ export class ProverNodeRewardsMetrics {
49
+ meter;
50
+ coinbase;
51
+ rollup;
52
+ logger;
53
+ rewards;
54
+ accumulatedRewards;
55
+ prevEpoch;
56
+ proofSubmissionEpochs;
57
+ constructor(meter, coinbase, rollup, logger = createLogger('prover-node:publisher:metrics')){
58
+ this.meter = meter;
59
+ this.coinbase = coinbase;
60
+ this.rollup = rollup;
61
+ this.logger = logger;
62
+ this.prevEpoch = -1n;
63
+ this.proofSubmissionEpochs = 0;
64
+ this.observe = async (observer)=>{
65
+ const epoch = await this.rollup.getCurrentEpochNumber();
66
+ if (epoch > this.proofSubmissionEpochs) {
67
+ // look at the prev epoch so that we get an accurate value, after proof submission window has closed
68
+ // For example, if proof submission window is 1 epoch, and we are in epoch 2, we should be looking at epoch 0.
69
+ // Similarly, if the proof submission window is 0, and we are in epoch 1, we should be looking at epoch 0.
70
+ const closedEpoch = BigInt(epoch) - BigInt(this.proofSubmissionEpochs) - 1n;
71
+ const rewards = await this.rollup.getSpecificProverRewardsForEpoch(closedEpoch, this.coinbase);
72
+ const fmt = parseFloat(formatUnits(rewards, 18));
73
+ observer.observe(this.rewards, fmt, {
74
+ [Attributes.COINBASE]: this.coinbase.toString()
75
+ });
76
+ // only accumulate once per epoch
77
+ if (closedEpoch > this.prevEpoch) {
78
+ this.prevEpoch = closedEpoch;
79
+ this.accumulatedRewards.add(fmt, {
80
+ [Attributes.COINBASE]: this.coinbase.toString()
81
+ });
82
+ }
83
+ }
84
+ };
85
+ this.rewards = this.meter.createObservableGauge(Metrics.PROVER_NODE_REWARDS_PER_EPOCH, {
86
+ valueType: ValueType.DOUBLE,
87
+ description: 'The rewards earned'
88
+ });
89
+ this.accumulatedRewards = this.meter.createUpDownCounter(Metrics.PROVER_NODE_REWARDS_TOTAL, {
90
+ valueType: ValueType.DOUBLE,
91
+ description: 'The rewards earned (total)'
92
+ });
93
+ }
94
+ async start() {
95
+ const proofSubmissionEpochs = await this.rollup.getProofSubmissionEpochs();
96
+ this.proofSubmissionEpochs = Number(proofSubmissionEpochs);
97
+ this.meter.addBatchObservableCallback(this.observe, [
98
+ this.rewards
99
+ ]);
100
+ }
101
+ stop() {
102
+ this.meter.removeBatchObservableCallback(this.observe, [
103
+ this.rewards
104
+ ]);
105
+ }
106
+ observe;
107
+ }
108
+ export class ProverNodePublisherMetrics {
109
+ client;
110
+ logger;
111
+ gasPrice;
112
+ txCount;
113
+ txDuration;
114
+ txGas;
115
+ txCalldataSize;
116
+ txCalldataGas;
117
+ txBlobDataGasUsed;
118
+ txBlobDataGasCost;
119
+ txTotalFee;
120
+ senderBalance;
121
+ meter;
122
+ constructor(client, name = 'ProverNode', logger = createLogger('prover-node:publisher:metrics')){
123
+ this.client = client;
124
+ this.logger = logger;
125
+ this.meter = client.getMeter(name);
126
+ this.gasPrice = this.meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE, {
43
127
  description: 'The gas price used for transactions',
44
128
  unit: 'gwei',
45
129
  valueType: ValueType.DOUBLE
46
130
  });
47
- this.txCount = meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT, {
131
+ this.txCount = this.meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT, {
48
132
  description: 'The number of transactions processed'
49
133
  });
50
- this.txDuration = meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION, {
134
+ this.txDuration = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION, {
51
135
  description: 'The duration of transaction processing',
52
136
  unit: 'ms',
53
137
  valueType: ValueType.INT
54
138
  });
55
- this.txGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS, {
139
+ this.txGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS, {
56
140
  description: 'The gas consumed by transactions',
57
141
  unit: 'gas',
58
142
  valueType: ValueType.INT
59
143
  });
60
- this.txCalldataSize = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE, {
144
+ this.txCalldataSize = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE, {
61
145
  description: 'The size of the calldata in transactions',
62
146
  unit: 'By',
63
147
  valueType: ValueType.INT
64
148
  });
65
- this.txCalldataGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS, {
149
+ this.txCalldataGas = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS, {
66
150
  description: 'The gas consumed by the calldata in transactions',
67
151
  unit: 'gas',
68
152
  valueType: ValueType.INT
69
153
  });
70
- this.txBlobDataGasUsed = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED, {
154
+ this.txBlobDataGasUsed = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED, {
71
155
  description: 'The amount of blob gas used in transactions',
72
156
  unit: 'gas',
73
157
  valueType: ValueType.INT
74
158
  });
75
- this.txBlobDataGasCost = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST, {
159
+ this.txBlobDataGasCost = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST, {
76
160
  description: 'The gas cost of blobs in transactions',
77
161
  unit: 'gwei',
78
162
  valueType: ValueType.INT
79
163
  });
80
- this.senderBalance = meter.createGauge(Metrics.L1_PUBLISHER_BALANCE, {
164
+ this.txTotalFee = this.meter.createHistogram(Metrics.L1_PUBLISHER_TX_TOTAL_FEE, {
165
+ description: 'How much L1 tx costs',
166
+ unit: 'gwei',
167
+ valueType: ValueType.DOUBLE,
168
+ advice: {
169
+ explicitBucketBoundaries: [
170
+ 0.001,
171
+ 0.002,
172
+ 0.004,
173
+ 0.008,
174
+ 0.01,
175
+ 0.02,
176
+ 0.04,
177
+ 0.08,
178
+ 0.1,
179
+ 0.2,
180
+ 0.4,
181
+ 0.8,
182
+ 1,
183
+ 1.2,
184
+ 1.4,
185
+ 1.8,
186
+ 2
187
+ ]
188
+ }
189
+ });
190
+ this.senderBalance = this.meter.createGauge(Metrics.L1_PUBLISHER_BALANCE, {
81
191
  unit: 'eth',
82
192
  description: 'The balance of the sender address',
83
193
  valueType: ValueType.DOUBLE
@@ -92,12 +202,6 @@ export class ProverNodeMetrics {
92
202
  recordSubmitProof(durationMs, stats) {
93
203
  this.recordTx(durationMs, stats);
94
204
  }
95
- recordProvingJob(executionTimeMs, totalTimeMs, numBlocks, numTxs) {
96
- this.proverEpochExecutionDuration.record(Math.ceil(executionTimeMs));
97
- this.provingJobDuration.record(totalTimeMs / 1000);
98
- this.provingJobBlocks.record(Math.floor(numBlocks));
99
- this.provingJobTransactions.record(Math.floor(numTxs));
100
- }
101
205
  recordSenderBalance(wei, senderAddress) {
102
206
  const eth = parseFloat(formatEther(wei, 'wei'));
103
207
  this.senderBalance.record(eth, {
@@ -122,7 +226,15 @@ export class ProverNodeMetrics {
122
226
  this.txBlobDataGasUsed.record(Number(stats.blobGasUsed), attributes);
123
227
  try {
124
228
  this.gasPrice.record(parseInt(formatEther(stats.gasPrice, 'gwei'), 10));
125
- } catch (e) {
229
+ } catch {
230
+ // ignore
231
+ }
232
+ const executionFee = stats.gasUsed * stats.gasPrice;
233
+ const blobFee = stats.blobGasUsed * stats.blobDataGas;
234
+ const totalFee = executionFee + blobFee;
235
+ try {
236
+ this.txTotalFee.record(parseFloat(formatEther(totalFee)));
237
+ } catch {
126
238
  // ignore
127
239
  }
128
240
  }
@@ -1,8 +1,9 @@
1
+ import { EpochNumber } from '@aztec/foundation/branded-types';
1
2
  import type { L2BlockSource } from '@aztec/stdlib/block';
2
3
  import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
3
4
  import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
4
5
  export interface EpochMonitorHandler {
5
- handleEpochReadyToProve(epochNumber: bigint): Promise<void>;
6
+ handleEpochReadyToProve(epochNumber: EpochNumber): Promise<boolean>;
6
7
  }
7
8
  /**
8
9
  * Fires an event when a new epoch ready to prove is detected.
@@ -26,9 +27,11 @@ export declare class EpochMonitor implements Traceable {
26
27
  private latestEpochNumber;
27
28
  constructor(l2BlockSource: L2BlockSource, l1Constants: Pick<L1RollupConstants, 'epochDuration'>, options: {
28
29
  pollingIntervalMs: number;
30
+ provingDelayMs?: number;
29
31
  }, telemetry?: TelemetryClient);
30
32
  static create(l2BlockSource: L2BlockSource, options: {
31
33
  pollingIntervalMs: number;
34
+ provingDelayMs?: number;
32
35
  }, telemetry?: TelemetryClient): Promise<EpochMonitor>;
33
36
  start(handler: EpochMonitorHandler): void;
34
37
  /** Exposed for testing */
@@ -37,4 +40,4 @@ export declare class EpochMonitor implements Traceable {
37
40
  work(): Promise<void>;
38
41
  private getEpochNumberToProve;
39
42
  }
40
- //# sourceMappingURL=epoch-monitor.d.ts.map
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBvY2gtbW9uaXRvci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vbml0b3JzL2Vwb2NoLW1vbml0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFlLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBSTNFLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUFrQixNQUFNLDZCQUE2QixDQUFDO0FBQ3JGLE9BQU8sRUFDTCxLQUFLLGVBQWUsRUFDcEIsS0FBSyxTQUFTLEVBQ2QsS0FBSyxNQUFNLEVBR1osTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxNQUFNLFdBQVcsbUJBQW1CO0lBQ2xDLHVCQUF1QixDQUFDLFdBQVcsRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0NBQ3JFO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILHFCQUFhLFlBQWEsWUFBVyxTQUFTO0lBUzFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsYUFBYTtJQUM5QixPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVc7SUFDNUIsT0FBTyxDQUFDLE9BQU87SUFWakIsT0FBTyxDQUFDLGNBQWMsQ0FBaUI7SUFDdkMsT0FBTyxDQUFDLEdBQUcsQ0FBNkM7SUFDeEQsU0FBZ0IsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUUvQixPQUFPLENBQUMsT0FBTyxDQUFrQztJQUNqRCxPQUFPLENBQUMsaUJBQWlCLENBQTBCO0lBRW5ELFlBQ21CLGFBQWEsRUFBRSxhQUFhLEVBQzVCLFdBQVcsRUFBRSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsZUFBZSxDQUFDLEVBQzlELE9BQU8sRUFBRTtRQUFFLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztRQUFDLGNBQWMsQ0FBQyxFQUFFLE1BQU0sQ0FBQTtLQUFFLEVBQ3ZFLFNBQVMsR0FBRSxlQUFzQyxFQU9sRDtJQUVELE9BQW9CLE1BQU0sQ0FDeEIsYUFBYSxFQUFFLGFBQWEsRUFDNUIsT0FBTyxFQUFFO1FBQUUsaUJBQWlCLEVBQUUsTUFBTSxDQUFDO1FBQUMsY0FBYyxDQUFDLEVBQUUsTUFBTSxDQUFBO0tBQUUsRUFDL0QsU0FBUyxHQUFFLGVBQXNDLEdBQ2hELE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FHdkI7SUFFTSxLQUFLLENBQUMsT0FBTyxFQUFFLG1CQUFtQixRQUl4QztJQUVELDBCQUEwQjtJQUNuQixVQUFVLENBQUMsT0FBTyxFQUFFLG1CQUFtQixRQUU3QztJQUVZLElBQUksa0JBR2hCO0lBR1ksSUFBSSxrQkEyQmhCO1lBRWEscUJBQXFCO0NBWXBDIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"epoch-monitor.d.ts","sourceRoot":"","sources":["../../src/monitors/epoch-monitor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,KAAK,iBAAiB,EAAkB,MAAM,6BAA6B,CAAC;AACrF,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IAClC,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,YAAW,SAAS;IAS1C,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,OAAO;IAVjB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,GAAG,CAA6C;IACxD,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,iBAAiB,CAAqB;gBAG3B,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,EAC9D,OAAO,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAA;KAAE,EAC9C,SAAS,GAAE,eAAsC;WAM/B,MAAM,CACxB,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAA;KAAE,EACtC,SAAS,GAAE,eAAsC,GAChD,OAAO,CAAC,YAAY,CAAC;IAKjB,KAAK,CAAC,OAAO,EAAE,mBAAmB;IAMzC,0BAA0B;IACnB,UAAU,CAAC,OAAO,EAAE,mBAAmB;IAIjC,IAAI;IAMJ,IAAI;YAsBH,qBAAqB;CAYpC"}
1
+ {"version":3,"file":"epoch-monitor.d.ts","sourceRoot":"","sources":["../../src/monitors/epoch-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAI3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,KAAK,iBAAiB,EAAkB,MAAM,6BAA6B,CAAC;AACrF,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IAClC,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACrE;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,YAAW,SAAS;IAS1C,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,OAAO;IAVjB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,GAAG,CAA6C;IACxD,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,iBAAiB,CAA0B;IAEnD,YACmB,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,EAC9D,OAAO,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,EACvE,SAAS,GAAE,eAAsC,EAOlD;IAED,OAAoB,MAAM,CACxB,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,EAC/D,SAAS,GAAE,eAAsC,GAChD,OAAO,CAAC,YAAY,CAAC,CAGvB;IAEM,KAAK,CAAC,OAAO,EAAE,mBAAmB,QAIxC;IAED,0BAA0B;IACnB,UAAU,CAAC,OAAO,EAAE,mBAAmB,QAE7C;IAEY,IAAI,kBAGhB;IAGY,IAAI,kBA2BhB;YAEa,qBAAqB;CAYpC"}
@@ -4,8 +4,10 @@ function _ts_decorate(decorators, target, key, desc) {
4
4
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  }
7
+ import { BlockNumber } from '@aztec/foundation/branded-types';
7
8
  import { createLogger } from '@aztec/foundation/log';
8
9
  import { RunningPromise } from '@aztec/foundation/running-promise';
10
+ import { sleep } from '@aztec/foundation/sleep';
9
11
  import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
10
12
  import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
11
13
  /**
@@ -34,6 +36,9 @@ import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
34
36
  this.log = createLogger('prover-node:epoch-monitor');
35
37
  this.tracer = telemetry.getTracer('EpochMonitor');
36
38
  this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.options.pollingIntervalMs);
39
+ if (this.options.provingDelayMs) {
40
+ this.log.warn(`Prover node epoch monitor running with delay of ${this.options.provingDelayMs}ms`);
41
+ }
37
42
  }
38
43
  static async create(l2BlockSource, options, telemetry = getTelemetryClient()) {
39
44
  const l1Constants = await l2BlockSource.getL1Constants();
@@ -53,6 +58,10 @@ import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
53
58
  }
54
59
  async work() {
55
60
  const { epochToProve, blockNumber, slotNumber } = await this.getEpochNumberToProve();
61
+ this.log.debug(`Epoch to prove: ${epochToProve}`, {
62
+ blockNumber,
63
+ slotNumber
64
+ });
56
65
  if (epochToProve === undefined) {
57
66
  this.log.trace(`Next block to prove ${blockNumber} not yet mined`, {
58
67
  blockNumber
@@ -76,13 +85,18 @@ import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
76
85
  });
77
86
  return;
78
87
  }
88
+ if (this.options.provingDelayMs) {
89
+ this.log.debug(`Waiting ${this.options.provingDelayMs}ms before proving epoch ${epochToProve}`);
90
+ await sleep(this.options.provingDelayMs);
91
+ }
79
92
  this.log.debug(`Epoch ${epochToProve} is ready to be proven`);
80
- await this.handler?.handleEpochReadyToProve(epochToProve);
81
- this.latestEpochNumber = epochToProve;
93
+ if (await this.handler?.handleEpochReadyToProve(epochToProve)) {
94
+ this.latestEpochNumber = epochToProve;
95
+ }
82
96
  }
83
97
  async getEpochNumberToProve() {
84
98
  const lastBlockProven = await this.l2BlockSource.getProvenBlockNumber();
85
- const firstBlockToProve = lastBlockProven + 1;
99
+ const firstBlockToProve = BlockNumber(lastBlockProven + 1);
86
100
  const firstBlockHeaderToProve = await this.l2BlockSource.getBlockHeader(firstBlockToProve);
87
101
  if (!firstBlockHeaderToProve) {
88
102
  return {
@@ -1,2 +1,2 @@
1
1
  export * from './epoch-monitor.js';
2
- //# sourceMappingURL=index.d.ts.map
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb25pdG9ycy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLG9CQUFvQixDQUFDIn0=
@@ -1,22 +1,20 @@
1
+ import { BatchedBlob } from '@aztec/blob-lib';
1
2
  import { AZTEC_MAX_EPOCH_DURATION } from '@aztec/constants';
2
- import type { L1TxUtils, RollupContract } from '@aztec/ethereum';
3
+ import type { RollupContract, ViemCommitteeAttestation } from '@aztec/ethereum/contracts';
4
+ import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
5
+ import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
6
+ import { Fr } from '@aztec/foundation/curves/bn254';
3
7
  import { EthAddress } from '@aztec/foundation/eth-address';
4
- import { Fr } from '@aztec/foundation/fields';
5
- import { type Tuple } from '@aztec/foundation/serialize';
8
+ import type { Tuple } from '@aztec/foundation/serialize';
6
9
  import type { PublisherConfig, TxSenderConfig } from '@aztec/sequencer-client';
7
10
  import type { Proof } from '@aztec/stdlib/proofs';
8
11
  import type { FeeRecipient, RootRollupPublicInputs } from '@aztec/stdlib/rollup';
9
12
  import { type TelemetryClient } from '@aztec/telemetry-client';
10
- /**
11
- * Stats for a sent transaction.
12
- */
13
13
  /** Arguments to the submitEpochProof method of the rollup contract */
14
14
  export type L1SubmitEpochProofArgs = {
15
15
  epochSize: number;
16
16
  previousArchive: Fr;
17
17
  endArchive: Fr;
18
- previousBlockHash: Fr;
19
- endBlockHash: Fr;
20
18
  endTimestamp: Fr;
21
19
  outHash: Fr;
22
20
  proverId: Fr;
@@ -24,8 +22,6 @@ export type L1SubmitEpochProofArgs = {
24
22
  proof: Proof;
25
23
  };
26
24
  export declare class ProverNodePublisher {
27
- private interruptibleSleep;
28
- private sleepTimeMs;
29
25
  private interrupted;
30
26
  private metrics;
31
27
  protected log: import("@aztec/foundation/log").Logger;
@@ -36,6 +32,7 @@ export declare class ProverNodePublisher {
36
32
  l1TxUtils: L1TxUtils;
37
33
  telemetry?: TelemetryClient;
38
34
  });
35
+ getRollupContract(): RollupContract;
39
36
  /**
40
37
  * Calling `interrupt` will cause any in progress call to `publishRollup` to return `false` asap.
41
38
  * Be warned, the call may return false even if the tx subsequently gets successfully mined.
@@ -47,15 +44,17 @@ export declare class ProverNodePublisher {
47
44
  restart(): void;
48
45
  getSenderAddress(): EthAddress;
49
46
  submitEpochProof(args: {
50
- epochNumber: number;
51
- fromBlock: number;
52
- toBlock: number;
47
+ epochNumber: EpochNumber;
48
+ fromCheckpoint: CheckpointNumber;
49
+ toCheckpoint: CheckpointNumber;
53
50
  publicInputs: RootRollupPublicInputs;
54
51
  proof: Proof;
52
+ batchedBlobInputs: BatchedBlob;
53
+ attestations: ViemCommitteeAttestation[];
55
54
  }): Promise<boolean>;
56
55
  private validateEpochProofSubmission;
57
56
  private sendSubmitEpochProofTx;
57
+ private getEpochProofPublicInputsArgs;
58
58
  private getSubmitEpochProofArgs;
59
- protected sleepOrInterrupted(): Promise<void>;
60
59
  }
61
- //# sourceMappingURL=prover-node-publisher.d.ts.map
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLW5vZGUtcHVibGlzaGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLW5vZGUtcHVibGlzaGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQThCLE1BQU0saUJBQWlCLENBQUM7QUFDMUUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDMUYsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRWhGLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFM0QsT0FBTyxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFHekQsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRS9FLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWpGLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBc0IsTUFBTSx5QkFBeUIsQ0FBQztBQU9uRixzRUFBc0U7QUFDdEUsTUFBTSxNQUFNLHNCQUFzQixHQUFHO0lBQ25DLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsZUFBZSxFQUFFLEVBQUUsQ0FBQztJQUNwQixVQUFVLEVBQUUsRUFBRSxDQUFDO0lBQ2YsWUFBWSxFQUFFLEVBQUUsQ0FBQztJQUNqQixPQUFPLEVBQUUsRUFBRSxDQUFDO0lBQ1osUUFBUSxFQUFFLEVBQUUsQ0FBQztJQUNiLElBQUksRUFBRSxLQUFLLENBQUMsWUFBWSxFQUFFLE9BQU8sd0JBQXdCLENBQUMsQ0FBQztJQUMzRCxLQUFLLEVBQUUsS0FBSyxDQUFDO0NBQ2QsQ0FBQztBQUVGLHFCQUFhLG1CQUFtQjtJQUM5QixPQUFPLENBQUMsV0FBVyxDQUFTO0lBQzVCLE9BQU8sQ0FBQyxPQUFPLENBQTZCO0lBRTVDLFNBQVMsQ0FBQyxHQUFHLHlDQUErQztJQUU1RCxTQUFTLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQztJQUV6QyxTQUFnQixTQUFTLEVBQUUsU0FBUyxDQUFDO0lBRXJDLFlBQ0UsTUFBTSxFQUFFLGNBQWMsR0FBRyxlQUFlLEVBQ3hDLElBQUksRUFBRTtRQUNKLGNBQWMsRUFBRSxjQUFjLENBQUM7UUFDL0IsU0FBUyxFQUFFLFNBQVMsQ0FBQztRQUNyQixTQUFTLENBQUMsRUFBRSxlQUFlLENBQUM7S0FDN0IsRUFRRjtJQUVNLGlCQUFpQixtQkFFdkI7SUFFRDs7Ozs7T0FLRztJQUNJLFNBQVMsU0FHZjtJQUVELHdEQUF3RDtJQUNqRCxPQUFPLFNBR2I7SUFFTSxnQkFBZ0IsZUFFdEI7SUFFWSxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUU7UUFDbEMsV0FBVyxFQUFFLFdBQVcsQ0FBQztRQUN6QixjQUFjLEVBQUUsZ0JBQWdCLENBQUM7UUFDakMsWUFBWSxFQUFFLGdCQUFnQixDQUFDO1FBQy9CLFlBQVksRUFBRSxzQkFBc0IsQ0FBQztRQUNyQyxLQUFLLEVBQUUsS0FBSyxDQUFDO1FBQ2IsaUJBQWlCLEVBQUUsV0FBVyxDQUFDO1FBQy9CLFlBQVksRUFBRSx3QkFBd0IsRUFBRSxDQUFDO0tBQzFDLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQWlEbkI7WUFFYSw0QkFBNEI7WUErRDVCLHNCQUFzQjtJQTRDcEMsT0FBTyxDQUFDLDZCQUE2QjtJQXlCckMsT0FBTyxDQUFDLHVCQUF1QjtDQXVCaEMifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"prover-node-publisher.d.ts","sourceRoot":"","sources":["../src/prover-node-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,EAAE,KAAK,KAAK,EAAqB,MAAM,6BAA6B,CAAC;AAI5E,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAMnF;;GAEG;AACH,sEAAsE;AACtE,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,EAAE,CAAC;IACpB,UAAU,EAAE,EAAE,CAAC;IACf,iBAAiB,EAAE,EAAE,CAAC;IACtB,YAAY,EAAE,EAAE,CAAC;IACjB,YAAY,EAAE,EAAE,CAAC;IACjB,OAAO,EAAE,EAAE,CAAC;IACZ,QAAQ,EAAE,EAAE,CAAC;IACb,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,wBAAwB,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAoB;IAEnC,SAAS,CAAC,GAAG,yCAA+C;IAE5D,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC;IAEzC,SAAgB,SAAS,EAAE,SAAS,CAAC;gBAGnC,MAAM,EAAE,cAAc,GAAG,eAAe,EACxC,IAAI,EAAE;QACJ,cAAc,EAAE,cAAc,CAAC;QAC/B,SAAS,EAAE,SAAS,CAAC;QACrB,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B;IAYH;;;;;OAKG;IACI,SAAS;IAKhB,wDAAwD;IACjD,OAAO;IAIP,gBAAgB;IAIV,gBAAgB,CAAC,IAAI,EAAE;QAClC,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,sBAAsB,CAAC;QACrC,KAAK,EAAE,KAAK,CAAC;KACd,GAAG,OAAO,CAAC,OAAO,CAAC;YAgDN,4BAA4B;YAyD5B,sBAAsB;IAoDpC,OAAO,CAAC,uBAAuB;cA+Bf,kBAAkB;CAGnC"}
1
+ {"version":3,"file":"prover-node-publisher.d.ts","sourceRoot":"","sources":["../src/prover-node-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAA8B,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAGzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAOnF,sEAAsE;AACtE,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,EAAE,CAAC;IACpB,UAAU,EAAE,EAAE,CAAC;IACf,YAAY,EAAE,EAAE,CAAC;IACjB,OAAO,EAAE,EAAE,CAAC;IACZ,QAAQ,EAAE,EAAE,CAAC;IACb,IAAI,EAAE,KAAK,CAAC,YAAY,EAAE,OAAO,wBAAwB,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAA6B;IAE5C,SAAS,CAAC,GAAG,yCAA+C;IAE5D,SAAS,CAAC,cAAc,EAAE,cAAc,CAAC;IAEzC,SAAgB,SAAS,EAAE,SAAS,CAAC;IAErC,YACE,MAAM,EAAE,cAAc,GAAG,eAAe,EACxC,IAAI,EAAE;QACJ,cAAc,EAAE,cAAc,CAAC;QAC/B,SAAS,EAAE,SAAS,CAAC;QACrB,SAAS,CAAC,EAAE,eAAe,CAAC;KAC7B,EAQF;IAEM,iBAAiB,mBAEvB;IAED;;;;;OAKG;IACI,SAAS,SAGf;IAED,wDAAwD;IACjD,OAAO,SAGb;IAEM,gBAAgB,eAEtB;IAEY,gBAAgB,CAAC,IAAI,EAAE;QAClC,WAAW,EAAE,WAAW,CAAC;QACzB,cAAc,EAAE,gBAAgB,CAAC;QACjC,YAAY,EAAE,gBAAgB,CAAC;QAC/B,YAAY,EAAE,sBAAsB,CAAC;QACrC,KAAK,EAAE,KAAK,CAAC;QACb,iBAAiB,EAAE,WAAW,CAAC;QAC/B,YAAY,EAAE,wBAAwB,EAAE,CAAC;KAC1C,GAAG,OAAO,CAAC,OAAO,CAAC,CAiDnB;YAEa,4BAA4B;YA+D5B,sBAAsB;IA4CpC,OAAO,CAAC,6BAA6B;IAyBrC,OAAO,CAAC,uBAAuB;CAuBhC"}