@aztec/sequencer-client 2.0.3 → 2.1.0-rc.10
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 -4
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -0
- package/dest/global_variable_builder/global_builder.js +1 -1
- package/dest/publisher/config.d.ts +2 -4
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +7 -10
- package/dest/publisher/index.d.ts +1 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/index.js +1 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts +5 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +8 -1
- package/dest/publisher/sequencer-publisher-metrics.js +1 -1
- package/dest/publisher/sequencer-publisher.d.ts +17 -23
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +54 -59
- package/dest/sequencer/errors.d.ts +11 -0
- package/dest/sequencer/errors.d.ts.map +1 -0
- package/dest/sequencer/errors.js +15 -0
- package/dest/sequencer/metrics.d.ts +5 -17
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +23 -89
- package/dest/sequencer/sequencer.d.ts +5 -4
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +37 -22
- package/dest/sequencer/timetable.d.ts +0 -6
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +2 -9
- package/dest/sequencer/utils.d.ts +10 -24
- package/dest/sequencer/utils.d.ts.map +1 -1
- package/dest/sequencer/utils.js +9 -24
- package/package.json +30 -30
- package/src/client/sequencer-client.ts +6 -2
- package/src/config.ts +7 -0
- package/src/global_variable_builder/global_builder.ts +1 -1
- package/src/publisher/config.ts +13 -11
- package/src/publisher/index.ts +1 -1
- package/src/publisher/sequencer-publisher-factory.ts +12 -2
- package/src/publisher/sequencer-publisher-metrics.ts +1 -1
- package/src/publisher/sequencer-publisher.ts +78 -78
- package/src/sequencer/errors.ts +21 -0
- package/src/sequencer/metrics.ts +24 -100
- package/src/sequencer/sequencer.ts +62 -49
- package/src/sequencer/timetable.ts +2 -13
- package/src/sequencer/utils.ts +10 -24
|
@@ -4,15 +4,19 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
4
4
|
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
}
|
|
7
|
-
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
7
|
+
import { BLOBS_PER_BLOCK, FIELDS_PER_BLOB, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
8
8
|
import { FormattedViemError, NoCommitteeError } from '@aztec/ethereum';
|
|
9
9
|
import { omit, pick } from '@aztec/foundation/collection';
|
|
10
|
+
import { randomInt } from '@aztec/foundation/crypto';
|
|
10
11
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
12
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
11
13
|
import { Fr } from '@aztec/foundation/fields';
|
|
12
14
|
import { createLogger } from '@aztec/foundation/log';
|
|
13
15
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
14
16
|
import { Timer } from '@aztec/foundation/timer';
|
|
15
|
-
import {
|
|
17
|
+
import { unfreeze } from '@aztec/foundation/types';
|
|
18
|
+
import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
19
|
+
import { getSlotAtTimestamp, getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
16
20
|
import { Gas } from '@aztec/stdlib/gas';
|
|
17
21
|
import { SequencerConfigSchema } from '@aztec/stdlib/interfaces/server';
|
|
18
22
|
import { orderAttestations } from '@aztec/stdlib/p2p';
|
|
@@ -22,8 +26,9 @@ import { ContentCommitment, ProposedBlockHeader } from '@aztec/stdlib/tx';
|
|
|
22
26
|
import { AttestationTimeoutError } from '@aztec/stdlib/validators';
|
|
23
27
|
import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
24
28
|
import EventEmitter from 'node:events';
|
|
29
|
+
import { SequencerInterruptedError, SequencerTooSlowError } from './errors.js';
|
|
25
30
|
import { SequencerMetrics } from './metrics.js';
|
|
26
|
-
import { SequencerTimetable
|
|
31
|
+
import { SequencerTimetable } from './timetable.js';
|
|
27
32
|
import { SequencerState } from './utils.js';
|
|
28
33
|
export { SequencerState };
|
|
29
34
|
/**
|
|
@@ -72,10 +77,7 @@ export { SequencerState };
|
|
|
72
77
|
publisher;
|
|
73
78
|
constructor(publisherFactory, validatorClient, globalsBuilder, p2pClient, worldState, slasherClient, l2BlockSource, l1ToL2MessageSource, blockBuilder, l1Constants, dateProvider, epochCache, rollupContract, config, telemetry = getTelemetryClient(), log = createLogger('sequencer')){
|
|
74
79
|
super(), this.publisherFactory = publisherFactory, this.validatorClient = validatorClient, this.globalsBuilder = globalsBuilder, this.p2pClient = p2pClient, this.worldState = worldState, this.slasherClient = slasherClient, this.l2BlockSource = l2BlockSource, this.l1ToL2MessageSource = l1ToL2MessageSource, this.blockBuilder = blockBuilder, this.l1Constants = l1Constants, this.dateProvider = dateProvider, this.epochCache = epochCache, this.rollupContract = rollupContract, this.config = config, this.telemetry = telemetry, this.log = log, this.pollingIntervalMs = 1000, this.maxTxsPerBlock = 32, this.minTxsPerBlock = 1, this.maxL1TxInclusionTimeIntoSlot = 0, this.state = SequencerState.STOPPED, this.maxBlockSizeInBytes = 1024 * 1024, this.maxBlockGas = new Gas(100e9, 100e9), this.enforceTimeTable = false;
|
|
75
|
-
|
|
76
|
-
const validatorAddresses = this.validatorClient?.getValidatorAddresses() ?? [];
|
|
77
|
-
const coinbase = validatorAddresses.length === 0 ? EthAddress.ZERO : this.validatorClient?.getCoinbaseForAttestor(validatorAddresses[0]) ?? EthAddress.ZERO;
|
|
78
|
-
this.metrics = new SequencerMetrics(telemetry, ()=>this.state, coinbase, this.rollupContract, 'Sequencer');
|
|
80
|
+
this.metrics = new SequencerMetrics(telemetry, this.rollupContract, 'Sequencer');
|
|
79
81
|
// Initialize config
|
|
80
82
|
this.updateConfig(this.config);
|
|
81
83
|
}
|
|
@@ -140,7 +142,6 @@ export { SequencerState };
|
|
|
140
142
|
/**
|
|
141
143
|
* Starts the sequencer and moves to IDLE state.
|
|
142
144
|
*/ start() {
|
|
143
|
-
this.metrics.start();
|
|
144
145
|
this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.pollingIntervalMs);
|
|
145
146
|
this.setState(SequencerState.IDLE, undefined, {
|
|
146
147
|
force: true
|
|
@@ -152,9 +153,10 @@ export { SequencerState };
|
|
|
152
153
|
* Stops the sequencer from processing txs and moves to STOPPED state.
|
|
153
154
|
*/ async stop() {
|
|
154
155
|
this.log.info(`Stopping sequencer`);
|
|
155
|
-
this.
|
|
156
|
+
this.setState(SequencerState.STOPPING, undefined, {
|
|
157
|
+
force: true
|
|
158
|
+
});
|
|
156
159
|
this.publisher?.interrupt();
|
|
157
|
-
await this.validatorClient?.stop();
|
|
158
160
|
await this.runningPromise?.stop();
|
|
159
161
|
this.setState(SequencerState.STOPPED, undefined, {
|
|
160
162
|
force: true
|
|
@@ -259,7 +261,6 @@ export { SequencerState };
|
|
|
259
261
|
this.publisher = publisher;
|
|
260
262
|
const coinbase = this.validatorClient.getCoinbaseForAttestor(attestorAddress);
|
|
261
263
|
const feeRecipient = this.validatorClient.getFeeRecipientForAttestor(attestorAddress);
|
|
262
|
-
this.metrics.setCoinbase(coinbase);
|
|
263
264
|
// Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
|
|
264
265
|
const invalidateBlock = await publisher.simulateInvalidateBlock(syncedTo.pendingChainValidationStatus);
|
|
265
266
|
const canProposeCheck = await publisher.canProposeAtNextEthBlock(chainTipArchive, proposerAddressInNextSlot, invalidateBlock);
|
|
@@ -317,6 +318,7 @@ export { SequencerState };
|
|
|
317
318
|
publisher.enqueueInvalidateBlock(invalidateBlock);
|
|
318
319
|
}
|
|
319
320
|
this.setState(SequencerState.INITIALIZING_PROPOSAL, slot);
|
|
321
|
+
this.metrics.incOpenSlot(slot, proposerAddressInNextSlot.toString());
|
|
320
322
|
this.log.verbose(`Preparing proposal for block ${newBlockNumber} at slot ${slot}`, {
|
|
321
323
|
proposer: proposerInNextSlot?.toString(),
|
|
322
324
|
coinbase,
|
|
@@ -379,7 +381,7 @@ export { SequencerState };
|
|
|
379
381
|
blockNumber: newBlockNumber,
|
|
380
382
|
slot: Number(slot)
|
|
381
383
|
});
|
|
382
|
-
this.metrics.incFilledSlot(publisher.getSenderAddress().toString());
|
|
384
|
+
await this.metrics.incFilledSlot(publisher.getSenderAddress().toString(), coinbase);
|
|
383
385
|
} else if (block) {
|
|
384
386
|
this.emit('block-publish-failed', l1Response ?? {});
|
|
385
387
|
}
|
|
@@ -407,6 +409,10 @@ export { SequencerState };
|
|
|
407
409
|
}
|
|
408
410
|
}
|
|
409
411
|
setState(proposedState, slotNumber, opts = {}) {
|
|
412
|
+
if (this.state === SequencerState.STOPPING && proposedState !== SequencerState.STOPPED && !opts.force) {
|
|
413
|
+
this.log.warn(`Cannot set sequencer to ${proposedState} as it is stopping.`);
|
|
414
|
+
throw new SequencerInterruptedError();
|
|
415
|
+
}
|
|
410
416
|
if (this.state === SequencerState.STOPPED && !opts.force) {
|
|
411
417
|
this.log.warn(`Cannot set sequencer from ${this.state} to ${proposedState} as it is stopped.`);
|
|
412
418
|
return;
|
|
@@ -452,6 +458,7 @@ export { SequencerState };
|
|
|
452
458
|
maxTransactions: this.maxTxsPerBlock,
|
|
453
459
|
maxBlockSize: this.maxBlockSizeInBytes,
|
|
454
460
|
maxBlockGas: this.maxBlockGas,
|
|
461
|
+
maxBlobFields: BLOBS_PER_BLOCK * FIELDS_PER_BLOB,
|
|
455
462
|
deadline
|
|
456
463
|
};
|
|
457
464
|
}
|
|
@@ -470,7 +477,6 @@ export { SequencerState };
|
|
|
470
477
|
const blockNumber = newGlobalVariables.blockNumber;
|
|
471
478
|
const slot = proposalHeader.slotNumber.toBigInt();
|
|
472
479
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockNumber);
|
|
473
|
-
// this.metrics.recordNewBlock(blockNumber, validTxs.length);
|
|
474
480
|
const workTimer = new Timer();
|
|
475
481
|
this.setState(SequencerState.CREATING_BLOCK, slot);
|
|
476
482
|
try {
|
|
@@ -515,7 +521,9 @@ export { SequencerState };
|
|
|
515
521
|
blockNumber
|
|
516
522
|
});
|
|
517
523
|
}
|
|
518
|
-
|
|
524
|
+
const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations ?? []);
|
|
525
|
+
const attestationsAndSignersSignature = this.validatorClient ? await this.validatorClient.signAttestationsAndSigners(attestationsAndSigners, proposerAddress) : Signature.empty();
|
|
526
|
+
await this.enqueuePublishL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, invalidateBlock, publisher);
|
|
519
527
|
this.metrics.recordBuiltBlock(blockBuildDuration, publicGas.l2Gas);
|
|
520
528
|
return block;
|
|
521
529
|
} catch (err) {
|
|
@@ -561,32 +569,39 @@ export { SequencerState };
|
|
|
561
569
|
const attestationTimeAllowed = this.enforceTimeTable ? this.timetable.getMaxAllowedTime(SequencerState.PUBLISHING_BLOCK) : this.aztecSlotDuration;
|
|
562
570
|
this.metrics.recordRequiredAttestations(numberOfRequiredAttestations, attestationTimeAllowed);
|
|
563
571
|
const timer = new Timer();
|
|
564
|
-
let
|
|
572
|
+
let collectedAttestationsCount = 0;
|
|
565
573
|
try {
|
|
566
574
|
const attestationDeadline = new Date(this.dateProvider.now() + attestationTimeAllowed * 1000);
|
|
567
575
|
const attestations = await this.validatorClient.collectAttestations(proposal, numberOfRequiredAttestations, attestationDeadline);
|
|
568
|
-
|
|
576
|
+
collectedAttestationsCount = attestations.length;
|
|
569
577
|
// note: the smart contract requires that the signatures are provided in the order of the committee
|
|
570
|
-
|
|
578
|
+
const sorted = orderAttestations(attestations, committee);
|
|
579
|
+
if (this.config.injectFakeAttestation) {
|
|
580
|
+
const nonEmpty = sorted.filter((a)=>!a.signature.isEmpty());
|
|
581
|
+
const randomIndex = randomInt(nonEmpty.length);
|
|
582
|
+
this.log.warn(`Injecting fake attestation in block ${block.number}`);
|
|
583
|
+
unfreeze(nonEmpty[randomIndex]).signature = Signature.random();
|
|
584
|
+
}
|
|
585
|
+
return sorted;
|
|
571
586
|
} catch (err) {
|
|
572
587
|
if (err && err instanceof AttestationTimeoutError) {
|
|
573
|
-
|
|
588
|
+
collectedAttestationsCount = err.collectedCount;
|
|
574
589
|
}
|
|
575
590
|
throw err;
|
|
576
591
|
} finally{
|
|
577
|
-
this.metrics.recordCollectedAttestations(
|
|
592
|
+
this.metrics.recordCollectedAttestations(collectedAttestationsCount, timer.ms());
|
|
578
593
|
}
|
|
579
594
|
}
|
|
580
595
|
/**
|
|
581
596
|
* Publishes the L2Block to the rollup contract.
|
|
582
597
|
* @param block - The L2Block to be published.
|
|
583
|
-
*/ async enqueuePublishL2Block(block,
|
|
598
|
+
*/ async enqueuePublishL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, invalidateBlock, publisher) {
|
|
584
599
|
// Publishes new block to the network and awaits the tx to be mined
|
|
585
600
|
this.setState(SequencerState.PUBLISHING_BLOCK, block.header.globalVariables.slotNumber.toBigInt());
|
|
586
601
|
// Time out tx at the end of the slot
|
|
587
602
|
const slot = block.header.globalVariables.slotNumber.toNumber();
|
|
588
603
|
const txTimeoutAt = new Date((this.getSlotStartBuildTimestamp(slot) + this.aztecSlotDuration) * 1000);
|
|
589
|
-
const enqueued = await publisher.enqueueProposeL2Block(block,
|
|
604
|
+
const enqueued = await publisher.enqueueProposeL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, {
|
|
590
605
|
txTimeoutAt,
|
|
591
606
|
forcePendingBlockNumber: invalidateBlock?.forcePendingBlockNumber
|
|
592
607
|
});
|
|
@@ -689,7 +704,7 @@ export { SequencerState };
|
|
|
689
704
|
await publisher.sendRequests();
|
|
690
705
|
}
|
|
691
706
|
getSlotStartBuildTimestamp(slotNumber) {
|
|
692
|
-
return
|
|
707
|
+
return getSlotStartBuildTimestamp(slotNumber, this.l1Constants);
|
|
693
708
|
}
|
|
694
709
|
getSecondsIntoSlot(slotNumber) {
|
|
695
710
|
const slotStartTimestamp = this.getSlotStartBuildTimestamp(slotNumber);
|
|
@@ -45,10 +45,4 @@ export declare class SequencerTimetable {
|
|
|
45
45
|
getMaxAllowedTime(state: SequencerState): number | undefined;
|
|
46
46
|
assertTimeLeft(newState: SequencerState, secondsIntoSlot: number): void;
|
|
47
47
|
}
|
|
48
|
-
export declare class SequencerTooSlowError extends Error {
|
|
49
|
-
readonly proposedState: SequencerState;
|
|
50
|
-
readonly maxAllowedTime: number;
|
|
51
|
-
readonly currentTime: number;
|
|
52
|
-
constructor(proposedState: SequencerState, maxAllowedTime: number, currentTime: number);
|
|
53
|
-
}
|
|
54
48
|
//# sourceMappingURL=timetable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAM5C,qBAAa,kBAAkB;IA+C3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IA/CtB;;;;OAIG;IACH,SAAgB,kBAAkB,EAAE,MAAM,CAAC;IAE3C;;;;OAIG;IACH,SAAgB,gBAAgB,SAAC;IAEjC,sHAAsH;IACtH,SAAgB,gBAAgB,EAAE,MAAM,CAAsB;IAE9D,uDAAuD;IACvD,SAAgB,gBAAgB,EAAE,MAAM,CAAsB;IAE9D,mGAAmG;IACnG,SAAgB,0BAA0B,EAAE,MAAM,CAAC;IAEnD,mIAAmI;IACnI,SAAgB,mBAAmB,EAAE,MAAM,CAAyB;IAEpE,wCAAwC;IACxC,SAAgB,oBAAoB,EAAE,MAAM,CAAC;IAE7C,kFAAkF;IAClF,SAAgB,iBAAiB,EAAE,MAAM,CAAC;IAE1C,2IAA2I;IAC3I,SAAgB,4BAA4B,EAAE,MAAM,CAAC;IAErD,4DAA4D;IAC5D,SAAgB,OAAO,EAAE,OAAO,CAAC;gBAG/B,IAAI,EAAE;QACJ,oBAAoB,EAAE,MAAM,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,4BAA4B,EAAE,MAAM,CAAC;QACrC,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,OAAO,EAAE,OAAO,CAAC;KAClB,EACgB,OAAO,CAAC,EAAE,gBAAgB,YAAA,EAC1B,GAAG,mCAAsC;IA+C5D,OAAO,KAAK,yCAAyC,GAEpD;IAEM,2BAA2B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM;IAenE,OAAO,KAAK,0BAA0B,GAErC;IAEM,yBAAyB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM;IAU3D,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS;IAuB5D,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM;CAkBxE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/aztec.js';
|
|
2
2
|
import { DEFAULT_ATTESTATION_PROPAGATION_TIME } from '../config.js';
|
|
3
|
+
import { SequencerTooSlowError } from './errors.js';
|
|
3
4
|
import { SequencerState } from './utils.js';
|
|
4
5
|
const MIN_EXECUTION_TIME = 1;
|
|
5
6
|
const BLOCK_PREPARE_TIME = 1;
|
|
@@ -95,6 +96,7 @@ export class SequencerTimetable {
|
|
|
95
96
|
getMaxAllowedTime(state) {
|
|
96
97
|
switch(state){
|
|
97
98
|
case SequencerState.STOPPED:
|
|
99
|
+
case SequencerState.STOPPING:
|
|
98
100
|
case SequencerState.IDLE:
|
|
99
101
|
case SequencerState.SYNCHRONIZING:
|
|
100
102
|
return; // We don't really care about times for this states
|
|
@@ -133,12 +135,3 @@ export class SequencerTimetable {
|
|
|
133
135
|
});
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
|
-
export class SequencerTooSlowError extends Error {
|
|
137
|
-
proposedState;
|
|
138
|
-
maxAllowedTime;
|
|
139
|
-
currentTime;
|
|
140
|
-
constructor(proposedState, maxAllowedTime, currentTime){
|
|
141
|
-
super(`Too far into slot for ${proposedState} (time into slot ${currentTime}s greater than ${maxAllowedTime}s allowance)`), this.proposedState = proposedState, this.maxAllowedTime = maxAllowedTime, this.currentTime = currentTime;
|
|
142
|
-
this.name = 'SequencerTooSlowError';
|
|
143
|
-
}
|
|
144
|
-
}
|
|
@@ -1,35 +1,21 @@
|
|
|
1
1
|
export declare enum SequencerState {
|
|
2
|
-
/**
|
|
3
|
-
* Sequencer is stopped and not processing any txs from the pool.
|
|
4
|
-
*/
|
|
2
|
+
/** Sequencer is stopped and not processing any txs from the pool. */
|
|
5
3
|
STOPPED = "STOPPED",
|
|
6
|
-
/**
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
/** Sequencer is being stopped. Will move to STOPPED shortly. */
|
|
5
|
+
STOPPING = "STOPPING",
|
|
6
|
+
/** Sequencer is awaiting the next call to work(). */
|
|
9
7
|
IDLE = "IDLE",
|
|
10
|
-
/**
|
|
11
|
-
* Synchronizing with the L2 chain.
|
|
12
|
-
*/
|
|
8
|
+
/** Synchronizing with the L2 chain. */
|
|
13
9
|
SYNCHRONIZING = "SYNCHRONIZING",
|
|
14
|
-
/**
|
|
15
|
-
* Checking if we are the proposer for the current slot.
|
|
16
|
-
*/
|
|
10
|
+
/** Checking if we are the proposer for the current slot. */
|
|
17
11
|
PROPOSER_CHECK = "PROPOSER_CHECK",
|
|
18
|
-
/**
|
|
19
|
-
* Initializing the block proposal. Will move to CREATING_BLOCK if there are valid txs to include, or back to SYNCHRONIZING otherwise.
|
|
20
|
-
*/
|
|
12
|
+
/** Initializing the block proposal. Will move to CREATING_BLOCK if there are valid txs to include, or back to SYNCHRONIZING otherwise. */
|
|
21
13
|
INITIALIZING_PROPOSAL = "INITIALIZING_PROPOSAL",
|
|
22
|
-
/**
|
|
23
|
-
* Creating a new L2 block. Includes processing public function calls and running rollup circuits. Will move to PUBLISHING_CONTRACT_DATA.
|
|
24
|
-
*/
|
|
14
|
+
/** Creating a new L2 block. Includes processing public function calls and running rollup circuits. Will move to PUBLISHING_CONTRACT_DATA. */
|
|
25
15
|
CREATING_BLOCK = "CREATING_BLOCK",
|
|
26
|
-
/**
|
|
27
|
-
* Collecting attestations from its peers. Will move to PUBLISHING_BLOCK.
|
|
28
|
-
*/
|
|
16
|
+
/** Collecting attestations from its peers. Will move to PUBLISHING_BLOCK. */
|
|
29
17
|
COLLECTING_ATTESTATIONS = "COLLECTING_ATTESTATIONS",
|
|
30
|
-
/**
|
|
31
|
-
* Sending the tx to L1 with the L2 block data and awaiting it to be mined. Will move to SYNCHRONIZING.
|
|
32
|
-
*/
|
|
18
|
+
/** Sending the tx to L1 with the L2 block data and awaiting it to be mined. Will move to SYNCHRONIZING. */
|
|
33
19
|
PUBLISHING_BLOCK = "PUBLISHING_BLOCK"
|
|
34
20
|
}
|
|
35
21
|
export type SequencerStateWithSlot = SequencerState.INITIALIZING_PROPOSAL | SequencerState.CREATING_BLOCK | SequencerState.COLLECTING_ATTESTATIONS | SequencerState.PUBLISHING_BLOCK | SequencerState.PROPOSER_CHECK;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sequencer/utils.ts"],"names":[],"mappings":"AAAA,oBAAY,cAAc;IACxB
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/sequencer/utils.ts"],"names":[],"mappings":"AAAA,oBAAY,cAAc;IACxB,qEAAqE;IACrE,OAAO,YAAY;IACnB,gEAAgE;IAChE,QAAQ,aAAa;IACrB,qDAAqD;IACrD,IAAI,SAAS;IACb,uCAAuC;IACvC,aAAa,kBAAkB;IAC/B,4DAA4D;IAC5D,cAAc,mBAAmB;IACjC,0IAA0I;IAC1I,qBAAqB,0BAA0B;IAC/C,6IAA6I;IAC7I,cAAc,mBAAmB;IACjC,6EAA6E;IAC7E,uBAAuB,4BAA4B;IACnD,2GAA2G;IAC3G,gBAAgB,qBAAqB;CACtC;AAED,MAAM,MAAM,sBAAsB,GAC9B,cAAc,CAAC,qBAAqB,GACpC,cAAc,CAAC,cAAc,GAC7B,cAAc,CAAC,uBAAuB,GACtC,cAAc,CAAC,gBAAgB,GAC/B,cAAc,CAAC,cAAc,CAAC;AAElC,MAAM,MAAM,sBAAsB,GAAG,MAAM,cAAc,CAAC;AAE1D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAEpE"}
|
package/dest/sequencer/utils.js
CHANGED
|
@@ -1,28 +1,13 @@
|
|
|
1
1
|
export var SequencerState = /*#__PURE__*/ function(SequencerState) {
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Checking if we are the proposer for the current slot.
|
|
13
|
-
*/ SequencerState["PROPOSER_CHECK"] = "PROPOSER_CHECK";
|
|
14
|
-
/**
|
|
15
|
-
* Initializing the block proposal. Will move to CREATING_BLOCK if there are valid txs to include, or back to SYNCHRONIZING otherwise.
|
|
16
|
-
*/ SequencerState["INITIALIZING_PROPOSAL"] = "INITIALIZING_PROPOSAL";
|
|
17
|
-
/**
|
|
18
|
-
* Creating a new L2 block. Includes processing public function calls and running rollup circuits. Will move to PUBLISHING_CONTRACT_DATA.
|
|
19
|
-
*/ SequencerState["CREATING_BLOCK"] = "CREATING_BLOCK";
|
|
20
|
-
/**
|
|
21
|
-
* Collecting attestations from its peers. Will move to PUBLISHING_BLOCK.
|
|
22
|
-
*/ SequencerState["COLLECTING_ATTESTATIONS"] = "COLLECTING_ATTESTATIONS";
|
|
23
|
-
/**
|
|
24
|
-
* Sending the tx to L1 with the L2 block data and awaiting it to be mined. Will move to SYNCHRONIZING.
|
|
25
|
-
*/ SequencerState["PUBLISHING_BLOCK"] = "PUBLISHING_BLOCK";
|
|
2
|
+
/** Sequencer is stopped and not processing any txs from the pool. */ SequencerState["STOPPED"] = "STOPPED";
|
|
3
|
+
/** Sequencer is being stopped. Will move to STOPPED shortly. */ SequencerState["STOPPING"] = "STOPPING";
|
|
4
|
+
/** Sequencer is awaiting the next call to work(). */ SequencerState["IDLE"] = "IDLE";
|
|
5
|
+
/** Synchronizing with the L2 chain. */ SequencerState["SYNCHRONIZING"] = "SYNCHRONIZING";
|
|
6
|
+
/** Checking if we are the proposer for the current slot. */ SequencerState["PROPOSER_CHECK"] = "PROPOSER_CHECK";
|
|
7
|
+
/** Initializing the block proposal. Will move to CREATING_BLOCK if there are valid txs to include, or back to SYNCHRONIZING otherwise. */ SequencerState["INITIALIZING_PROPOSAL"] = "INITIALIZING_PROPOSAL";
|
|
8
|
+
/** Creating a new L2 block. Includes processing public function calls and running rollup circuits. Will move to PUBLISHING_CONTRACT_DATA. */ SequencerState["CREATING_BLOCK"] = "CREATING_BLOCK";
|
|
9
|
+
/** Collecting attestations from its peers. Will move to PUBLISHING_BLOCK. */ SequencerState["COLLECTING_ATTESTATIONS"] = "COLLECTING_ATTESTATIONS";
|
|
10
|
+
/** Sending the tx to L1 with the L2 block data and awaiting it to be mined. Will move to SYNCHRONIZING. */ SequencerState["PUBLISHING_BLOCK"] = "PUBLISHING_BLOCK";
|
|
26
11
|
return SequencerState;
|
|
27
12
|
}({});
|
|
28
13
|
export function sequencerStateToNumber(state) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.1.0-rc.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,37 +26,37 @@
|
|
|
26
26
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@aztec/aztec.js": "2.0.
|
|
30
|
-
"@aztec/bb-prover": "2.0.
|
|
31
|
-
"@aztec/blob-lib": "2.0.
|
|
32
|
-
"@aztec/blob-sink": "2.0.
|
|
33
|
-
"@aztec/constants": "2.0.
|
|
34
|
-
"@aztec/epoch-cache": "2.0.
|
|
35
|
-
"@aztec/ethereum": "2.0.
|
|
36
|
-
"@aztec/foundation": "2.0.
|
|
37
|
-
"@aztec/l1-artifacts": "2.0.
|
|
38
|
-
"@aztec/merkle-tree": "2.0.
|
|
39
|
-
"@aztec/
|
|
40
|
-
"@aztec/noir-
|
|
41
|
-
"@aztec/noir-
|
|
42
|
-
"@aztec/noir-types": "2.0.
|
|
43
|
-
"@aztec/
|
|
44
|
-
"@aztec/
|
|
45
|
-
"@aztec/
|
|
46
|
-
"@aztec/
|
|
47
|
-
"@aztec/
|
|
48
|
-
"@aztec/
|
|
49
|
-
"@aztec/
|
|
50
|
-
"@aztec/
|
|
51
|
-
"@aztec/
|
|
29
|
+
"@aztec/aztec.js": "2.1.0-rc.10",
|
|
30
|
+
"@aztec/bb-prover": "2.1.0-rc.10",
|
|
31
|
+
"@aztec/blob-lib": "2.1.0-rc.10",
|
|
32
|
+
"@aztec/blob-sink": "2.1.0-rc.10",
|
|
33
|
+
"@aztec/constants": "2.1.0-rc.10",
|
|
34
|
+
"@aztec/epoch-cache": "2.1.0-rc.10",
|
|
35
|
+
"@aztec/ethereum": "2.1.0-rc.10",
|
|
36
|
+
"@aztec/foundation": "2.1.0-rc.10",
|
|
37
|
+
"@aztec/l1-artifacts": "2.1.0-rc.10",
|
|
38
|
+
"@aztec/merkle-tree": "2.1.0-rc.10",
|
|
39
|
+
"@aztec/node-keystore": "2.1.0-rc.10",
|
|
40
|
+
"@aztec/noir-acvm_js": "2.1.0-rc.10",
|
|
41
|
+
"@aztec/noir-contracts.js": "2.1.0-rc.10",
|
|
42
|
+
"@aztec/noir-protocol-circuits-types": "2.1.0-rc.10",
|
|
43
|
+
"@aztec/noir-types": "2.1.0-rc.10",
|
|
44
|
+
"@aztec/p2p": "2.1.0-rc.10",
|
|
45
|
+
"@aztec/protocol-contracts": "2.1.0-rc.10",
|
|
46
|
+
"@aztec/prover-client": "2.1.0-rc.10",
|
|
47
|
+
"@aztec/simulator": "2.1.0-rc.10",
|
|
48
|
+
"@aztec/slasher": "2.1.0-rc.10",
|
|
49
|
+
"@aztec/stdlib": "2.1.0-rc.10",
|
|
50
|
+
"@aztec/telemetry-client": "2.1.0-rc.10",
|
|
51
|
+
"@aztec/validator-client": "2.1.0-rc.10",
|
|
52
|
+
"@aztec/world-state": "2.1.0-rc.10",
|
|
53
|
+
"@spalladino/viem": "2.38.2-eip7594.0",
|
|
52
54
|
"lodash.chunk": "^4.2.0",
|
|
53
|
-
"
|
|
54
|
-
"tslib": "^2.4.0",
|
|
55
|
-
"viem": "2.23.7"
|
|
55
|
+
"tslib": "^2.4.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@aztec/archiver": "2.0.
|
|
59
|
-
"@aztec/kv-store": "2.0.
|
|
58
|
+
"@aztec/archiver": "2.1.0-rc.10",
|
|
59
|
+
"@aztec/kv-store": "2.1.0-rc.10",
|
|
60
60
|
"@jest/globals": "^30.0.0",
|
|
61
61
|
"@types/jest": "^30.0.0",
|
|
62
62
|
"@types/lodash.chunk": "^4.2.7",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"@types/node": "^22.15.17",
|
|
65
65
|
"concurrently": "^7.6.0",
|
|
66
66
|
"eslint": "^9.26.0",
|
|
67
|
-
"express": "^4.21.
|
|
67
|
+
"express": "^4.21.2",
|
|
68
68
|
"jest": "^30.0.0",
|
|
69
69
|
"jest-mock-extended": "^4.0.0",
|
|
70
70
|
"prettier": "^3.5.3",
|
|
@@ -84,7 +84,7 @@ export class SequencerClient {
|
|
|
84
84
|
telemetry: telemetryClient,
|
|
85
85
|
} = deps;
|
|
86
86
|
const { l1RpcUrls: rpcUrls, l1ChainId: chainId } = config;
|
|
87
|
-
const log = createLogger('sequencer
|
|
87
|
+
const log = createLogger('sequencer');
|
|
88
88
|
const publicClient = getPublicClient(config);
|
|
89
89
|
const l1TxUtils = deps.l1TxUtils;
|
|
90
90
|
const l1Metrics = new L1Metrics(
|
|
@@ -92,7 +92,7 @@ export class SequencerClient {
|
|
|
92
92
|
publicClient,
|
|
93
93
|
l1TxUtils.map(x => x.getSenderAddress()),
|
|
94
94
|
);
|
|
95
|
-
const publisherManager = new PublisherManager(l1TxUtils);
|
|
95
|
+
const publisherManager = new PublisherManager(l1TxUtils, config);
|
|
96
96
|
const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
|
|
97
97
|
const [l1GenesisTime, slotDuration] = await Promise.all([
|
|
98
98
|
rollupContract.getL1GenesisTime(),
|
|
@@ -133,6 +133,7 @@ export class SequencerClient {
|
|
|
133
133
|
dateProvider: deps.dateProvider,
|
|
134
134
|
publisherManager,
|
|
135
135
|
nodeKeyStore: NodeKeystoreAdapter.fromKeyStoreManager(deps.nodeKeyStore),
|
|
136
|
+
logger: log,
|
|
136
137
|
});
|
|
137
138
|
const globalsBuilder = new GlobalVariableBuilder(config);
|
|
138
139
|
|
|
@@ -178,6 +179,7 @@ export class SequencerClient {
|
|
|
178
179
|
rollupContract,
|
|
179
180
|
{ ...config, maxL1TxInclusionTimeIntoSlot, maxL2BlockGas: sequencerManaLimit },
|
|
180
181
|
telemetryClient,
|
|
182
|
+
log,
|
|
181
183
|
);
|
|
182
184
|
|
|
183
185
|
await sequencer.init();
|
|
@@ -200,6 +202,7 @@ export class SequencerClient {
|
|
|
200
202
|
await this.validatorClient?.start();
|
|
201
203
|
this.sequencer.start();
|
|
202
204
|
this.l1Metrics?.start();
|
|
205
|
+
await this.publisherManager.loadState();
|
|
203
206
|
}
|
|
204
207
|
|
|
205
208
|
/**
|
|
@@ -207,6 +210,7 @@ export class SequencerClient {
|
|
|
207
210
|
*/
|
|
208
211
|
public async stop() {
|
|
209
212
|
await this.sequencer.stop();
|
|
213
|
+
await this.validatorClient?.stop();
|
|
210
214
|
this.publisherManager.interrupt();
|
|
211
215
|
this.l1Metrics?.stop();
|
|
212
216
|
}
|
package/src/config.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
pickConfigMappings,
|
|
13
13
|
} from '@aztec/foundation/config';
|
|
14
14
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
15
|
+
import { type KeyStoreConfig, keyStoreConfigMappings } from '@aztec/node-keystore';
|
|
15
16
|
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p';
|
|
16
17
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
17
18
|
import { type ChainConfig, type SequencerConfig, chainConfigMappings } from '@aztec/stdlib/config';
|
|
@@ -33,6 +34,7 @@ export const DEFAULT_ATTESTATION_PROPAGATION_TIME = 2;
|
|
|
33
34
|
* Configuration settings for the SequencerClient.
|
|
34
35
|
*/
|
|
35
36
|
export type SequencerClientConfig = PublisherConfig &
|
|
37
|
+
KeyStoreConfig &
|
|
36
38
|
ValidatorClientConfig &
|
|
37
39
|
TxSenderConfig &
|
|
38
40
|
SequencerConfig &
|
|
@@ -143,12 +145,17 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
143
145
|
description: 'Do not invalidate the previous block if invalid when we are the proposer (for testing only)',
|
|
144
146
|
...booleanConfigHelper(false),
|
|
145
147
|
},
|
|
148
|
+
injectFakeAttestation: {
|
|
149
|
+
description: 'Inject a fake attestation (for testing only)',
|
|
150
|
+
...booleanConfigHelper(false),
|
|
151
|
+
},
|
|
146
152
|
...pickConfigMappings(p2pConfigMappings, ['txPublicSetupAllowList']),
|
|
147
153
|
};
|
|
148
154
|
|
|
149
155
|
export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientConfig> = {
|
|
150
156
|
...validatorClientConfigMappings,
|
|
151
157
|
...sequencerConfigMappings,
|
|
158
|
+
...keyStoreConfigMappings,
|
|
152
159
|
...l1ReaderConfigMappings,
|
|
153
160
|
...getTxSenderConfigMappings('SEQ'),
|
|
154
161
|
...getPublisherConfigMappings('SEQ'),
|
|
@@ -13,7 +13,7 @@ import { GasFees } from '@aztec/stdlib/gas';
|
|
|
13
13
|
import type { GlobalVariableBuilder as GlobalVariableBuilderInterface } from '@aztec/stdlib/tx';
|
|
14
14
|
import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
15
15
|
|
|
16
|
-
import { createPublicClient, fallback, http } from 'viem';
|
|
16
|
+
import { createPublicClient, fallback, http } from '@spalladino/viem';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Simple global variables builder.
|
package/src/publisher/config.ts
CHANGED
|
@@ -5,7 +5,12 @@ import {
|
|
|
5
5
|
l1ReaderConfigMappings,
|
|
6
6
|
l1TxUtilsConfigMappings,
|
|
7
7
|
} from '@aztec/ethereum';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type ConfigMappingsType,
|
|
10
|
+
SecretValue,
|
|
11
|
+
booleanConfigHelper,
|
|
12
|
+
getConfigFromMappings,
|
|
13
|
+
} from '@aztec/foundation/config';
|
|
9
14
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
10
15
|
|
|
11
16
|
/**
|
|
@@ -28,10 +33,8 @@ export type TxSenderConfig = L1ReaderConfig & {
|
|
|
28
33
|
*/
|
|
29
34
|
export type PublisherConfig = L1TxUtilsConfig &
|
|
30
35
|
BlobSinkConfig & {
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
*/
|
|
34
|
-
l1PublishRetryIntervalMS: number;
|
|
36
|
+
/** True to use publishers in invalid states (timed out, cancelled, etc) if no other is available */
|
|
37
|
+
publisherAllowInvalidStates?: boolean;
|
|
35
38
|
};
|
|
36
39
|
|
|
37
40
|
export const getTxSenderConfigMappings: (
|
|
@@ -43,7 +46,7 @@ export const getTxSenderConfigMappings: (
|
|
|
43
46
|
description: 'The private keys to be used by the publisher.',
|
|
44
47
|
parseEnv: (val: string) => val.split(',').map(key => new SecretValue(`0x${key.replace('0x', '')}`)),
|
|
45
48
|
defaultValue: [],
|
|
46
|
-
fallback: scope === 'PROVER' ?
|
|
49
|
+
fallback: [scope === 'PROVER' ? `PROVER_PUBLISHER_PRIVATE_KEY` : `SEQ_PUBLISHER_PRIVATE_KEY`],
|
|
47
50
|
},
|
|
48
51
|
publisherAddresses: {
|
|
49
52
|
env: scope === 'PROVER' ? `PROVER_PUBLISHER_ADDRESSES` : `SEQ_PUBLISHER_ADDRESSES`,
|
|
@@ -60,11 +63,10 @@ export function getTxSenderConfigFromEnv(scope: 'PROVER' | 'SEQ'): Omit<TxSender
|
|
|
60
63
|
export const getPublisherConfigMappings: (
|
|
61
64
|
scope: 'PROVER' | 'SEQ',
|
|
62
65
|
) => ConfigMappingsType<PublisherConfig & L1TxUtilsConfig> = scope => ({
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
description: 'The interval to wait between publish retries.',
|
|
66
|
+
publisherAllowInvalidStates: {
|
|
67
|
+
description: 'True to use publishers in invalid states (timed out, cancelled, etc) if no other is available',
|
|
68
|
+
env: scope === `PROVER` ? `PROVER_PUBLISHER_ALLOW_INVALID_STATES` : `SEQ_PUBLISHER_ALLOW_INVALID_STATES`,
|
|
69
|
+
...booleanConfigHelper(true),
|
|
68
70
|
},
|
|
69
71
|
...l1TxUtilsConfigMappings,
|
|
70
72
|
...blobSinkConfigMapping,
|
package/src/publisher/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EthAddress } from '@aztec/aztec.js';
|
|
1
|
+
import { EthAddress, type Logger, createLogger } from '@aztec/aztec.js';
|
|
2
2
|
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
3
3
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
4
4
|
import type { GovernanceProposerContract, PublisherFilter, PublisherManager, RollupContract } from '@aztec/ethereum';
|
|
@@ -10,7 +10,7 @@ import { NodeKeystoreAdapter } from '@aztec/validator-client';
|
|
|
10
10
|
|
|
11
11
|
import type { SequencerClientConfig } from '../config.js';
|
|
12
12
|
import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
|
|
13
|
-
import { SequencerPublisher } from './sequencer-publisher.js';
|
|
13
|
+
import { type Action, SequencerPublisher } from './sequencer-publisher.js';
|
|
14
14
|
|
|
15
15
|
export type AttestorPublisherPair = {
|
|
16
16
|
attestorAddress: EthAddress;
|
|
@@ -19,6 +19,12 @@ export type AttestorPublisherPair = {
|
|
|
19
19
|
|
|
20
20
|
export class SequencerPublisherFactory {
|
|
21
21
|
private publisherMetrics: SequencerPublisherMetrics;
|
|
22
|
+
|
|
23
|
+
/** Stores the last slot in which every action was carried out by a publisher */
|
|
24
|
+
private lastActions: Partial<Record<Action, bigint>> = {};
|
|
25
|
+
|
|
26
|
+
private logger: Logger;
|
|
27
|
+
|
|
22
28
|
constructor(
|
|
23
29
|
private sequencerConfig: SequencerClientConfig,
|
|
24
30
|
private deps: {
|
|
@@ -31,9 +37,11 @@ export class SequencerPublisherFactory {
|
|
|
31
37
|
governanceProposerContract: GovernanceProposerContract;
|
|
32
38
|
slashFactoryContract: SlashFactoryContract;
|
|
33
39
|
nodeKeyStore: NodeKeystoreAdapter;
|
|
40
|
+
logger?: Logger;
|
|
34
41
|
},
|
|
35
42
|
) {
|
|
36
43
|
this.publisherMetrics = new SequencerPublisherMetrics(deps.telemetry, 'SequencerPublisher');
|
|
44
|
+
this.logger = deps.logger ?? createLogger('sequencer');
|
|
37
45
|
}
|
|
38
46
|
/**
|
|
39
47
|
* Creates a new SequencerPublisher instance.
|
|
@@ -69,6 +77,8 @@ export class SequencerPublisherFactory {
|
|
|
69
77
|
slashFactoryContract: this.deps.slashFactoryContract,
|
|
70
78
|
dateProvider: this.deps.dateProvider,
|
|
71
79
|
metrics: this.publisherMetrics,
|
|
80
|
+
lastActions: this.lastActions,
|
|
81
|
+
log: this.logger.createChild('publisher'),
|
|
72
82
|
});
|
|
73
83
|
|
|
74
84
|
return {
|