@aztec/sequencer-client 0.0.1-commit.6b113946b → 0.0.1-commit.6bd18f1aa
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 +4 -1
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +8 -13
- package/dest/global_variable_builder/global_builder.d.ts +13 -7
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +22 -22
- package/dest/global_variable_builder/index.d.ts +2 -2
- package/dest/global_variable_builder/index.d.ts.map +1 -1
- package/dest/publisher/config.d.ts +13 -1
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +17 -2
- package/dest/publisher/sequencer-publisher-factory.d.ts +3 -3
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +2 -2
- package/dest/publisher/sequencer-publisher.d.ts +10 -5
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +46 -33
- package/dest/sequencer/checkpoint_proposal_job.js +1 -1
- 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/dest/sequencer/sequencer.js +3 -3
- package/package.json +27 -27
- package/src/client/sequencer-client.ts +11 -17
- package/src/global_variable_builder/global_builder.ts +22 -24
- package/src/global_variable_builder/index.ts +1 -1
- package/src/publisher/config.ts +32 -0
- package/src/publisher/sequencer-publisher-factory.ts +3 -3
- package/src/publisher/sequencer-publisher.ts +37 -39
- package/src/sequencer/checkpoint_proposal_job.ts +1 -1
- package/src/sequencer/checkpoint_voter.ts +1 -12
- package/src/sequencer/sequencer.ts +3 -3
|
@@ -391,6 +391,7 @@ import { Timer } from '@aztec/foundation/timer';
|
|
|
391
391
|
import { EmpireBaseAbi, ErrorsAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
392
392
|
import { encodeSlashConsensusVotes } from '@aztec/slasher';
|
|
393
393
|
import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
394
|
+
import { getLastL1SlotTimestampForL2Slot, getNextL1SlotTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
394
395
|
import { getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
395
396
|
import { encodeFunctionData, keccak256, multicall3Abi, toHex } from 'viem';
|
|
396
397
|
import { createL1TxFailedStore } from './l1_tx_failed_store/index.js';
|
|
@@ -442,6 +443,7 @@ export class SequencerPublisher {
|
|
|
442
443
|
log;
|
|
443
444
|
ethereumSlotDuration;
|
|
444
445
|
aztecSlotDuration;
|
|
446
|
+
dateProvider;
|
|
445
447
|
blobClient;
|
|
446
448
|
/** Address to use for simulations in fisherman mode (actual proposer's address) */ proposerAddressForSimulation;
|
|
447
449
|
/** Optional callback to obtain a replacement publisher when the current one fails to send. */ getNextPublisher;
|
|
@@ -470,6 +472,7 @@ export class SequencerPublisher {
|
|
|
470
472
|
this.log = deps.log ?? createLogger('sequencer:publisher');
|
|
471
473
|
this.ethereumSlotDuration = BigInt(config.ethereumSlotDuration);
|
|
472
474
|
this.aztecSlotDuration = BigInt(config.aztecSlotDuration);
|
|
475
|
+
this.dateProvider = deps.dateProvider;
|
|
473
476
|
this.epochCache = deps.epochCache;
|
|
474
477
|
this.lastActions = deps.lastActions;
|
|
475
478
|
this.blobClient = deps.blobClient;
|
|
@@ -840,7 +843,8 @@ export class SequencerPublisher {
|
|
|
840
843
|
];
|
|
841
844
|
const pipelined = opts.pipelined ?? this.epochCache.isProposerPipeliningEnabled();
|
|
842
845
|
const slotOffset = pipelined ? this.aztecSlotDuration : 0n;
|
|
843
|
-
|
|
846
|
+
const nextL1SlotTs = this.getNextL1SlotTimestamp() + slotOffset;
|
|
847
|
+
return this.rollupContract.canProposeAt(tipArchive.toBuffer(), msgSender.toString(), nextL1SlotTs, {
|
|
844
848
|
forcePendingCheckpointNumber: opts.forcePendingCheckpointNumber
|
|
845
849
|
}).catch((err)=>{
|
|
846
850
|
if (err instanceof FormattedViemError && ignoredErrors.find((e)=>err.message.includes(e))) {
|
|
@@ -872,7 +876,7 @@ export class SequencerPublisher {
|
|
|
872
876
|
header.blobsHash.toString(),
|
|
873
877
|
flags
|
|
874
878
|
];
|
|
875
|
-
const ts =
|
|
879
|
+
const ts = this.getSimulationTimestamp(header.slotNumber);
|
|
876
880
|
const stateOverrides = await this.rollupContract.makePendingCheckpointNumberOverride(opts?.forcePendingCheckpointNumber);
|
|
877
881
|
let balance = 0n;
|
|
878
882
|
if (this.config.fishermanMode) {
|
|
@@ -895,7 +899,7 @@ export class SequencerPublisher {
|
|
|
895
899
|
}),
|
|
896
900
|
from: MULTI_CALL_3_ADDRESS
|
|
897
901
|
}, {
|
|
898
|
-
time: ts
|
|
902
|
+
time: ts
|
|
899
903
|
}, stateOverrides);
|
|
900
904
|
this.log.debug(`Simulated validateHeader`);
|
|
901
905
|
}
|
|
@@ -1015,9 +1019,6 @@ export class SequencerPublisher {
|
|
|
1015
1019
|
}
|
|
1016
1020
|
}
|
|
1017
1021
|
/** Simulates `propose` to make sure that the checkpoint is valid for submission */ async validateCheckpointForSubmission(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, options) {
|
|
1018
|
-
// Anchor the simulation timestamp to the checkpoint's own slot start time
|
|
1019
|
-
// rather than the current L1 block timestamp, which may overshoot into the next slot if the build ran late.
|
|
1020
|
-
const ts = checkpoint.header.timestamp;
|
|
1021
1022
|
const blobFields = checkpoint.toBlobFields();
|
|
1022
1023
|
const blobs = await getBlobsPerL1Block(blobFields);
|
|
1023
1024
|
const blobInput = getPrefixedEthBlobCommitments(blobs);
|
|
@@ -1034,10 +1035,9 @@ export class SequencerPublisher {
|
|
|
1034
1035
|
attestationsAndSignersSignature.toViemSignature(),
|
|
1035
1036
|
blobInput
|
|
1036
1037
|
];
|
|
1037
|
-
await this.simulateProposeTx(args,
|
|
1038
|
-
return ts;
|
|
1038
|
+
await this.simulateProposeTx(args, options);
|
|
1039
1039
|
}
|
|
1040
|
-
async enqueueCastSignalHelper(slotNumber,
|
|
1040
|
+
async enqueueCastSignalHelper(slotNumber, signalType, payload, base, signerAddress, signer) {
|
|
1041
1041
|
if (this.lastActions[signalType] && this.lastActions[signalType] === slotNumber) {
|
|
1042
1042
|
this.log.debug(`Skipping duplicate vote cast signal ${signalType} for slot ${slotNumber}`);
|
|
1043
1043
|
return false;
|
|
@@ -1094,6 +1094,7 @@ export class SequencerPublisher {
|
|
|
1094
1094
|
lastValidL2Slot: slotNumber
|
|
1095
1095
|
});
|
|
1096
1096
|
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
1097
|
+
const timestamp = this.getSimulationTimestamp(slotNumber);
|
|
1097
1098
|
try {
|
|
1098
1099
|
await this.l1TxUtils.simulate(request, {
|
|
1099
1100
|
time: timestamp
|
|
@@ -1106,7 +1107,10 @@ export class SequencerPublisher {
|
|
|
1106
1107
|
});
|
|
1107
1108
|
} catch (err) {
|
|
1108
1109
|
const viemError = formatViemError(err);
|
|
1109
|
-
this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError
|
|
1110
|
+
this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError, {
|
|
1111
|
+
simulationTimestamp: timestamp,
|
|
1112
|
+
l1BlockNumber
|
|
1113
|
+
});
|
|
1110
1114
|
this.backupFailedTx({
|
|
1111
1115
|
id: keccak256(request.data),
|
|
1112
1116
|
failureType: 'simulation',
|
|
@@ -1171,12 +1175,11 @@ export class SequencerPublisher {
|
|
|
1171
1175
|
/**
|
|
1172
1176
|
* Enqueues a governance castSignal transaction to cast a signal for a given slot number.
|
|
1173
1177
|
* @param slotNumber - The slot number to cast a signal for.
|
|
1174
|
-
* @param timestamp - The timestamp of the slot to cast a signal for.
|
|
1175
1178
|
* @returns True if the signal was successfully enqueued, false otherwise.
|
|
1176
|
-
*/ enqueueGovernanceCastSignal(governancePayload, slotNumber,
|
|
1177
|
-
return this.enqueueCastSignalHelper(slotNumber,
|
|
1179
|
+
*/ enqueueGovernanceCastSignal(governancePayload, slotNumber, signerAddress, signer) {
|
|
1180
|
+
return this.enqueueCastSignalHelper(slotNumber, 'governance-signal', governancePayload, this.govProposerContract, signerAddress, signer);
|
|
1178
1181
|
}
|
|
1179
|
-
/** Enqueues all slashing actions as returned by the slasher client. */ async enqueueSlashingActions(actions, slotNumber,
|
|
1182
|
+
/** Enqueues all slashing actions as returned by the slasher client. */ async enqueueSlashingActions(actions, slotNumber, signerAddress, signer) {
|
|
1180
1183
|
if (actions.length === 0) {
|
|
1181
1184
|
this.log.debug(`No slashing actions to enqueue for slot ${slotNumber}`);
|
|
1182
1185
|
return false;
|
|
@@ -1192,7 +1195,7 @@ export class SequencerPublisher {
|
|
|
1192
1195
|
this.log.debug(`Enqueuing slashing vote for payload ${action.payload} at slot ${slotNumber}`, {
|
|
1193
1196
|
signerAddress
|
|
1194
1197
|
});
|
|
1195
|
-
await this.enqueueCastSignalHelper(slotNumber,
|
|
1198
|
+
await this.enqueueCastSignalHelper(slotNumber, 'empire-slashing-signal', action.payload, this.slashingProposerContract, signerAddress, signer);
|
|
1196
1199
|
break;
|
|
1197
1200
|
}
|
|
1198
1201
|
case 'create-empire-payload':
|
|
@@ -1202,7 +1205,7 @@ export class SequencerPublisher {
|
|
|
1202
1205
|
signerAddress
|
|
1203
1206
|
});
|
|
1204
1207
|
const request = this.slashFactoryContract.buildCreatePayloadRequest(action.data);
|
|
1205
|
-
await this.simulateAndEnqueueRequest('create-empire-payload', request, (receipt)=>!!this.slashFactoryContract.tryExtractSlashPayloadCreatedEvent(receipt.logs), slotNumber
|
|
1208
|
+
await this.simulateAndEnqueueRequest('create-empire-payload', request, (receipt)=>!!this.slashFactoryContract.tryExtractSlashPayloadCreatedEvent(receipt.logs), slotNumber);
|
|
1206
1209
|
break;
|
|
1207
1210
|
}
|
|
1208
1211
|
case 'execute-empire-payload':
|
|
@@ -1217,7 +1220,7 @@ export class SequencerPublisher {
|
|
|
1217
1220
|
}
|
|
1218
1221
|
const empireSlashingProposer = this.slashingProposerContract;
|
|
1219
1222
|
const request = empireSlashingProposer.buildExecuteRoundRequest(action.round);
|
|
1220
|
-
await this.simulateAndEnqueueRequest('execute-empire-payload', request, (receipt)=>!!empireSlashingProposer.tryExtractPayloadSubmittedEvent(receipt.logs), slotNumber
|
|
1223
|
+
await this.simulateAndEnqueueRequest('execute-empire-payload', request, (receipt)=>!!empireSlashingProposer.tryExtractPayloadSubmittedEvent(receipt.logs), slotNumber);
|
|
1221
1224
|
break;
|
|
1222
1225
|
}
|
|
1223
1226
|
case 'vote-offenses':
|
|
@@ -1235,7 +1238,7 @@ export class SequencerPublisher {
|
|
|
1235
1238
|
const tallySlashingProposer = this.slashingProposerContract;
|
|
1236
1239
|
const votes = bufferToHex(encodeSlashConsensusVotes(action.votes));
|
|
1237
1240
|
const request = await tallySlashingProposer.buildVoteRequestFromSigner(votes, slotNumber, signer);
|
|
1238
|
-
await this.simulateAndEnqueueRequest('vote-offenses', request, (receipt)=>!!tallySlashingProposer.tryExtractVoteCastEvent(receipt.logs), slotNumber
|
|
1241
|
+
await this.simulateAndEnqueueRequest('vote-offenses', request, (receipt)=>!!tallySlashingProposer.tryExtractVoteCastEvent(receipt.logs), slotNumber);
|
|
1239
1242
|
break;
|
|
1240
1243
|
}
|
|
1241
1244
|
case 'execute-slash':
|
|
@@ -1251,7 +1254,7 @@ export class SequencerPublisher {
|
|
|
1251
1254
|
}
|
|
1252
1255
|
const tallySlashingProposer = this.slashingProposerContract;
|
|
1253
1256
|
const request = tallySlashingProposer.buildExecuteRoundRequest(action.round, action.committees);
|
|
1254
|
-
await this.simulateAndEnqueueRequest('execute-slash', request, (receipt)=>!!tallySlashingProposer.tryExtractRoundExecutedEvent(receipt.logs), slotNumber
|
|
1257
|
+
await this.simulateAndEnqueueRequest('execute-slash', request, (receipt)=>!!tallySlashingProposer.tryExtractRoundExecutedEvent(receipt.logs), slotNumber);
|
|
1255
1258
|
break;
|
|
1256
1259
|
}
|
|
1257
1260
|
default:
|
|
@@ -1275,14 +1278,13 @@ export class SequencerPublisher {
|
|
|
1275
1278
|
attestationsAndSignersSignature,
|
|
1276
1279
|
feeAssetPriceModifier: checkpoint.feeAssetPriceModifier
|
|
1277
1280
|
};
|
|
1278
|
-
let ts;
|
|
1279
1281
|
try {
|
|
1280
1282
|
// @note This will make sure that we are passing the checks for our header ASSUMING that the data is also made available
|
|
1281
1283
|
// This means that we can avoid the simulation issues in later checks.
|
|
1282
1284
|
// By simulation issue, I mean the fact that the block.timestamp is equal to the last block, not the next, which
|
|
1283
1285
|
// make time consistency checks break.
|
|
1284
1286
|
// TODO(palla): Check whether we're validating twice, once here and once within addProposeTx, since we call simulateProposeTx in both places.
|
|
1285
|
-
|
|
1287
|
+
await this.validateCheckpointForSubmission(checkpoint, attestationsAndSigners, attestationsAndSignersSignature, opts);
|
|
1286
1288
|
} catch (err) {
|
|
1287
1289
|
this.log.error(`Checkpoint validation failed. ${err instanceof Error ? err.message : 'No error message'}`, err, {
|
|
1288
1290
|
...checkpoint.getStats(),
|
|
@@ -1295,7 +1297,7 @@ export class SequencerPublisher {
|
|
|
1295
1297
|
...checkpoint.toCheckpointInfo(),
|
|
1296
1298
|
...opts
|
|
1297
1299
|
});
|
|
1298
|
-
await this.addProposeTx(checkpoint, proposeTxArgs, opts
|
|
1300
|
+
await this.addProposeTx(checkpoint, proposeTxArgs, opts);
|
|
1299
1301
|
}
|
|
1300
1302
|
enqueueInvalidateCheckpoint(request, opts = {}) {
|
|
1301
1303
|
if (!request) {
|
|
@@ -1336,7 +1338,8 @@ export class SequencerPublisher {
|
|
|
1336
1338
|
}
|
|
1337
1339
|
});
|
|
1338
1340
|
}
|
|
1339
|
-
async simulateAndEnqueueRequest(action, request, checkSuccess, slotNumber
|
|
1341
|
+
async simulateAndEnqueueRequest(action, request, checkSuccess, slotNumber) {
|
|
1342
|
+
const timestamp = this.getSimulationTimestamp(slotNumber);
|
|
1340
1343
|
const logData = {
|
|
1341
1344
|
slotNumber,
|
|
1342
1345
|
timestamp,
|
|
@@ -1358,7 +1361,7 @@ export class SequencerPublisher {
|
|
|
1358
1361
|
try {
|
|
1359
1362
|
({ gasUsed } = await this.l1TxUtils.simulate(request, {
|
|
1360
1363
|
time: timestamp
|
|
1361
|
-
}, [], simulateAbi));
|
|
1364
|
+
}, [], simulateAbi));
|
|
1362
1365
|
this.log.verbose(`Simulation for ${action} succeeded`, {
|
|
1363
1366
|
...logData,
|
|
1364
1367
|
request,
|
|
@@ -1439,7 +1442,7 @@ export class SequencerPublisher {
|
|
|
1439
1442
|
this.interrupted = false;
|
|
1440
1443
|
this.l1TxUtils.restart();
|
|
1441
1444
|
}
|
|
1442
|
-
async prepareProposeTx(encodedData,
|
|
1445
|
+
async prepareProposeTx(encodedData, options) {
|
|
1443
1446
|
const kzg = Blob.getViemKzgInstance();
|
|
1444
1447
|
const blobInput = getPrefixedEthBlobCommitments(encodedData.blobs);
|
|
1445
1448
|
this.log.debug('Validating blob input', {
|
|
@@ -1516,7 +1519,7 @@ export class SequencerPublisher {
|
|
|
1516
1519
|
encodedData.attestationsAndSignersSignature.toViemSignature(),
|
|
1517
1520
|
blobInput
|
|
1518
1521
|
];
|
|
1519
|
-
const { rollupData, simulationResult } = await this.simulateProposeTx(args,
|
|
1522
|
+
const { rollupData, simulationResult } = await this.simulateProposeTx(args, options);
|
|
1520
1523
|
return {
|
|
1521
1524
|
args,
|
|
1522
1525
|
blobEvaluationGas,
|
|
@@ -1527,9 +1530,8 @@ export class SequencerPublisher {
|
|
|
1527
1530
|
/**
|
|
1528
1531
|
* Simulates the propose tx with eth_simulateV1
|
|
1529
1532
|
* @param args - The propose tx args
|
|
1530
|
-
* @param timestamp - The timestamp to simulate proposal at
|
|
1531
1533
|
* @returns The simulation result
|
|
1532
|
-
*/ async simulateProposeTx(args,
|
|
1534
|
+
*/ async simulateProposeTx(args, options) {
|
|
1533
1535
|
const rollupData = encodeFunctionData({
|
|
1534
1536
|
abi: RollupAbi,
|
|
1535
1537
|
functionName: 'propose',
|
|
@@ -1558,6 +1560,7 @@ export class SequencerPublisher {
|
|
|
1558
1560
|
});
|
|
1559
1561
|
}
|
|
1560
1562
|
const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
|
|
1563
|
+
const simTs = this.getSimulationTimestamp(SlotNumber.fromBigInt(args[0].header.slotNumber));
|
|
1561
1564
|
const simulationResult = await this.l1TxUtils.simulate({
|
|
1562
1565
|
to: this.rollupContract.address,
|
|
1563
1566
|
data: rollupData,
|
|
@@ -1566,8 +1569,7 @@ export class SequencerPublisher {
|
|
|
1566
1569
|
from: this.proposerAddressForSimulation.toString()
|
|
1567
1570
|
}
|
|
1568
1571
|
}, {
|
|
1569
|
-
|
|
1570
|
-
time: timestamp + 1n,
|
|
1572
|
+
time: simTs,
|
|
1571
1573
|
// @note reth should have a 30m gas limit per block but throws errors that this tx is beyond limit so we increase here
|
|
1572
1574
|
gasLimit: MAX_L1_TX_LIMIT * 2n
|
|
1573
1575
|
}, stateOverrides, RollupAbi, {
|
|
@@ -1584,7 +1586,9 @@ export class SequencerPublisher {
|
|
|
1584
1586
|
logs: []
|
|
1585
1587
|
};
|
|
1586
1588
|
}
|
|
1587
|
-
this.log.error(`Failed to simulate propose tx`, viemError
|
|
1589
|
+
this.log.error(`Failed to simulate propose tx`, viemError, {
|
|
1590
|
+
simulationTimestamp: simTs
|
|
1591
|
+
});
|
|
1588
1592
|
this.backupFailedTx({
|
|
1589
1593
|
id: keccak256(rollupData),
|
|
1590
1594
|
failureType: 'simulation',
|
|
@@ -1612,11 +1616,11 @@ export class SequencerPublisher {
|
|
|
1612
1616
|
simulationResult
|
|
1613
1617
|
};
|
|
1614
1618
|
}
|
|
1615
|
-
async addProposeTx(checkpoint, encodedData, opts = {}
|
|
1619
|
+
async addProposeTx(checkpoint, encodedData, opts = {}) {
|
|
1616
1620
|
const slot = checkpoint.header.slotNumber;
|
|
1617
1621
|
const timer = new Timer();
|
|
1618
1622
|
const kzg = Blob.getViemKzgInstance();
|
|
1619
|
-
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData,
|
|
1623
|
+
const { rollupData, simulationResult, blobEvaluationGas } = await this.prepareProposeTx(encodedData, opts);
|
|
1620
1624
|
const startBlock = await this.l1TxUtils.getBlockNumber();
|
|
1621
1625
|
const gasLimit = this.l1TxUtils.bumpGasLimit(BigInt(Math.ceil(Number(simulationResult.gasUsed) * 64 / 63)) + blobEvaluationGas + SequencerPublisher.MULTICALL_OVERHEAD_GAS_GUESS);
|
|
1622
1626
|
// Send the blobs to the blob client preemptively. This helps in tests where the sequencer mistakingly thinks that the propose
|
|
@@ -1681,4 +1685,13 @@ export class SequencerPublisher {
|
|
|
1681
1685
|
}
|
|
1682
1686
|
});
|
|
1683
1687
|
}
|
|
1688
|
+
/** Returns the timestamp of the last L1 slot within a given L2 slot. Used as the simulation timestamp
|
|
1689
|
+
* for eth_simulateV1 calls, since it's guaranteed to be greater than any L1 block produced during the slot. */ getSimulationTimestamp(slot) {
|
|
1690
|
+
const l1Constants = this.epochCache.getL1Constants();
|
|
1691
|
+
return getLastL1SlotTimestampForL2Slot(slot, l1Constants);
|
|
1692
|
+
}
|
|
1693
|
+
/** Returns the timestamp of the next L1 slot boundary after now. */ getNextL1SlotTimestamp() {
|
|
1694
|
+
const l1Constants = this.epochCache.getL1Constants();
|
|
1695
|
+
return getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), l1Constants);
|
|
1696
|
+
}
|
|
1684
1697
|
}
|
|
@@ -1216,7 +1216,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1216
1216
|
* Gossip doesn't echo messages back to the sender, so the proposer's archiver/world-state
|
|
1217
1217
|
* would never receive its own block without this explicit sync.
|
|
1218
1218
|
*/ async syncProposedBlockToArchiver(block) {
|
|
1219
|
-
if (this.config.skipPushProposedBlocksToArchiver
|
|
1219
|
+
if (this.config.skipPushProposedBlocksToArchiver) {
|
|
1220
1220
|
this.log.warn(`Skipping push of proposed block ${block.number} to archiver`, {
|
|
1221
1221
|
blockNumber: block.number,
|
|
1222
1222
|
slot: block.header.globalVariables.slotNumber
|
|
@@ -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`, {
|
|
@@ -494,7 +494,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
494
494
|
this.setState(SequencerState.STOPPING, undefined, {
|
|
495
495
|
force: true
|
|
496
496
|
});
|
|
497
|
-
this.publisherFactory.
|
|
497
|
+
await this.publisherFactory.stopAll();
|
|
498
498
|
await this.runningPromise?.stop();
|
|
499
499
|
this.setState(SequencerState.STOPPED, undefined, {
|
|
500
500
|
force: true
|
|
@@ -751,8 +751,8 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
751
751
|
* We don't check against the previous block submitted since it may have been reorg'd out.
|
|
752
752
|
*/ async checkSync(args) {
|
|
753
753
|
// Check that the archiver has fully synced the L2 slot before the one we want to propose in.
|
|
754
|
-
//
|
|
755
|
-
//
|
|
754
|
+
// The archiver reports sync progress via L1 block timestamps and synced checkpoint slots.
|
|
755
|
+
// See getSyncedL2SlotNumber for how missed L1 blocks are handled.
|
|
756
756
|
const syncedL2Slot = await this.l2BlockSource.getSyncedL2SlotNumber();
|
|
757
757
|
const { slot } = args;
|
|
758
758
|
if (syncedL2Slot === undefined || syncedL2Slot + 1 < slot) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.6bd18f1aa",
|
|
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": "0.0.1-commit.
|
|
30
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
31
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
32
|
-
"@aztec/blob-lib": "0.0.1-commit.
|
|
33
|
-
"@aztec/constants": "0.0.1-commit.
|
|
34
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
35
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
36
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
37
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
38
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
39
|
-
"@aztec/noir-acvm_js": "0.0.1-commit.
|
|
40
|
-
"@aztec/noir-contracts.js": "0.0.1-commit.
|
|
41
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
42
|
-
"@aztec/noir-types": "0.0.1-commit.
|
|
43
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
44
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
45
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
46
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
47
|
-
"@aztec/slasher": "0.0.1-commit.
|
|
48
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
49
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
50
|
-
"@aztec/validator-client": "0.0.1-commit.
|
|
51
|
-
"@aztec/validator-ha-signer": "0.0.1-commit.
|
|
52
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
29
|
+
"@aztec/aztec.js": "0.0.1-commit.6bd18f1aa",
|
|
30
|
+
"@aztec/bb-prover": "0.0.1-commit.6bd18f1aa",
|
|
31
|
+
"@aztec/blob-client": "0.0.1-commit.6bd18f1aa",
|
|
32
|
+
"@aztec/blob-lib": "0.0.1-commit.6bd18f1aa",
|
|
33
|
+
"@aztec/constants": "0.0.1-commit.6bd18f1aa",
|
|
34
|
+
"@aztec/epoch-cache": "0.0.1-commit.6bd18f1aa",
|
|
35
|
+
"@aztec/ethereum": "0.0.1-commit.6bd18f1aa",
|
|
36
|
+
"@aztec/foundation": "0.0.1-commit.6bd18f1aa",
|
|
37
|
+
"@aztec/l1-artifacts": "0.0.1-commit.6bd18f1aa",
|
|
38
|
+
"@aztec/node-keystore": "0.0.1-commit.6bd18f1aa",
|
|
39
|
+
"@aztec/noir-acvm_js": "0.0.1-commit.6bd18f1aa",
|
|
40
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.6bd18f1aa",
|
|
41
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.6bd18f1aa",
|
|
42
|
+
"@aztec/noir-types": "0.0.1-commit.6bd18f1aa",
|
|
43
|
+
"@aztec/p2p": "0.0.1-commit.6bd18f1aa",
|
|
44
|
+
"@aztec/protocol-contracts": "0.0.1-commit.6bd18f1aa",
|
|
45
|
+
"@aztec/prover-client": "0.0.1-commit.6bd18f1aa",
|
|
46
|
+
"@aztec/simulator": "0.0.1-commit.6bd18f1aa",
|
|
47
|
+
"@aztec/slasher": "0.0.1-commit.6bd18f1aa",
|
|
48
|
+
"@aztec/stdlib": "0.0.1-commit.6bd18f1aa",
|
|
49
|
+
"@aztec/telemetry-client": "0.0.1-commit.6bd18f1aa",
|
|
50
|
+
"@aztec/validator-client": "0.0.1-commit.6bd18f1aa",
|
|
51
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.6bd18f1aa",
|
|
52
|
+
"@aztec/world-state": "0.0.1-commit.6bd18f1aa",
|
|
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": "0.0.1-commit.
|
|
59
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
58
|
+
"@aztec/archiver": "0.0.1-commit.6bd18f1aa",
|
|
59
|
+
"@aztec/kv-store": "0.0.1-commit.6bd18f1aa",
|
|
60
60
|
"@electric-sql/pglite": "^0.3.14",
|
|
61
61
|
"@jest/globals": "^30.0.0",
|
|
62
62
|
"@types/jest": "^30.0.0",
|
|
@@ -20,7 +20,7 @@ import { L1Metrics, type TelemetryClient } from '@aztec/telemetry-client';
|
|
|
20
20
|
import { FullNodeCheckpointsBuilder, NodeKeystoreAdapter, type ValidatorClient } from '@aztec/validator-client';
|
|
21
21
|
|
|
22
22
|
import { type SequencerClientConfig, getPublisherConfigFromSequencerConfig } from '../config.js';
|
|
23
|
-
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
23
|
+
import type { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
24
24
|
import { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
|
|
25
25
|
import { Sequencer, type SequencerConfig } from '../sequencer/index.js';
|
|
26
26
|
|
|
@@ -65,7 +65,9 @@ export class SequencerClient {
|
|
|
65
65
|
dateProvider: DateProvider;
|
|
66
66
|
epochCache?: EpochCache;
|
|
67
67
|
l1TxUtils: L1TxUtils[];
|
|
68
|
+
funderL1TxUtils?: L1TxUtils;
|
|
68
69
|
nodeKeyStore: KeystoreManager;
|
|
70
|
+
globalVariableBuilder: GlobalVariableBuilder;
|
|
69
71
|
},
|
|
70
72
|
) {
|
|
71
73
|
const {
|
|
@@ -87,16 +89,14 @@ export class SequencerClient {
|
|
|
87
89
|
publicClient,
|
|
88
90
|
l1TxUtils.map(x => x.getSenderAddress()),
|
|
89
91
|
);
|
|
90
|
-
const publisherManager = new PublisherManager(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
);
|
|
92
|
+
const publisherManager = new PublisherManager(l1TxUtils, getPublisherConfigFromSequencerConfig(config), {
|
|
93
|
+
bindings: log.getBindings(),
|
|
94
|
+
funder: deps.funderL1TxUtils,
|
|
95
|
+
});
|
|
95
96
|
const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
|
|
96
|
-
const [l1GenesisTime, slotDuration,
|
|
97
|
+
const [l1GenesisTime, slotDuration, rollupManaLimit] = await Promise.all([
|
|
97
98
|
rollupContract.getL1GenesisTime(),
|
|
98
99
|
rollupContract.getSlotDuration(),
|
|
99
|
-
rollupContract.getVersion(),
|
|
100
100
|
rollupContract.getManaLimit().then(Number),
|
|
101
101
|
] as const);
|
|
102
102
|
|
|
@@ -140,13 +140,7 @@ export class SequencerClient {
|
|
|
140
140
|
|
|
141
141
|
const ethereumSlotDuration = config.ethereumSlotDuration;
|
|
142
142
|
|
|
143
|
-
const globalsBuilder =
|
|
144
|
-
...config,
|
|
145
|
-
l1GenesisTime,
|
|
146
|
-
slotDuration: Number(slotDuration),
|
|
147
|
-
ethereumSlotDuration,
|
|
148
|
-
rollupVersion,
|
|
149
|
-
});
|
|
143
|
+
const globalsBuilder = deps.globalVariableBuilder;
|
|
150
144
|
|
|
151
145
|
// When running in anvil, assume we can post a tx up until one second before the end of an L1 slot.
|
|
152
146
|
// Otherwise, we need the full L1 slot duration for publishing to ensure inclusion.
|
|
@@ -202,7 +196,7 @@ export class SequencerClient {
|
|
|
202
196
|
await this.validatorClient?.start();
|
|
203
197
|
this.sequencer.start();
|
|
204
198
|
this.l1Metrics?.start();
|
|
205
|
-
await this.publisherManager.
|
|
199
|
+
await this.publisherManager.start();
|
|
206
200
|
}
|
|
207
201
|
|
|
208
202
|
/**
|
|
@@ -211,7 +205,7 @@ export class SequencerClient {
|
|
|
211
205
|
public async stop() {
|
|
212
206
|
await this.sequencer.stop();
|
|
213
207
|
await this.validatorClient?.stop();
|
|
214
|
-
this.publisherManager.
|
|
208
|
+
await this.publisherManager.stop();
|
|
215
209
|
this.l1Metrics?.stop();
|
|
216
210
|
}
|
|
217
211
|
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
2
|
-
import { makeL1HttpTransport } from '@aztec/ethereum/client';
|
|
3
|
-
import type { L1ContractsConfig } from '@aztec/ethereum/config';
|
|
4
1
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
5
|
-
import type {
|
|
2
|
+
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
6
3
|
import type { ViemPublicClient } from '@aztec/ethereum/types';
|
|
7
4
|
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
8
5
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
9
6
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
10
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
11
9
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
|
-
import { type L1RollupConstants, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
10
|
+
import { type L1RollupConstants, getNextL1SlotTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
13
11
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
14
12
|
import type {
|
|
15
13
|
CheckpointGlobalVariables,
|
|
@@ -17,7 +15,12 @@ import type {
|
|
|
17
15
|
} from '@aztec/stdlib/tx';
|
|
18
16
|
import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
/** Configuration for the GlobalVariableBuilder (excludes L1 client config). */
|
|
19
|
+
export type GlobalVariableBuilderConfig = {
|
|
20
|
+
l1Contracts: Pick<L1ContractAddresses, 'rollupAddress'>;
|
|
21
|
+
ethereumSlotDuration: number;
|
|
22
|
+
rollupVersion: bigint;
|
|
23
|
+
} & Pick<L1RollupConstants, 'slotDuration' | 'l1GenesisTime'>;
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* Simple global variables builder.
|
|
@@ -28,7 +31,6 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
28
31
|
private currentL1BlockNumber: bigint | undefined = undefined;
|
|
29
32
|
|
|
30
33
|
private readonly rollupContract: RollupContract;
|
|
31
|
-
private readonly publicClient: ViemPublicClient;
|
|
32
34
|
private readonly ethereumSlotDuration: number;
|
|
33
35
|
private readonly aztecSlotDuration: number;
|
|
34
36
|
private readonly l1GenesisTime: bigint;
|
|
@@ -37,28 +39,18 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
37
39
|
private version: Fr;
|
|
38
40
|
|
|
39
41
|
constructor(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
private readonly dateProvider: DateProvider,
|
|
43
|
+
private readonly publicClient: ViemPublicClient,
|
|
44
|
+
config: GlobalVariableBuilderConfig,
|
|
43
45
|
) {
|
|
44
|
-
const { l1RpcUrls, l1ChainId: chainId, l1Contracts } = config;
|
|
45
|
-
|
|
46
|
-
const chain = createEthereumChain(l1RpcUrls, chainId);
|
|
47
|
-
|
|
48
46
|
this.version = new Fr(config.rollupVersion);
|
|
49
|
-
this.chainId = new Fr(
|
|
47
|
+
this.chainId = new Fr(this.publicClient.chain!.id);
|
|
50
48
|
|
|
51
49
|
this.ethereumSlotDuration = config.ethereumSlotDuration;
|
|
52
50
|
this.aztecSlotDuration = config.slotDuration;
|
|
53
51
|
this.l1GenesisTime = config.l1GenesisTime;
|
|
54
52
|
|
|
55
|
-
this.
|
|
56
|
-
chain: chain.chainInfo,
|
|
57
|
-
transport: makeL1HttpTransport(chain.rpcUrls, { timeout: config.l1HttpTimeoutMS }),
|
|
58
|
-
pollingInterval: config.viemPollingIntervalMS,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
this.rollupContract = new RollupContract(this.publicClient, l1Contracts.rollupAddress);
|
|
53
|
+
this.rollupContract = new RollupContract(this.publicClient, config.l1Contracts.rollupAddress);
|
|
62
54
|
}
|
|
63
55
|
|
|
64
56
|
/**
|
|
@@ -74,7 +66,10 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
74
66
|
const earliestTimestamp = await this.rollupContract.getTimestampForSlot(
|
|
75
67
|
SlotNumber.fromBigInt(BigInt(lastCheckpoint.slotNumber) + 1n),
|
|
76
68
|
);
|
|
77
|
-
const nextEthTimestamp =
|
|
69
|
+
const nextEthTimestamp = getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), {
|
|
70
|
+
l1GenesisTime: this.l1GenesisTime,
|
|
71
|
+
ethereumSlotDuration: this.ethereumSlotDuration,
|
|
72
|
+
});
|
|
78
73
|
const timestamp = earliestTimestamp > nextEthTimestamp ? earliestTimestamp : nextEthTimestamp;
|
|
79
74
|
|
|
80
75
|
return new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
|
|
@@ -109,7 +104,10 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
109
104
|
const slot: SlotNumber =
|
|
110
105
|
maybeSlot ??
|
|
111
106
|
(await this.rollupContract.getSlotAt(
|
|
112
|
-
|
|
107
|
+
getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), {
|
|
108
|
+
l1GenesisTime: this.l1GenesisTime,
|
|
109
|
+
ethereumSlotDuration: this.ethereumSlotDuration,
|
|
110
|
+
}),
|
|
113
111
|
));
|
|
114
112
|
|
|
115
113
|
const checkpointGlobalVariables = await this.buildCheckpointGlobalVariables(coinbase, feeRecipient, slot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { GlobalVariableBuilder } from './global_builder.js';
|
|
1
|
+
export { GlobalVariableBuilder, type GlobalVariableBuilderConfig } from './global_builder.js';
|