@aztec/sequencer-client 0.0.1-commit.1bb068fb5 → 0.0.1-commit.1de2a32
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 +23 -7
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +99 -16
- package/dest/config.d.ts +24 -5
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +36 -20
- package/dest/global_variable_builder/global_builder.d.ts +2 -4
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/publisher/config.d.ts +35 -17
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +106 -42
- package/dest/publisher/index.d.ts +2 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
- package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +59 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/index.js +2 -0
- package/dest/publisher/sequencer-publisher-factory.d.ts +11 -3
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +27 -2
- package/dest/publisher/sequencer-publisher.d.ts +19 -7
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +285 -25
- package/dest/sequencer/checkpoint_proposal_job.d.ts +2 -4
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +94 -43
- package/dest/sequencer/metrics.d.ts +14 -5
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +61 -15
- package/dest/sequencer/sequencer.d.ts +23 -12
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +24 -26
- package/dest/sequencer/timetable.d.ts +4 -3
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +6 -7
- package/dest/sequencer/types.d.ts +5 -2
- package/dest/sequencer/types.d.ts.map +1 -1
- package/dest/test/index.d.ts +3 -5
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +4 -6
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.js +39 -30
- package/package.json +28 -28
- package/src/client/sequencer-client.ts +135 -18
- package/src/config.ts +45 -27
- package/src/global_variable_builder/global_builder.ts +1 -1
- package/src/publisher/config.ts +121 -43
- package/src/publisher/index.ts +3 -0
- package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
- package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +55 -0
- package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
- package/src/publisher/l1_tx_failed_store/index.ts +3 -0
- package/src/publisher/sequencer-publisher-factory.ts +38 -6
- package/src/publisher/sequencer-publisher.ts +273 -38
- package/src/sequencer/checkpoint_proposal_job.ts +129 -51
- package/src/sequencer/metrics.ts +68 -18
- package/src/sequencer/sequencer.ts +32 -31
- package/src/sequencer/timetable.ts +7 -7
- package/src/sequencer/types.ts +4 -1
- package/src/test/index.ts +2 -4
- package/src/test/mock_checkpoint_builder.ts +48 -45
|
@@ -380,16 +380,19 @@ import { sumBigint } from '@aztec/foundation/bigint';
|
|
|
380
380
|
import { toHex as toPaddedHex } from '@aztec/foundation/bigint-buffer';
|
|
381
381
|
import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
382
382
|
import { pick } from '@aztec/foundation/collection';
|
|
383
|
+
import { TimeoutError } from '@aztec/foundation/error';
|
|
383
384
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
384
385
|
import { Signature } from '@aztec/foundation/eth-signature';
|
|
385
386
|
import { createLogger } from '@aztec/foundation/log';
|
|
387
|
+
import { makeBackoff, retry } from '@aztec/foundation/retry';
|
|
386
388
|
import { bufferToHex } from '@aztec/foundation/string';
|
|
387
389
|
import { Timer } from '@aztec/foundation/timer';
|
|
388
390
|
import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
389
391
|
import { encodeSlashConsensusVotes } from '@aztec/slasher';
|
|
390
392
|
import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
391
393
|
import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
392
|
-
import { encodeFunctionData, toHex } from 'viem';
|
|
394
|
+
import { encodeFunctionData, keccak256, multicall3Abi, toHex } from 'viem';
|
|
395
|
+
import { createL1TxFailedStore } from './l1_tx_failed_store/index.js';
|
|
393
396
|
import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
|
|
394
397
|
export const Actions = [
|
|
395
398
|
'invalidate-by-invalid-attestation',
|
|
@@ -429,14 +432,17 @@ export class SequencerPublisher {
|
|
|
429
432
|
interrupted;
|
|
430
433
|
metrics;
|
|
431
434
|
epochCache;
|
|
435
|
+
failedTxStore;
|
|
432
436
|
governanceLog;
|
|
433
437
|
slashingLog;
|
|
434
438
|
lastActions;
|
|
435
439
|
isPayloadEmptyCache;
|
|
440
|
+
payloadProposedCache;
|
|
436
441
|
log;
|
|
437
442
|
ethereumSlotDuration;
|
|
438
443
|
blobClient;
|
|
439
444
|
/** Address to use for simulations in fisherman mode (actual proposer's address) */ proposerAddressForSimulation;
|
|
445
|
+
/** Optional callback to obtain a replacement publisher when the current one fails to send. */ getNextPublisher;
|
|
440
446
|
/** L1 fee analyzer for fisherman mode */ l1FeeAnalyzer;
|
|
441
447
|
/** Fee asset price oracle for computing price modifiers from Uniswap V4 */ feeAssetPriceOracle;
|
|
442
448
|
// A CALL to a cold address is 2700 gas
|
|
@@ -457,6 +463,7 @@ export class SequencerPublisher {
|
|
|
457
463
|
this.slashingLog = createLogger('sequencer:publisher:slashing');
|
|
458
464
|
this.lastActions = {};
|
|
459
465
|
this.isPayloadEmptyCache = new Map();
|
|
466
|
+
this.payloadProposedCache = new Set();
|
|
460
467
|
this.requests = [];
|
|
461
468
|
this.log = deps.log ?? createLogger('sequencer:publisher');
|
|
462
469
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
@@ -467,6 +474,7 @@ export class SequencerPublisher {
|
|
|
467
474
|
this.metrics = deps.metrics ?? new SequencerPublisherMetrics(telemetry, 'SequencerPublisher');
|
|
468
475
|
this.tracer = telemetry.getTracer('SequencerPublisher');
|
|
469
476
|
this.l1TxUtils = deps.l1TxUtils;
|
|
477
|
+
this.getNextPublisher = deps.getNextPublisher;
|
|
470
478
|
this.rollupContract = deps.rollupContract;
|
|
471
479
|
this.govProposerContract = deps.governanceProposerContract;
|
|
472
480
|
this.slashingProposerContract = deps.slashingProposerContract;
|
|
@@ -482,6 +490,24 @@ export class SequencerPublisher {
|
|
|
482
490
|
}
|
|
483
491
|
// Initialize fee asset price oracle
|
|
484
492
|
this.feeAssetPriceOracle = new FeeAssetPriceOracle(this.l1TxUtils.client, this.rollupContract, createLogger('sequencer:publisher:price-oracle'));
|
|
493
|
+
// Initialize failed L1 tx store (optional, for test networks)
|
|
494
|
+
this.failedTxStore = createL1TxFailedStore(config.l1TxFailedStore, this.log);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Backs up a failed L1 transaction to the configured store for debugging.
|
|
498
|
+
* Does nothing if no store is configured.
|
|
499
|
+
*/ backupFailedTx(failedTx) {
|
|
500
|
+
if (!this.failedTxStore) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
const tx = {
|
|
504
|
+
...failedTx,
|
|
505
|
+
timestamp: Date.now()
|
|
506
|
+
};
|
|
507
|
+
// Fire and forget - don't block on backup
|
|
508
|
+
void this.failedTxStore.then((store)=>store?.saveFailedTx(tx)).catch((err)=>{
|
|
509
|
+
this.log.warn(`Failed to backup failed L1 tx to store`, err);
|
|
510
|
+
});
|
|
485
511
|
}
|
|
486
512
|
getRollupContract() {
|
|
487
513
|
return this.rollupContract;
|
|
@@ -627,12 +653,34 @@ export class SequencerPublisher {
|
|
|
627
653
|
// This ensures the committee gets precomputed correctly
|
|
628
654
|
validRequests.sort((a, b)=>compareActions(a.action, b.action));
|
|
629
655
|
try {
|
|
656
|
+
// Capture context for failed tx backup before sending
|
|
657
|
+
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
658
|
+
const multicallData = encodeFunctionData({
|
|
659
|
+
abi: multicall3Abi,
|
|
660
|
+
functionName: 'aggregate3',
|
|
661
|
+
args: [
|
|
662
|
+
validRequests.map((r)=>({
|
|
663
|
+
target: r.request.to,
|
|
664
|
+
callData: r.request.data,
|
|
665
|
+
allowFailure: true
|
|
666
|
+
}))
|
|
667
|
+
]
|
|
668
|
+
});
|
|
669
|
+
const blobDataHex = blobConfig?.blobs?.map((b)=>toHex(b));
|
|
670
|
+
const txContext = {
|
|
671
|
+
multicallData,
|
|
672
|
+
blobData: blobDataHex,
|
|
673
|
+
l1BlockNumber
|
|
674
|
+
};
|
|
630
675
|
this.log.debug('Forwarding transactions', {
|
|
631
676
|
validRequests: validRequests.map((request)=>request.action),
|
|
632
677
|
txConfig
|
|
633
678
|
});
|
|
634
|
-
const result = await
|
|
635
|
-
|
|
679
|
+
const result = await this.forwardWithPublisherRotation(validRequests, txConfig, blobConfig);
|
|
680
|
+
if (result === undefined) {
|
|
681
|
+
return undefined;
|
|
682
|
+
}
|
|
683
|
+
const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(validRequests, result, txContext);
|
|
636
684
|
return {
|
|
637
685
|
result,
|
|
638
686
|
expiredActions,
|
|
@@ -652,10 +700,67 @@ export class SequencerPublisher {
|
|
|
652
700
|
}
|
|
653
701
|
}
|
|
654
702
|
}
|
|
655
|
-
|
|
703
|
+
/**
|
|
704
|
+
* Forwards transactions via Multicall3, rotating to the next available publisher if a send
|
|
705
|
+
* failure occurs (i.e. the tx never reached the chain).
|
|
706
|
+
* On-chain reverts and simulation errors are returned as-is without rotation.
|
|
707
|
+
*/ async forwardWithPublisherRotation(validRequests, txConfig, blobConfig) {
|
|
708
|
+
const triedAddresses = [];
|
|
709
|
+
let currentPublisher = this.l1TxUtils;
|
|
710
|
+
while(true){
|
|
711
|
+
triedAddresses.push(currentPublisher.getSenderAddress());
|
|
712
|
+
try {
|
|
713
|
+
const result = await Multicall3.forward(validRequests.map((r)=>r.request), currentPublisher, txConfig, blobConfig, this.rollupContract.address, this.log);
|
|
714
|
+
this.l1TxUtils = currentPublisher;
|
|
715
|
+
return result;
|
|
716
|
+
} catch (err) {
|
|
717
|
+
if (err instanceof TimeoutError) {
|
|
718
|
+
throw err;
|
|
719
|
+
}
|
|
720
|
+
const viemError = formatViemError(err);
|
|
721
|
+
if (!this.getNextPublisher) {
|
|
722
|
+
this.log.error('Failed to publish bundled transactions', viemError);
|
|
723
|
+
return undefined;
|
|
724
|
+
}
|
|
725
|
+
this.log.warn(`Publisher ${currentPublisher.getSenderAddress()} failed to send, rotating to next publisher`, viemError);
|
|
726
|
+
const nextPublisher = await this.getNextPublisher([
|
|
727
|
+
...triedAddresses
|
|
728
|
+
]);
|
|
729
|
+
if (!nextPublisher) {
|
|
730
|
+
this.log.error('All available publishers exhausted, failed to publish bundled transactions');
|
|
731
|
+
return undefined;
|
|
732
|
+
}
|
|
733
|
+
currentPublisher = nextPublisher;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
callbackBundledTransactions(requests, result, txContext) {
|
|
656
738
|
const actionsListStr = requests.map((r)=>r.action).join(', ');
|
|
657
739
|
if (result instanceof FormattedViemError) {
|
|
658
740
|
this.log.error(`Failed to publish bundled transactions (${actionsListStr})`, result);
|
|
741
|
+
this.backupFailedTx({
|
|
742
|
+
id: keccak256(txContext.multicallData),
|
|
743
|
+
failureType: 'send-error',
|
|
744
|
+
request: {
|
|
745
|
+
to: MULTI_CALL_3_ADDRESS,
|
|
746
|
+
data: txContext.multicallData
|
|
747
|
+
},
|
|
748
|
+
blobData: txContext.blobData,
|
|
749
|
+
l1BlockNumber: txContext.l1BlockNumber.toString(),
|
|
750
|
+
error: {
|
|
751
|
+
message: result.message,
|
|
752
|
+
name: result.name
|
|
753
|
+
},
|
|
754
|
+
context: {
|
|
755
|
+
actions: requests.map((r)=>r.action),
|
|
756
|
+
requests: requests.map((r)=>({
|
|
757
|
+
action: r.action,
|
|
758
|
+
to: r.request.to,
|
|
759
|
+
data: r.request.data
|
|
760
|
+
})),
|
|
761
|
+
sender: this.getSenderAddress().toString()
|
|
762
|
+
}
|
|
763
|
+
});
|
|
659
764
|
return {
|
|
660
765
|
failedActions: requests.map((r)=>r.action)
|
|
661
766
|
};
|
|
@@ -673,6 +778,37 @@ export class SequencerPublisher {
|
|
|
673
778
|
failedActions.push(request.action);
|
|
674
779
|
}
|
|
675
780
|
}
|
|
781
|
+
// Single backup for the whole reverted tx
|
|
782
|
+
if (failedActions.length > 0 && result?.receipt?.status === 'reverted') {
|
|
783
|
+
this.backupFailedTx({
|
|
784
|
+
id: result.receipt.transactionHash,
|
|
785
|
+
failureType: 'revert',
|
|
786
|
+
request: {
|
|
787
|
+
to: MULTI_CALL_3_ADDRESS,
|
|
788
|
+
data: txContext.multicallData
|
|
789
|
+
},
|
|
790
|
+
blobData: txContext.blobData,
|
|
791
|
+
l1BlockNumber: result.receipt.blockNumber.toString(),
|
|
792
|
+
receipt: {
|
|
793
|
+
transactionHash: result.receipt.transactionHash,
|
|
794
|
+
blockNumber: result.receipt.blockNumber.toString(),
|
|
795
|
+
gasUsed: (result.receipt.gasUsed ?? 0n).toString(),
|
|
796
|
+
status: 'reverted'
|
|
797
|
+
},
|
|
798
|
+
error: {
|
|
799
|
+
message: result.errorMsg ?? 'Transaction reverted'
|
|
800
|
+
},
|
|
801
|
+
context: {
|
|
802
|
+
actions: failedActions,
|
|
803
|
+
requests: requests.filter((r)=>failedActions.includes(r.action)).map((r)=>({
|
|
804
|
+
action: r.action,
|
|
805
|
+
to: r.request.to,
|
|
806
|
+
data: r.request.data
|
|
807
|
+
})),
|
|
808
|
+
sender: this.getSenderAddress().toString()
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
}
|
|
676
812
|
return {
|
|
677
813
|
successfulActions,
|
|
678
814
|
failedActions
|
|
@@ -775,6 +911,7 @@ export class SequencerPublisher {
|
|
|
775
911
|
...logData,
|
|
776
912
|
request
|
|
777
913
|
});
|
|
914
|
+
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
778
915
|
try {
|
|
779
916
|
const { gasUsed } = await this.l1TxUtils.simulate(request, undefined, undefined, mergeAbis([
|
|
780
917
|
request.abi ?? [],
|
|
@@ -817,6 +954,27 @@ export class SequencerPublisher {
|
|
|
817
954
|
}
|
|
818
955
|
// Otherwise, throw. We cannot build the next checkpoint if we cannot invalidate the previous one.
|
|
819
956
|
this.log.error(`Simulation for invalidate checkpoint ${checkpointNumber} failed`, viemError, logData);
|
|
957
|
+
this.backupFailedTx({
|
|
958
|
+
id: keccak256(request.data),
|
|
959
|
+
failureType: 'simulation',
|
|
960
|
+
request: {
|
|
961
|
+
to: request.to,
|
|
962
|
+
data: request.data,
|
|
963
|
+
value: request.value?.toString()
|
|
964
|
+
},
|
|
965
|
+
l1BlockNumber: l1BlockNumber.toString(),
|
|
966
|
+
error: {
|
|
967
|
+
message: viemError.message,
|
|
968
|
+
name: viemError.name
|
|
969
|
+
},
|
|
970
|
+
context: {
|
|
971
|
+
actions: [
|
|
972
|
+
`invalidate-${reason}`
|
|
973
|
+
],
|
|
974
|
+
checkpointNumber,
|
|
975
|
+
sender: this.getSenderAddress().toString()
|
|
976
|
+
}
|
|
977
|
+
});
|
|
820
978
|
throw new Error(`Failed to simulate invalidate checkpoint ${checkpointNumber}`, {
|
|
821
979
|
cause: viemError
|
|
822
980
|
});
|
|
@@ -844,22 +1002,8 @@ export class SequencerPublisher {
|
|
|
844
1002
|
}
|
|
845
1003
|
/** Simulates `propose` to make sure that the checkpoint is valid for submission */ async validateCheckpointForSubmission(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, options) {
|
|
846
1004
|
const ts = BigInt((await this.l1TxUtils.getBlock()).timestamp + this.ethereumSlotDuration);
|
|
847
|
-
// TODO(palla/mbps): This should not be needed, there's no flow where we propose with zero attestations. Or is there?
|
|
848
|
-
// If we have no attestations, we still need to provide the empty attestations
|
|
849
|
-
// so that the committee is recalculated correctly
|
|
850
|
-
// const ignoreSignatures = attestationsAndSigners.attestations.length === 0;
|
|
851
|
-
// if (ignoreSignatures) {
|
|
852
|
-
// const { committee } = await this.epochCache.getCommittee(block.header.globalVariables.slotNumber);
|
|
853
|
-
// if (!committee) {
|
|
854
|
-
// this.log.warn(`No committee found for slot ${block.header.globalVariables.slotNumber}`);
|
|
855
|
-
// throw new Error(`No committee found for slot ${block.header.globalVariables.slotNumber}`);
|
|
856
|
-
// }
|
|
857
|
-
// attestationsAndSigners.attestations = committee.map(committeeMember =>
|
|
858
|
-
// CommitteeAttestation.fromAddress(committeeMember),
|
|
859
|
-
// );
|
|
860
|
-
// }
|
|
861
1005
|
const blobFields = checkpoint.toBlobFields();
|
|
862
|
-
const blobs = getBlobsPerL1Block(blobFields);
|
|
1006
|
+
const blobs = await getBlobsPerL1Block(blobFields);
|
|
863
1007
|
const blobInput = getPrefixedEthBlobCommitments(blobs);
|
|
864
1008
|
const args = [
|
|
865
1009
|
{
|
|
@@ -901,6 +1045,28 @@ export class SequencerPublisher {
|
|
|
901
1045
|
this.log.warn(`Skipping vote cast for payload with empty code`);
|
|
902
1046
|
return false;
|
|
903
1047
|
}
|
|
1048
|
+
// Check if payload was already submitted to governance
|
|
1049
|
+
const cacheKey = payload.toString();
|
|
1050
|
+
if (!this.payloadProposedCache.has(cacheKey)) {
|
|
1051
|
+
try {
|
|
1052
|
+
const l1StartBlock = await this.rollupContract.getL1StartBlock();
|
|
1053
|
+
const proposed = await retry(()=>base.hasPayloadBeenProposed(payload.toString(), l1StartBlock), 'Check if payload was proposed', makeBackoff([
|
|
1054
|
+
0,
|
|
1055
|
+
1,
|
|
1056
|
+
2
|
|
1057
|
+
]), this.log, true);
|
|
1058
|
+
if (proposed) {
|
|
1059
|
+
this.payloadProposedCache.add(cacheKey);
|
|
1060
|
+
}
|
|
1061
|
+
} catch (err) {
|
|
1062
|
+
this.log.warn(`Failed to check if payload ${payload} was proposed after retries, skipping signal`, err);
|
|
1063
|
+
return false;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
if (this.payloadProposedCache.has(cacheKey)) {
|
|
1067
|
+
this.log.info(`Payload ${payload} was already proposed to governance, stopping signals`);
|
|
1068
|
+
return false;
|
|
1069
|
+
}
|
|
904
1070
|
const cachedLastVote = this.lastActions[signalType];
|
|
905
1071
|
this.lastActions[signalType] = slotNumber;
|
|
906
1072
|
const action = signalType;
|
|
@@ -911,6 +1077,7 @@ export class SequencerPublisher {
|
|
|
911
1077
|
signer: this.l1TxUtils.client.account?.address,
|
|
912
1078
|
lastValidL2Slot: slotNumber
|
|
913
1079
|
});
|
|
1080
|
+
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
914
1081
|
try {
|
|
915
1082
|
await this.l1TxUtils.simulate(request, {
|
|
916
1083
|
time: timestamp
|
|
@@ -922,7 +1089,29 @@ export class SequencerPublisher {
|
|
|
922
1089
|
request
|
|
923
1090
|
});
|
|
924
1091
|
} catch (err) {
|
|
925
|
-
|
|
1092
|
+
const viemError = formatViemError(err);
|
|
1093
|
+
this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError);
|
|
1094
|
+
this.backupFailedTx({
|
|
1095
|
+
id: keccak256(request.data),
|
|
1096
|
+
failureType: 'simulation',
|
|
1097
|
+
request: {
|
|
1098
|
+
to: request.to,
|
|
1099
|
+
data: request.data,
|
|
1100
|
+
value: request.value?.toString()
|
|
1101
|
+
},
|
|
1102
|
+
l1BlockNumber: l1BlockNumber.toString(),
|
|
1103
|
+
error: {
|
|
1104
|
+
message: viemError.message,
|
|
1105
|
+
name: viemError.name
|
|
1106
|
+
},
|
|
1107
|
+
context: {
|
|
1108
|
+
actions: [
|
|
1109
|
+
action
|
|
1110
|
+
],
|
|
1111
|
+
slot: slotNumber,
|
|
1112
|
+
sender: this.getSenderAddress().toString()
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
926
1115
|
// Yes, we enqueue the request anyway, in case there was a bug with the simulation itself
|
|
927
1116
|
}
|
|
928
1117
|
// TODO(palla/slash): All votes (governance and slashing) should txTimeoutAt at the end of the slot.
|
|
@@ -1061,7 +1250,7 @@ export class SequencerPublisher {
|
|
|
1061
1250
|
/** Simulates and enqueues a proposal for a checkpoint on L1 */ async enqueueProposeCheckpoint(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, opts = {}) {
|
|
1062
1251
|
const checkpointHeader = checkpoint.header;
|
|
1063
1252
|
const blobFields = checkpoint.toBlobFields();
|
|
1064
|
-
const blobs = getBlobsPerL1Block(blobFields);
|
|
1253
|
+
const blobs = await getBlobsPerL1Block(blobFields);
|
|
1065
1254
|
const proposeTxArgs = {
|
|
1066
1255
|
header: checkpointHeader,
|
|
1067
1256
|
archive: checkpoint.archive.root.toBuffer(),
|
|
@@ -1144,6 +1333,7 @@ export class SequencerPublisher {
|
|
|
1144
1333
|
const cachedLastActionSlot = this.lastActions[action];
|
|
1145
1334
|
this.lastActions[action] = slotNumber;
|
|
1146
1335
|
this.log.debug(`Simulating ${action} for slot ${slotNumber}`, logData);
|
|
1336
|
+
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
1147
1337
|
let gasUsed;
|
|
1148
1338
|
const simulateAbi = mergeAbis([
|
|
1149
1339
|
request.abi ?? [],
|
|
@@ -1161,6 +1351,27 @@ export class SequencerPublisher {
|
|
|
1161
1351
|
} catch (err) {
|
|
1162
1352
|
const viemError = formatViemError(err, simulateAbi);
|
|
1163
1353
|
this.log.error(`Simulation for ${action} at ${slotNumber} failed`, viemError, logData);
|
|
1354
|
+
this.backupFailedTx({
|
|
1355
|
+
id: keccak256(request.data),
|
|
1356
|
+
failureType: 'simulation',
|
|
1357
|
+
request: {
|
|
1358
|
+
to: request.to,
|
|
1359
|
+
data: request.data,
|
|
1360
|
+
value: request.value?.toString()
|
|
1361
|
+
},
|
|
1362
|
+
l1BlockNumber: l1BlockNumber.toString(),
|
|
1363
|
+
error: {
|
|
1364
|
+
message: viemError.message,
|
|
1365
|
+
name: viemError.name
|
|
1366
|
+
},
|
|
1367
|
+
context: {
|
|
1368
|
+
actions: [
|
|
1369
|
+
action
|
|
1370
|
+
],
|
|
1371
|
+
slot: slotNumber,
|
|
1372
|
+
sender: this.getSenderAddress().toString()
|
|
1373
|
+
}
|
|
1374
|
+
});
|
|
1164
1375
|
return false;
|
|
1165
1376
|
}
|
|
1166
1377
|
// We issued the simulation against the rollup contract, so we need to account for the overhead of the multicall3
|
|
@@ -1239,10 +1450,38 @@ export class SequencerPublisher {
|
|
|
1239
1450
|
}, {}, {
|
|
1240
1451
|
blobs: encodedData.blobs.map((b)=>b.data),
|
|
1241
1452
|
kzg
|
|
1242
|
-
}).catch((err)=>{
|
|
1243
|
-
const
|
|
1244
|
-
this.log.error(`Failed to validate blobs`, message, {
|
|
1245
|
-
metaMessages
|
|
1453
|
+
}).catch(async (err)=>{
|
|
1454
|
+
const viemError = formatViemError(err);
|
|
1455
|
+
this.log.error(`Failed to validate blobs`, viemError.message, {
|
|
1456
|
+
metaMessages: viemError.metaMessages
|
|
1457
|
+
});
|
|
1458
|
+
const validateBlobsData = encodeFunctionData({
|
|
1459
|
+
abi: RollupAbi,
|
|
1460
|
+
functionName: 'validateBlobs',
|
|
1461
|
+
args: [
|
|
1462
|
+
blobInput
|
|
1463
|
+
]
|
|
1464
|
+
});
|
|
1465
|
+
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
1466
|
+
this.backupFailedTx({
|
|
1467
|
+
id: keccak256(validateBlobsData),
|
|
1468
|
+
failureType: 'simulation',
|
|
1469
|
+
request: {
|
|
1470
|
+
to: this.rollupContract.address,
|
|
1471
|
+
data: validateBlobsData
|
|
1472
|
+
},
|
|
1473
|
+
blobData: encodedData.blobs.map((b)=>toHex(b.data)),
|
|
1474
|
+
l1BlockNumber: l1BlockNumber.toString(),
|
|
1475
|
+
error: {
|
|
1476
|
+
message: viemError.message,
|
|
1477
|
+
name: viemError.name
|
|
1478
|
+
},
|
|
1479
|
+
context: {
|
|
1480
|
+
actions: [
|
|
1481
|
+
'validate-blobs'
|
|
1482
|
+
],
|
|
1483
|
+
sender: this.getSenderAddress().toString()
|
|
1484
|
+
}
|
|
1246
1485
|
});
|
|
1247
1486
|
throw new Error('Failed to validate blobs');
|
|
1248
1487
|
});
|
|
@@ -1302,6 +1541,7 @@ export class SequencerPublisher {
|
|
|
1302
1541
|
balance: 10n * WEI_CONST * WEI_CONST
|
|
1303
1542
|
});
|
|
1304
1543
|
}
|
|
1544
|
+
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
1305
1545
|
const simulationResult = await this.l1TxUtils.simulate({
|
|
1306
1546
|
to: this.rollupContract.address,
|
|
1307
1547
|
data: rollupData,
|
|
@@ -1329,6 +1569,26 @@ export class SequencerPublisher {
|
|
|
1329
1569
|
};
|
|
1330
1570
|
}
|
|
1331
1571
|
this.log.error(`Failed to simulate propose tx`, viemError);
|
|
1572
|
+
this.backupFailedTx({
|
|
1573
|
+
id: keccak256(rollupData),
|
|
1574
|
+
failureType: 'simulation',
|
|
1575
|
+
request: {
|
|
1576
|
+
to: this.rollupContract.address,
|
|
1577
|
+
data: rollupData
|
|
1578
|
+
},
|
|
1579
|
+
l1BlockNumber: l1BlockNumber.toString(),
|
|
1580
|
+
error: {
|
|
1581
|
+
message: viemError.message,
|
|
1582
|
+
name: viemError.name
|
|
1583
|
+
},
|
|
1584
|
+
context: {
|
|
1585
|
+
actions: [
|
|
1586
|
+
'propose'
|
|
1587
|
+
],
|
|
1588
|
+
slot: Number(args[0].header.slotNumber),
|
|
1589
|
+
sender: this.getSenderAddress().toString()
|
|
1590
|
+
}
|
|
1591
|
+
});
|
|
1332
1592
|
throw err;
|
|
1333
1593
|
});
|
|
1334
1594
|
return {
|
|
@@ -7,7 +7,7 @@ import { type TypedEventEmitter } from '@aztec/foundation/types';
|
|
|
7
7
|
import type { P2P } from '@aztec/p2p';
|
|
8
8
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
9
9
|
import { L2Block, type L2BlockSink, type L2BlockSource } from '@aztec/stdlib/block';
|
|
10
|
-
import type
|
|
10
|
+
import { type Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
11
11
|
import { type ResolvedSequencerConfig, type WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
12
12
|
import { type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
13
13
|
import { Tx } from '@aztec/stdlib/tx';
|
|
@@ -71,11 +71,9 @@ export declare class CheckpointProposalJob implements Traceable {
|
|
|
71
71
|
indexWithinCheckpoint: IndexWithinCheckpoint;
|
|
72
72
|
buildDeadline: Date | undefined;
|
|
73
73
|
txHashesAlreadyIncluded: Set<string>;
|
|
74
|
-
remainingBlobFields: number;
|
|
75
74
|
}): Promise<{
|
|
76
75
|
block: L2Block;
|
|
77
76
|
usedTxs: Tx[];
|
|
78
|
-
remainingBlobFields: number;
|
|
79
77
|
} | {
|
|
80
78
|
error: Error;
|
|
81
79
|
} | undefined>;
|
|
@@ -99,4 +97,4 @@ export declare class CheckpointProposalJob implements Traceable {
|
|
|
99
97
|
private getSecondsIntoSlot;
|
|
100
98
|
getPublisher(): SequencerPublisher;
|
|
101
99
|
}
|
|
102
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
100
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9wcm9wb3NhbF9qb2IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXF1ZW5jZXIvY2hlY2twb2ludF9wcm9wb3NhbF9qb2IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUNMLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUNYLHFCQUFxQixFQUNyQixVQUFVLEVBQ1gsTUFBTSxpQ0FBaUMsQ0FBQztBQVF6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFHM0QsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFFLEtBQUssY0FBYyxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBRXZGLE9BQU8sRUFBRSxLQUFLLFlBQVksRUFBUyxNQUFNLHlCQUF5QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUEwQixNQUFNLHlCQUF5QixDQUFDO0FBQ3pGLE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdELE9BQU8sRUFHTCxPQUFPLEVBQ1AsS0FBSyxXQUFXLEVBQ2hCLEtBQUssYUFBYSxFQUVuQixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxLQUFLLFVBQVUsRUFBc0IsTUFBTSwwQkFBMEIsQ0FBQztBQUcvRSxPQUFPLEVBR0wsS0FBSyx1QkFBdUIsRUFDNUIsS0FBSyxzQkFBc0IsRUFDNUIsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxtQkFBbUIsRUFBbUMsTUFBTSx5QkFBeUIsQ0FBQztBQUlwRyxPQUFPLEVBQWlCLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXJELE9BQU8sRUFBYyxLQUFLLFNB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint_proposal_job.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_proposal_job.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkpoint_proposal_job.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_proposal_job.ts"],"names":[],"mappings":"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"}
|