@aztec/aztec-node 3.0.0-canary.a9708bd → 3.0.0-devnet.2-patch.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/aztec-node/config.d.ts +9 -4
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +22 -20
- package/dest/aztec-node/node_metrics.d.ts +5 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +21 -0
- package/dest/aztec-node/server.d.ts +57 -37
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +163 -65
- package/dest/bin/index.d.ts +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/sentinel/config.d.ts +2 -1
- package/dest/sentinel/config.d.ts.map +1 -1
- package/dest/sentinel/config.js +16 -0
- package/dest/sentinel/factory.d.ts +1 -1
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +3 -1
- package/dest/sentinel/index.d.ts +1 -1
- package/dest/sentinel/sentinel.d.ts +23 -21
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +86 -80
- package/dest/sentinel/store.d.ts +8 -5
- package/dest/sentinel/store.d.ts.map +1 -1
- package/dest/sentinel/store.js +8 -4
- package/dest/test/index.d.ts +1 -1
- package/package.json +29 -28
- package/src/aztec-node/config.ts +36 -41
- package/src/aztec-node/node_metrics.ts +28 -0
- package/src/aztec-node/server.ts +230 -119
- package/src/sentinel/config.ts +18 -0
- package/src/sentinel/factory.ts +5 -1
- package/src/sentinel/sentinel.ts +123 -106
- package/src/sentinel/store.ts +18 -13
|
@@ -9,35 +9,40 @@ import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@azte
|
|
|
9
9
|
import { createBlobSinkClient } from '@aztec/blob-sink/client';
|
|
10
10
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
11
11
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
13
|
+
import { getPublicClient } from '@aztec/ethereum/client';
|
|
14
|
+
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
15
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
14
16
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
17
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
15
18
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
16
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
17
19
|
import { BadRequestError } from '@aztec/foundation/json-rpc';
|
|
18
20
|
import { createLogger } from '@aztec/foundation/log';
|
|
19
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
20
21
|
import { count } from '@aztec/foundation/string';
|
|
21
22
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
22
23
|
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
23
24
|
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
24
25
|
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
|
|
26
|
+
import { createForwarderL1TxUtilsFromEthSigner, createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/node-lib/factories';
|
|
25
27
|
import { createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
26
28
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
27
29
|
import { BlockBuilder, GlobalVariableBuilder, SequencerClient, createValidatorForAcceptingTxs } from '@aztec/sequencer-client';
|
|
28
30
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
29
31
|
import { AttestationsBlockWatcher, EpochPruneWatcher, createSlasher } from '@aztec/slasher';
|
|
32
|
+
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
30
33
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
31
34
|
import { L2BlockHash } from '@aztec/stdlib/block';
|
|
35
|
+
import { GasFees } from '@aztec/stdlib/gas';
|
|
32
36
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
33
37
|
import { AztecNodeAdminConfigSchema } from '@aztec/stdlib/interfaces/client';
|
|
34
38
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
39
|
+
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
35
40
|
import { P2PClientType } from '@aztec/stdlib/p2p';
|
|
36
41
|
import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
37
42
|
import { PublicSimulationOutput, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
38
43
|
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
39
44
|
import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
40
|
-
import { NodeKeystoreAdapter, ValidatorClient, createValidatorClient } from '@aztec/validator-client';
|
|
45
|
+
import { NodeKeystoreAdapter, ValidatorClient, createBlockProposalHandler, createValidatorClient } from '@aztec/validator-client';
|
|
41
46
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
42
47
|
import { createPublicClient, fallback, http } from 'viem';
|
|
43
48
|
import { createSentinel } from '../sentinel/factory.js';
|
|
@@ -68,8 +73,6 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
68
73
|
metrics;
|
|
69
74
|
// Prevent two snapshot operations to happen simultaneously
|
|
70
75
|
isUploadingSnapshot;
|
|
71
|
-
// Serial queue to ensure that we only send one tx at a time
|
|
72
|
-
txQueue;
|
|
73
76
|
tracer;
|
|
74
77
|
constructor(config, p2pClient, blockSource, logsSource, contractDataSource, l1ToL2MessageSource, worldStateSynchronizer, sequencer, slasherClient, validatorsSentinel, epochPruneWatcher, l1ChainId, version, globalVariableBuilder, epochCache, packageVersion, proofVerifier, telemetry = getTelemetryClient(), log = createLogger('node')){
|
|
75
78
|
this.config = config;
|
|
@@ -92,10 +95,8 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
92
95
|
this.telemetry = telemetry;
|
|
93
96
|
this.log = log;
|
|
94
97
|
this.isUploadingSnapshot = false;
|
|
95
|
-
this.txQueue = new SerialQueue();
|
|
96
98
|
this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
|
|
97
99
|
this.tracer = telemetry.getTracer('AztecNodeService');
|
|
98
|
-
this.txQueue.start();
|
|
99
100
|
this.log.info(`Aztec Node version: ${this.packageVersion}`);
|
|
100
101
|
this.log.info(`Aztec Node started on chain 0x${l1ChainId.toString(16)}`, config.l1Contracts);
|
|
101
102
|
}
|
|
@@ -134,6 +135,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
134
135
|
keyStoreManager = new KeystoreManager(keyStore);
|
|
135
136
|
}
|
|
136
137
|
}
|
|
138
|
+
await keyStoreManager?.validateSigners();
|
|
137
139
|
// If we are a validator, verify our configuration before doing too much more.
|
|
138
140
|
if (!config.disableValidator) {
|
|
139
141
|
if (keyStoreManager === undefined) {
|
|
@@ -142,7 +144,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
142
144
|
if (!keyStoreProvided) {
|
|
143
145
|
log.warn('KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS');
|
|
144
146
|
}
|
|
145
|
-
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager);
|
|
147
|
+
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager, log);
|
|
146
148
|
}
|
|
147
149
|
// validate that the actual chain id matches that specified in configuration
|
|
148
150
|
if (config.l1ChainId !== ethereumChain.chainInfo.id) {
|
|
@@ -180,49 +182,27 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
180
182
|
telemetry,
|
|
181
183
|
dateProvider
|
|
182
184
|
}, {
|
|
183
|
-
blockUntilSync:
|
|
185
|
+
blockUntilSync: !config.skipArchiverInitialSync
|
|
184
186
|
});
|
|
185
187
|
// now create the merkle trees and the world state synchronizer
|
|
186
188
|
const worldStateSynchronizer = await createWorldStateSynchronizer(config, archiver, options.prefilledPublicData, telemetry);
|
|
187
|
-
const circuitVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier();
|
|
189
|
+
const circuitVerifier = config.realProofs || config.debugForceTxProofVerification ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier(config.proverTestVerificationDelayMs);
|
|
188
190
|
if (!config.realProofs) {
|
|
189
191
|
log.warn(`Aztec node is accepting fake proofs`);
|
|
190
192
|
}
|
|
191
193
|
const proofVerifier = new QueuedIVCVerifier(config, circuitVerifier);
|
|
192
194
|
// create the tx pool and the p2p client, which will need the l2 block source
|
|
193
195
|
const p2pClient = await createP2PClient(P2PClientType.Full, config, archiver, proofVerifier, worldStateSynchronizer, epochCache, packageVersion, dateProvider, telemetry, deps.p2pClientDeps);
|
|
194
|
-
//
|
|
195
|
-
await worldStateSynchronizer.start();
|
|
196
|
-
// Start p2p. Note that it depends on world state to be running.
|
|
197
|
-
await p2pClient.start();
|
|
196
|
+
// We should really not be modifying the config object
|
|
198
197
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
199
198
|
const blockBuilder = new BlockBuilder({
|
|
200
199
|
...config,
|
|
201
200
|
l1GenesisTime,
|
|
202
201
|
slotDuration: Number(slotDuration)
|
|
203
202
|
}, worldStateSynchronizer, archiver, dateProvider, telemetry);
|
|
203
|
+
// We'll accumulate sentinel watchers here
|
|
204
204
|
const watchers = [];
|
|
205
|
-
|
|
206
|
-
if (validatorsSentinel) {
|
|
207
|
-
// we can run a sentinel without trying to slash.
|
|
208
|
-
await validatorsSentinel.start();
|
|
209
|
-
if (config.slashInactivityPenalty > 0n) {
|
|
210
|
-
watchers.push(validatorsSentinel);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
let epochPruneWatcher;
|
|
214
|
-
if (config.slashPrunePenalty > 0n || config.slashDataWithholdingPenalty > 0n) {
|
|
215
|
-
epochPruneWatcher = new EpochPruneWatcher(archiver, archiver, epochCache, p2pClient.getTxProvider(), blockBuilder, config);
|
|
216
|
-
await epochPruneWatcher.start();
|
|
217
|
-
watchers.push(epochPruneWatcher);
|
|
218
|
-
}
|
|
219
|
-
// We assume we want to slash for invalid attestations unless all max penalties are set to 0
|
|
220
|
-
let attestationsBlockWatcher;
|
|
221
|
-
if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) {
|
|
222
|
-
attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config);
|
|
223
|
-
await attestationsBlockWatcher.start();
|
|
224
|
-
watchers.push(attestationsBlockWatcher);
|
|
225
|
-
}
|
|
205
|
+
// Create validator client if required
|
|
226
206
|
const validatorClient = createValidatorClient(config, {
|
|
227
207
|
p2pClient,
|
|
228
208
|
telemetry,
|
|
@@ -233,10 +213,56 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
233
213
|
l1ToL2MessageSource: archiver,
|
|
234
214
|
keyStoreManager
|
|
235
215
|
});
|
|
216
|
+
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
217
|
+
// and have it register callbacks on the p2p client *before* we start it, otherwise messages
|
|
218
|
+
// like attestations or auths will fail.
|
|
236
219
|
if (validatorClient) {
|
|
237
220
|
watchers.push(validatorClient);
|
|
221
|
+
if (!options.dontStartSequencer) {
|
|
222
|
+
await validatorClient.registerHandlers();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// If there's no validator client but alwaysReexecuteBlockProposals is enabled,
|
|
226
|
+
// create a BlockProposalHandler to reexecute block proposals for monitoring
|
|
227
|
+
if (!validatorClient && config.alwaysReexecuteBlockProposals) {
|
|
228
|
+
log.info('Setting up block proposal reexecution for monitoring');
|
|
229
|
+
createBlockProposalHandler(config, {
|
|
230
|
+
blockBuilder,
|
|
231
|
+
epochCache,
|
|
232
|
+
blockSource: archiver,
|
|
233
|
+
l1ToL2MessageSource: archiver,
|
|
234
|
+
p2pClient,
|
|
235
|
+
dateProvider,
|
|
236
|
+
telemetry
|
|
237
|
+
}).registerForReexecution(p2pClient);
|
|
238
238
|
}
|
|
239
|
-
|
|
239
|
+
// Start world state and wait for it to sync to the archiver.
|
|
240
|
+
await worldStateSynchronizer.start();
|
|
241
|
+
// Start p2p. Note that it depends on world state to be running.
|
|
242
|
+
await p2pClient.start();
|
|
243
|
+
const validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, config);
|
|
244
|
+
if (validatorsSentinel && config.slashInactivityPenalty > 0n) {
|
|
245
|
+
watchers.push(validatorsSentinel);
|
|
246
|
+
}
|
|
247
|
+
let epochPruneWatcher;
|
|
248
|
+
if (config.slashPrunePenalty > 0n || config.slashDataWithholdingPenalty > 0n) {
|
|
249
|
+
epochPruneWatcher = new EpochPruneWatcher(archiver, archiver, epochCache, p2pClient.getTxProvider(), blockBuilder, config);
|
|
250
|
+
watchers.push(epochPruneWatcher);
|
|
251
|
+
}
|
|
252
|
+
// We assume we want to slash for invalid attestations unless all max penalties are set to 0
|
|
253
|
+
let attestationsBlockWatcher;
|
|
254
|
+
if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) {
|
|
255
|
+
attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config);
|
|
256
|
+
watchers.push(attestationsBlockWatcher);
|
|
257
|
+
}
|
|
258
|
+
// Start p2p-related services once the archiver has completed sync
|
|
259
|
+
void archiver.waitForInitialSync().then(async ()=>{
|
|
260
|
+
await p2pClient.start();
|
|
261
|
+
await validatorsSentinel?.start();
|
|
262
|
+
await epochPruneWatcher?.start();
|
|
263
|
+
await attestationsBlockWatcher?.start();
|
|
264
|
+
log.info(`All p2p services started`);
|
|
265
|
+
}).catch((err)=>log.error('Failed to start p2p services after archiver sync', err));
|
|
240
266
|
// Validator enabled, create/start relevant service
|
|
241
267
|
let sequencer;
|
|
242
268
|
let slasherClient;
|
|
@@ -246,12 +272,23 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
246
272
|
const validatorAddresses = keyStoreManager ? NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager).getAddresses() : [];
|
|
247
273
|
slasherClient = await createSlasher(config, config.l1Contracts, getPublicClient(config), watchers, dateProvider, epochCache, validatorAddresses, undefined);
|
|
248
274
|
await slasherClient.start();
|
|
249
|
-
const l1TxUtils = keyStoreManager.createAllValidatorPublisherSigners().
|
|
250
|
-
|
|
275
|
+
const l1TxUtils = config.publisherForwarderAddress ? await createForwarderL1TxUtilsFromEthSigner(publicClient, keyStoreManager.createAllValidatorPublisherSigners(), config.publisherForwarderAddress, {
|
|
276
|
+
...config,
|
|
277
|
+
scope: 'sequencer'
|
|
278
|
+
}, {
|
|
279
|
+
telemetry,
|
|
280
|
+
logger: log.createChild('l1-tx-utils'),
|
|
281
|
+
dateProvider
|
|
282
|
+
}) : await createL1TxUtilsWithBlobsFromEthSigner(publicClient, keyStoreManager.createAllValidatorPublisherSigners(), {
|
|
283
|
+
...config,
|
|
284
|
+
scope: 'sequencer'
|
|
285
|
+
}, {
|
|
286
|
+
telemetry,
|
|
287
|
+
logger: log.createChild('l1-tx-utils'),
|
|
288
|
+
dateProvider
|
|
251
289
|
});
|
|
290
|
+
// Create and start the sequencer client
|
|
252
291
|
sequencer = await SequencerClient.new(config, {
|
|
253
|
-
// if deps were provided, they should override the defaults,
|
|
254
|
-
// or things that we created in this function
|
|
255
292
|
...deps,
|
|
256
293
|
epochCache,
|
|
257
294
|
l1TxUtils,
|
|
@@ -271,6 +308,8 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
271
308
|
if (!options.dontStartSequencer && sequencer) {
|
|
272
309
|
await sequencer.start();
|
|
273
310
|
log.verbose(`Sequencer started`);
|
|
311
|
+
} else if (sequencer) {
|
|
312
|
+
log.warn(`Sequencer created but not started`);
|
|
274
313
|
}
|
|
275
314
|
return new AztecNodeService(config, p2pClient, archiver, archiver, archiver, archiver, worldStateSynchronizer, sequencer, slasherClient, validatorsSentinel, epochPruneWatcher, ethereumChain.chainInfo.id, config.rollupVersion, new GlobalVariableBuilder(config), epochCache, packageVersion, proofVerifier, telemetry, log);
|
|
276
315
|
}
|
|
@@ -298,6 +337,9 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
298
337
|
getEncodedEnr() {
|
|
299
338
|
return Promise.resolve(this.p2pClient.getEnr()?.encodeTxt());
|
|
300
339
|
}
|
|
340
|
+
async getAllowedPublicSetup() {
|
|
341
|
+
return this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
342
|
+
}
|
|
301
343
|
/**
|
|
302
344
|
* Method to determine if the node is ready to accept transactions.
|
|
303
345
|
* @returns - Flag indicating the readiness for tx submission.
|
|
@@ -328,7 +370,24 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
328
370
|
* @param number - The block number being requested.
|
|
329
371
|
* @returns The requested block.
|
|
330
372
|
*/ async getBlock(number) {
|
|
331
|
-
|
|
373
|
+
const blockNumber = number === 'latest' ? await this.getBlockNumber() : number;
|
|
374
|
+
return await this.blockSource.getBlock(blockNumber);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get a block specified by its hash.
|
|
378
|
+
* @param blockHash - The block hash being requested.
|
|
379
|
+
* @returns The requested block.
|
|
380
|
+
*/ async getBlockByHash(blockHash) {
|
|
381
|
+
const publishedBlock = await this.blockSource.getPublishedBlockByHash(blockHash);
|
|
382
|
+
return publishedBlock?.block;
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Get a block specified by its archive root.
|
|
386
|
+
* @param archive - The archive root being requested.
|
|
387
|
+
* @returns The requested block.
|
|
388
|
+
*/ async getBlockByArchive(archive) {
|
|
389
|
+
const publishedBlock = await this.blockSource.getPublishedBlockByArchive(archive);
|
|
390
|
+
return publishedBlock?.block;
|
|
332
391
|
}
|
|
333
392
|
/**
|
|
334
393
|
* Method to request blocks. Will attempt to return all requested blocks but will return only those available.
|
|
@@ -347,6 +406,15 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
347
406
|
*/ async getCurrentBaseFees() {
|
|
348
407
|
return await this.globalVariableBuilder.getCurrentBaseFees();
|
|
349
408
|
}
|
|
409
|
+
async getMaxPriorityFees() {
|
|
410
|
+
for await (const tx of this.p2pClient.iteratePendingTxs()){
|
|
411
|
+
return tx.getGasSettings().maxPriorityFeesPerGas;
|
|
412
|
+
}
|
|
413
|
+
return GasFees.from({
|
|
414
|
+
feePerDaGas: 0n,
|
|
415
|
+
feePerL2Gas: 0n
|
|
416
|
+
});
|
|
417
|
+
}
|
|
350
418
|
/**
|
|
351
419
|
* Method to fetch the latest block number synchronized by the node.
|
|
352
420
|
* @returns The block number.
|
|
@@ -381,14 +449,6 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
381
449
|
return this.contractDataSource.getContract(address);
|
|
382
450
|
}
|
|
383
451
|
/**
|
|
384
|
-
* Retrieves all private logs from up to `limit` blocks, starting from the block number `from`.
|
|
385
|
-
* @param from - The block number from which to begin retrieving logs.
|
|
386
|
-
* @param limit - The maximum number of blocks to retrieve logs from.
|
|
387
|
-
* @returns An array of private logs from the specified range of blocks.
|
|
388
|
-
*/ getPrivateLogs(from, limit) {
|
|
389
|
-
return this.logsSource.getPrivateLogs(from, limit);
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
452
|
* Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
|
|
393
453
|
* @param tags - The tags to filter the logs by.
|
|
394
454
|
* @param logsPerTag - The maximum number of logs to return for each tag. By default no limit is set
|
|
@@ -415,7 +475,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
415
475
|
* Method to submit a transaction to the p2p pool.
|
|
416
476
|
* @param tx - The transaction to be submitted.
|
|
417
477
|
*/ async sendTx(tx) {
|
|
418
|
-
await this
|
|
478
|
+
await this.#sendTx(tx);
|
|
419
479
|
}
|
|
420
480
|
async #sendTx(tx) {
|
|
421
481
|
const timer = new Timer();
|
|
@@ -456,7 +516,6 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
456
516
|
* Method to stop the aztec node.
|
|
457
517
|
*/ async stop() {
|
|
458
518
|
this.log.info(`Stopping Aztec Node`);
|
|
459
|
-
await this.txQueue.end();
|
|
460
519
|
await tryStop(this.validatorsSentinel);
|
|
461
520
|
await tryStop(this.epochPruneWatcher);
|
|
462
521
|
await tryStop(this.slasherClient);
|
|
@@ -520,7 +579,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
520
579
|
// Now we obtain the block hashes from the archive tree by calling await `committedDb.getLeafValue(treeId, index)`
|
|
521
580
|
// (note that block number corresponds to the leaf index in the archive tree).
|
|
522
581
|
const blockHashes = await Promise.all(uniqueBlockNumbers.map((blockNumber)=>{
|
|
523
|
-
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber);
|
|
582
|
+
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
|
|
524
583
|
}));
|
|
525
584
|
// If any of the block hashes are undefined, we throw an error.
|
|
526
585
|
for(let i = 0; i < uniqueBlockNumbers.length; i++){
|
|
@@ -528,7 +587,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
528
587
|
throw new Error(`Block hash is undefined for block number ${uniqueBlockNumbers[i]}`);
|
|
529
588
|
}
|
|
530
589
|
}
|
|
531
|
-
// Create
|
|
590
|
+
// Create DataInBlock objects by combining indices, blockNumbers and blockHashes and return them.
|
|
532
591
|
return maybeIndices.map((index, i)=>{
|
|
533
592
|
if (index === undefined) {
|
|
534
593
|
return undefined;
|
|
@@ -543,7 +602,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
543
602
|
return undefined;
|
|
544
603
|
}
|
|
545
604
|
return {
|
|
546
|
-
l2BlockNumber: Number(blockNumber),
|
|
605
|
+
l2BlockNumber: BlockNumber(Number(blockNumber)),
|
|
547
606
|
l2BlockHash: L2BlockHash.fromField(blockHash),
|
|
548
607
|
data: index
|
|
549
608
|
};
|
|
@@ -600,12 +659,17 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
600
659
|
witness.path
|
|
601
660
|
];
|
|
602
661
|
}
|
|
662
|
+
async getL1ToL2MessageBlock(l1ToL2Message) {
|
|
663
|
+
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
664
|
+
return messageIndex ? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex)) : undefined;
|
|
665
|
+
}
|
|
603
666
|
/**
|
|
604
667
|
* Returns whether an L1 to L2 message is synced by archiver and if it's ready to be included in a block.
|
|
605
668
|
* @param l1ToL2Message - The L1 to L2 message to check.
|
|
606
669
|
* @returns Whether the message is synced and ready to be included in a block.
|
|
607
670
|
*/ async isL1ToL2MessageSynced(l1ToL2Message) {
|
|
608
|
-
|
|
671
|
+
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
672
|
+
return messageIndex !== undefined;
|
|
609
673
|
}
|
|
610
674
|
/**
|
|
611
675
|
* Returns all the L2 to L1 messages in a block.
|
|
@@ -715,7 +779,21 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
715
779
|
* Returns the currently committed block header, or the initial header if no blocks have been produced.
|
|
716
780
|
* @returns The current committed block header.
|
|
717
781
|
*/ async getBlockHeader(blockNumber = 'latest') {
|
|
718
|
-
return blockNumber ===
|
|
782
|
+
return blockNumber === BlockNumber.ZERO || blockNumber === 'latest' && await this.blockSource.getBlockNumber() === BlockNumber.ZERO ? this.worldStateSynchronizer.getCommitted().getInitialHeader() : this.blockSource.getBlockHeader(blockNumber === 'latest' ? blockNumber : blockNumber);
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Get a block header specified by its hash.
|
|
786
|
+
* @param blockHash - The block hash being requested.
|
|
787
|
+
* @returns The requested block header.
|
|
788
|
+
*/ async getBlockHeaderByHash(blockHash) {
|
|
789
|
+
return await this.blockSource.getBlockHeaderByHash(blockHash);
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Get a block header specified by its archive root.
|
|
793
|
+
* @param archive - The archive root being requested.
|
|
794
|
+
* @returns The requested block header.
|
|
795
|
+
*/ async getBlockHeaderByArchive(archive) {
|
|
796
|
+
return await this.blockSource.getBlockHeaderByArchive(archive);
|
|
719
797
|
}
|
|
720
798
|
/**
|
|
721
799
|
* Simulates the public part of a transaction with the current state.
|
|
@@ -729,7 +807,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
729
807
|
throw new BadRequestError(`Transaction total gas limit ${txGasLimit + teardownGasLimit} (${txGasLimit} + ${teardownGasLimit}) exceeds maximum gas limit ${this.config.rpcSimulatePublicMaxGasLimit} for simulation`);
|
|
730
808
|
}
|
|
731
809
|
const txHash = tx.getTxHash();
|
|
732
|
-
const blockNumber = await this.blockSource.getBlockNumber() + 1;
|
|
810
|
+
const blockNumber = BlockNumber(await this.blockSource.getBlockNumber() + 1);
|
|
733
811
|
// If sequencer is not initialized, we just set these values to zero for simulation.
|
|
734
812
|
const coinbase = EthAddress.ZERO;
|
|
735
813
|
const feeRecipient = AztecAddress.ZERO;
|
|
@@ -742,7 +820,17 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
742
820
|
});
|
|
743
821
|
const merkleTreeFork = await this.worldStateSynchronizer.fork();
|
|
744
822
|
try {
|
|
745
|
-
const
|
|
823
|
+
const config = PublicSimulatorConfig.from({
|
|
824
|
+
skipFeeEnforcement,
|
|
825
|
+
collectDebugLogs: true,
|
|
826
|
+
collectHints: false,
|
|
827
|
+
collectCallMetadata: true,
|
|
828
|
+
collectStatistics: false,
|
|
829
|
+
collectionLimits: CollectionLimitsConfig.from({
|
|
830
|
+
maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads
|
|
831
|
+
})
|
|
832
|
+
});
|
|
833
|
+
const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, config);
|
|
746
834
|
// REFACTOR: Consider merging ProcessReturnValues into ProcessedTx
|
|
747
835
|
const [processedTxs, failedTxs, _usedTxs, returns] = await processor.process([
|
|
748
836
|
tx
|
|
@@ -765,7 +853,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
765
853
|
const verifier = isSimulation ? undefined : this.proofVerifier;
|
|
766
854
|
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
767
855
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
768
|
-
const blockNumber = await this.blockSource.getBlockNumber() + 1;
|
|
856
|
+
const blockNumber = BlockNumber(await this.blockSource.getBlockNumber() + 1);
|
|
769
857
|
const validator = createValidatorForAcceptingTxs(db, this.contractDataSource, verifier, {
|
|
770
858
|
timestamp: nextSlotTimestamp,
|
|
771
859
|
blockNumber,
|
|
@@ -788,11 +876,14 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
788
876
|
...this.config,
|
|
789
877
|
...config
|
|
790
878
|
};
|
|
791
|
-
this.sequencer?.
|
|
879
|
+
this.sequencer?.updateConfig(config);
|
|
792
880
|
this.slasherClient?.updateConfig(config);
|
|
793
881
|
this.validatorsSentinel?.updateConfig(config);
|
|
794
|
-
// this.blockBuilder.updateConfig(config); // TODO: Spyros has a PR to add the builder to `this`, so we can do this
|
|
795
882
|
await this.p2pClient.updateP2PConfig(config);
|
|
883
|
+
const archiver = this.blockSource;
|
|
884
|
+
if ('updateConfig' in archiver) {
|
|
885
|
+
archiver.updateConfig(config);
|
|
886
|
+
}
|
|
796
887
|
if (newConfig.realProofs !== this.config.realProofs) {
|
|
797
888
|
this.proofVerifier = config.realProofs ? await BBCircuitVerifier.new(newConfig) : new TestCircuitVerifier();
|
|
798
889
|
}
|
|
@@ -823,26 +914,33 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
823
914
|
// We break support for archiver running remotely to the node
|
|
824
915
|
const archiver = this.blockSource;
|
|
825
916
|
if (!('backupTo' in archiver)) {
|
|
917
|
+
this.metrics.recordSnapshotError();
|
|
826
918
|
throw new Error('Archiver implementation does not support backups. Cannot generate snapshot.');
|
|
827
919
|
}
|
|
828
920
|
// Test that the archiver has done an initial sync.
|
|
829
921
|
if (!archiver.isInitialSyncComplete()) {
|
|
922
|
+
this.metrics.recordSnapshotError();
|
|
830
923
|
throw new Error(`Archiver initial sync not complete. Cannot start snapshot.`);
|
|
831
924
|
}
|
|
832
925
|
// And it has an L2 block hash
|
|
833
926
|
const l2BlockHash = await archiver.getL2Tips().then((tips)=>tips.latest.hash);
|
|
834
927
|
if (!l2BlockHash) {
|
|
928
|
+
this.metrics.recordSnapshotError();
|
|
835
929
|
throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
|
|
836
930
|
}
|
|
837
931
|
if (this.isUploadingSnapshot) {
|
|
932
|
+
this.metrics.recordSnapshotError();
|
|
838
933
|
throw new Error(`Snapshot upload already in progress. Cannot start another one until complete.`);
|
|
839
934
|
}
|
|
840
935
|
// Do not wait for the upload to be complete to return to the caller, but flag that an operation is in progress
|
|
841
936
|
this.isUploadingSnapshot = true;
|
|
937
|
+
const timer = new Timer();
|
|
842
938
|
void uploadSnapshot(location, this.blockSource, this.worldStateSynchronizer, this.config, this.log).then(()=>{
|
|
843
939
|
this.isUploadingSnapshot = false;
|
|
940
|
+
this.metrics.recordSnapshot(timer.ms());
|
|
844
941
|
}).catch((err)=>{
|
|
845
942
|
this.isUploadingSnapshot = false;
|
|
943
|
+
this.metrics.recordSnapshotError();
|
|
846
944
|
this.log.error(`Error uploading snapshot: ${err}`);
|
|
847
945
|
});
|
|
848
946
|
return Promise.resolve();
|
|
@@ -915,7 +1013,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
915
1013
|
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
916
1014
|
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
917
1015
|
}
|
|
918
|
-
let blockSyncedTo =
|
|
1016
|
+
let blockSyncedTo = BlockNumber.ZERO;
|
|
919
1017
|
try {
|
|
920
1018
|
// Attempt to sync the world state if necessary
|
|
921
1019
|
blockSyncedTo = await this.#syncWorldState();
|
|
@@ -938,7 +1036,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
938
1036
|
* @returns A promise that fulfils once the world state is synced
|
|
939
1037
|
*/ async #syncWorldState() {
|
|
940
1038
|
const blockSourceHeight = await this.blockSource.getBlockNumber();
|
|
941
|
-
return this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
1039
|
+
return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
942
1040
|
}
|
|
943
1041
|
}
|
|
944
1042
|
_ts_decorate([
|
package/dest/bin/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env -S node --no-warnings
|
|
2
2
|
export {};
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9iaW4vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
|
package/dest/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './aztec-node/config.js';
|
|
2
2
|
export * from './aztec-node/server.js';
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHdCQUF3QixDQUFDO0FBQ3ZDLGNBQWMsd0JBQXdCLENBQUMifQ==
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type ConfigMappingsType } from '@aztec/foundation/config';
|
|
2
2
|
export type SentinelConfig = {
|
|
3
3
|
sentinelHistoryLengthInEpochs: number;
|
|
4
|
+
sentinelHistoricProvenPerformanceLengthInEpochs: number;
|
|
4
5
|
sentinelEnabled: boolean;
|
|
5
6
|
};
|
|
6
7
|
export declare const sentinelConfigMappings: ConfigMappingsType<SentinelConfig>;
|
|
7
|
-
//# sourceMappingURL=
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VudGluZWwvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLGtCQUFrQixFQUEyQyxNQUFNLDBCQUEwQixDQUFDO0FBRTVHLE1BQU0sTUFBTSxjQUFjLEdBQUc7SUFDM0IsNkJBQTZCLEVBQUUsTUFBTSxDQUFDO0lBQ3RDLCtDQUErQyxFQUFFLE1BQU0sQ0FBQztJQUN4RCxlQUFlLEVBQUUsT0FBTyxDQUFDO0NBQzFCLENBQUM7QUFFRixlQUFPLE1BQU0sc0JBQXNCLEVBQUUsa0JBQWtCLENBQUMsY0FBYyxDQTRCckUsQ0FBQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/sentinel/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAA2C,MAAM,0BAA0B,CAAC;AAE5G,MAAM,MAAM,cAAc,GAAG;IAC3B,6BAA6B,EAAE,MAAM,CAAC;IACtC,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,CAAC,cAAc,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/sentinel/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAA2C,MAAM,0BAA0B,CAAC;AAE5G,MAAM,MAAM,cAAc,GAAG;IAC3B,6BAA6B,EAAE,MAAM,CAAC;IACtC,+CAA+C,EAAE,MAAM,CAAC;IACxD,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,kBAAkB,CAAC,cAAc,CA4BrE,CAAC"}
|
package/dest/sentinel/config.js
CHANGED
|
@@ -5,6 +5,22 @@ export const sentinelConfigMappings = {
|
|
|
5
5
|
env: 'SENTINEL_HISTORY_LENGTH_IN_EPOCHS',
|
|
6
6
|
...numberConfigHelper(24)
|
|
7
7
|
},
|
|
8
|
+
/**
|
|
9
|
+
* The number of L2 epochs kept of proven performance history for each validator.
|
|
10
|
+
* This value must be large enough so that we have proven performance for every validator
|
|
11
|
+
* for at least slashInactivityConsecutiveEpochThreshold. Assuming this value is 3,
|
|
12
|
+
* and the committee size is 48, and we have 10k validators, then we pick 48 out of 10k each draw.
|
|
13
|
+
* For any fixed element, per-draw prob = 48/10000 = 0.0048.
|
|
14
|
+
* After n draws, count ~ Binomial(n, 0.0048). We want P(X >= 3).
|
|
15
|
+
* Results (exact binomial):
|
|
16
|
+
* - 90% chance: n = 1108
|
|
17
|
+
* - 95% chance: n = 1310
|
|
18
|
+
* - 99% chance: n = 1749
|
|
19
|
+
*/ sentinelHistoricProvenPerformanceLengthInEpochs: {
|
|
20
|
+
description: 'The number of L2 epochs kept of proven performance history for each validator.',
|
|
21
|
+
env: 'SENTINEL_HISTORIC_PROVEN_PERFORMANCE_LENGTH_IN_EPOCHS',
|
|
22
|
+
...numberConfigHelper(2000)
|
|
23
|
+
},
|
|
8
24
|
sentinelEnabled: {
|
|
9
25
|
description: 'Whether the sentinel is enabled or not.',
|
|
10
26
|
env: 'SENTINEL_ENABLED',
|
|
@@ -6,4 +6,4 @@ import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
|
|
|
6
6
|
import type { SentinelConfig } from './config.js';
|
|
7
7
|
import { Sentinel } from './sentinel.js';
|
|
8
8
|
export declare function createSentinel(epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, config: SentinelConfig & DataStoreConfig & SlasherConfig, logger?: import("@aztec/foundation/log").Logger): Promise<Sentinel | undefined>;
|
|
9
|
-
//# sourceMappingURL=
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlbnRpbmVsL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFOUQsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXJFLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3pDLHdCQUFzQixjQUFjLENBQ2xDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLEdBQUcsRUFBRSxTQUFTLEVBQ2QsTUFBTSxFQUFFLGNBQWMsR0FBRyxlQUFlLEdBQUcsYUFBYSxFQUN4RCxNQUFNLHlDQUFnQyxHQUNyQyxPQUFPLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQyxDQWlCL0IifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/sentinel/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAsB,cAAc,CAClC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,EACxD,MAAM,yCAAgC,GACrC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/sentinel/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAsB,cAAc,CAClC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,EACxD,MAAM,yCAAgC,GACrC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAiB/B"}
|
package/dest/sentinel/factory.js
CHANGED
|
@@ -8,8 +8,10 @@ export async function createSentinel(epochCache, archiver, p2p, config, logger =
|
|
|
8
8
|
}
|
|
9
9
|
const kvStore = await createStore('sentinel', SentinelStore.SCHEMA_VERSION, config, createLogger('node:sentinel:lmdb'));
|
|
10
10
|
const storeHistoryLength = config.sentinelHistoryLengthInEpochs * epochCache.getL1Constants().epochDuration;
|
|
11
|
+
const storeHistoricProvenPerformanceLength = config.sentinelHistoricProvenPerformanceLengthInEpochs;
|
|
11
12
|
const sentinelStore = new SentinelStore(kvStore, {
|
|
12
|
-
historyLength: storeHistoryLength
|
|
13
|
+
historyLength: storeHistoryLength,
|
|
14
|
+
historicProvenPerformanceLength: storeHistoricProvenPerformanceLength
|
|
13
15
|
});
|
|
14
16
|
return new Sentinel(epochCache, archiver, p2p, sentinelStore, config, logger);
|
|
15
17
|
}
|
package/dest/sentinel/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { Sentinel } from './sentinel.js';
|
|
2
2
|
export type { ValidatorsStats, ValidatorStats, ValidatorStatusHistory, ValidatorStatusInSlot, } from '@aztec/stdlib/validators';
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZW50aW5lbC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXpDLFlBQVksRUFDVixlQUFlLEVBQ2YsY0FBYyxFQUNkLHNCQUFzQixFQUN0QixxQkFBcUIsR0FDdEIsTUFBTSwwQkFBMEIsQ0FBQyJ9
|