@aztec/sequencer-client 4.2.0-nightly.20260330 → 4.2.0-nightly.20260331
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/publisher/sequencer-publisher.d.ts +12 -7
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +46 -46
- package/dest/sequencer/checkpoint_voter.d.ts +1 -2
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_voter.js +2 -5
- package/package.json +28 -28
- package/src/publisher/sequencer-publisher.ts +40 -55
- package/src/sequencer/checkpoint_voter.ts +1 -12
|
@@ -54,6 +54,7 @@ export declare class SequencerPublisher {
|
|
|
54
54
|
private payloadProposedCache;
|
|
55
55
|
protected log: Logger;
|
|
56
56
|
protected ethereumSlotDuration: bigint;
|
|
57
|
+
protected aztecSlotDuration: bigint;
|
|
57
58
|
private dateProvider;
|
|
58
59
|
private blobClient;
|
|
59
60
|
/** Address to use for simulations in fisherman mode (actual proposer's address) */
|
|
@@ -71,7 +72,7 @@ export declare class SequencerPublisher {
|
|
|
71
72
|
slashFactoryContract: SlashFactoryContract;
|
|
72
73
|
readonly tracer: Tracer;
|
|
73
74
|
protected requests: RequestWithExpiry[];
|
|
74
|
-
constructor(config: Pick<SequencerPublisherConfig, 'fishermanMode'> & Pick<L1ContractsConfig, 'ethereumSlotDuration'> & {
|
|
75
|
+
constructor(config: Pick<SequencerPublisherConfig, 'fishermanMode'> & Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration'> & {
|
|
75
76
|
l1ChainId: number;
|
|
76
77
|
}, deps: {
|
|
77
78
|
telemetry?: TelemetryClient;
|
|
@@ -147,6 +148,7 @@ export declare class SequencerPublisher {
|
|
|
147
148
|
*/
|
|
148
149
|
canProposeAt(tipArchive: Fr, msgSender: EthAddress, opts?: {
|
|
149
150
|
forcePendingCheckpointNumber?: CheckpointNumber;
|
|
151
|
+
pipelined?: boolean;
|
|
150
152
|
}): Promise<{
|
|
151
153
|
slot: SlotNumber;
|
|
152
154
|
checkpointNumber: CheckpointNumber;
|
|
@@ -170,18 +172,17 @@ export declare class SequencerPublisher {
|
|
|
170
172
|
/** Simulates `propose` to make sure that the checkpoint is valid for submission */
|
|
171
173
|
validateCheckpointForSubmission(checkpoint: Checkpoint, attestationsAndSigners: CommitteeAttestationsAndSigners, attestationsAndSignersSignature: Signature, options: {
|
|
172
174
|
forcePendingCheckpointNumber?: CheckpointNumber;
|
|
173
|
-
}): Promise<
|
|
175
|
+
}): Promise<void>;
|
|
174
176
|
private enqueueCastSignalHelper;
|
|
175
177
|
private isPayloadEmpty;
|
|
176
178
|
/**
|
|
177
179
|
* Enqueues a governance castSignal transaction to cast a signal for a given slot number.
|
|
178
180
|
* @param slotNumber - The slot number to cast a signal for.
|
|
179
|
-
* @param timestamp - The timestamp of the slot to cast a signal for.
|
|
180
181
|
* @returns True if the signal was successfully enqueued, false otherwise.
|
|
181
182
|
*/
|
|
182
|
-
enqueueGovernanceCastSignal(governancePayload: EthAddress, slotNumber: SlotNumber,
|
|
183
|
+
enqueueGovernanceCastSignal(governancePayload: EthAddress, slotNumber: SlotNumber, signerAddress: EthAddress, signer: (msg: TypedDataDefinition) => Promise<`0x${string}`>): Promise<boolean>;
|
|
183
184
|
/** Enqueues all slashing actions as returned by the slasher client. */
|
|
184
|
-
enqueueSlashingActions(actions: ProposerSlashAction[], slotNumber: SlotNumber,
|
|
185
|
+
enqueueSlashingActions(actions: ProposerSlashAction[], slotNumber: SlotNumber, signerAddress: EthAddress, signer: (msg: TypedDataDefinition) => Promise<`0x${string}`>): Promise<boolean>;
|
|
185
186
|
/** Simulates and enqueues a proposal for a checkpoint on L1 */
|
|
186
187
|
enqueueProposeCheckpoint(checkpoint: Checkpoint, attestationsAndSigners: CommitteeAttestationsAndSigners, attestationsAndSignersSignature: Signature, opts?: {
|
|
187
188
|
txTimeoutAt?: Date;
|
|
@@ -203,7 +204,11 @@ export declare class SequencerPublisher {
|
|
|
203
204
|
private prepareProposeTx;
|
|
204
205
|
private simulateProposeTx;
|
|
205
206
|
private addProposeTx;
|
|
206
|
-
|
|
207
|
+
/** Returns the timestamp of the last L1 slot within a given L2 slot. Used as the simulation timestamp
|
|
208
|
+
* for eth_simulateV1 calls, since it's guaranteed to be greater than any L1 block produced during the slot. */
|
|
209
|
+
private getSimulationTimestamp;
|
|
210
|
+
/** Returns the timestamp of the next L1 slot boundary after now. */
|
|
211
|
+
private getNextL1SlotTimestamp;
|
|
207
212
|
}
|
|
208
213
|
export {};
|
|
209
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
214
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLXB1Ymxpc2hlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3B1Ymxpc2hlci9zZXF1ZW5jZXItcHVibGlzaGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFckUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRSxPQUFPLEVBQ0wsS0FBSyw4QkFBOEIsRUFFbkMsS0FBSywwQkFBMEIsRUFJL0IsY0FBYyxFQUNkLEtBQUssNkJBQTZCLEVBR25DLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLEtBQUssbUJBQW1CLEVBQUUsYUFBYSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUYsT0FBTyxFQUNMLEtBQUssWUFBWSxFQUNqQixLQUFLLFVBQVUsRUFDZixLQUFLLFdBQVcsRUFDaEIsS0FBSyxTQUFTLEVBRWQsS0FBSyxnQkFBZ0IsRUFFdEIsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsa0JBQWtCLEVBQStDLE1BQU0sdUJBQXVCLENBQUM7QUFHeEcsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRy9FLE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3pELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFzQixNQUFNLGlDQUFpQyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxLQUFLLE1BQU0sRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUdsRSxPQUFPLEVBQUUsWUFBWSxFQUFTLE1BQU0seUJBQXlCLENBQUM7QUFFOUQsT0FBTyxF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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACL,KAAK,8BAA8B,EAEnC,KAAK,0BAA0B,EAI/B,cAAc,EACd,KAAK,6BAA6B,EAGnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,KAAK,mBAAmB,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,SAAS,EAEd,KAAK,gBAAgB,EAEtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAA+C,MAAM,uBAAuB,CAAC;AAGxG,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAG/E,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAsB,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAS,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAE,KAAK,mBAAmB,EAA6B,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,+BAA+B,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACrG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,MAAM,EAAiC,MAAM,yBAAyB,CAAC;AAE3G,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAA6B,MAAM,MAAM,CAAC;AAExH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAkB7E,eAAO,MAAM,OAAO,0OAUV,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAK9C,eAAO,MAAM,cAAc,geAAoE,CAAC;AAEhG,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,qBAAqB,GAAG,2BAA2B,CAAC;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,4BAA4B,EAAE,gBAAgB,CAAC;CAChD,CAAC;AAEF,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;IACrB,eAAe,EAAE,UAAU,CAAC;IAC5B,SAAS,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC;IACzD,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,YAAY,EAAE,CACZ,OAAO,EAAE,WAAW,EACpB,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,kBAAkB,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAClF,OAAO,CAAC;CACd;AAED,qBAAa,kBAAkB;
|
|
1
|
+
{"version":3,"file":"sequencer-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/sequencer-publisher.ts"],"names":[],"mappings":"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"}
|
|
@@ -390,7 +390,7 @@ import { Timer } from '@aztec/foundation/timer';
|
|
|
390
390
|
import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
391
391
|
import { encodeSlashConsensusVotes } from '@aztec/slasher';
|
|
392
392
|
import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
393
|
-
import { getNextL1SlotTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
393
|
+
import { getLastL1SlotTimestampForL2Slot, getNextL1SlotTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
394
394
|
import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
395
395
|
import { encodeFunctionData, toHex } from 'viem';
|
|
396
396
|
import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
|
|
@@ -439,6 +439,7 @@ export class SequencerPublisher {
|
|
|
439
439
|
payloadProposedCache;
|
|
440
440
|
log;
|
|
441
441
|
ethereumSlotDuration;
|
|
442
|
+
aztecSlotDuration;
|
|
442
443
|
dateProvider;
|
|
443
444
|
blobClient;
|
|
444
445
|
/** Address to use for simulations in fisherman mode (actual proposer's address) */ proposerAddressForSimulation;
|
|
@@ -466,6 +467,7 @@ export class SequencerPublisher {
|
|
|
466
467
|
this.requests = [];
|
|
467
468
|
this.log = deps.log ?? createLogger('sequencer:publisher');
|
|
468
469
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
470
|
+
this.aztecSlotDuration = BigInt(config.aztecSlotDuration);
|
|
469
471
|
this.dateProvider = deps.dateProvider;
|
|
470
472
|
this.epochCache = deps.epochCache;
|
|
471
473
|
this.lastActions = deps.lastActions;
|
|
@@ -699,14 +701,16 @@ export class SequencerPublisher {
|
|
|
699
701
|
* @notice Will call `canProposeAt` to make sure that it is possible to propose
|
|
700
702
|
* @param tipArchive - The archive to check
|
|
701
703
|
* @returns The slot and block number if it is possible to propose, undefined otherwise
|
|
702
|
-
*/
|
|
704
|
+
*/ canProposeAt(tipArchive, msgSender, opts = {}) {
|
|
703
705
|
// TODO: #14291 - should loop through multiple keys to check if any of them can propose
|
|
704
706
|
const ignoredErrors = [
|
|
705
707
|
'SlotAlreadyInChain',
|
|
706
708
|
'InvalidProposer',
|
|
707
709
|
'InvalidArchive'
|
|
708
710
|
];
|
|
709
|
-
const
|
|
711
|
+
const pipelined = opts.pipelined ?? false;
|
|
712
|
+
const slotOffset = pipelined ? this.aztecSlotDuration : 0n;
|
|
713
|
+
const nextL1SlotTs = this.getNextL1SlotTimestamp() + slotOffset;
|
|
710
714
|
return this.rollupContract.canProposeAt(tipArchive.toBuffer(), msgSender.toString(), nextL1SlotTs, {
|
|
711
715
|
forcePendingCheckpointNumber: opts.forcePendingCheckpointNumber
|
|
712
716
|
}).catch((err)=>{
|
|
@@ -739,7 +743,7 @@ export class SequencerPublisher {
|
|
|
739
743
|
header.blobsHash.toString(),
|
|
740
744
|
flags
|
|
741
745
|
];
|
|
742
|
-
const ts =
|
|
746
|
+
const ts = this.getSimulationTimestamp(header.slotNumber);
|
|
743
747
|
const stateOverrides = await this.rollupContract.makePendingCheckpointNumberOverride(opts?.forcePendingCheckpointNumber);
|
|
744
748
|
let balance = 0n;
|
|
745
749
|
if (this.config.fishermanMode) {
|
|
@@ -762,7 +766,7 @@ export class SequencerPublisher {
|
|
|
762
766
|
}),
|
|
763
767
|
from: MULTI_CALL_3_ADDRESS
|
|
764
768
|
}, {
|
|
765
|
-
time: ts
|
|
769
|
+
time: ts
|
|
766
770
|
}, stateOverrides);
|
|
767
771
|
this.log.debug(`Simulated validateHeader`);
|
|
768
772
|
}
|
|
@@ -860,7 +864,6 @@ export class SequencerPublisher {
|
|
|
860
864
|
}
|
|
861
865
|
}
|
|
862
866
|
/** Simulates `propose` to make sure that the checkpoint is valid for submission */ async validateCheckpointForSubmission(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, options) {
|
|
863
|
-
const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
|
|
864
867
|
const blobFields = checkpoint.toBlobFields();
|
|
865
868
|
const blobs = await getBlobsPerL1Block(blobFields);
|
|
866
869
|
const blobInput = getPrefixedEthBlobCommitments(blobs);
|
|
@@ -877,10 +880,9 @@ export class SequencerPublisher {
|
|
|
877
880
|
attestationsAndSignersSignature.toViemSignature(),
|
|
878
881
|
blobInput
|
|
879
882
|
];
|
|
880
|
-
await this.simulateProposeTx(args,
|
|
881
|
-
return ts;
|
|
883
|
+
await this.simulateProposeTx(args, options);
|
|
882
884
|
}
|
|
883
|
-
async enqueueCastSignalHelper(slotNumber,
|
|
885
|
+
async enqueueCastSignalHelper(slotNumber, signalType, payload, base, signerAddress, signer) {
|
|
884
886
|
if (this.lastActions[signalType] && this.lastActions[signalType] === slotNumber) {
|
|
885
887
|
this.log.debug(`Skipping duplicate vote cast signal ${signalType} for slot ${slotNumber}`);
|
|
886
888
|
return false;
|
|
@@ -936,6 +938,7 @@ export class SequencerPublisher {
|
|
|
936
938
|
signer: this.l1TxUtils.client.account?.address,
|
|
937
939
|
lastValidL2Slot: slotNumber
|
|
938
940
|
});
|
|
941
|
+
const timestamp = this.getSimulationTimestamp(slotNumber);
|
|
939
942
|
try {
|
|
940
943
|
await this.l1TxUtils.simulate(request, {
|
|
941
944
|
time: timestamp
|
|
@@ -947,7 +950,10 @@ export class SequencerPublisher {
|
|
|
947
950
|
request
|
|
948
951
|
});
|
|
949
952
|
} catch (err) {
|
|
950
|
-
|
|
953
|
+
const viemError = formatViemError(err);
|
|
954
|
+
this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError, {
|
|
955
|
+
simulationTimestamp: timestamp
|
|
956
|
+
});
|
|
951
957
|
// Yes, we enqueue the request anyway, in case there was a bug with the simulation itself
|
|
952
958
|
}
|
|
953
959
|
// TODO(palla/slash): All votes (governance and slashing) should txTimeoutAt at the end of the slot.
|
|
@@ -991,12 +997,11 @@ export class SequencerPublisher {
|
|
|
991
997
|
/**
|
|
992
998
|
* Enqueues a governance castSignal transaction to cast a signal for a given slot number.
|
|
993
999
|
* @param slotNumber - The slot number to cast a signal for.
|
|
994
|
-
* @param timestamp - The timestamp of the slot to cast a signal for.
|
|
995
1000
|
* @returns True if the signal was successfully enqueued, false otherwise.
|
|
996
|
-
*/ enqueueGovernanceCastSignal(governancePayload, slotNumber,
|
|
997
|
-
return this.enqueueCastSignalHelper(slotNumber,
|
|
1001
|
+
*/ enqueueGovernanceCastSignal(governancePayload, slotNumber, signerAddress, signer) {
|
|
1002
|
+
return this.enqueueCastSignalHelper(slotNumber, 'governance-signal', governancePayload, this.govProposerContract, signerAddress, signer);
|
|
998
1003
|
}
|
|
999
|
-
/** Enqueues all slashing actions as returned by the slasher client. */ async enqueueSlashingActions(actions, slotNumber,
|
|
1004
|
+
/** Enqueues all slashing actions as returned by the slasher client. */ async enqueueSlashingActions(actions, slotNumber, signerAddress, signer) {
|
|
1000
1005
|
if (actions.length === 0) {
|
|
1001
1006
|
this.log.debug(`No slashing actions to enqueue for slot ${slotNumber}`);
|
|
1002
1007
|
return false;
|
|
@@ -1012,7 +1017,7 @@ export class SequencerPublisher {
|
|
|
1012
1017
|
this.log.debug(`Enqueuing slashing vote for payload ${action.payload} at slot ${slotNumber}`, {
|
|
1013
1018
|
signerAddress
|
|
1014
1019
|
});
|
|
1015
|
-
await this.enqueueCastSignalHelper(slotNumber,
|
|
1020
|
+
await this.enqueueCastSignalHelper(slotNumber, 'empire-slashing-signal', action.payload, this.slashingProposerContract, signerAddress, signer);
|
|
1016
1021
|
break;
|
|
1017
1022
|
}
|
|
1018
1023
|
case 'create-empire-payload':
|
|
@@ -1022,7 +1027,7 @@ export class SequencerPublisher {
|
|
|
1022
1027
|
signerAddress
|
|
1023
1028
|
});
|
|
1024
1029
|
const request = this.slashFactoryContract.buildCreatePayloadRequest(action.data);
|
|
1025
|
-
await this.simulateAndEnqueueRequest('create-empire-payload', request, (receipt)=>!!this.slashFactoryContract.tryExtractSlashPayloadCreatedEvent(receipt.logs), slotNumber
|
|
1030
|
+
await this.simulateAndEnqueueRequest('create-empire-payload', request, (receipt)=>!!this.slashFactoryContract.tryExtractSlashPayloadCreatedEvent(receipt.logs), slotNumber);
|
|
1026
1031
|
break;
|
|
1027
1032
|
}
|
|
1028
1033
|
case 'execute-empire-payload':
|
|
@@ -1037,7 +1042,7 @@ export class SequencerPublisher {
|
|
|
1037
1042
|
}
|
|
1038
1043
|
const empireSlashingProposer = this.slashingProposerContract;
|
|
1039
1044
|
const request = empireSlashingProposer.buildExecuteRoundRequest(action.round);
|
|
1040
|
-
await this.simulateAndEnqueueRequest('execute-empire-payload', request, (receipt)=>!!empireSlashingProposer.tryExtractPayloadSubmittedEvent(receipt.logs), slotNumber
|
|
1045
|
+
await this.simulateAndEnqueueRequest('execute-empire-payload', request, (receipt)=>!!empireSlashingProposer.tryExtractPayloadSubmittedEvent(receipt.logs), slotNumber);
|
|
1041
1046
|
break;
|
|
1042
1047
|
}
|
|
1043
1048
|
case 'vote-offenses':
|
|
@@ -1055,7 +1060,7 @@ export class SequencerPublisher {
|
|
|
1055
1060
|
const tallySlashingProposer = this.slashingProposerContract;
|
|
1056
1061
|
const votes = bufferToHex(encodeSlashConsensusVotes(action.votes));
|
|
1057
1062
|
const request = await tallySlashingProposer.buildVoteRequestFromSigner(votes, slotNumber, signer);
|
|
1058
|
-
await this.simulateAndEnqueueRequest('vote-offenses', request, (receipt)=>!!tallySlashingProposer.tryExtractVoteCastEvent(receipt.logs), slotNumber
|
|
1063
|
+
await this.simulateAndEnqueueRequest('vote-offenses', request, (receipt)=>!!tallySlashingProposer.tryExtractVoteCastEvent(receipt.logs), slotNumber);
|
|
1059
1064
|
break;
|
|
1060
1065
|
}
|
|
1061
1066
|
case 'execute-slash':
|
|
@@ -1071,7 +1076,7 @@ export class SequencerPublisher {
|
|
|
1071
1076
|
}
|
|
1072
1077
|
const tallySlashingProposer = this.slashingProposerContract;
|
|
1073
1078
|
const request = tallySlashingProposer.buildExecuteRoundRequest(action.round, action.committees);
|
|
1074
|
-
await this.simulateAndEnqueueRequest('execute-slash', request, (receipt)=>!!tallySlashingProposer.tryExtractRoundExecutedEvent(receipt.logs), slotNumber
|
|
1079
|
+
await this.simulateAndEnqueueRequest('execute-slash', request, (receipt)=>!!tallySlashingProposer.tryExtractRoundExecutedEvent(receipt.logs), slotNumber);
|
|
1075
1080
|
break;
|
|
1076
1081
|
}
|
|
1077
1082
|
default:
|
|
@@ -1095,14 +1100,13 @@ export class SequencerPublisher {
|
|
|
1095
1100
|
attestationsAndSignersSignature,
|
|
1096
1101
|
feeAssetPriceModifier: checkpoint.feeAssetPriceModifier
|
|
1097
1102
|
};
|
|
1098
|
-
let ts;
|
|
1099
1103
|
try {
|
|
1100
1104
|
// @note This will make sure that we are passing the checks for our header ASSUMING that the data is also made available
|
|
1101
1105
|
// This means that we can avoid the simulation issues in later checks.
|
|
1102
1106
|
// By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which
|
|
1103
1107
|
// make time consistency checks break.
|
|
1104
1108
|
// TODO(palla): Check whether we're validating twice, once here and once within addProposeTx, since we call simulateProposeTx in both places.
|
|
1105
|
-
|
|
1109
|
+
await this.validateCheckpointForSubmission(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, opts);
|
|
1106
1110
|
} catch (err) {
|
|
1107
1111
|
this.log.error(`Checkpoint validation failed. ${err instanceof Error ? err.message : 'No error message'}`, err, {
|
|
1108
1112
|
...checkpoint.getStats(),
|
|
@@ -1115,7 +1119,7 @@ export class SequencerPublisher {
|
|
|
1115
1119
|
...checkpoint.toCheckpointInfo(),
|
|
1116
1120
|
...opts
|
|
1117
1121
|
});
|
|
1118
|
-
await this.addProposeTx(checkpoint, proposeTxArgs, opts
|
|
1122
|
+
await this.addProposeTx(checkpoint, proposeTxArgs, opts);
|
|
1119
1123
|
}
|
|
1120
1124
|
enqueueInvalidateCheckpoint(request, opts = {}) {
|
|
1121
1125
|
if (!request) {
|
|
@@ -1156,7 +1160,8 @@ export class SequencerPublisher {
|
|
|
1156
1160
|
}
|
|
1157
1161
|
});
|
|
1158
1162
|
}
|
|
1159
|
-
async simulateAndEnqueueRequest(action, request, checkSuccess, slotNumber
|
|
1163
|
+
async simulateAndEnqueueRequest(action, request, checkSuccess, slotNumber) {
|
|
1164
|
+
const timestamp = this.getSimulationTimestamp(slotNumber);
|
|
1160
1165
|
const logData = {
|
|
1161
1166
|
slotNumber,
|
|
1162
1167
|
timestamp,
|
|
@@ -1177,7 +1182,7 @@ export class SequencerPublisher {
|
|
|
1177
1182
|
try {
|
|
1178
1183
|
({ gasUsed } = await this.l1TxUtils.simulate(request, {
|
|
1179
1184
|
time: timestamp
|
|
1180
|
-
}, [], simulateAbi));
|
|
1185
|
+
}, [], simulateAbi));
|
|
1181
1186
|
this.log.verbose(`Simulation for ${action} succeeded`, {
|
|
1182
1187
|
...logData,
|
|
1183
1188
|
request,
|
|
@@ -1237,7 +1242,7 @@ export class SequencerPublisher {
|
|
|
1237
1242
|
this.interrupted = false;
|
|
1238
1243
|
this.l1TxUtils.restart();
|
|
1239
1244
|
}
|
|
1240
|
-
async prepareProposeTx(encodedData,
|
|
1245
|
+
async prepareProposeTx(encodedData, options) {
|
|
1241
1246
|
const kzg = Blob.getViemKzgInstance();
|
|
1242
1247
|
const blobInput = getPrefixedEthBlobCommitments(encodedData.blobs);
|
|
1243
1248
|
this.log.debug('Validating blob input', {
|
|
@@ -1286,7 +1291,7 @@ export class SequencerPublisher {
|
|
|
1286
1291
|
encodedData.attestationsAndSignersSignature.toViemSignature(),
|
|
1287
1292
|
blobInput
|
|
1288
1293
|
];
|
|
1289
|
-
const { rollupData, simulationResult } = await this.simulateProposeTx(args,
|
|
1294
|
+
const { rollupData, simulationResult } = await this.simulateProposeTx(args, options);
|
|
1290
1295
|
return {
|
|
1291
1296
|
args,
|
|
1292
1297
|
blobEvaluationGas,
|
|
@@ -1297,9 +1302,8 @@ export class SequencerPublisher {
|
|
|
1297
1302
|
/**
|
|
1298
1303
|
* Simulates the propose tx with eth_simulateV1
|
|
1299
1304
|
* @param args - The propose tx args
|
|
1300
|
-
* @param timestamp - The timestamp to simulate proposal at
|
|
1301
1305
|
* @returns The simulation result
|
|
1302
|
-
*/ async simulateProposeTx(args,
|
|
1306
|
+
*/ async simulateProposeTx(args, options) {
|
|
1303
1307
|
const rollupData = encodeFunctionData({
|
|
1304
1308
|
abi: RollupAbi,
|
|
1305
1309
|
functionName: 'propose',
|
|
@@ -1327,6 +1331,7 @@ export class SequencerPublisher {
|
|
|
1327
1331
|
balance: 10n * WEI_CONST * WEI_CONST
|
|
1328
1332
|
});
|
|
1329
1333
|
}
|
|
1334
|
+
const simTs = this.getSimulationTimestamp(SlotNumber.fromBigInt(args[0].header.slotNumber));
|
|
1330
1335
|
const simulationResult = await this.l1TxUtils.simulate({
|
|
1331
1336
|
to: this.rollupContract.address,
|
|
1332
1337
|
data: rollupData,
|
|
@@ -1335,8 +1340,7 @@ export class SequencerPublisher {
|
|
|
1335
1340
|
from: this.proposerAddressForSimulation.toString()
|
|
1336
1341
|
}
|
|
1337
1342
|
}, {
|
|
1338
|
-
|
|
1339
|
-
time: timestamp + 1n,
|
|
1343
|
+
time: simTs,
|
|
1340
1344
|
// @note reth should have a 30m gas limit per block but throws errors that this tx is beyond limit so we increase here
|
|
1341
1345
|
gasLimit: MAX_L1_TX_LIMIT * 2n
|
|
1342
1346
|
}, stateOverrides, RollupAbi, {
|
|
@@ -1353,7 +1357,9 @@ export class SequencerPublisher {
|
|
|
1353
1357
|
logs: []
|
|
1354
1358
|
};
|
|
1355
1359
|
}
|
|
1356
|
-
this.log.error(`Failed to simulate propose tx`, viemError
|
|
1360
|
+
this.log.error(`Failed to simulate propose tx`, viemError, {
|
|
1361
|
+
simulationTimestamp: simTs
|
|
1362
|
+
});
|
|
1357
1363
|
throw err;
|
|
1358
1364
|
});
|
|
1359
1365
|
return {
|
|
@@ -1361,11 +1367,11 @@ export class SequencerPublisher {
|
|
|
1361
1367
|
simulationResult
|
|
1362
1368
|
};
|
|
1363
1369
|
}
|
|
1364
|
-
async addProposeTx(checkpoint, encodedData, opts = {}
|
|
1370
|
+
async addProposeTx(checkpoint, encodedData, opts = {}) {
|
|
1365
1371
|
const slot = checkpoint.header.slotNumber;
|
|
1366
1372
|
const timer = new Timer();
|
|
1367
1373
|
const kzg = Blob.getViemKzgInstance();
|
|
1368
|
-
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData,
|
|
1374
|
+
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData, opts);
|
|
1369
1375
|
const startBlock = await this.l1TxUtils.getBlockNumber();
|
|
1370
1376
|
const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil(Number(simulationResult.gasUsed) * 64 / 63)) + blobEvaluationGas + SequencerPublisher.MULTICALL_OVERHEAD_GAS_GUESS);
|
|
1371
1377
|
// Send the blobs to the blob client preemptively. This helps in tests where the sequencer mistakingly thinks that the propose
|
|
@@ -1430,19 +1436,13 @@ export class SequencerPublisher {
|
|
|
1430
1436
|
}
|
|
1431
1437
|
});
|
|
1432
1438
|
}
|
|
1433
|
-
/**
|
|
1434
|
-
*
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
* still in the previous L2 slot.
|
|
1440
|
-
* TODO(palla): Properly fix by keeping dateProvider synced with anvil's chain time on every block.
|
|
1441
|
-
*/ async getNextL1SlotTimestampWithL1Floor() {
|
|
1439
|
+
/** Returns the timestamp of the last L1 slot within a given L2 slot. Used as the simulation timestamp
|
|
1440
|
+
* for eth_simulateV1 calls, since it's guaranteed to be greater than any L1 block produced during the slot. */ getSimulationTimestamp(slot) {
|
|
1441
|
+
const l1Constants = this.epochCache.getL1Constants();
|
|
1442
|
+
return getLastL1SlotTimestampForL2Slot(slot, l1Constants);
|
|
1443
|
+
}
|
|
1444
|
+
/** Returns the timestamp of the next L1 slot boundary after now. */ getNextL1SlotTimestamp() {
|
|
1442
1445
|
const l1Constants = this.epochCache.getL1Constants();
|
|
1443
|
-
|
|
1444
|
-
const latestBlock = await this.l1TxUtils.client.getBlock();
|
|
1445
|
-
const fromL1Block = latestBlock.timestamp + BigInt(l1Constants.ethereumSlotDuration);
|
|
1446
|
-
return fromWallClock > fromL1Block ? fromWallClock : fromL1Block;
|
|
1446
|
+
return getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), l1Constants);
|
|
1447
1447
|
}
|
|
1448
1448
|
}
|
|
@@ -20,7 +20,6 @@ export declare class CheckpointVoter {
|
|
|
20
20
|
private readonly config;
|
|
21
21
|
private readonly metrics;
|
|
22
22
|
private readonly log;
|
|
23
|
-
private slotTimestamp;
|
|
24
23
|
private governanceSigner;
|
|
25
24
|
private slashingSigner;
|
|
26
25
|
constructor(slot: SlotNumber, publisher: SequencerPublisher, attestorAddress: EthAddress, validatorClient: ValidatorClient, slasherClient: SlasherClientInterface | undefined, l1Constants: SequencerRollupConstants, config: ResolvedSequencerConfig, metrics: SequencerMetrics, log: Logger);
|
|
@@ -32,4 +31,4 @@ export declare class CheckpointVoter {
|
|
|
32
31
|
private enqueueGovernanceVote;
|
|
33
32
|
private enqueueSlashingVote;
|
|
34
33
|
}
|
|
35
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF92b3Rlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcXVlbmNlci9jaGVja3BvaW50X3ZvdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2hFLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3BELE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0QsT0FBTyxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMvRSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQU0vRCxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzlFLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3JELE9BQU8sS0FBSyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTNEOztHQUVHO0FBQ0gscUJBQWEsZUFBZTtJQUt4QixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUk7SUFDckIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTO0lBQzFCLE9BQU8sQ0FBQyxRQUFRLENBQUMsZUFBZTtJQUNoQyxPQUFPLENBQUMsUUFBUSxDQUFDLGVBQWU7SUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhO0lBQzlCLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVztJQUM1QixPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07SUFDdkIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPO0lBQ3hCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRztJQVp0QixPQUFPLENBQUMsZ0JBQWdCLENBQXVEO0lBQy9FLE9BQU8sQ0FBQyxjQUFjLENBQXVEO0lBRTdFLFlBQ21CLElBQUksRUFBRSxVQUFVLEVBQ2hCLFNBQVMsRUFBRSxrQkFBa0IsRUFDN0IsZUFBZSxFQUFFLFVBQVUsRUFDM0IsZUFBZSxFQUFFLGVBQWUsRUFDaEMsYUFBYSxFQUFFLHNCQUFzQixHQUFHLFNBQVMsRUFDakQsV0FBVyxFQUFFLHdCQUF3QixFQUNyQyxNQUFNLEVBQUUsdUJBQXVCLEVBQy9CLE9BQU8sRUFBRSxnQkFBZ0IsRUFDekIsR0FBRyxFQUFFLE1BQU0sRUFXN0I7SUFFRDs7O09BR0c7SUFDSCxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FVM0U7WUFFYSxxQkFBcUI7WUErQnJCLG1CQUFtQjtDQTJCbEMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint_voter.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_voter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"checkpoint_voter.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_voter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAM/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D;;GAEG;AACH,qBAAa,eAAe;IAKxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAZtB,OAAO,CAAC,gBAAgB,CAAuD;IAC/E,OAAO,CAAC,cAAc,CAAuD;IAE7E,YACmB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,kBAAkB,EAC7B,eAAe,EAAE,UAAU,EAC3B,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,sBAAsB,GAAG,SAAS,EACjD,WAAW,EAAE,wBAAwB,EACrC,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,MAAM,EAW7B;IAED;;;OAGG;IACH,YAAY,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CAU3E;YAEa,qBAAqB;YA+BrB,mBAAmB;CA2BlC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
2
1
|
import { DutyAlreadySignedError } from '@aztec/validator-ha-signer/errors';
|
|
3
2
|
import { DutyType } from '@aztec/validator-ha-signer/types';
|
|
4
3
|
/**
|
|
@@ -13,7 +12,6 @@ import { DutyType } from '@aztec/validator-ha-signer/types';
|
|
|
13
12
|
config;
|
|
14
13
|
metrics;
|
|
15
14
|
log;
|
|
16
|
-
slotTimestamp;
|
|
17
15
|
governanceSigner;
|
|
18
16
|
slashingSigner;
|
|
19
17
|
constructor(slot, publisher, attestorAddress, validatorClient, slasherClient, l1Constants, config, metrics, log){
|
|
@@ -26,7 +24,6 @@ import { DutyType } from '@aztec/validator-ha-signer/types';
|
|
|
26
24
|
this.config = config;
|
|
27
25
|
this.metrics = metrics;
|
|
28
26
|
this.log = log;
|
|
29
|
-
this.slotTimestamp = getTimestampForSlot(this.slot, this.l1Constants);
|
|
30
27
|
// Create separate signers with appropriate duty contexts for governance and slashing votes
|
|
31
28
|
// These use HA protection to ensure only one node signs per slot/duty
|
|
32
29
|
const governanceContext = {
|
|
@@ -69,7 +66,7 @@ import { DutyType } from '@aztec/validator-ha-signer/types';
|
|
|
69
66
|
governanceProposerPayload: governanceProposerPayload.toString()
|
|
70
67
|
});
|
|
71
68
|
try {
|
|
72
|
-
return await this.publisher.enqueueGovernanceCastSignal(governanceProposerPayload, this.slot, this.
|
|
69
|
+
return await this.publisher.enqueueGovernanceCastSignal(governanceProposerPayload, this.slot, this.attestorAddress, this.governanceSigner);
|
|
73
70
|
} catch (err) {
|
|
74
71
|
if (err instanceof DutyAlreadySignedError) {
|
|
75
72
|
this.log.info(`Governance vote already signed by another node`, {
|
|
@@ -93,7 +90,7 @@ import { DutyType } from '@aztec/validator-ha-signer/types';
|
|
|
93
90
|
actionCount: actions.length
|
|
94
91
|
});
|
|
95
92
|
this.metrics.recordSlashingAttempt(actions.length);
|
|
96
|
-
return await this.publisher.enqueueSlashingActions(actions, this.slot, this.
|
|
93
|
+
return await this.publisher.enqueueSlashingActions(actions, this.slot, this.attestorAddress, this.slashingSigner);
|
|
97
94
|
} catch (err) {
|
|
98
95
|
if (err instanceof DutyAlreadySignedError) {
|
|
99
96
|
this.log.info(`Slashing vote already signed by another node`, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "4.2.0-nightly.
|
|
3
|
+
"version": "4.2.0-nightly.20260331",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,38 +26,38 @@
|
|
|
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.2.0-nightly.
|
|
30
|
-
"@aztec/bb-prover": "4.2.0-nightly.
|
|
31
|
-
"@aztec/blob-client": "4.2.0-nightly.
|
|
32
|
-
"@aztec/blob-lib": "4.2.0-nightly.
|
|
33
|
-
"@aztec/constants": "4.2.0-nightly.
|
|
34
|
-
"@aztec/epoch-cache": "4.2.0-nightly.
|
|
35
|
-
"@aztec/ethereum": "4.2.0-nightly.
|
|
36
|
-
"@aztec/foundation": "4.2.0-nightly.
|
|
37
|
-
"@aztec/l1-artifacts": "4.2.0-nightly.
|
|
38
|
-
"@aztec/merkle-tree": "4.2.0-nightly.
|
|
39
|
-
"@aztec/node-keystore": "4.2.0-nightly.
|
|
40
|
-
"@aztec/noir-acvm_js": "4.2.0-nightly.
|
|
41
|
-
"@aztec/noir-contracts.js": "4.2.0-nightly.
|
|
42
|
-
"@aztec/noir-protocol-circuits-types": "4.2.0-nightly.
|
|
43
|
-
"@aztec/noir-types": "4.2.0-nightly.
|
|
44
|
-
"@aztec/p2p": "4.2.0-nightly.
|
|
45
|
-
"@aztec/protocol-contracts": "4.2.0-nightly.
|
|
46
|
-
"@aztec/prover-client": "4.2.0-nightly.
|
|
47
|
-
"@aztec/simulator": "4.2.0-nightly.
|
|
48
|
-
"@aztec/slasher": "4.2.0-nightly.
|
|
49
|
-
"@aztec/stdlib": "4.2.0-nightly.
|
|
50
|
-
"@aztec/telemetry-client": "4.2.0-nightly.
|
|
51
|
-
"@aztec/validator-client": "4.2.0-nightly.
|
|
52
|
-
"@aztec/validator-ha-signer": "4.2.0-nightly.
|
|
53
|
-
"@aztec/world-state": "4.2.0-nightly.
|
|
29
|
+
"@aztec/aztec.js": "4.2.0-nightly.20260331",
|
|
30
|
+
"@aztec/bb-prover": "4.2.0-nightly.20260331",
|
|
31
|
+
"@aztec/blob-client": "4.2.0-nightly.20260331",
|
|
32
|
+
"@aztec/blob-lib": "4.2.0-nightly.20260331",
|
|
33
|
+
"@aztec/constants": "4.2.0-nightly.20260331",
|
|
34
|
+
"@aztec/epoch-cache": "4.2.0-nightly.20260331",
|
|
35
|
+
"@aztec/ethereum": "4.2.0-nightly.20260331",
|
|
36
|
+
"@aztec/foundation": "4.2.0-nightly.20260331",
|
|
37
|
+
"@aztec/l1-artifacts": "4.2.0-nightly.20260331",
|
|
38
|
+
"@aztec/merkle-tree": "4.2.0-nightly.20260331",
|
|
39
|
+
"@aztec/node-keystore": "4.2.0-nightly.20260331",
|
|
40
|
+
"@aztec/noir-acvm_js": "4.2.0-nightly.20260331",
|
|
41
|
+
"@aztec/noir-contracts.js": "4.2.0-nightly.20260331",
|
|
42
|
+
"@aztec/noir-protocol-circuits-types": "4.2.0-nightly.20260331",
|
|
43
|
+
"@aztec/noir-types": "4.2.0-nightly.20260331",
|
|
44
|
+
"@aztec/p2p": "4.2.0-nightly.20260331",
|
|
45
|
+
"@aztec/protocol-contracts": "4.2.0-nightly.20260331",
|
|
46
|
+
"@aztec/prover-client": "4.2.0-nightly.20260331",
|
|
47
|
+
"@aztec/simulator": "4.2.0-nightly.20260331",
|
|
48
|
+
"@aztec/slasher": "4.2.0-nightly.20260331",
|
|
49
|
+
"@aztec/stdlib": "4.2.0-nightly.20260331",
|
|
50
|
+
"@aztec/telemetry-client": "4.2.0-nightly.20260331",
|
|
51
|
+
"@aztec/validator-client": "4.2.0-nightly.20260331",
|
|
52
|
+
"@aztec/validator-ha-signer": "4.2.0-nightly.20260331",
|
|
53
|
+
"@aztec/world-state": "4.2.0-nightly.20260331",
|
|
54
54
|
"lodash.chunk": "^4.2.0",
|
|
55
55
|
"tslib": "^2.4.0",
|
|
56
56
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@aztec/archiver": "4.2.0-nightly.
|
|
60
|
-
"@aztec/kv-store": "4.2.0-nightly.
|
|
59
|
+
"@aztec/archiver": "4.2.0-nightly.20260331",
|
|
60
|
+
"@aztec/kv-store": "4.2.0-nightly.20260331",
|
|
61
61
|
"@electric-sql/pglite": "^0.3.14",
|
|
62
62
|
"@jest/globals": "^30.0.0",
|
|
63
63
|
"@types/jest": "^30.0.0",
|
|
@@ -41,7 +41,7 @@ import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
|
41
41
|
import { type ProposerSlashAction, encodeSlashConsensusVotes } from '@aztec/slasher';
|
|
42
42
|
import { CommitteeAttestationsAndSigners, type ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
43
43
|
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
44
|
-
import { getNextL1SlotTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
44
|
+
import { getLastL1SlotTimestampForL2Slot, getNextL1SlotTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
45
45
|
import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
46
46
|
import type { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
47
47
|
import type { L1PublishCheckpointStats } from '@aztec/stdlib/stats';
|
|
@@ -122,6 +122,7 @@ export class SequencerPublisher {
|
|
|
122
122
|
|
|
123
123
|
protected log: Logger;
|
|
124
124
|
protected ethereumSlotDuration: bigint;
|
|
125
|
+
protected aztecSlotDuration: bigint;
|
|
125
126
|
private dateProvider: DateProvider;
|
|
126
127
|
|
|
127
128
|
private blobClient: BlobClientInterface;
|
|
@@ -153,7 +154,7 @@ export class SequencerPublisher {
|
|
|
153
154
|
|
|
154
155
|
constructor(
|
|
155
156
|
private config: Pick<SequencerPublisherConfig, 'fishermanMode'> &
|
|
156
|
-
Pick<L1ContractsConfig, 'ethereumSlotDuration'> & { l1ChainId: number },
|
|
157
|
+
Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration'> & { l1ChainId: number },
|
|
157
158
|
deps: {
|
|
158
159
|
telemetry?: TelemetryClient;
|
|
159
160
|
blobClient: BlobClientInterface;
|
|
@@ -171,6 +172,7 @@ export class SequencerPublisher {
|
|
|
171
172
|
) {
|
|
172
173
|
this.log = deps.log ?? createLogger('sequencer:publisher');
|
|
173
174
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
175
|
+
this.aztecSlotDuration = BigInt(config.aztecSlotDuration);
|
|
174
176
|
this.dateProvider = deps.dateProvider;
|
|
175
177
|
this.epochCache = deps.epochCache;
|
|
176
178
|
this.lastActions = deps.lastActions;
|
|
@@ -457,15 +459,17 @@ export class SequencerPublisher {
|
|
|
457
459
|
* @param tipArchive - The archive to check
|
|
458
460
|
* @returns The slot and block number if it is possible to propose, undefined otherwise
|
|
459
461
|
*/
|
|
460
|
-
public
|
|
462
|
+
public canProposeAt(
|
|
461
463
|
tipArchive: Fr,
|
|
462
464
|
msgSender: EthAddress,
|
|
463
|
-
opts: { forcePendingCheckpointNumber?: CheckpointNumber } = {},
|
|
465
|
+
opts: { forcePendingCheckpointNumber?: CheckpointNumber; pipelined?: boolean } = {},
|
|
464
466
|
) {
|
|
465
467
|
// TODO: #14291 - should loop through multiple keys to check if any of them can propose
|
|
466
468
|
const ignoredErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive'];
|
|
467
469
|
|
|
468
|
-
const
|
|
470
|
+
const pipelined = opts.pipelined ?? false;
|
|
471
|
+
const slotOffset = pipelined ? this.aztecSlotDuration : 0n;
|
|
472
|
+
const nextL1SlotTs = this.getNextL1SlotTimestamp() + slotOffset;
|
|
469
473
|
|
|
470
474
|
return this.rollupContract
|
|
471
475
|
.canProposeAt(tipArchive.toBuffer(), msgSender.toString(), nextL1SlotTs, {
|
|
@@ -505,7 +509,7 @@ export class SequencerPublisher {
|
|
|
505
509
|
flags,
|
|
506
510
|
] as const;
|
|
507
511
|
|
|
508
|
-
const ts =
|
|
512
|
+
const ts = this.getSimulationTimestamp(header.slotNumber);
|
|
509
513
|
const stateOverrides = await this.rollupContract.makePendingCheckpointNumberOverride(
|
|
510
514
|
opts?.forcePendingCheckpointNumber,
|
|
511
515
|
);
|
|
@@ -528,7 +532,7 @@ export class SequencerPublisher {
|
|
|
528
532
|
data: encodeFunctionData({ abi: RollupAbi, functionName: 'validateHeaderWithAttestations', args }),
|
|
529
533
|
from: MULTI_CALL_3_ADDRESS,
|
|
530
534
|
},
|
|
531
|
-
{ time: ts
|
|
535
|
+
{ time: ts },
|
|
532
536
|
stateOverrides,
|
|
533
537
|
);
|
|
534
538
|
this.log.debug(`Simulated validateHeader`);
|
|
@@ -655,8 +659,7 @@ export class SequencerPublisher {
|
|
|
655
659
|
attestationsAndSigners: CommitteeAttestationsAndSigners,
|
|
656
660
|
attestationsAndSignersSignature: Signature,
|
|
657
661
|
options: { forcePendingCheckpointNumber?: CheckpointNumber },
|
|
658
|
-
): Promise<
|
|
659
|
-
const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
|
|
662
|
+
): Promise<void> {
|
|
660
663
|
const blobFields = checkpoint.toBlobFields();
|
|
661
664
|
const blobs = await getBlobsPerL1Block(blobFields);
|
|
662
665
|
const blobInput = getPrefixedEthBlobCommitments(blobs);
|
|
@@ -675,13 +678,11 @@ export class SequencerPublisher {
|
|
|
675
678
|
blobInput,
|
|
676
679
|
] as const;
|
|
677
680
|
|
|
678
|
-
await this.simulateProposeTx(args,
|
|
679
|
-
return ts;
|
|
681
|
+
await this.simulateProposeTx(args, options);
|
|
680
682
|
}
|
|
681
683
|
|
|
682
684
|
private async enqueueCastSignalHelper(
|
|
683
685
|
slotNumber: SlotNumber,
|
|
684
|
-
timestamp: bigint,
|
|
685
686
|
signalType: GovernanceSignalAction,
|
|
686
687
|
payload: EthAddress,
|
|
687
688
|
base: IEmpireBase,
|
|
@@ -759,11 +760,16 @@ export class SequencerPublisher {
|
|
|
759
760
|
lastValidL2Slot: slotNumber,
|
|
760
761
|
});
|
|
761
762
|
|
|
763
|
+
const timestamp = this.getSimulationTimestamp(slotNumber);
|
|
764
|
+
|
|
762
765
|
try {
|
|
763
766
|
await this.l1TxUtils.simulate(request, { time: timestamp }, [], mergeAbis([request.abi ?? [], ErrorsAbi]));
|
|
764
767
|
this.log.debug(`Simulation for ${action} at slot ${slotNumber} succeeded`, { request });
|
|
765
768
|
} catch (err) {
|
|
766
|
-
|
|
769
|
+
const viemError = formatViemError(err);
|
|
770
|
+
this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError, {
|
|
771
|
+
simulationTimestamp: timestamp,
|
|
772
|
+
});
|
|
767
773
|
// Yes, we enqueue the request anyway, in case there was a bug with the simulation itself
|
|
768
774
|
}
|
|
769
775
|
|
|
@@ -814,19 +820,16 @@ export class SequencerPublisher {
|
|
|
814
820
|
/**
|
|
815
821
|
* Enqueues a governance castSignal transaction to cast a signal for a given slot number.
|
|
816
822
|
* @param slotNumber - The slot number to cast a signal for.
|
|
817
|
-
* @param timestamp - The timestamp of the slot to cast a signal for.
|
|
818
823
|
* @returns True if the signal was successfully enqueued, false otherwise.
|
|
819
824
|
*/
|
|
820
825
|
public enqueueGovernanceCastSignal(
|
|
821
826
|
governancePayload: EthAddress,
|
|
822
827
|
slotNumber: SlotNumber,
|
|
823
|
-
timestamp: bigint,
|
|
824
828
|
signerAddress: EthAddress,
|
|
825
829
|
signer: (msg: TypedDataDefinition) => Promise<`0x${string}`>,
|
|
826
830
|
): Promise<boolean> {
|
|
827
831
|
return this.enqueueCastSignalHelper(
|
|
828
832
|
slotNumber,
|
|
829
|
-
timestamp,
|
|
830
833
|
'governance-signal',
|
|
831
834
|
governancePayload,
|
|
832
835
|
this.govProposerContract,
|
|
@@ -839,7 +842,6 @@ export class SequencerPublisher {
|
|
|
839
842
|
public async enqueueSlashingActions(
|
|
840
843
|
actions: ProposerSlashAction[],
|
|
841
844
|
slotNumber: SlotNumber,
|
|
842
|
-
timestamp: bigint,
|
|
843
845
|
signerAddress: EthAddress,
|
|
844
846
|
signer: (msg: TypedDataDefinition) => Promise<`0x${string}`>,
|
|
845
847
|
): Promise<boolean> {
|
|
@@ -860,7 +862,6 @@ export class SequencerPublisher {
|
|
|
860
862
|
});
|
|
861
863
|
await this.enqueueCastSignalHelper(
|
|
862
864
|
slotNumber,
|
|
863
|
-
timestamp,
|
|
864
865
|
'empire-slashing-signal',
|
|
865
866
|
action.payload,
|
|
866
867
|
this.slashingProposerContract,
|
|
@@ -879,7 +880,6 @@ export class SequencerPublisher {
|
|
|
879
880
|
(receipt: TransactionReceipt) =>
|
|
880
881
|
!!this.slashFactoryContract.tryExtractSlashPayloadCreatedEvent(receipt.logs),
|
|
881
882
|
slotNumber,
|
|
882
|
-
timestamp,
|
|
883
883
|
);
|
|
884
884
|
break;
|
|
885
885
|
}
|
|
@@ -897,7 +897,6 @@ export class SequencerPublisher {
|
|
|
897
897
|
request,
|
|
898
898
|
(receipt: TransactionReceipt) => !!empireSlashingProposer.tryExtractPayloadSubmittedEvent(receipt.logs),
|
|
899
899
|
slotNumber,
|
|
900
|
-
timestamp,
|
|
901
900
|
);
|
|
902
901
|
break;
|
|
903
902
|
}
|
|
@@ -921,7 +920,6 @@ export class SequencerPublisher {
|
|
|
921
920
|
request,
|
|
922
921
|
(receipt: TransactionReceipt) => !!tallySlashingProposer.tryExtractVoteCastEvent(receipt.logs),
|
|
923
922
|
slotNumber,
|
|
924
|
-
timestamp,
|
|
925
923
|
);
|
|
926
924
|
break;
|
|
927
925
|
}
|
|
@@ -943,7 +941,6 @@ export class SequencerPublisher {
|
|
|
943
941
|
request,
|
|
944
942
|
(receipt: TransactionReceipt) => !!tallySlashingProposer.tryExtractRoundExecutedEvent(receipt.logs),
|
|
945
943
|
slotNumber,
|
|
946
|
-
timestamp,
|
|
947
944
|
);
|
|
948
945
|
break;
|
|
949
946
|
}
|
|
@@ -979,15 +976,13 @@ export class SequencerPublisher {
|
|
|
979
976
|
feeAssetPriceModifier: checkpoint.feeAssetPriceModifier,
|
|
980
977
|
};
|
|
981
978
|
|
|
982
|
-
let ts: bigint;
|
|
983
|
-
|
|
984
979
|
try {
|
|
985
980
|
// @note This will make sure that we are passing the checks for our header ASSUMING that the data is also made available
|
|
986
981
|
// This means that we can avoid the simulation issues in later checks.
|
|
987
982
|
// By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which
|
|
988
983
|
// make time consistency checks break.
|
|
989
984
|
// TODO(palla): Check whether we're validating twice, once here and once within addProposeTx, since we call simulateProposeTx in both places.
|
|
990
|
-
|
|
985
|
+
await this.validateCheckpointForSubmission(
|
|
991
986
|
checkpoint,
|
|
992
987
|
attestationsAndSigners,
|
|
993
988
|
attestationsAndSignersSignature,
|
|
@@ -1003,7 +998,7 @@ export class SequencerPublisher {
|
|
|
1003
998
|
}
|
|
1004
999
|
|
|
1005
1000
|
this.log.verbose(`Enqueuing checkpoint propose transaction`, { ...checkpoint.toCheckpointInfo(), ...opts });
|
|
1006
|
-
await this.addProposeTx(checkpoint, proposeTxArgs, opts
|
|
1001
|
+
await this.addProposeTx(checkpoint, proposeTxArgs, opts);
|
|
1007
1002
|
}
|
|
1008
1003
|
|
|
1009
1004
|
public enqueueInvalidateCheckpoint(
|
|
@@ -1046,8 +1041,8 @@ export class SequencerPublisher {
|
|
|
1046
1041
|
request: L1TxRequest,
|
|
1047
1042
|
checkSuccess: (receipt: TransactionReceipt) => boolean | undefined,
|
|
1048
1043
|
slotNumber: SlotNumber,
|
|
1049
|
-
timestamp: bigint,
|
|
1050
1044
|
) {
|
|
1045
|
+
const timestamp = this.getSimulationTimestamp(slotNumber);
|
|
1051
1046
|
const logData = { slotNumber, timestamp, gasLimit: undefined as bigint | undefined };
|
|
1052
1047
|
if (this.lastActions[action] && this.lastActions[action] === slotNumber) {
|
|
1053
1048
|
this.log.debug(`Skipping duplicate action ${action} for slot ${slotNumber}`);
|
|
@@ -1061,8 +1056,9 @@ export class SequencerPublisher {
|
|
|
1061
1056
|
|
|
1062
1057
|
let gasUsed: bigint;
|
|
1063
1058
|
const simulateAbi = mergeAbis([request.abi ?? [], ErrorsAbi]);
|
|
1059
|
+
|
|
1064
1060
|
try {
|
|
1065
|
-
({ gasUsed } = await this.l1TxUtils.simulate(request, { time: timestamp }, [], simulateAbi));
|
|
1061
|
+
({ gasUsed } = await this.l1TxUtils.simulate(request, { time: timestamp }, [], simulateAbi));
|
|
1066
1062
|
this.log.verbose(`Simulation for ${action} succeeded`, { ...logData, request, gasUsed });
|
|
1067
1063
|
} catch (err) {
|
|
1068
1064
|
const viemError = formatViemError(err, simulateAbi);
|
|
@@ -1118,7 +1114,6 @@ export class SequencerPublisher {
|
|
|
1118
1114
|
|
|
1119
1115
|
private async prepareProposeTx(
|
|
1120
1116
|
encodedData: L1ProcessArgs,
|
|
1121
|
-
timestamp: bigint,
|
|
1122
1117
|
options: { forcePendingCheckpointNumber?: CheckpointNumber },
|
|
1123
1118
|
) {
|
|
1124
1119
|
const kzg = Blob.getViemKzgInstance();
|
|
@@ -1173,7 +1168,7 @@ export class SequencerPublisher {
|
|
|
1173
1168
|
blobInput,
|
|
1174
1169
|
] as const;
|
|
1175
1170
|
|
|
1176
|
-
const { rollupData, simulationResult } = await this.simulateProposeTx(args,
|
|
1171
|
+
const { rollupData, simulationResult } = await this.simulateProposeTx(args, options);
|
|
1177
1172
|
|
|
1178
1173
|
return { args, blobEvaluationGas, rollupData, simulationResult };
|
|
1179
1174
|
}
|
|
@@ -1181,7 +1176,6 @@ export class SequencerPublisher {
|
|
|
1181
1176
|
/**
|
|
1182
1177
|
* Simulates the propose tx with eth_simulateV1
|
|
1183
1178
|
* @param args - The propose tx args
|
|
1184
|
-
* @param timestamp - The timestamp to simulate proposal at
|
|
1185
1179
|
* @returns The simulation result
|
|
1186
1180
|
*/
|
|
1187
1181
|
private async simulateProposeTx(
|
|
@@ -1198,7 +1192,6 @@ export class SequencerPublisher {
|
|
|
1198
1192
|
ViemSignature,
|
|
1199
1193
|
`0x${string}`,
|
|
1200
1194
|
],
|
|
1201
|
-
timestamp: bigint,
|
|
1202
1195
|
options: { forcePendingCheckpointNumber?: CheckpointNumber },
|
|
1203
1196
|
) {
|
|
1204
1197
|
const rollupData = encodeFunctionData({
|
|
@@ -1232,6 +1225,8 @@ export class SequencerPublisher {
|
|
|
1232
1225
|
});
|
|
1233
1226
|
}
|
|
1234
1227
|
|
|
1228
|
+
const simTs = this.getSimulationTimestamp(SlotNumber.fromBigInt(args[0].header.slotNumber));
|
|
1229
|
+
|
|
1235
1230
|
const simulationResult = await this.l1TxUtils
|
|
1236
1231
|
.simulate(
|
|
1237
1232
|
{
|
|
@@ -1241,8 +1236,7 @@ export class SequencerPublisher {
|
|
|
1241
1236
|
...(this.proposerAddressForSimulation && { from: this.proposerAddressForSimulation.toString() }),
|
|
1242
1237
|
},
|
|
1243
1238
|
{
|
|
1244
|
-
|
|
1245
|
-
time: timestamp + 1n,
|
|
1239
|
+
time: simTs,
|
|
1246
1240
|
// @note reth should have a 30m gas limit per block but throws errors that this tx is beyond limit so we increase here
|
|
1247
1241
|
gasLimit: MAX_L1_TX_LIMIT * 2n,
|
|
1248
1242
|
},
|
|
@@ -1264,7 +1258,7 @@ export class SequencerPublisher {
|
|
|
1264
1258
|
logs: [],
|
|
1265
1259
|
};
|
|
1266
1260
|
}
|
|
1267
|
-
this.log.error(`Failed to simulate propose tx`, viemError);
|
|
1261
|
+
this.log.error(`Failed to simulate propose tx`, viemError, { simulationTimestamp: simTs });
|
|
1268
1262
|
throw err;
|
|
1269
1263
|
});
|
|
1270
1264
|
|
|
@@ -1275,16 +1269,11 @@ export class SequencerPublisher {
|
|
|
1275
1269
|
checkpoint: Checkpoint,
|
|
1276
1270
|
encodedData: L1ProcessArgs,
|
|
1277
1271
|
opts: { txTimeoutAt?: Date; forcePendingCheckpointNumber?: CheckpointNumber } = {},
|
|
1278
|
-
timestamp: bigint,
|
|
1279
1272
|
): Promise<void> {
|
|
1280
1273
|
const slot = checkpoint.header.slotNumber;
|
|
1281
1274
|
const timer = new Timer();
|
|
1282
1275
|
const kzg = Blob.getViemKzgInstance();
|
|
1283
|
-
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(
|
|
1284
|
-
encodedData,
|
|
1285
|
-
timestamp,
|
|
1286
|
-
opts,
|
|
1287
|
-
);
|
|
1276
|
+
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData, opts);
|
|
1288
1277
|
const startBlock = await this.l1TxUtils.getBlockNumber();
|
|
1289
1278
|
const gasLimit = this.l1TxUtils.bumpGasLimit(
|
|
1290
1279
|
BigInt(Math.ceil((Number(simulationResult.gasUsed) * 64) / 63)) +
|
|
@@ -1361,20 +1350,16 @@ export class SequencerPublisher {
|
|
|
1361
1350
|
});
|
|
1362
1351
|
}
|
|
1363
1352
|
|
|
1364
|
-
/**
|
|
1365
|
-
*
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
private async getNextL1SlotTimestampWithL1Floor(): Promise<bigint> {
|
|
1353
|
+
/** Returns the timestamp of the last L1 slot within a given L2 slot. Used as the simulation timestamp
|
|
1354
|
+
* for eth_simulateV1 calls, since it's guaranteed to be greater than any L1 block produced during the slot. */
|
|
1355
|
+
private getSimulationTimestamp(slot: SlotNumber): bigint {
|
|
1356
|
+
const l1Constants = this.epochCache.getL1Constants();
|
|
1357
|
+
return getLastL1SlotTimestampForL2Slot(slot, l1Constants);
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
/** Returns the timestamp of the next L1 slot boundary after now. */
|
|
1361
|
+
private getNextL1SlotTimestamp(): bigint {
|
|
1374
1362
|
const l1Constants = this.epochCache.getL1Constants();
|
|
1375
|
-
|
|
1376
|
-
const latestBlock = await this.l1TxUtils.client.getBlock();
|
|
1377
|
-
const fromL1Block = latestBlock.timestamp + BigInt(l1Constants.ethereumSlotDuration);
|
|
1378
|
-
return fromWallClock > fromL1Block ? fromWallClock : fromL1Block;
|
|
1363
|
+
return getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), l1Constants);
|
|
1379
1364
|
}
|
|
1380
1365
|
}
|
|
@@ -2,7 +2,6 @@ import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
2
2
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
4
4
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
5
|
-
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
6
5
|
import type { ResolvedSequencerConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
6
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
8
7
|
import { DutyAlreadySignedError } from '@aztec/validator-ha-signer/errors';
|
|
@@ -18,7 +17,6 @@ import type { SequencerRollupConstants } from './types.js';
|
|
|
18
17
|
* Handles governance and slashing voting for a given slot.
|
|
19
18
|
*/
|
|
20
19
|
export class CheckpointVoter {
|
|
21
|
-
private slotTimestamp: bigint;
|
|
22
20
|
private governanceSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
23
21
|
private slashingSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
24
22
|
|
|
@@ -33,8 +31,6 @@ export class CheckpointVoter {
|
|
|
33
31
|
private readonly metrics: SequencerMetrics,
|
|
34
32
|
private readonly log: Logger,
|
|
35
33
|
) {
|
|
36
|
-
this.slotTimestamp = getTimestampForSlot(this.slot, this.l1Constants);
|
|
37
|
-
|
|
38
34
|
// Create separate signers with appropriate duty contexts for governance and slashing votes
|
|
39
35
|
// These use HA protection to ensure only one node signs per slot/duty
|
|
40
36
|
const governanceContext: SigningContext = { slot: this.slot, dutyType: DutyType.GOVERNANCE_VOTE };
|
|
@@ -77,7 +73,6 @@ export class CheckpointVoter {
|
|
|
77
73
|
return await this.publisher.enqueueGovernanceCastSignal(
|
|
78
74
|
governanceProposerPayload,
|
|
79
75
|
this.slot,
|
|
80
|
-
this.slotTimestamp,
|
|
81
76
|
this.attestorAddress,
|
|
82
77
|
this.governanceSigner,
|
|
83
78
|
);
|
|
@@ -108,13 +103,7 @@ export class CheckpointVoter {
|
|
|
108
103
|
|
|
109
104
|
this.metrics.recordSlashingAttempt(actions.length);
|
|
110
105
|
|
|
111
|
-
return await this.publisher.enqueueSlashingActions(
|
|
112
|
-
actions,
|
|
113
|
-
this.slot,
|
|
114
|
-
this.slotTimestamp,
|
|
115
|
-
this.attestorAddress,
|
|
116
|
-
this.slashingSigner,
|
|
117
|
-
);
|
|
106
|
+
return await this.publisher.enqueueSlashingActions(actions, this.slot, this.attestorAddress, this.slashingSigner);
|
|
118
107
|
} catch (err) {
|
|
119
108
|
if (err instanceof DutyAlreadySignedError) {
|
|
120
109
|
this.log.info(`Slashing vote already signed by another node`, {
|