@aztec/sequencer-client 4.0.0-nightly.20260107 → 4.0.0-nightly.20260108
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/global_variable_builder/global_builder.d.ts +4 -4
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +11 -11
- package/dest/publisher/sequencer-publisher.d.ts +3 -2
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +397 -2
- package/dest/sequencer/checkpoint_proposal_job.d.ts +5 -3
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +429 -1
- package/dest/sequencer/sequencer.d.ts +2 -1
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +18 -6
- package/package.json +27 -27
- package/src/global_variable_builder/global_builder.ts +11 -11
- package/src/publisher/sequencer-publisher.ts +8 -2
- package/src/sequencer/checkpoint_proposal_job.ts +17 -1
- package/src/sequencer/sequencer.ts +5 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "4.0.0-nightly.
|
|
3
|
+
"version": "4.0.0-nightly.20260108",
|
|
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": "4.0.0-nightly.
|
|
30
|
-
"@aztec/bb-prover": "4.0.0-nightly.
|
|
31
|
-
"@aztec/blob-client": "4.0.0-nightly.
|
|
32
|
-
"@aztec/blob-lib": "4.0.0-nightly.
|
|
33
|
-
"@aztec/constants": "4.0.0-nightly.
|
|
34
|
-
"@aztec/epoch-cache": "4.0.0-nightly.
|
|
35
|
-
"@aztec/ethereum": "4.0.0-nightly.
|
|
36
|
-
"@aztec/foundation": "4.0.0-nightly.
|
|
37
|
-
"@aztec/l1-artifacts": "4.0.0-nightly.
|
|
38
|
-
"@aztec/merkle-tree": "4.0.0-nightly.
|
|
39
|
-
"@aztec/node-keystore": "4.0.0-nightly.
|
|
40
|
-
"@aztec/noir-acvm_js": "4.0.0-nightly.
|
|
41
|
-
"@aztec/noir-contracts.js": "4.0.0-nightly.
|
|
42
|
-
"@aztec/noir-protocol-circuits-types": "4.0.0-nightly.
|
|
43
|
-
"@aztec/noir-types": "4.0.0-nightly.
|
|
44
|
-
"@aztec/p2p": "4.0.0-nightly.
|
|
45
|
-
"@aztec/protocol-contracts": "4.0.0-nightly.
|
|
46
|
-
"@aztec/prover-client": "4.0.0-nightly.
|
|
47
|
-
"@aztec/simulator": "4.0.0-nightly.
|
|
48
|
-
"@aztec/slasher": "4.0.0-nightly.
|
|
49
|
-
"@aztec/stdlib": "4.0.0-nightly.
|
|
50
|
-
"@aztec/telemetry-client": "4.0.0-nightly.
|
|
51
|
-
"@aztec/validator-client": "4.0.0-nightly.
|
|
52
|
-
"@aztec/world-state": "4.0.0-nightly.
|
|
29
|
+
"@aztec/aztec.js": "4.0.0-nightly.20260108",
|
|
30
|
+
"@aztec/bb-prover": "4.0.0-nightly.20260108",
|
|
31
|
+
"@aztec/blob-client": "4.0.0-nightly.20260108",
|
|
32
|
+
"@aztec/blob-lib": "4.0.0-nightly.20260108",
|
|
33
|
+
"@aztec/constants": "4.0.0-nightly.20260108",
|
|
34
|
+
"@aztec/epoch-cache": "4.0.0-nightly.20260108",
|
|
35
|
+
"@aztec/ethereum": "4.0.0-nightly.20260108",
|
|
36
|
+
"@aztec/foundation": "4.0.0-nightly.20260108",
|
|
37
|
+
"@aztec/l1-artifacts": "4.0.0-nightly.20260108",
|
|
38
|
+
"@aztec/merkle-tree": "4.0.0-nightly.20260108",
|
|
39
|
+
"@aztec/node-keystore": "4.0.0-nightly.20260108",
|
|
40
|
+
"@aztec/noir-acvm_js": "4.0.0-nightly.20260108",
|
|
41
|
+
"@aztec/noir-contracts.js": "4.0.0-nightly.20260108",
|
|
42
|
+
"@aztec/noir-protocol-circuits-types": "4.0.0-nightly.20260108",
|
|
43
|
+
"@aztec/noir-types": "4.0.0-nightly.20260108",
|
|
44
|
+
"@aztec/p2p": "4.0.0-nightly.20260108",
|
|
45
|
+
"@aztec/protocol-contracts": "4.0.0-nightly.20260108",
|
|
46
|
+
"@aztec/prover-client": "4.0.0-nightly.20260108",
|
|
47
|
+
"@aztec/simulator": "4.0.0-nightly.20260108",
|
|
48
|
+
"@aztec/slasher": "4.0.0-nightly.20260108",
|
|
49
|
+
"@aztec/stdlib": "4.0.0-nightly.20260108",
|
|
50
|
+
"@aztec/telemetry-client": "4.0.0-nightly.20260108",
|
|
51
|
+
"@aztec/validator-client": "4.0.0-nightly.20260108",
|
|
52
|
+
"@aztec/world-state": "4.0.0-nightly.20260108",
|
|
53
53
|
"lodash.chunk": "^4.2.0",
|
|
54
54
|
"tslib": "^2.4.0",
|
|
55
55
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@aztec/archiver": "4.0.0-nightly.
|
|
59
|
-
"@aztec/kv-store": "4.0.0-nightly.
|
|
58
|
+
"@aztec/archiver": "4.0.0-nightly.20260108",
|
|
59
|
+
"@aztec/kv-store": "4.0.0-nightly.20260108",
|
|
60
60
|
"@jest/globals": "^30.0.0",
|
|
61
61
|
"@types/jest": "^30.0.0",
|
|
62
62
|
"@types/lodash.chunk": "^4.2.7",
|
|
@@ -23,7 +23,7 @@ import { createPublicClient, fallback, http } from 'viem';
|
|
|
23
23
|
*/
|
|
24
24
|
export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
25
25
|
private log = createLogger('sequencer:global_variable_builder');
|
|
26
|
-
private
|
|
26
|
+
private currentMinFees: Promise<GasFees> = Promise.resolve(new GasFees(0, 0));
|
|
27
27
|
private currentL1BlockNumber: bigint | undefined = undefined;
|
|
28
28
|
|
|
29
29
|
private readonly rollupContract: RollupContract;
|
|
@@ -61,10 +61,10 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
|
-
* Computes the "current"
|
|
65
|
-
* @returns
|
|
64
|
+
* Computes the "current" min fees, e.g., the price that you currently should pay to get include in the next block
|
|
65
|
+
* @returns Min fees for the next block
|
|
66
66
|
*/
|
|
67
|
-
private async
|
|
67
|
+
private async computeCurrentMinFees(): Promise<GasFees> {
|
|
68
68
|
// Since this might be called in the middle of a slot where a block might have been published,
|
|
69
69
|
// we need to fetch the last block written, and estimate the earliest timestamp for the next block.
|
|
70
70
|
// The timestamp of that last block will act as a lower bound for the next block.
|
|
@@ -76,19 +76,19 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
76
76
|
const nextEthTimestamp = BigInt((await this.publicClient.getBlock()).timestamp + BigInt(this.ethereumSlotDuration));
|
|
77
77
|
const timestamp = earliestTimestamp > nextEthTimestamp ? earliestTimestamp : nextEthTimestamp;
|
|
78
78
|
|
|
79
|
-
return new GasFees(0, await this.rollupContract.
|
|
79
|
+
return new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
public async
|
|
82
|
+
public async getCurrentMinFees(): Promise<GasFees> {
|
|
83
83
|
// Get the current block number
|
|
84
84
|
const blockNumber = await this.publicClient.getBlockNumber();
|
|
85
85
|
|
|
86
|
-
// If the L1 block number has changed then chain a new promise to get the current
|
|
86
|
+
// If the L1 block number has changed then chain a new promise to get the current min fees
|
|
87
87
|
if (this.currentL1BlockNumber === undefined || blockNumber > this.currentL1BlockNumber) {
|
|
88
88
|
this.currentL1BlockNumber = blockNumber;
|
|
89
|
-
this.
|
|
89
|
+
this.currentMinFees = this.currentMinFees.then(() => this.computeCurrentMinFees());
|
|
90
90
|
}
|
|
91
|
-
return this.
|
|
91
|
+
return this.currentMinFees;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
@@ -128,9 +128,9 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
128
128
|
l1GenesisTime: this.l1GenesisTime,
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
// We can skip much of the logic in
|
|
131
|
+
// We can skip much of the logic in getCurrentMinFees since it we already check that we are not within a slot elsewhere.
|
|
132
132
|
// TODO(palla/mbps): Can we use a cached value here?
|
|
133
|
-
const gasFees = new GasFees(0, await this.rollupContract.
|
|
133
|
+
const gasFees = new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
|
|
134
134
|
|
|
135
135
|
return { chainId, version, slotNumber, timestamp, coinbase, feeRecipient, gasFees };
|
|
136
136
|
}
|
|
@@ -40,7 +40,7 @@ import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
|
40
40
|
import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
41
41
|
import type { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
42
42
|
import type { L1PublishCheckpointStats } from '@aztec/stdlib/stats';
|
|
43
|
-
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
43
|
+
import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
44
44
|
|
|
45
45
|
import { type StateOverride, type TransactionReceipt, type TypedDataDefinition, encodeFunctionData, toHex } from 'viem';
|
|
46
46
|
|
|
@@ -139,6 +139,8 @@ export class SequencerPublisher {
|
|
|
139
139
|
public slashingProposerContract: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
|
|
140
140
|
public slashFactoryContract: SlashFactoryContract;
|
|
141
141
|
|
|
142
|
+
public readonly tracer: Tracer;
|
|
143
|
+
|
|
142
144
|
protected requests: RequestWithExpiry[] = [];
|
|
143
145
|
|
|
144
146
|
constructor(
|
|
@@ -167,6 +169,7 @@ export class SequencerPublisher {
|
|
|
167
169
|
|
|
168
170
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
169
171
|
this.metrics = deps.metrics ?? new SequencerPublisherMetrics(telemetry, 'SequencerPublisher');
|
|
172
|
+
this.tracer = telemetry.getTracer('SequencerPublisher');
|
|
170
173
|
this.l1TxUtils = deps.l1TxUtils;
|
|
171
174
|
|
|
172
175
|
this.rollupContract = deps.rollupContract;
|
|
@@ -296,6 +299,7 @@ export class SequencerPublisher {
|
|
|
296
299
|
* - a receipt and errorMsg if it failed on L1
|
|
297
300
|
* - undefined if no valid requests are found OR the tx failed to send.
|
|
298
301
|
*/
|
|
302
|
+
@trackSpan('SequencerPublisher.sendRequests')
|
|
299
303
|
public async sendRequests() {
|
|
300
304
|
const requestsToProcess = [...this.requests];
|
|
301
305
|
this.requests = [];
|
|
@@ -442,10 +446,11 @@ export class SequencerPublisher {
|
|
|
442
446
|
* It will throw if the block header is invalid.
|
|
443
447
|
* @param header - The block header to validate
|
|
444
448
|
*/
|
|
449
|
+
@trackSpan('SequencerPublisher.validateBlockHeader')
|
|
445
450
|
public async validateBlockHeader(
|
|
446
451
|
header: CheckpointHeader,
|
|
447
452
|
opts?: { forcePendingBlockNumber: BlockNumber | undefined },
|
|
448
|
-
) {
|
|
453
|
+
): Promise<void> {
|
|
449
454
|
const flags = { ignoreDA: true, ignoreSignatures: true };
|
|
450
455
|
|
|
451
456
|
const args = [
|
|
@@ -588,6 +593,7 @@ export class SequencerPublisher {
|
|
|
588
593
|
}
|
|
589
594
|
|
|
590
595
|
/** Simulates `propose` to make sure that the checkpoint is valid for submission */
|
|
596
|
+
@trackSpan('SequencerPublisher.validateCheckpointForSubmission')
|
|
591
597
|
public async validateCheckpointForSubmission(
|
|
592
598
|
checkpoint: Checkpoint,
|
|
593
599
|
attestationsAndSigners: CommitteeAttestationsAndSigners,
|
|
@@ -32,6 +32,7 @@ import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
|
32
32
|
import type { L2BlockBuiltStats } from '@aztec/stdlib/stats';
|
|
33
33
|
import { type FailedTx, Tx } from '@aztec/stdlib/tx';
|
|
34
34
|
import { AttestationTimeoutError } from '@aztec/stdlib/validators';
|
|
35
|
+
import { Attributes, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
|
|
35
36
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
36
37
|
|
|
37
38
|
import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
|
|
@@ -54,7 +55,7 @@ const TXS_POLLING_MS = 500;
|
|
|
54
55
|
* as well as enqueueing votes for slashing and governance proposals. This class is created from
|
|
55
56
|
* the Sequencer once the check for being the proposer for the slot has succeeded.
|
|
56
57
|
*/
|
|
57
|
-
export class CheckpointProposalJob {
|
|
58
|
+
export class CheckpointProposalJob implements Traceable {
|
|
58
59
|
constructor(
|
|
59
60
|
private readonly slot: SlotNumber,
|
|
60
61
|
private readonly checkpointNumber: CheckpointNumber,
|
|
@@ -80,12 +81,14 @@ export class CheckpointProposalJob {
|
|
|
80
81
|
private readonly eventEmitter: TypedEventEmitter<SequencerEvents>,
|
|
81
82
|
private readonly setStateFn: (state: SequencerState, slot?: SlotNumber) => void,
|
|
82
83
|
protected readonly log: Logger,
|
|
84
|
+
public readonly tracer: Tracer,
|
|
83
85
|
) {}
|
|
84
86
|
|
|
85
87
|
/**
|
|
86
88
|
* Executes the checkpoint proposal job.
|
|
87
89
|
* Returns the published checkpoint if successful, undefined otherwise.
|
|
88
90
|
*/
|
|
91
|
+
@trackSpan('CheckpointProposalJob.execute')
|
|
89
92
|
public async execute(): Promise<Checkpoint | undefined> {
|
|
90
93
|
// Enqueue governance and slashing votes (returns promises that will be awaited later)
|
|
91
94
|
// In fisherman mode, we simulate slashing but don't actually publish to L1
|
|
@@ -132,6 +135,13 @@ export class CheckpointProposalJob {
|
|
|
132
135
|
}
|
|
133
136
|
}
|
|
134
137
|
|
|
138
|
+
@trackSpan('CheckpointProposalJob.proposeCheckpoint', function () {
|
|
139
|
+
return {
|
|
140
|
+
// nullish operator needed for tests
|
|
141
|
+
[Attributes.COINBASE]: this.validatorClient.getCoinbaseForAttestor(this.attestorAddress)?.toString(),
|
|
142
|
+
[Attributes.SLOT_NUMBER]: this.slot,
|
|
143
|
+
};
|
|
144
|
+
})
|
|
135
145
|
private async proposeCheckpoint(): Promise<Checkpoint | undefined> {
|
|
136
146
|
try {
|
|
137
147
|
// Get operator configured coinbase and fee recipient for this attestor
|
|
@@ -248,6 +258,7 @@ export class CheckpointProposalJob {
|
|
|
248
258
|
/**
|
|
249
259
|
* Builds blocks for a checkpoint within the current slot.
|
|
250
260
|
*/
|
|
261
|
+
@trackSpan('CheckpointProposalJob.buildBlocksForCheckpoint')
|
|
251
262
|
private async buildBlocksForCheckpoint(
|
|
252
263
|
checkpointBuilder: CheckpointBuilder,
|
|
253
264
|
timestamp: bigint,
|
|
@@ -366,6 +377,7 @@ export class CheckpointProposalJob {
|
|
|
366
377
|
}
|
|
367
378
|
|
|
368
379
|
/** Sleeps until it is time to produce the next block in the slot */
|
|
380
|
+
@trackSpan('CheckpointProposalJob.waitUntilNextSubslot')
|
|
369
381
|
private async waitUntilNextSubslot(nextSubslotStart: number) {
|
|
370
382
|
this.setStateFn(SequencerState.WAITING_UNTIL_NEXT_BLOCK, this.slot);
|
|
371
383
|
this.log.verbose(`Waiting until time for the next block at ${nextSubslotStart}s into slot`, { slot: this.slot });
|
|
@@ -373,6 +385,7 @@ export class CheckpointProposalJob {
|
|
|
373
385
|
}
|
|
374
386
|
|
|
375
387
|
/** Builds a single block. Called from the main block building loop. */
|
|
388
|
+
@trackSpan('CheckpointProposalJob.buildSingleBlock')
|
|
376
389
|
private async buildSingleBlock(
|
|
377
390
|
checkpointBuilder: CheckpointBuilder,
|
|
378
391
|
opts: {
|
|
@@ -484,6 +497,7 @@ export class CheckpointProposalJob {
|
|
|
484
497
|
}
|
|
485
498
|
|
|
486
499
|
/** Waits until minTxs are available on the pool for building a block. */
|
|
500
|
+
@trackSpan('CheckpointProposalJob.waitForMinTxs')
|
|
487
501
|
private async waitForMinTxs(opts: {
|
|
488
502
|
forceCreate?: boolean;
|
|
489
503
|
blockNumber: BlockNumber;
|
|
@@ -524,6 +538,7 @@ export class CheckpointProposalJob {
|
|
|
524
538
|
* Waits for enough attestations to be collected via p2p.
|
|
525
539
|
* This is run after all blocks for the checkpoint have been built.
|
|
526
540
|
*/
|
|
541
|
+
@trackSpan('CheckpointProposalJob.waitForAttestations')
|
|
527
542
|
private async waitForAttestations(proposal: BlockProposal): Promise<CommitteeAttestationsAndSigners> {
|
|
528
543
|
if (this.config.fishermanMode) {
|
|
529
544
|
this.log.debug('Skipping attestation collection in fisherman mode');
|
|
@@ -685,6 +700,7 @@ export class CheckpointProposalJob {
|
|
|
685
700
|
}
|
|
686
701
|
|
|
687
702
|
/** Waits until a specific time within the current slot */
|
|
703
|
+
@trackSpan('CheckpointProposalJob.waitUntilTimeInSlot')
|
|
688
704
|
protected async waitUntilTimeInSlot(targetSecondsIntoSlot: number): Promise<void> {
|
|
689
705
|
const slotStartTimestamp = this.getSlotStartBuildTimestamp();
|
|
690
706
|
const targetTimestamp = slotStartTimestamp + targetSecondsIntoSlot;
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
25
25
|
import { pickFromSchema } from '@aztec/stdlib/schemas';
|
|
26
26
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
27
|
-
import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
27
|
+
import { Attributes, type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
28
28
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
29
29
|
|
|
30
30
|
import EventEmitter from 'node:events';
|
|
@@ -160,7 +160,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
160
160
|
this.log.info('Stopped sequencer');
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
@trackSpan('Sequencer.work')
|
|
164
163
|
/** Main sequencer loop with a try/catch */
|
|
165
164
|
protected async safeWork() {
|
|
166
165
|
try {
|
|
@@ -198,6 +197,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
198
197
|
* - Collect attestations for the final block
|
|
199
198
|
* - Submit checkpoint
|
|
200
199
|
*/
|
|
200
|
+
@trackSpan('Sequencer.work')
|
|
201
201
|
protected async work() {
|
|
202
202
|
this.setState(SequencerState.SYNCHRONIZING, undefined);
|
|
203
203
|
const { slot, ts, now, epoch } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
@@ -233,6 +233,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
233
233
|
* This is the initial step in the main loop.
|
|
234
234
|
* @returns CheckpointProposalJob if successful, undefined if we are not yet synced or are not the proposer.
|
|
235
235
|
*/
|
|
236
|
+
@trackSpan('Sequencer.prepareCheckpointProposal')
|
|
236
237
|
private async prepareCheckpointProposal(
|
|
237
238
|
slot: SlotNumber,
|
|
238
239
|
ts: bigint,
|
|
@@ -401,6 +402,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
401
402
|
this,
|
|
402
403
|
this.setState.bind(this),
|
|
403
404
|
this.log,
|
|
405
|
+
this.tracer,
|
|
404
406
|
);
|
|
405
407
|
}
|
|
406
408
|
|
|
@@ -555,6 +557,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
555
557
|
* Tries to vote on slashing actions and governance when the sync check fails but we're past the max time for initializing a proposal.
|
|
556
558
|
* This allows the sequencer to participate in governance/slashing votes even when it cannot build blocks.
|
|
557
559
|
*/
|
|
560
|
+
@trackSpan('Seqeuencer.tryVoteWhenSyncFails', ({ slot }) => ({ [Attributes.SLOT_NUMBER]: slot }))
|
|
558
561
|
protected async tryVoteWhenSyncFails(args: { slot: SlotNumber; ts: bigint }): Promise<void> {
|
|
559
562
|
const { slot } = args;
|
|
560
563
|
|