@aztec/stdlib 5.0.0-nightly.20260611 → 5.0.0-nightly.20260613
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/block/l2_block_source.d.ts +7 -1
- package/dest/block/l2_block_source.d.ts.map +1 -1
- package/dest/block/l2_block_stream/interfaces.d.ts +44 -8
- package/dest/block/l2_block_stream/interfaces.d.ts.map +1 -1
- package/dest/block/l2_block_stream/l2_block_stream.d.ts +1 -1
- package/dest/block/l2_block_stream/l2_block_stream.d.ts.map +1 -1
- package/dest/block/l2_block_stream/l2_block_stream.js +13 -4
- package/dest/block/l2_block_stream/l2_tips_memory_store.d.ts +6 -12
- package/dest/block/l2_block_stream/l2_tips_memory_store.d.ts.map +1 -1
- package/dest/block/l2_block_stream/l2_tips_memory_store.js +8 -32
- package/dest/block/l2_block_stream/l2_tips_store_base.d.ts +9 -18
- package/dest/block/l2_block_stream/l2_tips_store_base.d.ts.map +1 -1
- package/dest/block/l2_block_stream/l2_tips_store_base.js +52 -58
- package/dest/block/test/l2_tips_store_test_suite.d.ts +1 -1
- package/dest/block/test/l2_tips_store_test_suite.d.ts.map +1 -1
- package/dest/block/test/l2_tips_store_test_suite.js +202 -34
- package/dest/config/index.d.ts +2 -1
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +1 -0
- package/dest/config/network-consensus-config.d.ts +72 -0
- package/dest/config/network-consensus-config.d.ts.map +1 -0
- package/dest/config/network-consensus-config.js +231 -0
- package/dest/config/sequencer-config.d.ts +3 -1
- package/dest/config/sequencer-config.d.ts.map +1 -1
- package/dest/config/sequencer-config.js +5 -4
- package/dest/contract/interfaces/node-info.d.ts +11 -1
- package/dest/contract/interfaces/node-info.d.ts.map +1 -1
- package/dest/contract/interfaces/node-info.js +7 -1
- package/dest/gas/gas_settings.d.ts +7 -13
- package/dest/gas/gas_settings.d.ts.map +1 -1
- package/dest/gas/gas_settings.js +9 -16
- package/dest/gas/index.d.ts +2 -1
- package/dest/gas/index.d.ts.map +1 -1
- package/dest/gas/index.js +1 -0
- package/dest/gas/tx_gas_limits.d.ts +72 -0
- package/dest/gas/tx_gas_limits.d.ts.map +1 -0
- package/dest/gas/tx_gas_limits.js +85 -0
- package/dest/interfaces/aztec-node-admin.d.ts +18 -17
- package/dest/interfaces/aztec-node-admin.d.ts.map +1 -1
- package/dest/interfaces/aztec-node-admin.js +1 -1
- package/dest/interfaces/aztec-node-debug.d.ts +15 -2
- package/dest/interfaces/aztec-node-debug.d.ts.map +1 -1
- package/dest/interfaces/aztec-node-debug.js +9 -1
- package/dest/interfaces/aztec-node.d.ts +40 -11
- package/dest/interfaces/aztec-node.d.ts.map +1 -1
- package/dest/interfaces/aztec-node.js +42 -5
- package/dest/interfaces/block-builder.d.ts +3 -1
- package/dest/interfaces/block-builder.d.ts.map +1 -1
- package/dest/interfaces/client.d.ts +2 -1
- package/dest/interfaces/client.d.ts.map +1 -1
- package/dest/interfaces/configs.d.ts +12 -6
- package/dest/interfaces/configs.d.ts.map +1 -1
- package/dest/interfaces/configs.js +2 -1
- package/dest/interfaces/get_tx_by_hash_options.d.ts +9 -0
- package/dest/interfaces/get_tx_by_hash_options.d.ts.map +1 -0
- package/dest/interfaces/get_tx_by_hash_options.js +4 -0
- package/dest/interfaces/p2p.d.ts +32 -8
- package/dest/interfaces/p2p.d.ts.map +1 -1
- package/dest/interfaces/p2p.js +12 -2
- package/dest/interfaces/proving-job.d.ts +70 -70
- package/dest/interfaces/validator.d.ts +3 -3
- package/dest/interfaces/validator.d.ts.map +1 -1
- package/dest/interfaces/validator.js +1 -1
- package/dest/tests/factories.d.ts +1 -1
- package/dest/tests/factories.d.ts.map +1 -1
- package/dest/tests/factories.js +4 -1
- package/dest/tests/mocks.d.ts +1 -1
- package/dest/tests/mocks.d.ts.map +1 -1
- package/dest/tests/mocks.js +3 -2
- package/dest/timetable/budgets.d.ts +4 -2
- package/dest/timetable/budgets.d.ts.map +1 -1
- package/dest/timetable/budgets.js +2 -1
- package/dest/timetable/build_proposer_timetable.d.ts +21 -0
- package/dest/timetable/build_proposer_timetable.d.ts.map +1 -0
- package/dest/timetable/build_proposer_timetable.js +17 -0
- package/dest/timetable/consensus_timetable.d.ts +5 -7
- package/dest/timetable/consensus_timetable.d.ts.map +1 -1
- package/dest/timetable/consensus_timetable.js +6 -8
- package/dest/timetable/index.d.ts +2 -1
- package/dest/timetable/index.d.ts.map +1 -1
- package/dest/timetable/index.js +1 -0
- package/dest/timetable/proposer_timetable.d.ts +18 -24
- package/dest/timetable/proposer_timetable.d.ts.map +1 -1
- package/dest/timetable/proposer_timetable.js +26 -55
- package/dest/tx/fee_provider.d.ts +2 -2
- package/dest/tx/fee_provider.d.ts.map +1 -1
- package/dest/tx/validator/error_texts.d.ts +2 -2
- package/dest/tx/validator/error_texts.d.ts.map +1 -1
- package/dest/tx/validator/error_texts.js +1 -1
- package/package.json +8 -8
- package/src/block/l2_block_source.ts +7 -0
- package/src/block/l2_block_stream/interfaces.ts +39 -7
- package/src/block/l2_block_stream/l2_block_stream.ts +21 -3
- package/src/block/l2_block_stream/l2_tips_memory_store.ts +12 -41
- package/src/block/l2_block_stream/l2_tips_store_base.ts +63 -93
- package/src/block/test/l2_tips_store_test_suite.ts +197 -24
- package/src/config/index.ts +1 -0
- package/src/config/network-consensus-config.ts +302 -0
- package/src/config/sequencer-config.ts +7 -5
- package/src/contract/interfaces/node-info.ts +11 -0
- package/src/gas/README.md +92 -0
- package/src/gas/gas_settings.ts +11 -21
- package/src/gas/index.ts +1 -0
- package/src/gas/tx_gas_limits.ts +123 -0
- package/src/interfaces/aztec-node-admin.ts +1 -1
- package/src/interfaces/aztec-node-debug.ts +17 -2
- package/src/interfaces/aztec-node.ts +74 -13
- package/src/interfaces/block-builder.ts +2 -0
- package/src/interfaces/client.ts +1 -0
- package/src/interfaces/configs.ts +10 -6
- package/src/interfaces/get_tx_by_hash_options.ts +14 -0
- package/src/interfaces/p2p.ts +21 -8
- package/src/interfaces/validator.ts +5 -5
- package/src/tests/factories.ts +7 -1
- package/src/tests/mocks.ts +7 -2
- package/src/timetable/README.md +10 -2
- package/src/timetable/budgets.ts +5 -2
- package/src/timetable/build_proposer_timetable.ts +42 -0
- package/src/timetable/consensus_timetable.ts +8 -14
- package/src/timetable/index.ts +1 -0
- package/src/timetable/proposer_timetable.ts +37 -61
- package/src/tx/fee_provider.ts +1 -1
- package/src/tx/validator/error_texts.ts +2 -1
|
@@ -17,18 +17,16 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
17
17
|
}
|
|
18
18
|
getL2Tips() {
|
|
19
19
|
return this.runInTransaction(async ()=>{
|
|
20
|
-
const [proposedBlockId, finalizedBlockId, provenBlockId, checkpointedBlockId
|
|
20
|
+
const [proposedBlockId, finalizedBlockId, provenBlockId, checkpointedBlockId] = await Promise.all([
|
|
21
21
|
this.getBlockId('proposed'),
|
|
22
22
|
this.getBlockId('finalized'),
|
|
23
23
|
this.getBlockId('proven'),
|
|
24
|
-
this.getBlockId('checkpointed')
|
|
25
|
-
this.getBlockId('proposedCheckpoint')
|
|
24
|
+
this.getBlockId('checkpointed')
|
|
26
25
|
]);
|
|
27
|
-
const [finalizedCheckpointId, provenCheckpointId, checkpointedCheckpointId
|
|
26
|
+
const [finalizedCheckpointId, provenCheckpointId, checkpointedCheckpointId] = await Promise.all([
|
|
28
27
|
this.getCheckpointId('finalized'),
|
|
29
28
|
this.getCheckpointId('proven'),
|
|
30
|
-
this.getCheckpointId('checkpointed')
|
|
31
|
-
this.getCheckpointId('proposedCheckpoint')
|
|
29
|
+
this.getCheckpointId('checkpointed')
|
|
32
30
|
]);
|
|
33
31
|
return {
|
|
34
32
|
proposed: proposedBlockId,
|
|
@@ -43,10 +41,6 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
43
41
|
checkpointed: {
|
|
44
42
|
block: checkpointedBlockId,
|
|
45
43
|
checkpoint: checkpointedCheckpointId
|
|
46
|
-
},
|
|
47
|
-
proposedCheckpoint: {
|
|
48
|
-
block: proposedCheckpointBlockId,
|
|
49
|
-
checkpoint: proposedCheckpointId
|
|
50
44
|
}
|
|
51
45
|
};
|
|
52
46
|
});
|
|
@@ -95,25 +89,22 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
95
89
|
async getCheckpointId(tag) {
|
|
96
90
|
const blockNumber = await this.getTip(tag);
|
|
97
91
|
if (blockNumber === undefined || blockNumber === 0) {
|
|
98
|
-
return
|
|
99
|
-
number: CheckpointNumber.ZERO,
|
|
100
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
const checkpointNumber = await this.getCheckpointNumberForBlock(blockNumber);
|
|
104
|
-
if (checkpointNumber === undefined) {
|
|
105
|
-
return {
|
|
106
|
-
number: CheckpointNumber.ZERO,
|
|
107
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
108
|
-
};
|
|
92
|
+
return this.genesisCheckpointId();
|
|
109
93
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
94
|
+
// The checkpoint id recorded for this cursor when it was last advanced is the single source of truth.
|
|
95
|
+
// The writers (handleChainCheckpointed/Proven/Finalized/Pruned) always record an id alongside any
|
|
96
|
+
// non-genesis cursor advance, so a missing id on a real block is genuine store corruption. Fail loudly
|
|
97
|
+
// rather than silently reporting checkpoint zero, which would drive a checkpoint-replay storm.
|
|
98
|
+
const storedCheckpoint = await this.getTipCheckpoint(tag);
|
|
99
|
+
if (storedCheckpoint !== undefined) {
|
|
100
|
+
return storedCheckpoint;
|
|
113
101
|
}
|
|
102
|
+
throw new Error(`No checkpoint id recorded for ${tag} tip at block ${blockNumber}; the L2 tips store is corrupted`);
|
|
103
|
+
}
|
|
104
|
+
genesisCheckpointId() {
|
|
114
105
|
return {
|
|
115
|
-
number:
|
|
116
|
-
hash:
|
|
106
|
+
number: CheckpointNumber.ZERO,
|
|
107
|
+
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
117
108
|
};
|
|
118
109
|
}
|
|
119
110
|
async handleBlocksAdded(event) {
|
|
@@ -133,14 +124,12 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
133
124
|
return;
|
|
134
125
|
}
|
|
135
126
|
await this.runInTransaction(async ()=>{
|
|
127
|
+
const checkpointId = {
|
|
128
|
+
number: event.checkpoint.checkpoint.number,
|
|
129
|
+
hash: event.checkpoint.checkpoint.hash().toString()
|
|
130
|
+
};
|
|
136
131
|
await this.saveTag('checkpointed', event.block);
|
|
137
|
-
await this.
|
|
138
|
-
// proposedCheckpoint is always >= checkpointed. If checkpointed has caught up
|
|
139
|
-
// or surpassed it, advance proposedCheckpoint to match.
|
|
140
|
-
const proposedCheckpointBlock = await this.getBlockId('proposedCheckpoint');
|
|
141
|
-
if (event.block.number > proposedCheckpointBlock.number) {
|
|
142
|
-
await this.saveTag('proposedCheckpoint', event.block);
|
|
143
|
-
}
|
|
132
|
+
await this.setTipCheckpoint('checkpointed', checkpointId);
|
|
144
133
|
});
|
|
145
134
|
}
|
|
146
135
|
async handleChainPruned(event) {
|
|
@@ -148,12 +137,32 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
148
137
|
return;
|
|
149
138
|
}
|
|
150
139
|
await this.runInTransaction(async ()=>{
|
|
140
|
+
// A prune is a rollback: the proposed tip moves to the prune target unconditionally, but
|
|
141
|
+
// checkpoint-bearing cursors may only move backward. Forward-advancing them onto an
|
|
142
|
+
// uncheckpointed block leaves them on a block with no recorded checkpoint id, which getCheckpointId
|
|
143
|
+
// would then throw on.
|
|
151
144
|
await this.saveTag('proposed', event.block);
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
145
|
+
// Clamp each checkpoint-bearing cursor down to its OWN source tip when it leads it. Clamping the proven
|
|
146
|
+
// cursor onto the checkpointed tip would transiently report unproven blocks as proven (the source's proven
|
|
147
|
+
// tip can sit below its checkpointed tip after a proof-tx reorg), until the corrective chain-proven event
|
|
148
|
+
// lands at the end of the same sync iteration. The event carries a valid (block, id) pair for each
|
|
149
|
+
// boundary, so the clamped cursor always resolves to a recorded id. The source guarantees proven <=
|
|
150
|
+
// checkpointed, so clamping each cursor to its own tip preserves the local proven <= checkpointed invariant.
|
|
151
|
+
for (const { tag, sourceTip } of [
|
|
152
|
+
{
|
|
153
|
+
tag: 'checkpointed',
|
|
154
|
+
sourceTip: event.checkpointed
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
tag: 'proven',
|
|
158
|
+
sourceTip: event.proven
|
|
159
|
+
}
|
|
160
|
+
]){
|
|
161
|
+
const current = await this.getTip(tag);
|
|
162
|
+
if (current !== undefined && current > sourceTip.block.number) {
|
|
163
|
+
await this.saveTag(tag, sourceTip.block);
|
|
164
|
+
await this.setTipCheckpoint(tag, sourceTip.checkpoint);
|
|
165
|
+
}
|
|
157
166
|
}
|
|
158
167
|
});
|
|
159
168
|
}
|
|
@@ -163,6 +172,7 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
163
172
|
}
|
|
164
173
|
await this.runInTransaction(async ()=>{
|
|
165
174
|
await this.saveTag('proven', event.block);
|
|
175
|
+
await this.setTipCheckpoint('proven', event.checkpoint);
|
|
166
176
|
});
|
|
167
177
|
}
|
|
168
178
|
async handleChainFinalized(event) {
|
|
@@ -171,26 +181,19 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
171
181
|
}
|
|
172
182
|
await this.runInTransaction(async ()=>{
|
|
173
183
|
await this.saveTag('finalized', event.block);
|
|
174
|
-
|
|
175
|
-
//
|
|
176
|
-
//
|
|
177
|
-
//
|
|
184
|
+
await this.setTipCheckpoint('finalized', event.checkpoint);
|
|
185
|
+
// Prune block hashes below the lowest live tip. Cap the deletion bound at the lowest live tip rather
|
|
186
|
+
// than the finalized tip alone: this should always be the finalized tip, but we have hit bugs where
|
|
187
|
+
// this is not the case. Deleting the block hash for a live tip would dangle subsequent `getBlockId`
|
|
178
188
|
// lookups and lock the block stream into an error loop.
|
|
179
189
|
const tips = await Promise.all([
|
|
180
190
|
this.getTip('proposed'),
|
|
181
|
-
this.getTip('proposedCheckpoint'),
|
|
182
191
|
this.getTip('checkpointed'),
|
|
183
192
|
this.getTip('proven')
|
|
184
193
|
]);
|
|
185
194
|
const liveTipBlocks = tips.filter((t)=>t !== undefined && t > 0);
|
|
186
195
|
const safeBlockBound = BlockNumber(Math.min(event.block.number, ...liveTipBlocks));
|
|
187
196
|
await this.deleteBlockHashesBefore(safeBlockBound);
|
|
188
|
-
await this.deleteBlockToCheckpointBefore(safeBlockBound);
|
|
189
|
-
if (finalizedCheckpointNumber !== undefined) {
|
|
190
|
-
const tipCheckpoints = await Promise.all(liveTipBlocks.map((b)=>this.getCheckpointNumberForBlock(b)));
|
|
191
|
-
const safeCheckpointBound = CheckpointNumber(Math.min(finalizedCheckpointNumber, ...tipCheckpoints.filter((c)=>c !== undefined && c > 0)));
|
|
192
|
-
await this.deleteCheckpointsBefore(safeCheckpointBound);
|
|
193
|
-
}
|
|
194
197
|
});
|
|
195
198
|
}
|
|
196
199
|
async saveTag(name, block) {
|
|
@@ -199,13 +202,4 @@ import { GENESIS_CHECKPOINT_HEADER_HASH } from '../l2_block_source.js';
|
|
|
199
202
|
await this.setBlockHash(block.number, block.hash);
|
|
200
203
|
}
|
|
201
204
|
}
|
|
202
|
-
async saveCheckpoint(publishedCheckpoint) {
|
|
203
|
-
const checkpoint = publishedCheckpoint.checkpoint;
|
|
204
|
-
const lastBlock = checkpoint.blocks.at(-1);
|
|
205
|
-
// Only store the mapping for the last block since tips only point to checkpoint boundaries
|
|
206
|
-
await Promise.all([
|
|
207
|
-
this.setCheckpointNumberForBlock(lastBlock.number, checkpoint.number),
|
|
208
|
-
this.saveCheckpointData(publishedCheckpoint)
|
|
209
|
-
]);
|
|
210
|
-
}
|
|
211
205
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { L2TipsStore } from '../l2_block_stream/index.js';
|
|
2
2
|
export declare function testL2TipsStore(makeTipsStore: () => Promise<L2TipsStore>): void;
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibDJfdGlwc19zdG9yZV90ZXN0X3N1aXRlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYmxvY2svdGVzdC9sMl90aXBzX3N0b3JlX3Rlc3Rfc3VpdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBZ0JBLE9BQU8sS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRS9ELHdCQUFnQixlQUFlLENBQUMsYUFBYSxFQUFFLE1BQU0sT0FBTyxDQUFDLFdBQVcsQ0FBQyxRQTByQnhFIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"l2_tips_store_test_suite.d.ts","sourceRoot":"","sources":["../../../src/block/test/l2_tips_store_test_suite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"l2_tips_store_test_suite.d.ts","sourceRoot":"","sources":["../../../src/block/test/l2_tips_store_test_suite.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE/D,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,QA0rBxE"}
|
|
@@ -62,12 +62,11 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
62
62
|
block: makeTip(blockNumber),
|
|
63
63
|
checkpoint: makeCheckpointIdForBlock(blockNumber)
|
|
64
64
|
});
|
|
65
|
-
const makeTips = (proposed, proven, finalized, checkpointed = 0
|
|
65
|
+
const makeTips = (proposed, proven, finalized, checkpointed = 0)=>({
|
|
66
66
|
proposed: makeTip(proposed),
|
|
67
67
|
proven: makeTipId(proven),
|
|
68
68
|
finalized: makeTipId(finalized),
|
|
69
|
-
checkpointed: makeTipId(checkpointed)
|
|
70
|
-
proposedCheckpoint: makeTipId(proposedCheckpoint)
|
|
69
|
+
checkpointed: makeTipId(checkpointed)
|
|
71
70
|
});
|
|
72
71
|
const makeCheckpoint = async (checkpointNumber, blocks)=>{
|
|
73
72
|
const checkpoint = await Checkpoint.random(CheckpointNumber(checkpointNumber), {
|
|
@@ -139,7 +138,8 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
139
138
|
// Prove up to block 5
|
|
140
139
|
await tipsStore.handleBlockStreamEvent({
|
|
141
140
|
type: 'chain-proven',
|
|
142
|
-
block: makeBlockId(5)
|
|
141
|
+
block: makeBlockId(5),
|
|
142
|
+
checkpoint: makeCheckpointIdForBlock(5)
|
|
143
143
|
});
|
|
144
144
|
const tips = await tipsStore.getL2Tips();
|
|
145
145
|
expect(tips.proposed).toEqual(makeTip(5));
|
|
@@ -161,11 +161,13 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
161
161
|
// Prove and finalize
|
|
162
162
|
await tipsStore.handleBlockStreamEvent({
|
|
163
163
|
type: 'chain-proven',
|
|
164
|
-
block: makeBlockId(5)
|
|
164
|
+
block: makeBlockId(5),
|
|
165
|
+
checkpoint: makeCheckpointIdForBlock(5)
|
|
165
166
|
});
|
|
166
167
|
await tipsStore.handleBlockStreamEvent({
|
|
167
168
|
type: 'chain-finalized',
|
|
168
|
-
block: makeBlockId(5)
|
|
169
|
+
block: makeBlockId(5),
|
|
170
|
+
checkpoint: makeCheckpointIdForBlock(5)
|
|
169
171
|
});
|
|
170
172
|
const tips = await tipsStore.getL2Tips();
|
|
171
173
|
expect(tips.proposed).toEqual(makeTip(5));
|
|
@@ -223,11 +225,13 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
223
225
|
// Prove and finalize up to block 3 (checkpoint 1)
|
|
224
226
|
await tipsStore.handleBlockStreamEvent({
|
|
225
227
|
type: 'chain-proven',
|
|
226
|
-
block: makeBlockId(3)
|
|
228
|
+
block: makeBlockId(3),
|
|
229
|
+
checkpoint: makeCheckpointIdForBlock(3)
|
|
227
230
|
});
|
|
228
231
|
await tipsStore.handleBlockStreamEvent({
|
|
229
232
|
type: 'chain-finalized',
|
|
230
|
-
block: makeBlockId(3)
|
|
233
|
+
block: makeBlockId(3),
|
|
234
|
+
checkpoint: makeCheckpointIdForBlock(3)
|
|
231
235
|
});
|
|
232
236
|
// Blocks before finalized should be cleared
|
|
233
237
|
expect(await tipsStore.getL2BlockHash(1)).toBeUndefined();
|
|
@@ -247,10 +251,8 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
247
251
|
await tipsStore.handleBlockStreamEvent({
|
|
248
252
|
type: 'chain-pruned',
|
|
249
253
|
block: makeBlockId(5),
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
253
|
-
}
|
|
254
|
+
checkpointed: makeTipId(0),
|
|
255
|
+
proven: makeTipId(0)
|
|
254
256
|
});
|
|
255
257
|
const tips = await tipsStore.getL2Tips();
|
|
256
258
|
expect(tips.proposed).toEqual(makeTip(5));
|
|
@@ -272,10 +274,8 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
272
274
|
await tipsStore.handleBlockStreamEvent({
|
|
273
275
|
type: 'chain-pruned',
|
|
274
276
|
block: makeTip(0),
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
278
|
-
}
|
|
277
|
+
checkpointed: makeTipId(0),
|
|
278
|
+
proven: makeTipId(0)
|
|
279
279
|
});
|
|
280
280
|
tips = await tipsStore.getL2Tips();
|
|
281
281
|
expect(tips.proposed).toEqual(makeTip(0));
|
|
@@ -336,10 +336,8 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
336
336
|
await tipsStore.handleBlockStreamEvent({
|
|
337
337
|
type: 'chain-pruned',
|
|
338
338
|
block: makeBlockId(5),
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
342
|
-
}
|
|
339
|
+
checkpointed: makeTipId(5),
|
|
340
|
+
proven: makeTipId(0)
|
|
343
341
|
});
|
|
344
342
|
tips = await tipsStore.getL2Tips();
|
|
345
343
|
expect(tips.proposed).toEqual(makeTip(5));
|
|
@@ -399,10 +397,8 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
399
397
|
await tipsStore.handleBlockStreamEvent({
|
|
400
398
|
type: 'chain-pruned',
|
|
401
399
|
block: makeBlockId(3),
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
405
|
-
}
|
|
400
|
+
checkpointed: makeTipId(3),
|
|
401
|
+
proven: makeTipId(0)
|
|
406
402
|
});
|
|
407
403
|
tips = await tipsStore.getL2Tips();
|
|
408
404
|
expect(tips.proposed).toEqual(makeTip(3));
|
|
@@ -439,7 +435,8 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
439
435
|
// Prove up to block 3
|
|
440
436
|
await tipsStore.handleBlockStreamEvent({
|
|
441
437
|
type: 'chain-proven',
|
|
442
|
-
block: makeBlockId(3)
|
|
438
|
+
block: makeBlockId(3),
|
|
439
|
+
checkpoint: makeCheckpointIdForBlock(3)
|
|
443
440
|
});
|
|
444
441
|
let tips = await tipsStore.getL2Tips();
|
|
445
442
|
expect(tips.proposed).toEqual(makeTip(3));
|
|
@@ -479,10 +476,8 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
479
476
|
await tipsStore.handleBlockStreamEvent({
|
|
480
477
|
type: 'chain-pruned',
|
|
481
478
|
block: makeBlockId(3),
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
hash: GENESIS_CHECKPOINT_HEADER_HASH.toString()
|
|
485
|
-
}
|
|
479
|
+
checkpointed: makeTipId(3),
|
|
480
|
+
proven: makeTipId(3)
|
|
486
481
|
});
|
|
487
482
|
tips = await tipsStore.getL2Tips();
|
|
488
483
|
expect(tips.proposed).toEqual(makeTip(3));
|
|
@@ -525,22 +520,195 @@ export function testL2TipsStore(makeTipsStore) {
|
|
|
525
520
|
expect(await tipsStore.getL2BlockHash(6)).not.toEqual(originalHash6);
|
|
526
521
|
expect(await tipsStore.getL2BlockHash(7)).not.toEqual(originalHash7);
|
|
527
522
|
});
|
|
528
|
-
// Regression test for #13142
|
|
529
|
-
|
|
523
|
+
// Regression test for #13142: proving an unseen block number (one with no local block->checkpoint
|
|
524
|
+
// mapping) must not blow up. With per-cursor checkpoint ids, the proven tip resolves to the
|
|
525
|
+
// checkpoint id carried by the event rather than falling back to checkpoint zero.
|
|
526
|
+
it('resolves the proven checkpoint from the carried id when setting proven on an unseen block number', async ()=>{
|
|
530
527
|
await tipsStore.handleBlockStreamEvent({
|
|
531
528
|
type: 'blocks-added',
|
|
532
529
|
blocks: [
|
|
533
530
|
await makeBlock(5)
|
|
534
531
|
]
|
|
535
532
|
});
|
|
533
|
+
// Block 3 has no local block->checkpoint mapping, but the event carries a real checkpoint id.
|
|
534
|
+
const carriedCheckpoint = {
|
|
535
|
+
number: CheckpointNumber(1),
|
|
536
|
+
hash: new Fr(42).toString()
|
|
537
|
+
};
|
|
536
538
|
await tipsStore.handleBlockStreamEvent({
|
|
537
539
|
type: 'chain-proven',
|
|
538
|
-
block: makeBlockId(3)
|
|
540
|
+
block: makeBlockId(3),
|
|
541
|
+
checkpoint: carriedCheckpoint
|
|
539
542
|
});
|
|
540
543
|
const tips = await tipsStore.getL2Tips();
|
|
541
544
|
expect(tips.proposed).toEqual(makeTip(5));
|
|
542
545
|
expect(tips.proven.block).toEqual(makeTip(3));
|
|
543
|
-
//
|
|
544
|
-
expect(tips.proven.checkpoint
|
|
546
|
+
// Resolved from the carried id, not the (missing) local mapping.
|
|
547
|
+
expect(tips.proven.checkpoint).toEqual(carriedCheckpoint);
|
|
548
|
+
});
|
|
549
|
+
// proven/finalized resolve to the carried checkpoint id even when the block has no local
|
|
550
|
+
// block->checkpoint mapping (the cursor legitimately leads the locally-checkpointed frontier).
|
|
551
|
+
it('resolves proven and finalized checkpoints from carried ids without a local mapping', async ()=>{
|
|
552
|
+
await tipsStore.handleBlockStreamEvent({
|
|
553
|
+
type: 'blocks-added',
|
|
554
|
+
blocks: [
|
|
555
|
+
await makeBlock(7)
|
|
556
|
+
]
|
|
557
|
+
});
|
|
558
|
+
const provenCheckpoint = {
|
|
559
|
+
number: CheckpointNumber(2),
|
|
560
|
+
hash: new Fr(101).toString()
|
|
561
|
+
};
|
|
562
|
+
const finalizedCheckpoint = {
|
|
563
|
+
number: CheckpointNumber(1),
|
|
564
|
+
hash: new Fr(100).toString()
|
|
565
|
+
};
|
|
566
|
+
await tipsStore.handleBlockStreamEvent({
|
|
567
|
+
type: 'chain-proven',
|
|
568
|
+
block: makeBlockId(5),
|
|
569
|
+
checkpoint: provenCheckpoint
|
|
570
|
+
});
|
|
571
|
+
await tipsStore.handleBlockStreamEvent({
|
|
572
|
+
type: 'chain-finalized',
|
|
573
|
+
block: makeBlockId(3),
|
|
574
|
+
checkpoint: finalizedCheckpoint
|
|
575
|
+
});
|
|
576
|
+
const tips = await tipsStore.getL2Tips();
|
|
577
|
+
expect(tips.proven.checkpoint).toEqual(provenCheckpoint);
|
|
578
|
+
expect(tips.finalized.checkpoint).toEqual(finalizedCheckpoint);
|
|
579
|
+
});
|
|
580
|
+
// Genuine corruption: a cursor points at a real (non-genesis) block that has a block hash but
|
|
581
|
+
// neither a stored per-cursor checkpoint id nor a block->checkpoint mapping. getL2Tips must throw
|
|
582
|
+
// loudly rather than silently report checkpoint zero. We reach this state by reaching past the
|
|
583
|
+
// event API to place the tip directly, since the normal writers always record an id.
|
|
584
|
+
it('throws when a cursor points at a real block with neither a stored id nor a mapping', async ()=>{
|
|
585
|
+
// blocks-added records the block hash for block 5 (so getBlockId succeeds) but no checkpoint id.
|
|
586
|
+
await tipsStore.handleBlockStreamEvent({
|
|
587
|
+
type: 'blocks-added',
|
|
588
|
+
blocks: [
|
|
589
|
+
await makeBlock(5)
|
|
590
|
+
]
|
|
591
|
+
});
|
|
592
|
+
// Corrupt the proven cursor to point at block 5 without any id or mapping.
|
|
593
|
+
const internal = tipsStore;
|
|
594
|
+
await internal.setTip('proven', BlockNumber(5));
|
|
595
|
+
await expect(tipsStore.getL2Tips()).rejects.toThrow(/checkpoint/i);
|
|
596
|
+
});
|
|
597
|
+
// Backward prune of a leading cursor: a checkpoint-bearing cursor that legitimately leads the source's
|
|
598
|
+
// confirmed checkpointed tip is clamped down to that tip, resolving to the id the prune event carries
|
|
599
|
+
// (never genesis, never a throw). This is the skipped-history shape where the cursor sits on a block
|
|
600
|
+
// ahead of the checkpointed frontier.
|
|
601
|
+
it('clamps a leading checkpoint cursor down to the source checkpointed tip carried by the prune event', async ()=>{
|
|
602
|
+
// Checkpoint blocks 1-5 (checkpointed = block 5 / ckpt 1), then add uncheckpointed blocks 6-10.
|
|
603
|
+
const blocks1to5 = await Promise.all(times(5, (i)=>makeBlock(i + 1)));
|
|
604
|
+
await tipsStore.handleBlockStreamEvent({
|
|
605
|
+
type: 'blocks-added',
|
|
606
|
+
blocks: blocks1to5
|
|
607
|
+
});
|
|
608
|
+
const checkpoint1 = await makeCheckpoint(1, blocks1to5);
|
|
609
|
+
await tipsStore.handleBlockStreamEvent(await makeCheckpointedEvent(checkpoint1));
|
|
610
|
+
const blocks6to10 = await Promise.all(times(5, (i)=>makeBlock(i + 6)));
|
|
611
|
+
await tipsStore.handleBlockStreamEvent({
|
|
612
|
+
type: 'blocks-added',
|
|
613
|
+
blocks: blocks6to10
|
|
614
|
+
});
|
|
615
|
+
// Advance the proven cursor onto an uncheckpointed block (8) via a carried id, so it LEADS the
|
|
616
|
+
// source checkpointed tip (block 5) and will be clamped down to it on prune.
|
|
617
|
+
await tipsStore.handleBlockStreamEvent({
|
|
618
|
+
type: 'chain-proven',
|
|
619
|
+
block: makeBlockId(8),
|
|
620
|
+
checkpoint: {
|
|
621
|
+
number: CheckpointNumber(2),
|
|
622
|
+
hash: new Fr(202).toString()
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
// Prune to block 7, carrying the source's confirmed checkpointed and proven tips (both block 5 / ckpt 1
|
|
626
|
+
// here, the source's proven tip having rolled back together with its checkpointed tip).
|
|
627
|
+
await tipsStore.handleBlockStreamEvent({
|
|
628
|
+
type: 'chain-pruned',
|
|
629
|
+
block: makeBlockId(7),
|
|
630
|
+
checkpointed: makeTipId(5),
|
|
631
|
+
proven: makeTipId(5)
|
|
632
|
+
});
|
|
633
|
+
// Must not throw; the proven cursor is clamped to the carried proven tip, resolving to ckpt 1.
|
|
634
|
+
const tips = await tipsStore.getL2Tips();
|
|
635
|
+
expect(tips.proposed).toEqual(makeTip(7));
|
|
636
|
+
expect(tips.proven.block).toEqual(makeTip(5));
|
|
637
|
+
expect(tips.proven.checkpoint.number).toEqual(CheckpointNumber(1));
|
|
638
|
+
});
|
|
639
|
+
it('keeps the checkpointed tip when pruning to an uncheckpointed block ahead of it', async ()=>{
|
|
640
|
+
const blocks1to5 = await Promise.all(times(5, (i)=>makeBlock(i + 1)));
|
|
641
|
+
await tipsStore.handleBlockStreamEvent({
|
|
642
|
+
type: 'blocks-added',
|
|
643
|
+
blocks: blocks1to5
|
|
644
|
+
});
|
|
645
|
+
const checkpoint1 = await makeCheckpoint(1, blocks1to5);
|
|
646
|
+
await tipsStore.handleBlockStreamEvent(await makeCheckpointedEvent(checkpoint1)); // checkpointed = block 5 / ckpt 1
|
|
647
|
+
const blocks6to7 = await Promise.all(times(2, (i)=>makeBlock(i + 6)));
|
|
648
|
+
await tipsStore.handleBlockStreamEvent({
|
|
649
|
+
type: 'blocks-added',
|
|
650
|
+
blocks: blocks6to7
|
|
651
|
+
}); // proposed = 7
|
|
652
|
+
// Prune to block 6: an uncheckpointed block AHEAD of the checkpointed tip (block 5). The source
|
|
653
|
+
// checkpointed tip is still block 5 / ckpt 1, so the checkpointed cursor must not move.
|
|
654
|
+
await tipsStore.handleBlockStreamEvent({
|
|
655
|
+
type: 'chain-pruned',
|
|
656
|
+
block: makeBlockId(6),
|
|
657
|
+
checkpointed: makeTipId(5),
|
|
658
|
+
proven: makeTipId(0)
|
|
659
|
+
});
|
|
660
|
+
const tips = await tipsStore.getL2Tips();
|
|
661
|
+
expect(tips.proposed).toEqual(makeTip(6));
|
|
662
|
+
expect(tips.checkpointed.block).toEqual(makeTip(5));
|
|
663
|
+
expect(tips.checkpointed.checkpoint.number).toEqual(CheckpointNumber(1)); // must NOT be zero
|
|
664
|
+
});
|
|
665
|
+
// Per-cursor clamping on prune: when the source rolls back its proven tip below its checkpointed tip
|
|
666
|
+
// (e.g. a proof tx dropped by an L1 reorg), the prune event carries both source tips and each local
|
|
667
|
+
// cursor must clamp to its OWN source tip. Clamping the proven cursor onto the (higher) checkpointed
|
|
668
|
+
// tip would transiently report unproven blocks as proven until the corrective chain-proven event lands.
|
|
669
|
+
it('clamps the proven cursor to the source proven tip, separately from the checkpointed cursor, on prune', async ()=>{
|
|
670
|
+
// Checkpoint blocks 1-15 across three checkpoints (ckpt 1 = 1-5, ckpt 2 = 6-10, ckpt 3 = 11-15).
|
|
671
|
+
const blocks1to5 = await Promise.all(times(5, (i)=>makeBlock(i + 1)));
|
|
672
|
+
await tipsStore.handleBlockStreamEvent({
|
|
673
|
+
type: 'blocks-added',
|
|
674
|
+
blocks: blocks1to5
|
|
675
|
+
});
|
|
676
|
+
await tipsStore.handleBlockStreamEvent(await makeCheckpointedEvent(await makeCheckpoint(1, blocks1to5)));
|
|
677
|
+
const blocks6to10 = await Promise.all(times(5, (i)=>makeBlock(i + 6)));
|
|
678
|
+
await tipsStore.handleBlockStreamEvent({
|
|
679
|
+
type: 'blocks-added',
|
|
680
|
+
blocks: blocks6to10
|
|
681
|
+
});
|
|
682
|
+
await tipsStore.handleBlockStreamEvent(await makeCheckpointedEvent(await makeCheckpoint(2, blocks6to10)));
|
|
683
|
+
const blocks11to15 = await Promise.all(times(5, (i)=>makeBlock(i + 11)));
|
|
684
|
+
await tipsStore.handleBlockStreamEvent({
|
|
685
|
+
type: 'blocks-added',
|
|
686
|
+
blocks: blocks11to15
|
|
687
|
+
});
|
|
688
|
+
await tipsStore.handleBlockStreamEvent(await makeCheckpointedEvent(await makeCheckpoint(3, blocks11to15)));
|
|
689
|
+
// Prove the whole chain up to block 15 (ckpt 3), so the local proven cursor leads both source tips below.
|
|
690
|
+
await tipsStore.handleBlockStreamEvent({
|
|
691
|
+
type: 'chain-proven',
|
|
692
|
+
block: makeBlockId(15),
|
|
693
|
+
checkpoint: makeCheckpointIdForBlock(15)
|
|
694
|
+
});
|
|
695
|
+
let tips = await tipsStore.getL2Tips();
|
|
696
|
+
expect(tips.checkpointed.block).toEqual(makeTip(15));
|
|
697
|
+
expect(tips.proven.block).toEqual(makeTip(15));
|
|
698
|
+
// Prune arrives with the source's proven tip (block 5 / ckpt 1) BELOW its checkpointed tip (block 10 /
|
|
699
|
+
// ckpt 2) and below the local proven cursor (block 15). Each cursor must clamp to its own source tip.
|
|
700
|
+
await tipsStore.handleBlockStreamEvent({
|
|
701
|
+
type: 'chain-pruned',
|
|
702
|
+
block: makeBlockId(10),
|
|
703
|
+
checkpointed: makeTipId(10),
|
|
704
|
+
proven: makeTipId(5)
|
|
705
|
+
});
|
|
706
|
+
tips = await tipsStore.getL2Tips();
|
|
707
|
+
// The proven cursor lands exactly on the source proven tip, NOT on the (higher) checkpointed tip.
|
|
708
|
+
expect(tips.proven.block).toEqual(makeTip(5));
|
|
709
|
+
expect(tips.proven.checkpoint.number).toEqual(CheckpointNumber(1));
|
|
710
|
+
// The checkpointed cursor lands on the source checkpointed tip.
|
|
711
|
+
expect(tips.checkpointed.block).toEqual(makeTip(10));
|
|
712
|
+
expect(tips.checkpointed.checkpoint.number).toEqual(CheckpointNumber(2));
|
|
545
713
|
});
|
|
546
714
|
}
|
package/dest/config/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './chain-config.js';
|
|
2
|
+
export * from './network-consensus-config.js';
|
|
2
3
|
export * from './node-rpc-config.js';
|
|
3
4
|
export * from './sequencer-config.js';
|
|
4
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLCtCQUErQixDQUFDO0FBQzlDLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyx1QkFBdUIsQ0FBQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC"}
|
package/dest/config/index.js
CHANGED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type L1ContractsConfig } from '@aztec/ethereum/config';
|
|
2
|
+
import type { SequencerConfig } from '../interfaces/configs.js';
|
|
3
|
+
/**
|
|
4
|
+
* Environment variables whose values must be identical across every node of a network. They fall into three
|
|
5
|
+
* categories, all consensus-critical:
|
|
6
|
+
*
|
|
7
|
+
* - Timing/protocol consensus: slot and epoch durations, block sub-slot duration, max blocks per checkpoint, and
|
|
8
|
+
* the checkpoint-proposal materialization grace. Proposers and validators must agree on these to land on the
|
|
9
|
+
* same proposed chain and the same checkpoint-proposal receive/handoff deadlines.
|
|
10
|
+
* - Network identity and L1-posted deployment params: the L1 chain id and the staking/governance/slashing
|
|
11
|
+
* parameters baked into the deployed rollup contract (committee size, lags, thresholds, mana target, fee
|
|
12
|
+
* pricing, governance/slashing round sizes, quorums, slash amounts, etc.). A node disagreeing with the rollup
|
|
13
|
+
* it points at would compute the wrong epoch geometry, fees, or slashing rounds.
|
|
14
|
+
* - Node-side slashing offense consensus: the offense detection/penalty parameters validators apply locally to
|
|
15
|
+
* decide which payloads to sign. Validators must agree on these to reach the on-chain slashing quorum.
|
|
16
|
+
*
|
|
17
|
+
* Deliberately excluded: bootnodes, P2P/store/OTEL/sentinel settings, SEQ_MIN_TX_PER_BLOCK, SEQ_MAX_TX_PER_*,
|
|
18
|
+
* AZTEC_SLASHER_ENABLED, PROVER_REAL_PROOFS, TRANSACTIONS_DISABLED, and AZTEC_ENTRY_QUEUE_* (mainnet-only genesis
|
|
19
|
+
* params enforced by L1).
|
|
20
|
+
*/
|
|
21
|
+
export declare const NETWORK_CONSENSUS_ENV_VARS: readonly ["ETHEREUM_SLOT_DURATION", "AZTEC_SLOT_DURATION", "AZTEC_EPOCH_DURATION", "SEQ_BLOCK_DURATION_MS", "MAX_BLOCKS_PER_CHECKPOINT", "CHECKPOINT_PROPOSAL_SYNC_GRACE_SECONDS", "L1_CHAIN_ID", "AZTEC_TARGET_COMMITTEE_SIZE", "AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET", "AZTEC_LAG_IN_EPOCHS_FOR_RANDAO", "AZTEC_ACTIVATION_THRESHOLD", "AZTEC_EJECTION_THRESHOLD", "AZTEC_LOCAL_EJECTION_THRESHOLD", "AZTEC_EXIT_DELAY_SECONDS", "AZTEC_INBOX_LAG", "AZTEC_PROOF_SUBMISSION_EPOCHS", "AZTEC_MANA_TARGET", "AZTEC_PROVING_COST_PER_MANA", "AZTEC_INITIAL_ETH_PER_FEE_ASSET", "AZTEC_GOVERNANCE_PROPOSER_ROUND_SIZE", "AZTEC_GOVERNANCE_PROPOSER_QUORUM", "AZTEC_SLASHING_QUORUM", "AZTEC_SLASHING_ROUND_SIZE_IN_EPOCHS", "AZTEC_SLASHING_LIFETIME_IN_ROUNDS", "AZTEC_SLASHING_OFFSET_IN_ROUNDS", "AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS", "AZTEC_SLASHING_VETOER", "AZTEC_SLASHING_DISABLE_DURATION", "AZTEC_SLASH_AMOUNT_SMALL", "AZTEC_SLASH_AMOUNT_MEDIUM", "AZTEC_SLASH_AMOUNT_LARGE", "SLASH_OFFENSE_EXPIRATION_ROUNDS", "SLASH_MAX_PAYLOAD_SIZE", "SLASH_EXECUTE_ROUNDS_LOOK_BACK", "SLASH_DATA_WITHHOLDING_TOLERANCE_SLOTS", "SLASH_DATA_WITHHOLDING_PENALTY", "SLASH_INACTIVITY_TARGET_PERCENTAGE", "SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD", "SLASH_INACTIVITY_PENALTY", "SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY", "SLASH_DUPLICATE_PROPOSAL_PENALTY", "SLASH_DUPLICATE_ATTESTATION_PENALTY", "SLASH_PROPOSE_DESCENDANT_OF_CHECKPOINT_WITH_INVALID_ATTESTATIONS_PENALTY", "SLASH_ATTEST_INVALID_CHECKPOINT_PROPOSAL_PENALTY", "SLASH_UNKNOWN_PENALTY", "SLASH_INVALID_BLOCK_PENALTY", "SLASH_INVALID_CHECKPOINT_PROPOSAL_PENALTY", "SLASH_GRACE_PERIOD_L2_SLOTS"];
|
|
22
|
+
/** A consensus-critical environment variable name; see {@link NETWORK_CONSENSUS_ENV_VARS}. */
|
|
23
|
+
export type ConsensusEnvVar = (typeof NETWORK_CONSENSUS_ENV_VARS)[number];
|
|
24
|
+
/**
|
|
25
|
+
* The subset of consensus-critical timing config whose geometry can be validated in isolation. Composed by
|
|
26
|
+
* picking the canonical fields from their owning config types so the field set never drifts from the config
|
|
27
|
+
* layer: slot durations from {@link L1ContractsConfig}, block sub-slot/checkpoint timings from
|
|
28
|
+
* {@link SequencerConfig} (whose fields are optional there, hence `Required`).
|
|
29
|
+
*/
|
|
30
|
+
export type NetworkConsensusConfig = Pick<L1ContractsConfig, 'aztecSlotDuration' | 'ethereumSlotDuration'> & Required<Pick<SequencerConfig, 'blockDurationMs' | 'maxBlocksPerCheckpoint' | 'checkpointProposalSyncGraceSeconds'>>;
|
|
31
|
+
/**
|
|
32
|
+
* Extracts the timing {@link NetworkConsensusConfig} from a generated network config object. The env-var names
|
|
33
|
+
* and the per-field parsing both come from the canonical config mappings (`l1ContractsConfigMappings` and
|
|
34
|
+
* `sharedSequencerConfigMappings`), so each field is parsed exactly as the node's config layer would parse it.
|
|
35
|
+
* A field whose env var is absent becomes `NaN`, which {@link validateNetworkConsensusConfig} reports as an
|
|
36
|
+
* error. Never throws: parse helpers that would throw or yield `undefined` are coerced to `NaN`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getConsensusConfigFromNetworkEnv(values: Record<string, string | number | boolean>): NetworkConsensusConfig;
|
|
39
|
+
/**
|
|
40
|
+
* Validates a {@link NetworkConsensusConfig} for self-consistency, returning a list of error messages (empty
|
|
41
|
+
* when valid). Used by the cli unit test that gates the generated network configs.
|
|
42
|
+
*
|
|
43
|
+
* The check requires `maxBlocksPerCheckpoint` to be *exactly* what a {@link ProposerTimetable} built from the
|
|
44
|
+
* same slot timings and the production default budgets derives. This exact-equality requirement ensures the
|
|
45
|
+
* published network value is precisely what the production default budgets produce, so every node running those
|
|
46
|
+
* defaults agrees on the per-checkpoint block count without clamping.
|
|
47
|
+
*/
|
|
48
|
+
export declare function validateNetworkConsensusConfig(config: NetworkConsensusConfig): string[];
|
|
49
|
+
/**
|
|
50
|
+
* Enforces that operators do not silently override consensus-critical values diverging from the network config.
|
|
51
|
+
*
|
|
52
|
+
* For each var in {@link NETWORK_CONSENSUS_ENV_VARS} present in `networkConfig`: if the operator set it in `env`
|
|
53
|
+
* to a conflicting value, this throws unless `ALLOW_OVERRIDING_NETWORK_CONFIG` is truthy (in which case it logs
|
|
54
|
+
* and keeps the operator value).
|
|
55
|
+
*
|
|
56
|
+
* This function is pure: it never writes to `env`. Instead it returns the canonical env writes the caller
|
|
57
|
+
* should apply — a map of env-var name to canonical string value for every numeric var whose env value matched
|
|
58
|
+
* the network value numerically. Applying these closes a bypass where the config layer parses some vars with
|
|
59
|
+
* `parseInt` (which reads '6e3' as 6); rewriting them to the network value's string form keeps the operator's
|
|
60
|
+
* numerically-equal value but in canonical form. Vars kept under `ALLOW_OVERRIDING_NETWORK_CONFIG` (genuine
|
|
61
|
+
* conflicts) are not included, so the operator value is preserved untouched.
|
|
62
|
+
*
|
|
63
|
+
* @returns Canonical env writes (env-var name -> canonical string value) for the caller to apply.
|
|
64
|
+
*/
|
|
65
|
+
export declare function checkConsensusEnvOverrides(networkConfig: Record<string, string | number | boolean>, env?: {
|
|
66
|
+
[key: string]: string | undefined;
|
|
67
|
+
}, log?: (msg: string) => void): Record<string, string>;
|
|
68
|
+
/** Whether the env opts into overriding network-wide consensus values (`ALLOW_OVERRIDING_NETWORK_CONFIG`). */
|
|
69
|
+
export declare function allowsNetworkConfigOverride(env?: {
|
|
70
|
+
[key: string]: string | undefined;
|
|
71
|
+
}): boolean;
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29yay1jb25zZW5zdXMtY29uZmlnLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL25ldHdvcmstY29uc2Vuc3VzLWNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxpQkFBaUIsRUFBNkIsTUFBTSx3QkFBd0IsQ0FBQztBQUczRixPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQVVoRTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxlQUFPLE1BQU0sMEJBQTBCLDJsREFzREQsQ0FBQztBQUV2Qyw4RkFBOEY7QUFDOUYsTUFBTSxNQUFNLGVBQWUsR0FBRyxDQUFDLE9BQU8sMEJBQTBCLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUUxRTs7Ozs7R0FLRztBQUNILE1BQU0sTUFBTSxzQkFBc0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsbUJBQW1CLEdBQUcsc0JBQXNCLENBQUMsR0FDeEcsUUFBUSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsaUJBQWlCLEdBQUcsd0JBQXdCLEdBQUcsb0NBQW9DLENBQUMsQ0FBQyxDQUFDO0FBWXZIOzs7Ozs7R0FNRztBQUNILHdCQUFnQixnQ0FBZ0MsQ0FDOUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FDaEQsc0JBQXNCLENBaUJ4QjtBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsd0JBQWdCLDhCQUE4QixDQUFDLE1BQU0sRUFBRSxzQkFBc0IsR0FBRyxNQUFNLEVBQUUsQ0E4RXZGO0FBRUQ7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsd0JBQWdCLDBCQUEwQixDQUN4QyxhQUFhLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQyxFQUN4RCxHQUFHLEdBQUU7SUFBRSxDQUFDLEdBQUcsRUFBRSxNQUFNLEdBQUcsTUFBTSxHQUFHLFNBQVMsQ0FBQTtDQUFnQixFQUN4RCxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxNQUFNLEtBQUssSUFBSSxHQUMxQixNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQWlEeEI7QUFFRCw4R0FBOEc7QUFDOUcsd0JBQWdCLDJCQUEyQixDQUFDLEdBQUcsR0FBRTtJQUFFLENBQUMsR0FBRyxFQUFFLE1BQU0sR0FBRyxNQUFNLEdBQUcsU0FBUyxDQUFBO0NBQWdCLEdBQUcsT0FBTyxDQUc3RyJ9
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-consensus-config.d.ts","sourceRoot":"","sources":["../../src/config/network-consensus-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAA6B,MAAM,wBAAwB,CAAC;AAG3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAUhE;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,2lDAsDD,CAAC;AAEvC,8FAA8F;AAC9F,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,mBAAmB,GAAG,sBAAsB,CAAC,GACxG,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,iBAAiB,GAAG,wBAAwB,GAAG,oCAAoC,CAAC,CAAC,CAAC;AAYvH;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAChD,sBAAsB,CAiBxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,EAAE,CA8EvF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACxD,GAAG,GAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAgB,EACxD,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC1B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiDxB;AAED,8GAA8G;AAC9G,wBAAgB,2BAA2B,CAAC,GAAG,GAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAgB,GAAG,OAAO,CAG7G"}
|