@aztec/prover-node 0.56.0 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dest/bond/bond-manager.d.ts +22 -0
  2. package/dest/bond/bond-manager.d.ts.map +1 -0
  3. package/dest/bond/bond-manager.js +42 -0
  4. package/dest/bond/config.d.ts +8 -0
  5. package/dest/bond/config.d.ts.map +1 -0
  6. package/dest/bond/config.js +17 -0
  7. package/dest/bond/escrow-contract.d.ts +22 -0
  8. package/dest/bond/escrow-contract.d.ts.map +1 -0
  9. package/dest/bond/escrow-contract.js +32 -0
  10. package/dest/bond/factory.d.ts +9 -0
  11. package/dest/bond/factory.d.ts.map +1 -0
  12. package/dest/bond/factory.js +18 -0
  13. package/dest/bond/index.d.ts +3 -0
  14. package/dest/bond/index.d.ts.map +1 -0
  15. package/dest/bond/index.js +3 -0
  16. package/dest/bond/token-contract.d.ts +29 -0
  17. package/dest/bond/token-contract.d.ts.map +1 -0
  18. package/dest/bond/token-contract.js +58 -0
  19. package/dest/config.d.ts +10 -4
  20. package/dest/config.d.ts.map +1 -1
  21. package/dest/config.js +30 -9
  22. package/dest/factory.d.ts.map +1 -1
  23. package/dest/factory.js +39 -9
  24. package/dest/job/{block-proving-job.d.ts → epoch-proving-job.d.ts} +13 -9
  25. package/dest/job/epoch-proving-job.d.ts.map +1 -0
  26. package/dest/job/epoch-proving-job.js +119 -0
  27. package/dest/monitors/claims-monitor.d.ts +22 -0
  28. package/dest/monitors/claims-monitor.d.ts.map +1 -0
  29. package/dest/monitors/claims-monitor.js +37 -0
  30. package/dest/monitors/epoch-monitor.d.ts +20 -0
  31. package/dest/monitors/epoch-monitor.d.ts.map +1 -0
  32. package/dest/monitors/epoch-monitor.js +34 -0
  33. package/dest/monitors/index.d.ts +3 -0
  34. package/dest/monitors/index.d.ts.map +1 -0
  35. package/dest/monitors/index.js +3 -0
  36. package/dest/prover-coordination/config.d.ts +7 -0
  37. package/dest/prover-coordination/config.d.ts.map +1 -0
  38. package/dest/prover-coordination/config.js +12 -0
  39. package/dest/prover-coordination/factory.d.ts +4 -0
  40. package/dest/prover-coordination/factory.d.ts.map +1 -0
  41. package/dest/prover-coordination/factory.js +10 -0
  42. package/dest/prover-coordination/index.d.ts +3 -0
  43. package/dest/prover-coordination/index.d.ts.map +1 -0
  44. package/dest/prover-coordination/index.js +3 -0
  45. package/dest/prover-node.d.ts +56 -32
  46. package/dest/prover-node.d.ts.map +1 -1
  47. package/dest/prover-node.js +124 -70
  48. package/dest/quote-provider/http.d.ts +15 -0
  49. package/dest/quote-provider/http.d.ts.map +1 -0
  50. package/dest/quote-provider/http.js +32 -0
  51. package/dest/quote-provider/index.d.ts +6 -0
  52. package/dest/quote-provider/index.d.ts.map +1 -0
  53. package/dest/quote-provider/index.js +2 -0
  54. package/dest/quote-provider/simple.d.ts +9 -0
  55. package/dest/quote-provider/simple.d.ts.map +1 -0
  56. package/dest/quote-provider/simple.js +11 -0
  57. package/dest/quote-provider/utils.d.ts +4 -0
  58. package/dest/quote-provider/utils.d.ts.map +1 -0
  59. package/dest/quote-provider/utils.js +8 -0
  60. package/dest/quote-signer.d.ts +13 -0
  61. package/dest/quote-signer.d.ts.map +1 -0
  62. package/dest/quote-signer.js +18 -0
  63. package/package.json +19 -13
  64. package/src/bond/bond-manager.ts +48 -0
  65. package/src/bond/config.ts +25 -0
  66. package/src/bond/escrow-contract.ts +63 -0
  67. package/src/bond/factory.ts +47 -0
  68. package/src/bond/index.ts +2 -0
  69. package/src/bond/token-contract.ts +85 -0
  70. package/src/config.ts +47 -12
  71. package/src/factory.ts +51 -10
  72. package/src/job/{block-proving-job.ts → epoch-proving-job.ts} +46 -56
  73. package/src/monitors/claims-monitor.ts +52 -0
  74. package/src/monitors/epoch-monitor.ts +48 -0
  75. package/src/monitors/index.ts +2 -0
  76. package/src/prover-coordination/config.ts +17 -0
  77. package/src/prover-coordination/factory.ts +11 -0
  78. package/src/{tx-provider → prover-coordination}/index.ts +1 -2
  79. package/src/prover-node.ts +163 -90
  80. package/src/quote-provider/http.ts +47 -0
  81. package/src/quote-provider/index.ts +8 -0
  82. package/src/quote-provider/simple.ts +15 -0
  83. package/src/quote-provider/utils.ts +10 -0
  84. package/src/quote-signer.ts +24 -0
  85. package/dest/job/block-proving-job.d.ts.map +0 -1
  86. package/dest/job/block-proving-job.js +0 -120
  87. package/dest/tx-provider/aztec-node-tx-provider.d.ts +0 -8
  88. package/dest/tx-provider/aztec-node-tx-provider.d.ts.map +0 -1
  89. package/dest/tx-provider/aztec-node-tx-provider.js +0 -10
  90. package/dest/tx-provider/config.d.ts +0 -7
  91. package/dest/tx-provider/config.d.ts.map +0 -1
  92. package/dest/tx-provider/config.js +0 -12
  93. package/dest/tx-provider/factory.d.ts +0 -4
  94. package/dest/tx-provider/factory.d.ts.map +0 -1
  95. package/dest/tx-provider/factory.js +0 -12
  96. package/dest/tx-provider/index.d.ts +0 -4
  97. package/dest/tx-provider/index.d.ts.map +0 -1
  98. package/dest/tx-provider/index.js +0 -4
  99. package/src/tx-provider/aztec-node-tx-provider.ts +0 -10
  100. package/src/tx-provider/config.ts +0 -17
  101. package/src/tx-provider/factory.ts +0 -13
@@ -1,49 +1,130 @@
1
+ import { EpochProofQuotePayload, } from '@aztec/circuit-types';
2
+ import { compact } from '@aztec/foundation/collection';
1
3
  import { createDebugLogger } from '@aztec/foundation/log';
2
- import { RunningPromise } from '@aztec/foundation/running-promise';
3
4
  import { PublicProcessorFactory } from '@aztec/simulator';
4
- import { BlockProvingJob } from './job/block-proving-job.js';
5
+ import { EpochProvingJob } from './job/epoch-proving-job.js';
5
6
  import { ProverNodeMetrics } from './metrics.js';
6
7
  /**
7
8
  * An Aztec Prover Node is a standalone process that monitors the unfinalised chain on L1 for unproven blocks,
8
- * fetches their txs from a tx source in the p2p network or an external node, re-executes their public functions,
9
- * creates a rollup proof, and submits it to L1.
9
+ * submits bids for proving them, and monitors if they are accepted. If so, the prover node fetches the txs
10
+ * from a tx source in the p2p network or an external node, re-executes their public functions, creates a rollup
11
+ * proof for the epoch, and submits it to L1.
10
12
  */
11
13
  export class ProverNode {
12
- constructor(prover, publisher, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, txProvider, simulator, telemetryClient, options = {}) {
14
+ constructor(prover, publisher, l2BlockSource, l1ToL2MessageSource, contractDataSource, worldState, coordination, simulator, quoteProvider, quoteSigner, claimsMonitor, epochsMonitor, bondManager, telemetryClient, options = {}) {
13
15
  this.prover = prover;
14
16
  this.publisher = publisher;
15
17
  this.l2BlockSource = l2BlockSource;
16
18
  this.l1ToL2MessageSource = l1ToL2MessageSource;
17
19
  this.contractDataSource = contractDataSource;
18
20
  this.worldState = worldState;
19
- this.txProvider = txProvider;
21
+ this.coordination = coordination;
20
22
  this.simulator = simulator;
23
+ this.quoteProvider = quoteProvider;
24
+ this.quoteSigner = quoteSigner;
25
+ this.claimsMonitor = claimsMonitor;
26
+ this.epochsMonitor = epochsMonitor;
27
+ this.bondManager = bondManager;
21
28
  this.telemetryClient = telemetryClient;
22
29
  this.log = createDebugLogger('aztec:prover-node');
23
30
  this.jobs = new Map();
24
31
  this.options = {
25
32
  pollingIntervalMs: 1000,
26
- disableAutomaticProving: false,
27
33
  maxPendingJobs: 100,
28
- ...options,
34
+ ...compact(options),
29
35
  };
30
36
  this.metrics = new ProverNodeMetrics(telemetryClient, 'ProverNode');
31
37
  }
38
+ async handleClaim(proofClaim) {
39
+ if (proofClaim.epochToProve === this.latestEpochWeAreProving) {
40
+ this.log.verbose(`Already proving claim for epoch ${proofClaim.epochToProve}`);
41
+ return;
42
+ }
43
+ try {
44
+ await this.startProof(proofClaim.epochToProve);
45
+ this.latestEpochWeAreProving = proofClaim.epochToProve;
46
+ }
47
+ catch (err) {
48
+ this.log.error(`Error handling claim for epoch ${proofClaim.epochToProve}`, err);
49
+ }
50
+ try {
51
+ // Staked amounts are lowered after a claim, so this is a good time for doing a top-up if needed
52
+ await this.bondManager.ensureBond();
53
+ }
54
+ catch (err) {
55
+ this.log.error(`Error ensuring prover bond after handling claim for epoch ${proofClaim.epochToProve}`, err);
56
+ }
57
+ }
32
58
  /**
33
- * Starts the prover node so it periodically checks for unproven blocks in the unfinalised chain from L1 and proves them.
34
- * This may change once we implement a prover coordination mechanism.
59
+ * Handles the epoch number to prove when the prover node starts by checking if there
60
+ * is an existing claim for it. If not, it creates and sends a quote for it.
61
+ * @param epochNumber - The epoch immediately before the current one when the prover node starts.
35
62
  */
36
- start() {
37
- this.runningPromise = new RunningPromise(this.work.bind(this), this.options.pollingIntervalMs);
38
- this.runningPromise.start();
39
- this.log.info('Started ProverNode');
63
+ async handleInitialEpochSync(epochNumber) {
64
+ try {
65
+ const claim = await this.publisher.getProofClaim();
66
+ if (!claim || claim.epochToProve < epochNumber) {
67
+ await this.handleEpochCompleted(epochNumber);
68
+ }
69
+ else if (claim && claim.bondProvider.equals(this.publisher.getSenderAddress())) {
70
+ const lastEpochProven = await this.l2BlockSource.getProvenL2EpochNumber();
71
+ if (lastEpochProven === undefined || lastEpochProven < claim.epochToProve) {
72
+ await this.handleClaim(claim);
73
+ }
74
+ }
75
+ }
76
+ catch (err) {
77
+ this.log.error(`Error handling initial epoch sync`, err);
78
+ }
79
+ }
80
+ /**
81
+ * Handles an epoch being completed by sending a quote for proving it.
82
+ * @param epochNumber - The epoch number that was just completed.
83
+ */
84
+ async handleEpochCompleted(epochNumber) {
85
+ try {
86
+ // Construct a quote for the epoch
87
+ const blocks = await this.l2BlockSource.getBlocksForEpoch(epochNumber);
88
+ const partialQuote = await this.quoteProvider.getQuote(Number(epochNumber), blocks);
89
+ if (!partialQuote) {
90
+ this.log.verbose(`No quote produced for epoch ${epochNumber}`);
91
+ return;
92
+ }
93
+ // Ensure we have deposited enough funds for sending this quote
94
+ await this.bondManager.ensureBond(partialQuote.bondAmount);
95
+ // Assemble and sign full quote
96
+ const quote = EpochProofQuotePayload.from({
97
+ ...partialQuote,
98
+ epochToProve: BigInt(epochNumber),
99
+ prover: this.publisher.getSenderAddress(),
100
+ validUntilSlot: partialQuote.validUntilSlot ?? BigInt(Number.MAX_SAFE_INTEGER), // Should we constrain this?
101
+ });
102
+ const signed = await this.quoteSigner.sign(quote);
103
+ // Send it to the coordinator
104
+ await this.sendEpochProofQuote(signed);
105
+ }
106
+ catch (err) {
107
+ this.log.error(`Error handling epoch completed`, err);
108
+ }
109
+ }
110
+ /**
111
+ * Starts the prover node so it periodically checks for unproven epochs in the unfinalised chain from L1 and sends
112
+ * quotes for them, as well as monitors the claims for the epochs it has sent quotes for and starts proving jobs.
113
+ * This method returns once the prover node has deposited an initial bond into the escrow contract.
114
+ */
115
+ async start() {
116
+ await this.bondManager.ensureBond();
117
+ this.epochsMonitor.start(this);
118
+ this.claimsMonitor.start(this);
119
+ this.log.info('Started ProverNode', this.options);
40
120
  }
41
121
  /**
42
122
  * Stops the prover node and all its dependencies.
43
123
  */
44
124
  async stop() {
45
125
  this.log.info('Stopping ProverNode');
46
- await this.runningPromise?.stop();
126
+ await this.epochsMonitor.stop();
127
+ await this.claimsMonitor.stop();
47
128
  await this.prover.stop();
48
129
  await this.l2BlockSource.stop();
49
130
  this.publisher.interrupt();
@@ -52,64 +133,25 @@ export class ProverNode {
52
133
  this.log.info('Stopped ProverNode');
53
134
  }
54
135
  /**
55
- * Single iteration of recurring work. This method is called periodically by the running promise.
56
- * Checks whether there are new blocks to prove, proves them, and submits them.
136
+ * Sends an epoch proof quote to the coordinator.
57
137
  */
58
- async work() {
59
- try {
60
- if (this.options.disableAutomaticProving) {
61
- return;
62
- }
63
- if (!this.checkMaximumPendingJobs()) {
64
- this.log.debug(`Maximum pending proving jobs reached. Skipping work.`, {
65
- maxPendingJobs: this.options.maxPendingJobs,
66
- pendingJobs: this.jobs.size,
67
- });
68
- return;
69
- }
70
- const [latestBlockNumber, latestProvenBlockNumber] = await Promise.all([
71
- this.l2BlockSource.getBlockNumber(),
72
- this.l2BlockSource.getProvenBlockNumber(),
73
- ]);
74
- // Consider both the latest block we are proving and the last block proven on the chain
75
- const latestBlockBeingProven = this.latestBlockWeAreProving ?? 0;
76
- const latestProven = Math.max(latestBlockBeingProven, latestProvenBlockNumber);
77
- if (latestProven >= latestBlockNumber) {
78
- this.log.debug(`No new blocks to prove`, {
79
- latestBlockNumber,
80
- latestProvenBlockNumber,
81
- latestBlockBeingProven,
82
- });
83
- return;
84
- }
85
- const fromBlock = latestProven + 1;
86
- const toBlock = fromBlock; // We only prove one block at a time for now
87
- try {
88
- await this.startProof(fromBlock, toBlock);
89
- }
90
- finally {
91
- // If we fail to create a proving job for the given block, skip it instead of getting stuck on it.
92
- this.log.verbose(`Setting ${toBlock} as latest block we are proving`);
93
- this.latestBlockWeAreProving = toBlock;
94
- }
95
- }
96
- catch (err) {
97
- this.log.error(`Error in prover node work`, err);
98
- }
138
+ sendEpochProofQuote(quote) {
139
+ this.log.info(`Sending quote for epoch`, quote.toViemArgs().quote);
140
+ return this.coordination.addEpochProofQuote(quote);
99
141
  }
100
142
  /**
101
143
  * Creates a proof for a block range. Returns once the proof has been submitted to L1.
102
144
  */
103
- async prove(fromBlock, toBlock) {
104
- const job = await this.createProvingJob(fromBlock);
105
- return job.run(fromBlock, toBlock);
145
+ async prove(epochNumber) {
146
+ const job = await this.createProvingJob(BigInt(epochNumber));
147
+ return job.run();
106
148
  }
107
149
  /**
108
150
  * Starts a proving process and returns immediately.
109
151
  */
110
- async startProof(fromBlock, toBlock) {
111
- const job = await this.createProvingJob(fromBlock);
112
- void job.run(fromBlock, toBlock);
152
+ async startProof(epochNumber) {
153
+ const job = await this.createProvingJob(BigInt(epochNumber));
154
+ void job.run().catch(err => this.log.error(`Error proving epoch ${epochNumber}`, err));
113
155
  }
114
156
  /**
115
157
  * Returns the prover instance.
@@ -127,15 +169,22 @@ export class ProverNode {
127
169
  const { maxPendingJobs } = this.options;
128
170
  return maxPendingJobs === 0 || this.jobs.size < maxPendingJobs;
129
171
  }
130
- async createProvingJob(fromBlock) {
172
+ async createProvingJob(epochNumber) {
131
173
  if (!this.checkMaximumPendingJobs()) {
132
174
  throw new Error(`Maximum pending proving jobs ${this.options.maxPendingJobs} reached. Cannot create new job.`);
133
175
  }
176
+ // Gather blocks for this epoch
177
+ const blocks = await this.l2BlockSource.getBlocksForEpoch(epochNumber);
178
+ if (blocks.length === 0) {
179
+ throw new Error(`No blocks found for epoch ${epochNumber}`);
180
+ }
181
+ const fromBlock = blocks[0].number;
182
+ const toBlock = blocks.at(-1).number;
134
183
  if ((await this.worldState.status()).syncedToL2Block >= fromBlock) {
135
184
  throw new Error(`Cannot create proving job for block ${fromBlock} as it is behind the current world state`);
136
185
  }
137
186
  // Fast forward world state to right before the target block and get a fork
138
- this.log.verbose(`Creating proving job for block ${fromBlock}`);
187
+ this.log.verbose(`Creating proving job for epoch ${epochNumber} for block range ${fromBlock} to ${toBlock}`);
139
188
  const db = await this.worldState.syncImmediateAndFork(fromBlock - 1, true);
140
189
  // Create a processor using the forked world state
141
190
  const publicProcessorFactory = new PublicProcessorFactory(db, this.contractDataSource, this.simulator, this.telemetryClient);
@@ -143,13 +192,18 @@ export class ProverNode {
143
192
  await db.delete();
144
193
  this.jobs.delete(job.getId());
145
194
  };
146
- const job = this.doCreateBlockProvingJob(db, publicProcessorFactory, cleanUp);
195
+ const job = this.doCreateEpochProvingJob(epochNumber, blocks, db, publicProcessorFactory, cleanUp);
147
196
  this.jobs.set(job.getId(), job);
148
197
  return job;
149
198
  }
150
199
  /** Extracted for testing purposes. */
151
- doCreateBlockProvingJob(db, publicProcessorFactory, cleanUp) {
152
- return new BlockProvingJob(this.prover.createBlockProver(db), publicProcessorFactory, this.publisher, this.l2BlockSource, this.l1ToL2MessageSource, this.txProvider, this.metrics, cleanUp);
200
+ doCreateEpochProvingJob(epochNumber, blocks, db, publicProcessorFactory, cleanUp) {
201
+ return new EpochProvingJob(epochNumber, blocks, this.prover.createEpochProver(db), publicProcessorFactory, this.publisher, this.l2BlockSource, this.l1ToL2MessageSource, this.coordination, this.metrics, cleanUp);
202
+ }
203
+ /** Extracted for testing purposes. */
204
+ async triggerMonitors() {
205
+ await this.epochsMonitor.work();
206
+ await this.claimsMonitor.work();
153
207
  }
154
208
  }
155
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLW5vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLW5vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBUUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxzQkFBc0IsRUFBMkIsTUFBTSxrQkFBa0IsQ0FBQztBQUluRixPQUFPLEVBQUUsZUFBZSxFQUE2QixNQUFNLDRCQUE0QixDQUFDO0FBQ3hGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFRckIsWUFDVSxNQUFvQixFQUNwQixTQUFzQixFQUN0QixhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsa0JBQXNDLEVBQ3RDLFVBQWtDLEVBQ2xDLFVBQXNCLEVBQ3RCLFNBQTZCLEVBQzdCLGVBQWdDLEVBQ3hDLFVBQXNHLEVBQUU7UUFUaEcsV0FBTSxHQUFOLE1BQU0sQ0FBYztRQUNwQixjQUFTLEdBQVQsU0FBUyxDQUFhO1FBQ3RCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxlQUFVLEdBQVYsVUFBVSxDQUF3QjtRQUNsQyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLGNBQVMsR0FBVCxTQUFTLENBQW9CO1FBQzdCLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQWhCbEMsUUFBRyxHQUFHLGlCQUFpQixDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFHN0MsU0FBSSxHQUFpQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBZ0JyRCxJQUFJLENBQUMsT0FBTyxHQUFHO1lBQ2IsaUJBQWlCLEVBQUUsSUFBSztZQUN4Qix1QkFBdUIsRUFBRSxL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
209
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmVyLW5vZGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcHJvdmVyLW5vZGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdMLHNCQUFzQixHQVF2QixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRCxPQUFPLEVBQUUsc0JBQXNCLEVBQTJCLE1BQU0sa0JBQWtCLENBQUM7QUFLbkYsT0FBTyxFQUFFLGVBQWUsRUFBNkIsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFXakQ7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQVFyQixZQUNtQixNQUEwQixFQUMxQixTQUFzQixFQUN0QixhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsa0JBQXNDLEVBQ3RDLFVBQWtDLEVBQ2xDLFlBQWdDLEVBQ2hDLFNBQTZCLEVBQzdCLGFBQTRCLEVBQzVCLFdBQXdCLEVBQ3hCLGFBQTRCLEVBQzVCLGFBQTJCLEVBQzNCLFdBQXdCLEVBQ3hCLGVBQWdDLEVBQ2pELFVBQXNDLEVBQUU7UUFkdkIsV0FBTSxHQUFOLE1BQU0sQ0FBb0I7UUFDMUIsY0FBUyxHQUFULFNBQVMsQ0FBYTtRQUN0QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQUM1Qix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsZUFBVSxHQUFWLFVBQVUsQ0FBd0I7UUFDbEMsaUJBQVksR0FBWixZQUFZLENBQW9CO1FBQ2hDLGNBQVMsR0FBVCxTQUFTLENBQW9CO1FBQzdCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLGtCQUFhLEdB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
@@ -0,0 +1,15 @@
1
+ import { type L2Block } from '@aztec/circuit-types';
2
+ import { type QuoteProvider, type QuoteProviderResult } from './index.js';
3
+ export declare class HttpQuoteProvider implements QuoteProvider {
4
+ private readonly url;
5
+ constructor(url: string);
6
+ getQuote(epochNumber: number, epoch: L2Block[]): Promise<QuoteProviderResult | undefined>;
7
+ }
8
+ export type HttpQuoteRequestPayload = {
9
+ epochNumber: number;
10
+ fromBlock: number;
11
+ toBlock: number;
12
+ totalFees: string;
13
+ txCount: number;
14
+ };
15
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/quote-provider/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAG1E,qBAAa,iBAAkB,YAAW,aAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,MAAM;IAE3B,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;CA8BvG;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { getTotalFees, getTxCount } from './utils.js';
2
+ export class HttpQuoteProvider {
3
+ constructor(url) {
4
+ this.url = url;
5
+ }
6
+ async getQuote(epochNumber, epoch) {
7
+ const payload = {
8
+ epochNumber,
9
+ fromBlock: epoch[0].number,
10
+ toBlock: epoch.at(-1).number,
11
+ totalFees: getTotalFees(epoch).toString(),
12
+ txCount: getTxCount(epoch),
13
+ };
14
+ const response = await fetch(this.url, {
15
+ method: 'POST',
16
+ body: JSON.stringify(payload),
17
+ headers: { 'content-type': 'application/json' },
18
+ });
19
+ if (!response.ok) {
20
+ throw new Error(`Failed to fetch quote: ${response.statusText}`);
21
+ }
22
+ const data = await response.json();
23
+ if (!data.basisPointFee || !data.bondAmount) {
24
+ throw new Error(`Missing required fields in response: ${JSON.stringify(data)}`);
25
+ }
26
+ const basisPointFee = Number(data.basisPointFee);
27
+ const bondAmount = BigInt(data.bondAmount);
28
+ const validUntilSlot = data.validUntilSlot ? BigInt(data.validUntilSlot) : undefined;
29
+ return { basisPointFee, bondAmount, validUntilSlot };
30
+ }
31
+ }
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9xdW90ZS1wcm92aWRlci9odHRwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRXRELE1BQU0sT0FBTyxpQkFBaUI7SUFDNUIsWUFBNkIsR0FBVztRQUFYLFFBQUcsR0FBSCxHQUFHLENBQVE7SUFBRyxDQUFDO0lBRXJDLEtBQUssQ0FBQyxRQUFRLENBQUMsV0FBbUIsRUFBRSxLQUFnQjtRQUN6RCxNQUFNLE9BQU8sR0FBNEI7WUFDdkMsV0FBVztZQUNYLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTTtZQUMxQixPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBRSxDQUFDLE1BQU07WUFDN0IsU0FBUyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUU7WUFDekMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUM7U0FDM0IsQ0FBQztRQUVGLE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDckMsTUFBTSxFQUFFLE1BQU07WUFDZCxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7WUFDN0IsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFFO1NBQ2hELENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzVDLE1BQU0sSUFBSSxLQUFLLENBQUMsd0NBQXdDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xGLENBQUM7UUFFRCxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2pELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDM0MsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBRXJGLE9BQU8sRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxDQUFDO0lBQ3ZELENBQUM7Q0FDRiJ9
@@ -0,0 +1,6 @@
1
+ import { type EpochProofQuotePayload, type L2Block } from '@aztec/circuit-types';
2
+ export type QuoteProviderResult = Pick<EpochProofQuotePayload, 'basisPointFee' | 'bondAmount'> & Partial<Pick<EpochProofQuotePayload, 'validUntilSlot'>>;
3
+ export interface QuoteProvider {
4
+ getQuote(epochNumber: number, epoch: L2Block[]): Promise<QuoteProviderResult | undefined>;
5
+ }
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/quote-provider/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEjF,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,YAAY,CAAC,GAC5F,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE1D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;CAC3F"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcXVvdGUtcHJvdmlkZXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,9 @@
1
+ import { type EpochProofQuotePayload, type L2Block } from '@aztec/circuit-types';
2
+ import { type QuoteProvider } from './index.js';
3
+ export declare class SimpleQuoteProvider implements QuoteProvider {
4
+ readonly basisPointFee: number;
5
+ readonly bondAmount: bigint;
6
+ constructor(basisPointFee: number, bondAmount: bigint);
7
+ getQuote(_epochNumber: number, _epoch: L2Block[]): Promise<Pick<EpochProofQuotePayload, 'basisPointFee' | 'bondAmount'>>;
8
+ }
9
+ //# sourceMappingURL=simple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simple.d.ts","sourceRoot":"","sources":["../../src/quote-provider/simple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,sBAAsB,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,mBAAoB,YAAW,aAAa;aAC3B,aAAa,EAAE,MAAM;aAAkB,UAAU,EAAE,MAAM;gBAAzD,aAAa,EAAE,MAAM,EAAkB,UAAU,EAAE,MAAM;IAErF,QAAQ,CACN,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,OAAO,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,eAAe,GAAG,YAAY,CAAC,CAAC;CAIzE"}
@@ -0,0 +1,11 @@
1
+ export class SimpleQuoteProvider {
2
+ constructor(basisPointFee, bondAmount) {
3
+ this.basisPointFee = basisPointFee;
4
+ this.bondAmount = bondAmount;
5
+ }
6
+ getQuote(_epochNumber, _epoch) {
7
+ const { basisPointFee, bondAmount } = this;
8
+ return Promise.resolve({ basisPointFee, bondAmount });
9
+ }
10
+ }
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2ltcGxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3F1b3RlLXByb3ZpZGVyL3NpbXBsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxNQUFNLE9BQU8sbUJBQW1CO0lBQzlCLFlBQTRCLGFBQXFCLEVBQWtCLFVBQWtCO1FBQXpELGtCQUFhLEdBQWIsYUFBYSxDQUFRO1FBQWtCLGVBQVUsR0FBVixVQUFVLENBQVE7SUFBRyxDQUFDO0lBRXpGLFFBQVEsQ0FDTixZQUFvQixFQUNwQixNQUFpQjtRQUVqQixNQUFNLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQztRQUMzQyxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUN4RCxDQUFDO0NBQ0YifQ==
@@ -0,0 +1,4 @@
1
+ import { type L2Block } from '@aztec/circuit-types';
2
+ export declare function getTotalFees(epoch: L2Block[]): bigint;
3
+ export declare function getTxCount(epoch: L2Block[]): number;
4
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/quote-provider/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAGpD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,UAE5C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,UAE1C"}
@@ -0,0 +1,8 @@
1
+ import { Fr } from '@aztec/circuits.js';
2
+ export function getTotalFees(epoch) {
3
+ return epoch.reduce((total, block) => total.add(block.header.totalFees), Fr.ZERO).toBigInt();
4
+ }
5
+ export function getTxCount(epoch) {
6
+ return epoch.reduce((total, block) => total + block.body.txEffects.length, 0);
7
+ }
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcXVvdGUtcHJvdmlkZXIvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXhDLE1BQU0sVUFBVSxZQUFZLENBQUMsS0FBZ0I7SUFDM0MsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUMvRixDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVUsQ0FBQyxLQUFnQjtJQUN6QyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2hGLENBQUMifQ==
@@ -0,0 +1,13 @@
1
+ import { EpochProofQuote, type EpochProofQuotePayload } from '@aztec/circuit-types';
2
+ import { Buffer32 } from '@aztec/foundation/buffer';
3
+ import { Secp256k1Signer } from '@aztec/foundation/crypto';
4
+ import { type RollupAbi } from '@aztec/l1-artifacts';
5
+ import { type GetContractReturnType, type PublicClient } from 'viem';
6
+ export declare class QuoteSigner {
7
+ private readonly signer;
8
+ private readonly quoteToDigest;
9
+ constructor(signer: Secp256k1Signer, quoteToDigest: (payload: EpochProofQuotePayload) => Promise<Buffer32>);
10
+ static new(privateKey: Buffer32, rollupContract: GetContractReturnType<typeof RollupAbi, PublicClient>): QuoteSigner;
11
+ sign(payload: EpochProofQuotePayload): Promise<EpochProofQuote>;
12
+ }
13
+ //# sourceMappingURL=quote-signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-signer.d.ts","sourceRoot":"","sources":["../src/quote-signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,MAAM,CAAC;AAErE,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;gBADb,MAAM,EAAE,eAAe,EACvB,aAAa,EAAE,CAAC,OAAO,EAAE,sBAAsB,KAAK,OAAO,CAAC,QAAQ,CAAC;IAGxF,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,qBAAqB,CAAC,OAAO,SAAS,EAAE,YAAY,CAAC,GAAG,WAAW;IAMvG,IAAI,CAAC,OAAO,EAAE,sBAAsB;CAIlD"}
@@ -0,0 +1,18 @@
1
+ import { EpochProofQuote } from '@aztec/circuit-types';
2
+ import { Buffer32 } from '@aztec/foundation/buffer';
3
+ import { Secp256k1Signer } from '@aztec/foundation/crypto';
4
+ export class QuoteSigner {
5
+ constructor(signer, quoteToDigest) {
6
+ this.signer = signer;
7
+ this.quoteToDigest = quoteToDigest;
8
+ }
9
+ static new(privateKey, rollupContract) {
10
+ const quoteToDigest = (payload) => rollupContract.read.quoteToDigest([payload.toViemArgs()]).then(Buffer32.fromString);
11
+ return new QuoteSigner(new Secp256k1Signer(privateKey), quoteToDigest);
12
+ }
13
+ async sign(payload) {
14
+ const digest = await this.quoteToDigest(payload);
15
+ return EpochProofQuote.new(digest, payload, this.signer);
16
+ }
17
+ }
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGUtc2lnbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3F1b3RlLXNpZ25lci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUErQixNQUFNLHNCQUFzQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFLM0QsTUFBTSxPQUFPLFdBQVc7SUFDdEIsWUFDbUIsTUFBdUIsRUFDdkIsYUFBcUU7UUFEckUsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7UUFDdkIsa0JBQWEsR0FBYixhQUFhLENBQXdEO0lBQ3JGLENBQUM7SUFFSixNQUFNLENBQUMsR0FBRyxDQUFDLFVBQW9CLEVBQUUsY0FBcUU7UUFDcEcsTUFBTSxhQUFhLEdBQUcsQ0FBQyxPQUErQixFQUFFLEVBQUUsQ0FDeEQsY0FBYyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEYsT0FBTyxJQUFJLFdBQVcsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxVQUFVLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUksQ0FBQyxPQUErQjtRQUMvQyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakQsT0FBTyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNELENBQUM7Q0FDRiJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/prover-node",
3
- "version": "0.56.0",
3
+ "version": "0.57.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js"
@@ -31,6 +31,9 @@
31
31
  "parser": {
32
32
  "syntax": "typescript",
33
33
  "decorators": true
34
+ },
35
+ "transform": {
36
+ "decoratorVersion": "2022-03"
34
37
  }
35
38
  }
36
39
  }
@@ -49,19 +52,22 @@
49
52
  ]
50
53
  },
51
54
  "dependencies": {
52
- "@aztec/archiver": "0.56.0",
53
- "@aztec/circuit-types": "0.56.0",
54
- "@aztec/circuits.js": "0.56.0",
55
- "@aztec/foundation": "0.56.0",
56
- "@aztec/kv-store": "0.56.0",
57
- "@aztec/prover-client": "0.56.0",
58
- "@aztec/sequencer-client": "0.56.0",
59
- "@aztec/simulator": "0.56.0",
60
- "@aztec/telemetry-client": "0.56.0",
61
- "@aztec/types": "0.56.0",
62
- "@aztec/world-state": "0.56.0",
55
+ "@aztec/archiver": "0.57.0",
56
+ "@aztec/circuit-types": "0.57.0",
57
+ "@aztec/circuits.js": "0.57.0",
58
+ "@aztec/ethereum": "0.57.0",
59
+ "@aztec/foundation": "0.57.0",
60
+ "@aztec/kv-store": "0.57.0",
61
+ "@aztec/l1-artifacts": "0.57.0",
62
+ "@aztec/prover-client": "0.57.0",
63
+ "@aztec/sequencer-client": "0.57.0",
64
+ "@aztec/simulator": "0.57.0",
65
+ "@aztec/telemetry-client": "0.57.0",
66
+ "@aztec/types": "0.57.0",
67
+ "@aztec/world-state": "0.57.0",
63
68
  "source-map-support": "^0.5.21",
64
- "tslib": "^2.4.0"
69
+ "tslib": "^2.4.0",
70
+ "viem": "^2.7.15"
65
71
  },
66
72
  "devDependencies": {
67
73
  "@jest/globals": "^29.5.0",
@@ -0,0 +1,48 @@
1
+ import { createDebugLogger } from '@aztec/foundation/log';
2
+
3
+ import { type EscrowContract } from './escrow-contract.js';
4
+ import { type TokenContract } from './token-contract.js';
5
+
6
+ export class BondManager {
7
+ private logger = createDebugLogger('aztec:prover-node:bond-manager');
8
+
9
+ constructor(
10
+ public readonly tokenContract: TokenContract,
11
+ public readonly escrowContract: EscrowContract,
12
+ /** Minimum escrowed bond. A top-up will be issued once this threshold is hit. */
13
+ public minimumAmount: bigint,
14
+ /** Target escrowed bond. Top-up will target this value. */
15
+ public targetAmount: bigint,
16
+ ) {}
17
+
18
+ /**
19
+ * Ensures the bond is at least minimumBond, or sends a tx to deposit the remaining to reach targetBond.
20
+ * @param overrideMinimum - Override the minimum bond threshold. Also overrides target if it is higher.
21
+ */
22
+ public async ensureBond(overrideMinimum?: bigint) {
23
+ const minimum = overrideMinimum ?? this.minimumAmount;
24
+ const target = overrideMinimum && overrideMinimum > this.targetAmount ? overrideMinimum : this.targetAmount;
25
+
26
+ try {
27
+ const current = await this.escrowContract.getProverDeposit();
28
+ if (current >= minimum) {
29
+ this.logger.debug(`Current prover bond ${current} is above minimum ${minimum}`);
30
+ return;
31
+ }
32
+
33
+ const topUpAmount = target - current;
34
+ this.logger.verbose(`Prover bond top-up ${topUpAmount} required to get ${current} to target ${target}`);
35
+
36
+ const balance = await this.tokenContract.getBalance();
37
+ if (balance < topUpAmount) {
38
+ throw new Error(`Not enough balance to top-up prover bond: ${balance} < ${topUpAmount}`);
39
+ }
40
+
41
+ await this.tokenContract.ensureAllowance(this.escrowContract.getEscrowAddress());
42
+ await this.escrowContract.depositProverBond(topUpAmount);
43
+ this.logger.verbose(`Prover bond top-up of ${topUpAmount} completed`);
44
+ } catch (err) {
45
+ throw new Error(`Could not set prover bond: ${err}`);
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,25 @@
1
+ import { type ConfigMappingsType, bigintConfigHelper, getConfigFromMappings } from '@aztec/foundation/config';
2
+
3
+ export type ProverBondManagerConfig = {
4
+ proverMinimumStakeAmount: bigint;
5
+ proverTargetStakeAmount?: bigint;
6
+ };
7
+
8
+ export const proverBondManagerConfigMappings: ConfigMappingsType<ProverBondManagerConfig> = {
9
+ proverMinimumStakeAmount: {
10
+ env: 'PROVER_MINIMUM_STAKE_AMOUNT',
11
+ description:
12
+ 'Minimum amount to ensure is staked in the escrow contract for this prover. Prover node will top up whenever escrow falls below this number.',
13
+ ...bigintConfigHelper(100000n),
14
+ },
15
+ proverTargetStakeAmount: {
16
+ env: 'PROVER_TARGET_STAKE_AMOUNT',
17
+ description:
18
+ 'Target amount to ensure is staked in the escrow contract for this prover. Prover node will top up to this value. Defaults to the minimum amount.',
19
+ ...bigintConfigHelper(),
20
+ },
21
+ };
22
+
23
+ export function getProverBondManagerConfigFromEnv(): ProverBondManagerConfig {
24
+ return getConfigFromMappings<ProverBondManagerConfig>(proverBondManagerConfigMappings);
25
+ }