@aztec/validator-client 1.0.0-staging.0 → 1.0.0-staging.1
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/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +35 -12
- package/package.json +10 -10
- package/src/validator.ts +48 -13
package/dest/validator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
|
package/dest/validator.js
CHANGED
|
@@ -2,6 +2,7 @@ import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
|
2
2
|
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
3
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
5
6
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
6
7
|
import { sleep } from '@aztec/foundation/sleep';
|
|
7
8
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
@@ -121,6 +122,9 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
121
122
|
const slotNumber = proposal.slotNumber.toNumber();
|
|
122
123
|
const blockNumber = proposal.blockNumber;
|
|
123
124
|
const proposer = proposal.getSender();
|
|
125
|
+
// Check that I have any address in current committee before attesting
|
|
126
|
+
const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
|
|
127
|
+
const partOfCommittee = inCommittee.length > 0;
|
|
124
128
|
const proposalInfo = {
|
|
125
129
|
slotNumber,
|
|
126
130
|
blockNumber,
|
|
@@ -135,7 +139,9 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
135
139
|
const invalidProposal = await this.blockProposalValidator.validate(proposal);
|
|
136
140
|
if (invalidProposal) {
|
|
137
141
|
this.log.warn(`Proposal is not valid, skipping attestation`);
|
|
138
|
-
|
|
142
|
+
if (partOfCommittee) {
|
|
143
|
+
this.metrics.incFailedAttestations(1, 'invalid_proposal');
|
|
144
|
+
}
|
|
139
145
|
return undefined;
|
|
140
146
|
}
|
|
141
147
|
// Check that the parent proposal is a block we know, otherwise reexecution would fail.
|
|
@@ -144,10 +150,23 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
144
150
|
// would not be rebroadcasted. But it also means that nodes that have not fully synced would
|
|
145
151
|
// not rebroadcast the proposal.
|
|
146
152
|
if (blockNumber > INITIAL_L2_BLOCK_NUM) {
|
|
147
|
-
const
|
|
153
|
+
const config = this.blockBuilder.getConfig();
|
|
154
|
+
const deadline = this.getReexecutionDeadline(proposal, config);
|
|
155
|
+
const currentTime = this.dateProvider.now();
|
|
156
|
+
const timeoutDurationMs = deadline.getTime() - currentTime;
|
|
157
|
+
const parentBlock = timeoutDurationMs <= 0 ? undefined : await retryUntil(async ()=>{
|
|
158
|
+
const block = await this.blockSource.getBlock(blockNumber - 1);
|
|
159
|
+
if (block) {
|
|
160
|
+
return block;
|
|
161
|
+
}
|
|
162
|
+
await this.blockSource.syncImmediate();
|
|
163
|
+
return await this.blockSource.getBlock(blockNumber - 1);
|
|
164
|
+
}, 'Force Archiver Sync', timeoutDurationMs / 1000, 0.5);
|
|
148
165
|
if (parentBlock === undefined) {
|
|
149
166
|
this.log.warn(`Parent block for ${blockNumber} not found, skipping attestation`);
|
|
150
|
-
|
|
167
|
+
if (partOfCommittee) {
|
|
168
|
+
this.metrics.incFailedAttestations(1, 'parent_block_not_found');
|
|
169
|
+
}
|
|
151
170
|
return undefined;
|
|
152
171
|
}
|
|
153
172
|
if (!proposal.payload.header.lastArchiveRoot.equals(parentBlock.archive.root)) {
|
|
@@ -156,25 +175,23 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
156
175
|
parentBlockArchiveRoot: parentBlock.archive.root.toString(),
|
|
157
176
|
...proposalInfo
|
|
158
177
|
});
|
|
159
|
-
|
|
178
|
+
if (partOfCommittee) {
|
|
179
|
+
this.metrics.incFailedAttestations(1, 'parent_block_does_not_match');
|
|
180
|
+
}
|
|
160
181
|
return undefined;
|
|
161
182
|
}
|
|
162
183
|
}
|
|
163
184
|
// Collect txs from the proposal
|
|
164
185
|
const { missing, txs } = await this.txCollector.collectForBlockProposal(proposal, proposalSender);
|
|
165
|
-
// Check that I have any address in current committee before attesting
|
|
166
|
-
const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
|
|
167
|
-
if (inCommittee.length === 0) {
|
|
168
|
-
this.log.verbose(`No validator in the committee, skipping attestation`);
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
186
|
// Check that all of the transactions in the proposal are available in the tx pool before attesting
|
|
172
187
|
if (missing && missing.length > 0) {
|
|
173
188
|
this.log.warn(`Missing ${missing.length}/${proposal.payload.txHashes.length} txs to attest to proposal`, {
|
|
174
189
|
...proposalInfo,
|
|
175
190
|
missing
|
|
176
191
|
});
|
|
177
|
-
|
|
192
|
+
if (partOfCommittee) {
|
|
193
|
+
this.metrics.incFailedAttestations(1, 'tx_not_available');
|
|
194
|
+
}
|
|
178
195
|
return undefined;
|
|
179
196
|
}
|
|
180
197
|
// Check that I have the same set of l1ToL2Messages as the proposal
|
|
@@ -187,7 +204,13 @@ const MAX_PROPOSERS_OF_INVALID_BLOCKS = 1000;
|
|
|
187
204
|
computedInHash: computedInHash.toString(),
|
|
188
205
|
...proposalInfo
|
|
189
206
|
});
|
|
190
|
-
|
|
207
|
+
if (partOfCommittee) {
|
|
208
|
+
this.metrics.incFailedAttestations(1, 'in_hash_mismatch');
|
|
209
|
+
}
|
|
210
|
+
return undefined;
|
|
211
|
+
}
|
|
212
|
+
if (!partOfCommittee) {
|
|
213
|
+
this.log.verbose(`No validator in the committee, skipping attestation`);
|
|
191
214
|
return undefined;
|
|
192
215
|
}
|
|
193
216
|
// Try re-executing the transactions in the proposal
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/validator-client",
|
|
3
|
-
"version": "1.0.0-staging.
|
|
3
|
+
"version": "1.0.0-staging.1",
|
|
4
4
|
"main": "dest/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -64,15 +64,15 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/constants": "1.0.0-staging.
|
|
68
|
-
"@aztec/epoch-cache": "1.0.0-staging.
|
|
69
|
-
"@aztec/ethereum": "1.0.0-staging.
|
|
70
|
-
"@aztec/foundation": "1.0.0-staging.
|
|
71
|
-
"@aztec/p2p": "1.0.0-staging.
|
|
72
|
-
"@aztec/prover-client": "1.0.0-staging.
|
|
73
|
-
"@aztec/slasher": "1.0.0-staging.
|
|
74
|
-
"@aztec/stdlib": "1.0.0-staging.
|
|
75
|
-
"@aztec/telemetry-client": "1.0.0-staging.
|
|
67
|
+
"@aztec/constants": "1.0.0-staging.1",
|
|
68
|
+
"@aztec/epoch-cache": "1.0.0-staging.1",
|
|
69
|
+
"@aztec/ethereum": "1.0.0-staging.1",
|
|
70
|
+
"@aztec/foundation": "1.0.0-staging.1",
|
|
71
|
+
"@aztec/p2p": "1.0.0-staging.1",
|
|
72
|
+
"@aztec/prover-client": "1.0.0-staging.1",
|
|
73
|
+
"@aztec/slasher": "1.0.0-staging.1",
|
|
74
|
+
"@aztec/stdlib": "1.0.0-staging.1",
|
|
75
|
+
"@aztec/telemetry-client": "1.0.0-staging.1",
|
|
76
76
|
"koa": "^2.16.1",
|
|
77
77
|
"koa-router": "^12.0.0",
|
|
78
78
|
"tslib": "^2.4.0",
|
package/src/validator.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Buffer32 } from '@aztec/foundation/buffer';
|
|
|
4
4
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { Fr } from '@aztec/foundation/fields';
|
|
6
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
7
|
+
import { retryUntil } from '@aztec/foundation/retry';
|
|
7
8
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
8
9
|
import { sleep } from '@aztec/foundation/sleep';
|
|
9
10
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
@@ -226,6 +227,10 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
226
227
|
const blockNumber = proposal.blockNumber;
|
|
227
228
|
const proposer = proposal.getSender();
|
|
228
229
|
|
|
230
|
+
// Check that I have any address in current committee before attesting
|
|
231
|
+
const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
|
|
232
|
+
const partOfCommittee = inCommittee.length > 0;
|
|
233
|
+
|
|
229
234
|
const proposalInfo = {
|
|
230
235
|
slotNumber,
|
|
231
236
|
blockNumber,
|
|
@@ -241,7 +246,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
241
246
|
const invalidProposal = await this.blockProposalValidator.validate(proposal);
|
|
242
247
|
if (invalidProposal) {
|
|
243
248
|
this.log.warn(`Proposal is not valid, skipping attestation`);
|
|
244
|
-
|
|
249
|
+
if (partOfCommittee) {
|
|
250
|
+
this.metrics.incFailedAttestations(1, 'invalid_proposal');
|
|
251
|
+
}
|
|
245
252
|
return undefined;
|
|
246
253
|
}
|
|
247
254
|
|
|
@@ -251,10 +258,34 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
251
258
|
// would not be rebroadcasted. But it also means that nodes that have not fully synced would
|
|
252
259
|
// not rebroadcast the proposal.
|
|
253
260
|
if (blockNumber > INITIAL_L2_BLOCK_NUM) {
|
|
254
|
-
const
|
|
261
|
+
const config = this.blockBuilder.getConfig();
|
|
262
|
+
const deadline = this.getReexecutionDeadline(proposal, config);
|
|
263
|
+
const currentTime = this.dateProvider.now();
|
|
264
|
+
const timeoutDurationMs = deadline.getTime() - currentTime;
|
|
265
|
+
const parentBlock =
|
|
266
|
+
timeoutDurationMs <= 0
|
|
267
|
+
? undefined
|
|
268
|
+
: await retryUntil(
|
|
269
|
+
async () => {
|
|
270
|
+
const block = await this.blockSource.getBlock(blockNumber - 1);
|
|
271
|
+
if (block) {
|
|
272
|
+
return block;
|
|
273
|
+
}
|
|
274
|
+
await this.blockSource.syncImmediate();
|
|
275
|
+
return await this.blockSource.getBlock(blockNumber - 1);
|
|
276
|
+
},
|
|
277
|
+
'Force Archiver Sync',
|
|
278
|
+
timeoutDurationMs / 1000, // Continue retrying until the deadline
|
|
279
|
+
0.5, // Retry every 500ms
|
|
280
|
+
);
|
|
281
|
+
|
|
255
282
|
if (parentBlock === undefined) {
|
|
256
283
|
this.log.warn(`Parent block for ${blockNumber} not found, skipping attestation`);
|
|
257
|
-
|
|
284
|
+
|
|
285
|
+
if (partOfCommittee) {
|
|
286
|
+
this.metrics.incFailedAttestations(1, 'parent_block_not_found');
|
|
287
|
+
}
|
|
288
|
+
|
|
258
289
|
return undefined;
|
|
259
290
|
}
|
|
260
291
|
if (!proposal.payload.header.lastArchiveRoot.equals(parentBlock.archive.root)) {
|
|
@@ -263,7 +294,9 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
263
294
|
parentBlockArchiveRoot: parentBlock.archive.root.toString(),
|
|
264
295
|
...proposalInfo,
|
|
265
296
|
});
|
|
266
|
-
|
|
297
|
+
if (partOfCommittee) {
|
|
298
|
+
this.metrics.incFailedAttestations(1, 'parent_block_does_not_match');
|
|
299
|
+
}
|
|
267
300
|
return undefined;
|
|
268
301
|
}
|
|
269
302
|
}
|
|
@@ -271,20 +304,15 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
271
304
|
// Collect txs from the proposal
|
|
272
305
|
const { missing, txs } = await this.txCollector.collectForBlockProposal(proposal, proposalSender);
|
|
273
306
|
|
|
274
|
-
// Check that I have any address in current committee before attesting
|
|
275
|
-
const inCommittee = await this.epochCache.filterInCommittee(this.keyStore.getAddresses());
|
|
276
|
-
if (inCommittee.length === 0) {
|
|
277
|
-
this.log.verbose(`No validator in the committee, skipping attestation`);
|
|
278
|
-
return undefined;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
307
|
// Check that all of the transactions in the proposal are available in the tx pool before attesting
|
|
282
308
|
if (missing && missing.length > 0) {
|
|
283
309
|
this.log.warn(`Missing ${missing.length}/${proposal.payload.txHashes.length} txs to attest to proposal`, {
|
|
284
310
|
...proposalInfo,
|
|
285
311
|
missing,
|
|
286
312
|
});
|
|
287
|
-
|
|
313
|
+
if (partOfCommittee) {
|
|
314
|
+
this.metrics.incFailedAttestations(1, 'tx_not_available');
|
|
315
|
+
}
|
|
288
316
|
return undefined;
|
|
289
317
|
}
|
|
290
318
|
|
|
@@ -298,7 +326,14 @@ export class ValidatorClient extends (EventEmitter as new () => WatcherEmitter)
|
|
|
298
326
|
computedInHash: computedInHash.toString(),
|
|
299
327
|
...proposalInfo,
|
|
300
328
|
});
|
|
301
|
-
|
|
329
|
+
if (partOfCommittee) {
|
|
330
|
+
this.metrics.incFailedAttestations(1, 'in_hash_mismatch');
|
|
331
|
+
}
|
|
332
|
+
return undefined;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (!partOfCommittee) {
|
|
336
|
+
this.log.verbose(`No validator in the committee, skipping attestation`);
|
|
302
337
|
return undefined;
|
|
303
338
|
}
|
|
304
339
|
|