@aztec/sequencer-client 0.85.0 → 0.86.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.
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +7 -7
- package/dest/publisher/sequencer-publisher.d.ts +14 -9
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +18 -8
- package/dest/sequencer/metrics.d.ts +16 -1
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +80 -11
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +12 -3
- package/dest/sequencer/utils.d.ts +1 -1
- package/dest/sequencer/utils.d.ts.map +1 -1
- package/dest/sequencer/utils.js +3 -5
- package/package.json +25 -27
- package/src/client/sequencer-client.ts +9 -10
- package/src/publisher/sequencer-publisher.ts +16 -10
- package/src/sequencer/metrics.ts +107 -16
- package/src/sequencer/sequencer.ts +23 -5
- package/src/sequencer/utils.ts +3 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;GAEG;AACH,qBAAa,eAAe;IACd,SAAS,CAAC,SAAS,EAAE,SAAS;gBAApB,SAAS,EAAE,SAAS;IAE1C;;;;;;;;;;;;OAYG;WACiB,GAAG,CACrB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE;QACJ,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;QAC7C,SAAS,EAAE,GAAG,CAAC;QACf,sBAAsB,EAAE,sBAAsB,CAAC;QAC/C,aAAa,EAAE,aAAa,CAAC;QAC7B,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,aAAa,EAAE,aAAa,CAAC;QAC7B,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,SAAS,EAAE,eAAe,CAAC;QAC3B,SAAS,CAAC,EAAE,kBAAkB,CAAC;QAC/B,cAAc,CAAC,EAAE,uBAAuB,CAAC;QACzC,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,SAAS,CAAC,EAAE,kBAAkB,CAAC;KAChC;
|
|
1
|
+
{"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAUhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;GAEG;AACH,qBAAa,eAAe;IACd,SAAS,CAAC,SAAS,EAAE,SAAS;gBAApB,SAAS,EAAE,SAAS;IAE1C;;;;;;;;;;;;OAYG;WACiB,GAAG,CACrB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE;QACJ,eAAe,EAAE,eAAe,GAAG,SAAS,CAAC;QAC7C,SAAS,EAAE,GAAG,CAAC;QACf,sBAAsB,EAAE,sBAAsB,CAAC;QAC/C,aAAa,EAAE,aAAa,CAAC;QAC7B,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,aAAa,EAAE,aAAa,CAAC;QAC7B,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,SAAS,EAAE,eAAe,CAAC;QAC3B,SAAS,CAAC,EAAE,kBAAkB,CAAC;QAC/B,cAAc,CAAC,EAAE,uBAAuB,CAAC;QACzC,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,SAAS,CAAC,EAAE,kBAAkB,CAAC;KAChC;IA0HH;;;OAGG;IACI,qBAAqB,CAAC,MAAM,EAAE,eAAe;IAIpD;;OAEG;IACU,IAAI;IAIjB,uGAAuG;IAChG,KAAK;IAIZ;;OAEG;IACI,OAAO;IAId,IAAI,QAAQ,IAAI,UAAU,CAEzB;IAED,IAAI,YAAY,IAAI,YAAY,CAE/B;IAED,IAAI,gBAAgB,IAAI,UAAU,CAEjC;IAED,IAAI,gBAAgB,IAAI,UAAU,GAAG,SAAS,CAE7C;IAED,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;CACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
-
import { ForwarderContract, GovernanceProposerContract, RollupContract, SlashingProposerContract, createEthereumChain,
|
|
2
|
+
import { ForwarderContract, GovernanceProposerContract, RollupContract, SlashingProposerContract, createEthereumChain, createExtendedL1Client, isAnvilTestChain } from '@aztec/ethereum';
|
|
3
3
|
import { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -32,17 +32,17 @@ import { Sequencer } from '../sequencer/index.js';
|
|
|
32
32
|
const { l1RpcUrls: rpcUrls, l1ChainId: chainId, publisherPrivateKey } = config;
|
|
33
33
|
const chain = createEthereumChain(rpcUrls, chainId);
|
|
34
34
|
const log = createLogger('sequencer-client');
|
|
35
|
-
const
|
|
36
|
-
const l1TxUtils = deps.l1TxUtils ?? new L1TxUtilsWithBlobs(
|
|
37
|
-
const rollupContract = new RollupContract(
|
|
35
|
+
const l1Client = createExtendedL1Client(rpcUrls, publisherPrivateKey, chain.chainInfo);
|
|
36
|
+
const l1TxUtils = deps.l1TxUtils ?? new L1TxUtilsWithBlobs(l1Client, log, config);
|
|
37
|
+
const rollupContract = new RollupContract(l1Client, config.l1Contracts.rollupAddress.toString());
|
|
38
38
|
const [l1GenesisTime, slotDuration] = await Promise.all([
|
|
39
39
|
rollupContract.getL1GenesisTime(),
|
|
40
40
|
rollupContract.getSlotDuration()
|
|
41
41
|
]);
|
|
42
|
-
const forwarderContract = config.customForwarderContractAddress && config.customForwarderContractAddress !== EthAddress.ZERO ? new ForwarderContract(
|
|
43
|
-
const governanceProposerContract = new GovernanceProposerContract(
|
|
42
|
+
const forwarderContract = config.customForwarderContractAddress && config.customForwarderContractAddress !== EthAddress.ZERO ? new ForwarderContract(l1Client, config.customForwarderContractAddress.toString(), config.l1Contracts.rollupAddress.toString()) : await ForwarderContract.create(l1Client.account.address, l1Client, log, config.l1Contracts.rollupAddress.toString());
|
|
43
|
+
const governanceProposerContract = new GovernanceProposerContract(l1Client, config.l1Contracts.governanceProposerAddress.toString());
|
|
44
44
|
const slashingProposerAddress = await rollupContract.getSlashingProposerAddress();
|
|
45
|
-
const slashingProposerContract = new SlashingProposerContract(
|
|
45
|
+
const slashingProposerContract = new SlashingProposerContract(l1Client, slashingProposerAddress.toString());
|
|
46
46
|
const epochCache = deps.epochCache ?? await EpochCache.create(config.l1Contracts.rollupAddress, {
|
|
47
47
|
l1RpcUrls: rpcUrls,
|
|
48
48
|
l1ChainId: chainId,
|
|
@@ -62,6 +62,7 @@ export declare class SequencerPublisher {
|
|
|
62
62
|
governanceProposerContract: GovernanceProposerContract;
|
|
63
63
|
epochCache: EpochCache;
|
|
64
64
|
});
|
|
65
|
+
getRollupContract(): RollupContract;
|
|
65
66
|
registerSlashPayloadGetter(callback: GetSlashPayloadCallBack): void;
|
|
66
67
|
getForwarderAddress(): EthAddress;
|
|
67
68
|
getSenderAddress(): EthAddress;
|
|
@@ -77,15 +78,19 @@ export declare class SequencerPublisher {
|
|
|
77
78
|
* - undefined if no valid requests are found OR the tx failed to send.
|
|
78
79
|
*/
|
|
79
80
|
sendRequests(): Promise<{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
result: {
|
|
82
|
+
receipt: TransactionReceipt<bigint, number, "success" | "reverted", import("viem").TransactionType>;
|
|
83
|
+
gasPrice: GasPrice;
|
|
84
|
+
stats: TransactionStats | undefined;
|
|
85
|
+
errorMsg?: undefined;
|
|
86
|
+
} | {
|
|
87
|
+
receipt: TransactionReceipt<bigint, number, "success" | "reverted", import("viem").TransactionType>;
|
|
88
|
+
gasPrice: GasPrice;
|
|
89
|
+
errorMsg: string | undefined;
|
|
90
|
+
stats?: undefined;
|
|
91
|
+
};
|
|
92
|
+
expiredActions: Action[];
|
|
93
|
+
validActions: Action[];
|
|
89
94
|
} | undefined>;
|
|
90
95
|
private callbackBundledTransactions;
|
|
91
96
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":";;AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,KAAK,uBAAuB,EAAwB,MAAM,yBAAyB,CAAC;AAC7F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,0BAA0B,EAE/B,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,cAAc,EACd,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAMjE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAGnF,OAAO,EAAE,KAAK,kBAAkB,EAAsB,MAAM,MAAM,CAAC;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,7 +46,9 @@ export class SequencerPublisher {
|
|
|
46
46
|
constructor(config, deps){
|
|
47
47
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
48
48
|
this.epochCache = deps.epochCache;
|
|
49
|
-
this.blobSinkClient = deps.blobSinkClient ?? createBlobSinkClient(config
|
|
49
|
+
this.blobSinkClient = deps.blobSinkClient ?? createBlobSinkClient(config, {
|
|
50
|
+
logger: createLogger('sequencer:blob-sink:client')
|
|
51
|
+
});
|
|
50
52
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
51
53
|
this.metrics = new SequencerPublisherMetrics(telemetry, 'SequencerPublisher');
|
|
52
54
|
this.l1TxUtils = deps.l1TxUtils;
|
|
@@ -55,6 +57,9 @@ export class SequencerPublisher {
|
|
|
55
57
|
this.govProposerContract = deps.governanceProposerContract;
|
|
56
58
|
this.slashingProposerContract = deps.slashingProposerContract;
|
|
57
59
|
}
|
|
60
|
+
getRollupContract() {
|
|
61
|
+
return this.rollupContract;
|
|
62
|
+
}
|
|
58
63
|
registerSlashPayloadGetter(callback) {
|
|
59
64
|
this.getSlashPayload = callback;
|
|
60
65
|
}
|
|
@@ -93,6 +98,8 @@ export class SequencerPublisher {
|
|
|
93
98
|
const currentL2Slot = this.getCurrentL2Slot();
|
|
94
99
|
this.log.debug(`Current L2 slot: ${currentL2Slot}`);
|
|
95
100
|
const validRequests = requestsToProcess.filter((request)=>request.lastValidL2Slot >= currentL2Slot);
|
|
101
|
+
const validActions = validRequests.map((x)=>x.action);
|
|
102
|
+
const expiredActions = requestsToProcess.filter((request)=>request.lastValidL2Slot < currentL2Slot).map((x)=>x.action);
|
|
96
103
|
if (validRequests.length !== requestsToProcess.length) {
|
|
97
104
|
this.log.warn(`Some requests were expired for slot ${currentL2Slot}`, {
|
|
98
105
|
validRequests: validRequests.map((request)=>({
|
|
@@ -125,7 +132,11 @@ export class SequencerPublisher {
|
|
|
125
132
|
});
|
|
126
133
|
const result = await this.forwarderContract.forward(validRequests.map((request)=>request.request), this.l1TxUtils, gasConfig, blobConfig, this.log);
|
|
127
134
|
this.callbackBundledTransactions(validRequests, result);
|
|
128
|
-
return
|
|
135
|
+
return {
|
|
136
|
+
result,
|
|
137
|
+
expiredActions,
|
|
138
|
+
validActions
|
|
139
|
+
};
|
|
129
140
|
} catch (err) {
|
|
130
141
|
const viemError = formatViemError(err);
|
|
131
142
|
this.log.error(`Failed to publish bundled transactions`, viemError);
|
|
@@ -275,12 +286,11 @@ export class SequencerPublisher {
|
|
|
275
286
|
* @returns True if the tx has been enqueued, throws otherwise. See #9315
|
|
276
287
|
*/ async enqueueProposeL2Block(block, attestations, txHashes, opts = {}) {
|
|
277
288
|
const consensusPayload = new ConsensusPayload(block.header, block.archive.root, txHashes ?? []);
|
|
278
|
-
const digest =
|
|
289
|
+
const digest = getHashedSignaturePayload(consensusPayload, SignatureDomainSeparator.blockAttestation);
|
|
279
290
|
const blobs = await Blob.getBlobs(block.body.toBlobFields());
|
|
280
291
|
const proposeTxArgs = {
|
|
281
292
|
header: block.header.toBuffer(),
|
|
282
293
|
archive: block.archive.root.toBuffer(),
|
|
283
|
-
blockHash: (await block.header.hash()).toBuffer(),
|
|
284
294
|
body: block.body.toBuffer(),
|
|
285
295
|
blobs,
|
|
286
296
|
attestations,
|
|
@@ -312,12 +322,15 @@ export class SequencerPublisher {
|
|
|
312
322
|
this.l1TxUtils.restart();
|
|
313
323
|
}
|
|
314
324
|
async prepareProposeTx(encodedData, timestamp) {
|
|
325
|
+
if (!this.l1TxUtils.client.account) {
|
|
326
|
+
throw new Error('L1 TX utils needs to be initialized with an account wallet.');
|
|
327
|
+
}
|
|
315
328
|
const kzg = Blob.getViemKzgInstance();
|
|
316
329
|
const blobInput = Blob.getEthBlobEvaluationInputs(encodedData.blobs);
|
|
317
330
|
this.log.debug('Validating blob input', {
|
|
318
331
|
blobInput
|
|
319
332
|
});
|
|
320
|
-
const blobEvaluationGas = await this.l1TxUtils.estimateGas(this.l1TxUtils.
|
|
333
|
+
const blobEvaluationGas = await this.l1TxUtils.estimateGas(this.l1TxUtils.client.account, {
|
|
321
334
|
to: this.rollupContract.address,
|
|
322
335
|
data: encodeFunctionData({
|
|
323
336
|
abi: RollupAbi,
|
|
@@ -346,7 +359,6 @@ export class SequencerPublisher {
|
|
|
346
359
|
// We are currently not modifying these. See #9963
|
|
347
360
|
feeAssetPriceModifier: 0n
|
|
348
361
|
},
|
|
349
|
-
blockHash: `0x${encodedData.blockHash.toString('hex')}`,
|
|
350
362
|
txHashes
|
|
351
363
|
},
|
|
352
364
|
attestations,
|
|
@@ -411,7 +423,6 @@ export class SequencerPublisher {
|
|
|
411
423
|
const kzg = Blob.getViemKzgInstance();
|
|
412
424
|
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData, timestamp);
|
|
413
425
|
const startBlock = await this.l1TxUtils.getBlockNumber();
|
|
414
|
-
const blockHash = await block.hash();
|
|
415
426
|
return this.addRequest({
|
|
416
427
|
action: 'propose',
|
|
417
428
|
request: {
|
|
@@ -462,7 +473,6 @@ export class SequencerPublisher {
|
|
|
462
473
|
this.log.error(`Rollup process tx reverted. ${errorMsg ?? 'No error message'}`, undefined, {
|
|
463
474
|
...block.getStats(),
|
|
464
475
|
txHash: receipt.transactionHash,
|
|
465
|
-
blockHash,
|
|
466
476
|
slotNumber: block.header.globalVariables.slotNumber.toBigInt()
|
|
467
477
|
});
|
|
468
478
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import type { EthAddress } from '@aztec/aztec.js';
|
|
2
|
+
import type { RollupContract } from '@aztec/ethereum';
|
|
1
3
|
import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
2
4
|
import { type SequencerState, type SequencerStateCallback } from './utils.js';
|
|
3
5
|
export declare class SequencerMetrics {
|
|
6
|
+
private coinbase;
|
|
7
|
+
private rollup;
|
|
4
8
|
readonly tracer: Tracer;
|
|
9
|
+
private meter;
|
|
5
10
|
private blockCounter;
|
|
6
11
|
private blockBuildDuration;
|
|
7
12
|
private blockBuildManaPerSecond;
|
|
@@ -10,7 +15,15 @@ export declare class SequencerMetrics {
|
|
|
10
15
|
private currentBlockSize;
|
|
11
16
|
private blockBuilderInsertions;
|
|
12
17
|
private timeToCollectAttestations;
|
|
13
|
-
|
|
18
|
+
private rewards;
|
|
19
|
+
private slots;
|
|
20
|
+
private filledSlots;
|
|
21
|
+
private missedSlots;
|
|
22
|
+
private lastSeenSlot?;
|
|
23
|
+
constructor(client: TelemetryClient, getState: SequencerStateCallback, coinbase: EthAddress, rollup: RollupContract, name?: string);
|
|
24
|
+
start(): void;
|
|
25
|
+
stop(): void;
|
|
26
|
+
private observe;
|
|
14
27
|
startCollectingAttestationsTimer(): () => void;
|
|
15
28
|
recordTimeToCollectAttestations(time: number): void;
|
|
16
29
|
recordBlockBuilderTreeInsertions(timeUs: number): void;
|
|
@@ -19,6 +32,8 @@ export declare class SequencerMetrics {
|
|
|
19
32
|
recordFailedBlock(): void;
|
|
20
33
|
recordNewBlock(blockNumber: number, txCount: number): void;
|
|
21
34
|
recordStateTransitionBufferMs(durationMs: number, state: SequencerState): void;
|
|
35
|
+
observeSlotChange(slot: bigint | undefined, proposer: string): void;
|
|
36
|
+
incFilledSlot(proposer: string): void;
|
|
22
37
|
private setCurrentBlock;
|
|
23
38
|
}
|
|
24
39
|
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/sequencer/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/sequencer/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAQL,KAAK,eAAe,EACpB,KAAK,MAAM,EAGZ,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,sBAAsB,EAA0B,MAAM,YAAY,CAAC;AAEtG,qBAAa,gBAAgB;IAyBzB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;IAzBhB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAQ;IAErB,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,uBAAuB,CAAQ;IACvC,OAAO,CAAC,6BAA6B,CAAY;IACjD,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,sBAAsB,CAAY;IAE1C,OAAO,CAAC,yBAAyB,CAAQ;IAEzC,OAAO,CAAC,OAAO,CAAkB;IAEjC,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,WAAW,CAAgB;IAEnC,OAAO,CAAC,YAAY,CAAC,CAAS;gBAG5B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,sBAAsB,EACxB,QAAQ,EAAE,UAAU,EACpB,MAAM,EAAE,cAAc,EAC9B,IAAI,SAAc;IA2Fb,KAAK;IAIL,IAAI;IAIX,OAAO,CAAC,OAAO,CAQb;IAEF,gCAAgC,IAAI,MAAM,IAAI;IAS9C,+BAA+B,CAAC,IAAI,EAAE,MAAM;IAI5C,gCAAgC,CAAC,MAAM,EAAE,MAAM;IAI/C,oBAAoB;IAOpB,gBAAgB,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAQ3D,iBAAiB;IAOjB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAInD,6BAA6B,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc;IAMvE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM;IAqB5D,aAAa,CAAC,QAAQ,EAAE,MAAM;IAO9B,OAAO,CAAC,eAAe;CAIxB"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
|
|
2
|
+
import { formatUnits } from 'viem';
|
|
2
3
|
import { sequencerStateToNumber } from './utils.js';
|
|
3
4
|
export class SequencerMetrics {
|
|
5
|
+
coinbase;
|
|
6
|
+
rollup;
|
|
4
7
|
tracer;
|
|
8
|
+
meter;
|
|
5
9
|
blockCounter;
|
|
6
10
|
blockBuildDuration;
|
|
7
11
|
blockBuildManaPerSecond;
|
|
@@ -10,44 +14,59 @@ export class SequencerMetrics {
|
|
|
10
14
|
currentBlockSize;
|
|
11
15
|
blockBuilderInsertions;
|
|
12
16
|
timeToCollectAttestations;
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
rewards;
|
|
18
|
+
slots;
|
|
19
|
+
filledSlots;
|
|
20
|
+
missedSlots;
|
|
21
|
+
lastSeenSlot;
|
|
22
|
+
constructor(client, getState, coinbase, rollup, name = 'Sequencer'){
|
|
23
|
+
this.coinbase = coinbase;
|
|
24
|
+
this.rollup = rollup;
|
|
25
|
+
this.observe = async (observer)=>{
|
|
26
|
+
let rewards = 0n;
|
|
27
|
+
rewards = await this.rollup.getSequencerRewards(this.coinbase);
|
|
28
|
+
const fmt = parseFloat(formatUnits(rewards, 18));
|
|
29
|
+
observer.observe(this.rewards, fmt, {
|
|
30
|
+
[Attributes.COINBASE]: this.coinbase.toString()
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
this.meter = client.getMeter(name);
|
|
15
34
|
this.tracer = client.getTracer(name);
|
|
16
|
-
this.blockCounter = meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_COUNT);
|
|
17
|
-
this.blockBuildDuration = meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION, {
|
|
35
|
+
this.blockCounter = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_COUNT);
|
|
36
|
+
this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION, {
|
|
18
37
|
unit: 'ms',
|
|
19
38
|
description: 'Duration to build a block',
|
|
20
39
|
valueType: ValueType.INT
|
|
21
40
|
});
|
|
22
|
-
this.blockBuildManaPerSecond = meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND, {
|
|
41
|
+
this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND, {
|
|
23
42
|
unit: 'mana/s',
|
|
24
43
|
description: 'Mana per second when building a block',
|
|
25
44
|
valueType: ValueType.INT
|
|
26
45
|
});
|
|
27
|
-
this.stateTransitionBufferDuration = meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION, {
|
|
46
|
+
this.stateTransitionBufferDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION, {
|
|
28
47
|
unit: 'ms',
|
|
29
48
|
description: 'The time difference between when the sequencer needed to transition to a new state and when it actually did.',
|
|
30
49
|
valueType: ValueType.INT
|
|
31
50
|
});
|
|
32
|
-
const currentState = meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
|
|
51
|
+
const currentState = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
|
|
33
52
|
description: 'Current state of the sequencer'
|
|
34
53
|
});
|
|
35
54
|
currentState.addCallback((observer)=>{
|
|
36
55
|
observer.observe(sequencerStateToNumber(getState()));
|
|
37
56
|
});
|
|
38
|
-
this.currentBlockNumber = meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
|
|
57
|
+
this.currentBlockNumber = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
|
|
39
58
|
description: 'Current block number',
|
|
40
59
|
valueType: ValueType.INT
|
|
41
60
|
});
|
|
42
|
-
this.currentBlockSize = meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
|
|
61
|
+
this.currentBlockSize = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
|
|
43
62
|
description: 'Current block size',
|
|
44
63
|
valueType: ValueType.INT
|
|
45
64
|
});
|
|
46
|
-
this.timeToCollectAttestations = meter.createGauge(Metrics.SEQUENCER_TIME_TO_COLLECT_ATTESTATIONS, {
|
|
65
|
+
this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_TIME_TO_COLLECT_ATTESTATIONS, {
|
|
47
66
|
description: 'The time spent collecting attestations from committee members',
|
|
48
67
|
valueType: ValueType.INT
|
|
49
68
|
});
|
|
50
|
-
this.blockBuilderInsertions = meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
|
|
69
|
+
this.blockBuilderInsertions = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
|
|
51
70
|
description: 'Timer for tree insertions performed by the block builder',
|
|
52
71
|
unit: 'us',
|
|
53
72
|
valueType: ValueType.INT
|
|
@@ -63,7 +82,34 @@ export class SequencerMetrics {
|
|
|
63
82
|
this.blockCounter.add(0, {
|
|
64
83
|
[Attributes.STATUS]: 'built'
|
|
65
84
|
});
|
|
85
|
+
this.rewards = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
|
|
86
|
+
valueType: ValueType.DOUBLE,
|
|
87
|
+
description: 'The rewards earned'
|
|
88
|
+
});
|
|
89
|
+
this.slots = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLOT_COUNT, {
|
|
90
|
+
valueType: ValueType.INT,
|
|
91
|
+
description: 'The number of slots this sequencer was selected for'
|
|
92
|
+
});
|
|
93
|
+
this.filledSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_FILLED_SLOT_COUNT, {
|
|
94
|
+
valueType: ValueType.INT,
|
|
95
|
+
description: 'The number of slots this sequencer has filled'
|
|
96
|
+
});
|
|
97
|
+
this.missedSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_MISSED_SLOT_COUNT, {
|
|
98
|
+
valueType: ValueType.INT,
|
|
99
|
+
description: 'The number of slots this sequencer has missed to fill'
|
|
100
|
+
});
|
|
66
101
|
}
|
|
102
|
+
start() {
|
|
103
|
+
this.meter.addBatchObservableCallback(this.observe, [
|
|
104
|
+
this.rewards
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
stop() {
|
|
108
|
+
this.meter.removeBatchObservableCallback(this.observe, [
|
|
109
|
+
this.rewards
|
|
110
|
+
]);
|
|
111
|
+
}
|
|
112
|
+
observe;
|
|
67
113
|
startCollectingAttestationsTimer() {
|
|
68
114
|
const startTime = Date.now();
|
|
69
115
|
const stop = ()=>{
|
|
@@ -105,6 +151,29 @@ export class SequencerMetrics {
|
|
|
105
151
|
[Attributes.SEQUENCER_STATE]: state
|
|
106
152
|
});
|
|
107
153
|
}
|
|
154
|
+
observeSlotChange(slot, proposer) {
|
|
155
|
+
// sequencer went through the loop a second time. Noop
|
|
156
|
+
if (slot === this.lastSeenSlot) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (typeof this.lastSeenSlot === 'bigint') {
|
|
160
|
+
this.missedSlots.add(1, {
|
|
161
|
+
[Attributes.BLOCK_PROPOSER]: proposer
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (typeof slot === 'bigint') {
|
|
165
|
+
this.slots.add(1, {
|
|
166
|
+
[Attributes.BLOCK_PROPOSER]: proposer
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
this.lastSeenSlot = slot;
|
|
170
|
+
}
|
|
171
|
+
incFilledSlot(proposer) {
|
|
172
|
+
this.filledSlots.add(1, {
|
|
173
|
+
[Attributes.BLOCK_PROPOSER]: proposer
|
|
174
|
+
});
|
|
175
|
+
this.lastSeenSlot = undefined;
|
|
176
|
+
}
|
|
108
177
|
setCurrentBlock(blockNumber, txCount) {
|
|
109
178
|
this.currentBlockNumber.record(blockNumber);
|
|
110
179
|
this.currentBlockSize.record(txCount);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
|
|
@@ -95,8 +95,8 @@ export { SequencerState };
|
|
|
95
95
|
this.maxBlockGas = new Gas(100e9, 100e9);
|
|
96
96
|
this.isFlushing = false;
|
|
97
97
|
this.enforceTimeTable = false;
|
|
98
|
-
this.metrics = new SequencerMetrics(telemetry, ()=>this.state, 'Sequencer');
|
|
99
|
-
this.l1Metrics = new L1Metrics(telemetry.getMeter('SequencerL1Metrics'), publisher.l1TxUtils.
|
|
98
|
+
this.metrics = new SequencerMetrics(telemetry, ()=>this.state, this._coinbase, this.publisher.getRollupContract(), 'Sequencer');
|
|
99
|
+
this.l1Metrics = new L1Metrics(telemetry.getMeter('SequencerL1Metrics'), publisher.l1TxUtils.client, [
|
|
100
100
|
publisher.getSenderAddress()
|
|
101
101
|
]);
|
|
102
102
|
// Register the block builder with the validator client for re-execution
|
|
@@ -167,6 +167,7 @@ export { SequencerState };
|
|
|
167
167
|
* Starts the sequencer and moves to IDLE state.
|
|
168
168
|
*/ async start() {
|
|
169
169
|
await this.updateConfig(this.config);
|
|
170
|
+
this.metrics.start();
|
|
170
171
|
this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.pollingIntervalMs);
|
|
171
172
|
this.setState(SequencerState.IDLE, 0n, true);
|
|
172
173
|
this.runningPromise.start();
|
|
@@ -177,6 +178,7 @@ export { SequencerState };
|
|
|
177
178
|
* Stops the sequencer from processing txs and moves to STOPPED state.
|
|
178
179
|
*/ async stop() {
|
|
179
180
|
this.log.debug(`Stopping sequencer`);
|
|
181
|
+
this.metrics.stop();
|
|
180
182
|
await this.validatorClient?.stop();
|
|
181
183
|
await this.runningPromise?.stop();
|
|
182
184
|
this.slasherClient.stop();
|
|
@@ -224,6 +226,7 @@ export { SequencerState };
|
|
|
224
226
|
// If we cannot find a tip archive, assume genesis.
|
|
225
227
|
const chainTipArchive = chainTip.archive;
|
|
226
228
|
const slot = await this.slotForProposal(chainTipArchive.toBuffer(), BigInt(newBlockNumber));
|
|
229
|
+
this.metrics.observeSlotChange(slot, this.publisher.getSenderAddress().toString());
|
|
227
230
|
if (!slot) {
|
|
228
231
|
this.log.debug(`Cannot propose block ${newBlockNumber}`);
|
|
229
232
|
return;
|
|
@@ -272,7 +275,13 @@ export { SequencerState };
|
|
|
272
275
|
slot
|
|
273
276
|
});
|
|
274
277
|
});
|
|
275
|
-
await this.publisher.sendRequests();
|
|
278
|
+
const resp = await this.publisher.sendRequests();
|
|
279
|
+
if (resp) {
|
|
280
|
+
const proposedBlock = resp.validActions.find((a)=>a === 'propose');
|
|
281
|
+
if (proposedBlock) {
|
|
282
|
+
this.metrics.incFilledSlot(this.publisher.getSenderAddress().toString());
|
|
283
|
+
}
|
|
284
|
+
}
|
|
276
285
|
if (finishedFlushing) {
|
|
277
286
|
this.isFlushing = false;
|
|
278
287
|
}
|
|
@@ -44,5 +44,5 @@ export declare function sequencerStateToNumber(state: SequencerState): number;
|
|
|
44
44
|
*
|
|
45
45
|
* @todo: perform this logic within the memory attestation store instead?
|
|
46
46
|
*/
|
|
47
|
-
export declare function orderAttestations(attestations: BlockAttestation[], orderAddresses: EthAddress[]):
|
|
47
|
+
export declare function orderAttestations(attestations: BlockAttestation[], orderAddresses: EthAddress[]): Signature[];
|
|
48
48
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sequencer/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,oBAAY,cAAc;IACxB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,aAAa,kBAAkB;IAC/B;;OAEG;IACH,cAAc,mBAAmB;IACjC;;OAEG;IACH,qBAAqB,0BAA0B;IAC/C;;OAEG;IACH,cAAc,mBAAmB;IACjC;;OAEG;IACH,uBAAuB,4BAA4B;IACnD;;OAEG;IACH,gBAAgB,qBAAqB;CACtC;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,cAAc,CAAC;AAE1D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEpE;AAED;;;;;;GAMG;AACH,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sequencer/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,oBAAY,cAAc;IACxB;;OAEG;IACH,OAAO,YAAY;IACnB;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,aAAa,kBAAkB;IAC/B;;OAEG;IACH,cAAc,mBAAmB;IACjC;;OAEG;IACH,qBAAqB,0BAA0B;IAC/C;;OAEG;IACH,cAAc,mBAAmB;IACjC;;OAEG;IACH,uBAAuB,4BAA4B;IACnD;;OAEG;IACH,gBAAgB,qBAAqB;CACtC;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,cAAc,CAAC;AAE1D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,gBAAgB,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,CAgB7G"}
|
package/dest/sequencer/utils.js
CHANGED
|
@@ -35,14 +35,12 @@ export function sequencerStateToNumber(state) {
|
|
|
35
35
|
* The rollup smart contract expects attestations to appear in the order of the committee
|
|
36
36
|
*
|
|
37
37
|
* @todo: perform this logic within the memory attestation store instead?
|
|
38
|
-
*/ export
|
|
38
|
+
*/ export function orderAttestations(attestations, orderAddresses) {
|
|
39
39
|
// Create a map of sender addresses to BlockAttestations
|
|
40
40
|
const attestationMap = new Map();
|
|
41
41
|
for (const attestation of attestations){
|
|
42
|
-
const sender =
|
|
43
|
-
|
|
44
|
-
attestationMap.set(sender.toString(), attestation);
|
|
45
|
-
}
|
|
42
|
+
const sender = attestation.getSender();
|
|
43
|
+
attestationMap.set(sender.toString(), attestation);
|
|
46
44
|
}
|
|
47
45
|
// Create the ordered array based on the orderAddresses, else return an empty signature
|
|
48
46
|
const orderedAttestations = orderAddresses.map((address)=>{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -21,43 +21,41 @@
|
|
|
21
21
|
"build": "yarn clean && tsc -b",
|
|
22
22
|
"build:dev": "tsc -b --watch",
|
|
23
23
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
24
|
-
"formatting": "run -T prettier --check ./src && run -T eslint ./src",
|
|
25
|
-
"formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
|
|
26
24
|
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}",
|
|
27
25
|
"test:integration": "concurrently -k -s first -c reset,dim -n test,anvil \"yarn test:integration:run\" \"anvil\"",
|
|
28
26
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
29
27
|
},
|
|
30
28
|
"dependencies": {
|
|
31
|
-
"@aztec/aztec.js": "0.
|
|
32
|
-
"@aztec/bb-prover": "0.
|
|
33
|
-
"@aztec/blob-lib": "0.
|
|
34
|
-
"@aztec/blob-sink": "0.
|
|
35
|
-
"@aztec/constants": "0.
|
|
36
|
-
"@aztec/epoch-cache": "0.
|
|
37
|
-
"@aztec/ethereum": "0.
|
|
38
|
-
"@aztec/foundation": "0.
|
|
39
|
-
"@aztec/l1-artifacts": "0.
|
|
40
|
-
"@aztec/merkle-tree": "0.
|
|
41
|
-
"@aztec/noir-acvm_js": "0.
|
|
42
|
-
"@aztec/noir-contracts.js": "0.
|
|
43
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
44
|
-
"@aztec/noir-types": "0.
|
|
45
|
-
"@aztec/p2p": "0.
|
|
46
|
-
"@aztec/protocol-contracts": "0.
|
|
47
|
-
"@aztec/prover-client": "0.
|
|
48
|
-
"@aztec/simulator": "0.
|
|
49
|
-
"@aztec/stdlib": "0.
|
|
50
|
-
"@aztec/telemetry-client": "0.
|
|
51
|
-
"@aztec/validator-client": "0.
|
|
52
|
-
"@aztec/world-state": "0.
|
|
29
|
+
"@aztec/aztec.js": "0.86.0",
|
|
30
|
+
"@aztec/bb-prover": "0.86.0",
|
|
31
|
+
"@aztec/blob-lib": "0.86.0",
|
|
32
|
+
"@aztec/blob-sink": "0.86.0",
|
|
33
|
+
"@aztec/constants": "0.86.0",
|
|
34
|
+
"@aztec/epoch-cache": "0.86.0",
|
|
35
|
+
"@aztec/ethereum": "0.86.0",
|
|
36
|
+
"@aztec/foundation": "0.86.0",
|
|
37
|
+
"@aztec/l1-artifacts": "0.86.0",
|
|
38
|
+
"@aztec/merkle-tree": "0.86.0",
|
|
39
|
+
"@aztec/noir-acvm_js": "0.86.0",
|
|
40
|
+
"@aztec/noir-contracts.js": "0.86.0",
|
|
41
|
+
"@aztec/noir-protocol-circuits-types": "0.86.0",
|
|
42
|
+
"@aztec/noir-types": "0.86.0",
|
|
43
|
+
"@aztec/p2p": "0.86.0",
|
|
44
|
+
"@aztec/protocol-contracts": "0.86.0",
|
|
45
|
+
"@aztec/prover-client": "0.86.0",
|
|
46
|
+
"@aztec/simulator": "0.86.0",
|
|
47
|
+
"@aztec/stdlib": "0.86.0",
|
|
48
|
+
"@aztec/telemetry-client": "0.86.0",
|
|
49
|
+
"@aztec/validator-client": "0.86.0",
|
|
50
|
+
"@aztec/world-state": "0.86.0",
|
|
53
51
|
"lodash.chunk": "^4.2.0",
|
|
54
52
|
"lodash.pick": "^4.4.0",
|
|
55
53
|
"tslib": "^2.4.0",
|
|
56
54
|
"viem": "2.23.7"
|
|
57
55
|
},
|
|
58
56
|
"devDependencies": {
|
|
59
|
-
"@aztec/archiver": "0.
|
|
60
|
-
"@aztec/kv-store": "0.
|
|
57
|
+
"@aztec/archiver": "0.86.0",
|
|
58
|
+
"@aztec/kv-store": "0.86.0",
|
|
61
59
|
"@jest/globals": "^29.5.0",
|
|
62
60
|
"@types/jest": "^29.5.0",
|
|
63
61
|
"@types/lodash.chunk": "^4.2.7",
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
RollupContract,
|
|
7
7
|
SlashingProposerContract,
|
|
8
8
|
createEthereumChain,
|
|
9
|
-
|
|
9
|
+
createExtendedL1Client,
|
|
10
10
|
isAnvilTestChain,
|
|
11
11
|
} from '@aztec/ethereum';
|
|
12
12
|
import { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
|
|
@@ -80,9 +80,9 @@ export class SequencerClient {
|
|
|
80
80
|
const { l1RpcUrls: rpcUrls, l1ChainId: chainId, publisherPrivateKey } = config;
|
|
81
81
|
const chain = createEthereumChain(rpcUrls, chainId);
|
|
82
82
|
const log = createLogger('sequencer-client');
|
|
83
|
-
const
|
|
84
|
-
const l1TxUtils = deps.l1TxUtils ?? new L1TxUtilsWithBlobs(
|
|
85
|
-
const rollupContract = new RollupContract(
|
|
83
|
+
const l1Client = createExtendedL1Client(rpcUrls, publisherPrivateKey, chain.chainInfo);
|
|
84
|
+
const l1TxUtils = deps.l1TxUtils ?? new L1TxUtilsWithBlobs(l1Client, log, config);
|
|
85
|
+
const rollupContract = new RollupContract(l1Client, config.l1Contracts.rollupAddress.toString());
|
|
86
86
|
const [l1GenesisTime, slotDuration] = await Promise.all([
|
|
87
87
|
rollupContract.getL1GenesisTime(),
|
|
88
88
|
rollupContract.getSlotDuration(),
|
|
@@ -90,24 +90,23 @@ export class SequencerClient {
|
|
|
90
90
|
const forwarderContract =
|
|
91
91
|
config.customForwarderContractAddress && config.customForwarderContractAddress !== EthAddress.ZERO
|
|
92
92
|
? new ForwarderContract(
|
|
93
|
-
|
|
93
|
+
l1Client,
|
|
94
94
|
config.customForwarderContractAddress.toString(),
|
|
95
95
|
config.l1Contracts.rollupAddress.toString(),
|
|
96
96
|
)
|
|
97
97
|
: await ForwarderContract.create(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
publicClient,
|
|
98
|
+
l1Client.account.address,
|
|
99
|
+
l1Client,
|
|
101
100
|
log,
|
|
102
101
|
config.l1Contracts.rollupAddress.toString(),
|
|
103
102
|
);
|
|
104
103
|
|
|
105
104
|
const governanceProposerContract = new GovernanceProposerContract(
|
|
106
|
-
|
|
105
|
+
l1Client,
|
|
107
106
|
config.l1Contracts.governanceProposerAddress.toString(),
|
|
108
107
|
);
|
|
109
108
|
const slashingProposerAddress = await rollupContract.getSlashingProposerAddress();
|
|
110
|
-
const slashingProposerContract = new SlashingProposerContract(
|
|
109
|
+
const slashingProposerContract = new SlashingProposerContract(l1Client, slashingProposerAddress.toString());
|
|
111
110
|
const epochCache =
|
|
112
111
|
deps.epochCache ??
|
|
113
112
|
(await EpochCache.create(
|
|
@@ -41,8 +41,6 @@ type L1ProcessArgs = {
|
|
|
41
41
|
header: Buffer;
|
|
42
42
|
/** A root of the archive tree after the L2 block is applied. */
|
|
43
43
|
archive: Buffer;
|
|
44
|
-
/** The L2 block's leaf in the archive tree. */
|
|
45
|
-
blockHash: Buffer;
|
|
46
44
|
/** L2 block blobs containing all tx effects. */
|
|
47
45
|
blobs: Blob[];
|
|
48
46
|
/** L2 block tx hashes */
|
|
@@ -122,7 +120,8 @@ export class SequencerPublisher {
|
|
|
122
120
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
123
121
|
this.epochCache = deps.epochCache;
|
|
124
122
|
|
|
125
|
-
this.blobSinkClient =
|
|
123
|
+
this.blobSinkClient =
|
|
124
|
+
deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('sequencer:blob-sink:client') });
|
|
126
125
|
|
|
127
126
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
128
127
|
this.metrics = new SequencerPublisherMetrics(telemetry, 'SequencerPublisher');
|
|
@@ -135,6 +134,10 @@ export class SequencerPublisher {
|
|
|
135
134
|
this.slashingProposerContract = deps.slashingProposerContract;
|
|
136
135
|
}
|
|
137
136
|
|
|
137
|
+
public getRollupContract(): RollupContract {
|
|
138
|
+
return this.rollupContract;
|
|
139
|
+
}
|
|
140
|
+
|
|
138
141
|
public registerSlashPayloadGetter(callback: GetSlashPayloadCallBack) {
|
|
139
142
|
this.getSlashPayload = callback;
|
|
140
143
|
}
|
|
@@ -179,6 +182,10 @@ export class SequencerPublisher {
|
|
|
179
182
|
const currentL2Slot = this.getCurrentL2Slot();
|
|
180
183
|
this.log.debug(`Current L2 slot: ${currentL2Slot}`);
|
|
181
184
|
const validRequests = requestsToProcess.filter(request => request.lastValidL2Slot >= currentL2Slot);
|
|
185
|
+
const validActions = validRequests.map(x => x.action);
|
|
186
|
+
const expiredActions = requestsToProcess
|
|
187
|
+
.filter(request => request.lastValidL2Slot < currentL2Slot)
|
|
188
|
+
.map(x => x.action);
|
|
182
189
|
|
|
183
190
|
if (validRequests.length !== requestsToProcess.length) {
|
|
184
191
|
this.log.warn(`Some requests were expired for slot ${currentL2Slot}`, {
|
|
@@ -223,7 +230,7 @@ export class SequencerPublisher {
|
|
|
223
230
|
this.log,
|
|
224
231
|
);
|
|
225
232
|
this.callbackBundledTransactions(validRequests, result);
|
|
226
|
-
return result;
|
|
233
|
+
return { result, expiredActions, validActions };
|
|
227
234
|
} catch (err) {
|
|
228
235
|
const viemError = formatViemError(err);
|
|
229
236
|
this.log.error(`Failed to publish bundled transactions`, viemError);
|
|
@@ -402,13 +409,12 @@ export class SequencerPublisher {
|
|
|
402
409
|
): Promise<boolean> {
|
|
403
410
|
const consensusPayload = new ConsensusPayload(block.header, block.archive.root, txHashes ?? []);
|
|
404
411
|
|
|
405
|
-
const digest =
|
|
412
|
+
const digest = getHashedSignaturePayload(consensusPayload, SignatureDomainSeparator.blockAttestation);
|
|
406
413
|
|
|
407
414
|
const blobs = await Blob.getBlobs(block.body.toBlobFields());
|
|
408
415
|
const proposeTxArgs = {
|
|
409
416
|
header: block.header.toBuffer(),
|
|
410
417
|
archive: block.archive.root.toBuffer(),
|
|
411
|
-
blockHash: (await block.header.hash()).toBuffer(),
|
|
412
418
|
body: block.body.toBuffer(),
|
|
413
419
|
blobs,
|
|
414
420
|
attestations,
|
|
@@ -447,12 +453,15 @@ export class SequencerPublisher {
|
|
|
447
453
|
}
|
|
448
454
|
|
|
449
455
|
private async prepareProposeTx(encodedData: L1ProcessArgs, timestamp: bigint) {
|
|
456
|
+
if (!this.l1TxUtils.client.account) {
|
|
457
|
+
throw new Error('L1 TX utils needs to be initialized with an account wallet.');
|
|
458
|
+
}
|
|
450
459
|
const kzg = Blob.getViemKzgInstance();
|
|
451
460
|
const blobInput = Blob.getEthBlobEvaluationInputs(encodedData.blobs);
|
|
452
461
|
this.log.debug('Validating blob input', { blobInput });
|
|
453
462
|
const blobEvaluationGas = await this.l1TxUtils
|
|
454
463
|
.estimateGas(
|
|
455
|
-
this.l1TxUtils.
|
|
464
|
+
this.l1TxUtils.client.account,
|
|
456
465
|
{
|
|
457
466
|
to: this.rollupContract.address,
|
|
458
467
|
data: encodeFunctionData({
|
|
@@ -485,7 +494,6 @@ export class SequencerPublisher {
|
|
|
485
494
|
// We are currently not modifying these. See #9963
|
|
486
495
|
feeAssetPriceModifier: 0n,
|
|
487
496
|
},
|
|
488
|
-
blockHash: `0x${encodedData.blockHash.toString('hex')}`,
|
|
489
497
|
txHashes,
|
|
490
498
|
},
|
|
491
499
|
attestations,
|
|
@@ -553,7 +561,6 @@ export class SequencerPublisher {
|
|
|
553
561
|
const kzg = Blob.getViemKzgInstance();
|
|
554
562
|
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData, timestamp);
|
|
555
563
|
const startBlock = await this.l1TxUtils.getBlockNumber();
|
|
556
|
-
const blockHash = await block.hash();
|
|
557
564
|
|
|
558
565
|
return this.addRequest({
|
|
559
566
|
action: 'propose',
|
|
@@ -605,7 +612,6 @@ export class SequencerPublisher {
|
|
|
605
612
|
this.log.error(`Rollup process tx reverted. ${errorMsg ?? 'No error message'}`, undefined, {
|
|
606
613
|
...block.getStats(),
|
|
607
614
|
txHash: receipt.transactionHash,
|
|
608
|
-
blockHash,
|
|
609
615
|
slotNumber: block.header.globalVariables.slotNumber.toBigInt(),
|
|
610
616
|
});
|
|
611
617
|
}
|
package/src/sequencer/metrics.ts
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
|
+
import type { EthAddress } from '@aztec/aztec.js';
|
|
2
|
+
import type { RollupContract } from '@aztec/ethereum';
|
|
1
3
|
import {
|
|
2
4
|
Attributes,
|
|
5
|
+
type BatchObservableResult,
|
|
3
6
|
type Gauge,
|
|
4
7
|
type Histogram,
|
|
8
|
+
type Meter,
|
|
5
9
|
Metrics,
|
|
10
|
+
type ObservableGauge,
|
|
6
11
|
type TelemetryClient,
|
|
7
12
|
type Tracer,
|
|
8
13
|
type UpDownCounter,
|
|
9
14
|
ValueType,
|
|
10
15
|
} from '@aztec/telemetry-client';
|
|
11
16
|
|
|
17
|
+
import { formatUnits } from 'viem';
|
|
18
|
+
|
|
12
19
|
import { type SequencerState, type SequencerStateCallback, sequencerStateToNumber } from './utils.js';
|
|
13
20
|
|
|
14
21
|
export class SequencerMetrics {
|
|
15
22
|
public readonly tracer: Tracer;
|
|
23
|
+
private meter: Meter;
|
|
16
24
|
|
|
17
25
|
private blockCounter: UpDownCounter;
|
|
18
26
|
private blockBuildDuration: Histogram;
|
|
@@ -24,32 +32,49 @@ export class SequencerMetrics {
|
|
|
24
32
|
|
|
25
33
|
private timeToCollectAttestations: Gauge;
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
private rewards: ObservableGauge;
|
|
36
|
+
|
|
37
|
+
private slots: UpDownCounter;
|
|
38
|
+
private filledSlots: UpDownCounter;
|
|
39
|
+
private missedSlots: UpDownCounter;
|
|
40
|
+
|
|
41
|
+
private lastSeenSlot?: bigint;
|
|
42
|
+
|
|
43
|
+
constructor(
|
|
44
|
+
client: TelemetryClient,
|
|
45
|
+
getState: SequencerStateCallback,
|
|
46
|
+
private coinbase: EthAddress,
|
|
47
|
+
private rollup: RollupContract,
|
|
48
|
+
name = 'Sequencer',
|
|
49
|
+
) {
|
|
50
|
+
this.meter = client.getMeter(name);
|
|
29
51
|
this.tracer = client.getTracer(name);
|
|
30
52
|
|
|
31
|
-
this.blockCounter = meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_COUNT);
|
|
53
|
+
this.blockCounter = this.meter.createUpDownCounter(Metrics.SEQUENCER_BLOCK_COUNT);
|
|
32
54
|
|
|
33
|
-
this.blockBuildDuration = meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION, {
|
|
55
|
+
this.blockBuildDuration = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_DURATION, {
|
|
34
56
|
unit: 'ms',
|
|
35
57
|
description: 'Duration to build a block',
|
|
36
58
|
valueType: ValueType.INT,
|
|
37
59
|
});
|
|
38
60
|
|
|
39
|
-
this.blockBuildManaPerSecond = meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND, {
|
|
61
|
+
this.blockBuildManaPerSecond = this.meter.createGauge(Metrics.SEQUENCER_BLOCK_BUILD_MANA_PER_SECOND, {
|
|
40
62
|
unit: 'mana/s',
|
|
41
63
|
description: 'Mana per second when building a block',
|
|
42
64
|
valueType: ValueType.INT,
|
|
43
65
|
});
|
|
44
66
|
|
|
45
|
-
this.stateTransitionBufferDuration = meter.createHistogram(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
this.stateTransitionBufferDuration = this.meter.createHistogram(
|
|
68
|
+
Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION,
|
|
69
|
+
{
|
|
70
|
+
unit: 'ms',
|
|
71
|
+
description:
|
|
72
|
+
'The time difference between when the sequencer needed to transition to a new state and when it actually did.',
|
|
73
|
+
valueType: ValueType.INT,
|
|
74
|
+
},
|
|
75
|
+
);
|
|
51
76
|
|
|
52
|
-
const currentState = meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
|
|
77
|
+
const currentState = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_STATE, {
|
|
53
78
|
description: 'Current state of the sequencer',
|
|
54
79
|
});
|
|
55
80
|
|
|
@@ -57,22 +82,22 @@ export class SequencerMetrics {
|
|
|
57
82
|
observer.observe(sequencerStateToNumber(getState()));
|
|
58
83
|
});
|
|
59
84
|
|
|
60
|
-
this.currentBlockNumber = meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
|
|
85
|
+
this.currentBlockNumber = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_NUMBER, {
|
|
61
86
|
description: 'Current block number',
|
|
62
87
|
valueType: ValueType.INT,
|
|
63
88
|
});
|
|
64
89
|
|
|
65
|
-
this.currentBlockSize = meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
|
|
90
|
+
this.currentBlockSize = this.meter.createGauge(Metrics.SEQUENCER_CURRENT_BLOCK_SIZE, {
|
|
66
91
|
description: 'Current block size',
|
|
67
92
|
valueType: ValueType.INT,
|
|
68
93
|
});
|
|
69
94
|
|
|
70
|
-
this.timeToCollectAttestations = meter.createGauge(Metrics.SEQUENCER_TIME_TO_COLLECT_ATTESTATIONS, {
|
|
95
|
+
this.timeToCollectAttestations = this.meter.createGauge(Metrics.SEQUENCER_TIME_TO_COLLECT_ATTESTATIONS, {
|
|
71
96
|
description: 'The time spent collecting attestations from committee members',
|
|
72
97
|
valueType: ValueType.INT,
|
|
73
98
|
});
|
|
74
99
|
|
|
75
|
-
this.blockBuilderInsertions = meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
|
|
100
|
+
this.blockBuilderInsertions = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_BUILD_INSERTION_TIME, {
|
|
76
101
|
description: 'Timer for tree insertions performed by the block builder',
|
|
77
102
|
unit: 'us',
|
|
78
103
|
valueType: ValueType.INT,
|
|
@@ -89,8 +114,46 @@ export class SequencerMetrics {
|
|
|
89
114
|
this.blockCounter.add(0, {
|
|
90
115
|
[Attributes.STATUS]: 'built',
|
|
91
116
|
});
|
|
117
|
+
|
|
118
|
+
this.rewards = this.meter.createObservableGauge(Metrics.SEQUENCER_CURRENT_BLOCK_REWARDS, {
|
|
119
|
+
valueType: ValueType.DOUBLE,
|
|
120
|
+
description: 'The rewards earned',
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
this.slots = this.meter.createUpDownCounter(Metrics.SEQUENCER_SLOT_COUNT, {
|
|
124
|
+
valueType: ValueType.INT,
|
|
125
|
+
description: 'The number of slots this sequencer was selected for',
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
this.filledSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_FILLED_SLOT_COUNT, {
|
|
129
|
+
valueType: ValueType.INT,
|
|
130
|
+
description: 'The number of slots this sequencer has filled',
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
this.missedSlots = this.meter.createUpDownCounter(Metrics.SEQUENCER_MISSED_SLOT_COUNT, {
|
|
134
|
+
valueType: ValueType.INT,
|
|
135
|
+
description: 'The number of slots this sequencer has missed to fill',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public start() {
|
|
140
|
+
this.meter.addBatchObservableCallback(this.observe, [this.rewards]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
public stop() {
|
|
144
|
+
this.meter.removeBatchObservableCallback(this.observe, [this.rewards]);
|
|
92
145
|
}
|
|
93
146
|
|
|
147
|
+
private observe = async (observer: BatchObservableResult): Promise<void> => {
|
|
148
|
+
let rewards = 0n;
|
|
149
|
+
rewards = await this.rollup.getSequencerRewards(this.coinbase);
|
|
150
|
+
|
|
151
|
+
const fmt = parseFloat(formatUnits(rewards, 18));
|
|
152
|
+
observer.observe(this.rewards, fmt, {
|
|
153
|
+
[Attributes.COINBASE]: this.coinbase.toString(),
|
|
154
|
+
});
|
|
155
|
+
};
|
|
156
|
+
|
|
94
157
|
startCollectingAttestationsTimer(): () => void {
|
|
95
158
|
const startTime = Date.now();
|
|
96
159
|
const stop = () => {
|
|
@@ -140,6 +203,34 @@ export class SequencerMetrics {
|
|
|
140
203
|
});
|
|
141
204
|
}
|
|
142
205
|
|
|
206
|
+
observeSlotChange(slot: bigint | undefined, proposer: string) {
|
|
207
|
+
// sequencer went through the loop a second time. Noop
|
|
208
|
+
if (slot === this.lastSeenSlot) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (typeof this.lastSeenSlot === 'bigint') {
|
|
213
|
+
this.missedSlots.add(1, {
|
|
214
|
+
[Attributes.BLOCK_PROPOSER]: proposer,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (typeof slot === 'bigint') {
|
|
219
|
+
this.slots.add(1, {
|
|
220
|
+
[Attributes.BLOCK_PROPOSER]: proposer,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
this.lastSeenSlot = slot;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
incFilledSlot(proposer: string) {
|
|
228
|
+
this.filledSlots.add(1, {
|
|
229
|
+
[Attributes.BLOCK_PROPOSER]: proposer,
|
|
230
|
+
});
|
|
231
|
+
this.lastSeenSlot = undefined;
|
|
232
|
+
}
|
|
233
|
+
|
|
143
234
|
private setCurrentBlock(blockNumber: number, txCount: number) {
|
|
144
235
|
this.currentBlockNumber.record(blockNumber);
|
|
145
236
|
this.currentBlockSize.record(txCount);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type L2Block, retryUntil } from '@aztec/aztec.js';
|
|
2
2
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
3
|
+
import type { ViemPublicClient } from '@aztec/ethereum';
|
|
3
4
|
import { omit } from '@aztec/foundation/collection';
|
|
4
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
6
|
import type { Signature } from '@aztec/foundation/eth-signature';
|
|
@@ -105,10 +106,18 @@ export class Sequencer {
|
|
|
105
106
|
telemetry: TelemetryClient = getTelemetryClient(),
|
|
106
107
|
protected log = createLogger('sequencer'),
|
|
107
108
|
) {
|
|
108
|
-
this.metrics = new SequencerMetrics(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
this.metrics = new SequencerMetrics(
|
|
110
|
+
telemetry,
|
|
111
|
+
() => this.state,
|
|
112
|
+
this._coinbase,
|
|
113
|
+
this.publisher.getRollupContract(),
|
|
114
|
+
'Sequencer',
|
|
115
|
+
);
|
|
116
|
+
this.l1Metrics = new L1Metrics(
|
|
117
|
+
telemetry.getMeter('SequencerL1Metrics'),
|
|
118
|
+
publisher.l1TxUtils.client as unknown as ViemPublicClient,
|
|
119
|
+
[publisher.getSenderAddress()],
|
|
120
|
+
);
|
|
112
121
|
|
|
113
122
|
// Register the block builder with the validator client for re-execution
|
|
114
123
|
this.validatorClient?.registerBlockBuilder(this.buildBlock.bind(this));
|
|
@@ -197,6 +206,7 @@ export class Sequencer {
|
|
|
197
206
|
*/
|
|
198
207
|
public async start() {
|
|
199
208
|
await this.updateConfig(this.config);
|
|
209
|
+
this.metrics.start();
|
|
200
210
|
this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.pollingIntervalMs);
|
|
201
211
|
this.setState(SequencerState.IDLE, 0n, true /** force */);
|
|
202
212
|
this.runningPromise.start();
|
|
@@ -209,6 +219,7 @@ export class Sequencer {
|
|
|
209
219
|
*/
|
|
210
220
|
public async stop(): Promise<void> {
|
|
211
221
|
this.log.debug(`Stopping sequencer`);
|
|
222
|
+
this.metrics.stop();
|
|
212
223
|
await this.validatorClient?.stop();
|
|
213
224
|
await this.runningPromise?.stop();
|
|
214
225
|
this.slasherClient.stop();
|
|
@@ -266,6 +277,7 @@ export class Sequencer {
|
|
|
266
277
|
const chainTipArchive = chainTip.archive;
|
|
267
278
|
|
|
268
279
|
const slot = await this.slotForProposal(chainTipArchive.toBuffer(), BigInt(newBlockNumber));
|
|
280
|
+
this.metrics.observeSlotChange(slot, this.publisher.getSenderAddress().toString());
|
|
269
281
|
if (!slot) {
|
|
270
282
|
this.log.debug(`Cannot propose block ${newBlockNumber}`);
|
|
271
283
|
return;
|
|
@@ -333,7 +345,13 @@ export class Sequencer {
|
|
|
333
345
|
this.log.error(`Error enqueuing slashing vote`, err, { blockNumber: newBlockNumber, slot });
|
|
334
346
|
});
|
|
335
347
|
|
|
336
|
-
await this.publisher.sendRequests();
|
|
348
|
+
const resp = await this.publisher.sendRequests();
|
|
349
|
+
if (resp) {
|
|
350
|
+
const proposedBlock = resp.validActions.find(a => a === 'propose');
|
|
351
|
+
if (proposedBlock) {
|
|
352
|
+
this.metrics.incFilledSlot(this.publisher.getSenderAddress().toString());
|
|
353
|
+
}
|
|
354
|
+
}
|
|
337
355
|
|
|
338
356
|
if (finishedFlushing) {
|
|
339
357
|
this.isFlushing = false;
|
package/src/sequencer/utils.ts
CHANGED
|
@@ -50,18 +50,13 @@ export function sequencerStateToNumber(state: SequencerState): number {
|
|
|
50
50
|
*
|
|
51
51
|
* @todo: perform this logic within the memory attestation store instead?
|
|
52
52
|
*/
|
|
53
|
-
export
|
|
54
|
-
attestations: BlockAttestation[],
|
|
55
|
-
orderAddresses: EthAddress[],
|
|
56
|
-
): Promise<Signature[]> {
|
|
53
|
+
export function orderAttestations(attestations: BlockAttestation[], orderAddresses: EthAddress[]): Signature[] {
|
|
57
54
|
// Create a map of sender addresses to BlockAttestations
|
|
58
55
|
const attestationMap = new Map<string, BlockAttestation>();
|
|
59
56
|
|
|
60
57
|
for (const attestation of attestations) {
|
|
61
|
-
const sender =
|
|
62
|
-
|
|
63
|
-
attestationMap.set(sender.toString(), attestation);
|
|
64
|
-
}
|
|
58
|
+
const sender = attestation.getSender();
|
|
59
|
+
attestationMap.set(sender.toString(), attestation);
|
|
65
60
|
}
|
|
66
61
|
|
|
67
62
|
// Create the ordered array based on the orderAddresses, else return an empty signature
|