@aztec/archiver 0.0.1-commit.03f7ef2 → 0.0.1-commit.1142ef1
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/README.md +14 -14
- package/dest/archiver/archiver.d.ts +13 -10
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +514 -57
- package/dest/archiver/archiver_store.d.ts +11 -4
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +16 -36
- package/dest/archiver/config.js +2 -2
- package/dest/archiver/instrumentation.d.ts +1 -1
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +15 -63
- package/dest/archiver/kv_archiver_store/block_store.d.ts +11 -4
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +22 -3
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +5 -4
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +3 -0
- package/dest/archiver/kv_archiver_store/log_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +11 -14
- package/dest/archiver/l1/calldata_retriever.d.ts +2 -2
- package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/archiver/l1/calldata_retriever.js +2 -2
- package/dest/archiver/l1/validate_trace.js +1 -1
- package/dest/archiver/validation.d.ts +4 -4
- package/dest/archiver/validation.d.ts.map +1 -1
- package/dest/archiver/validation.js +1 -1
- package/dest/test/mock_l1_to_l2_message_source.d.ts +2 -2
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +12 -3
- package/dest/test/mock_l2_block_source.d.ts +8 -4
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +65 -19
- package/package.json +13 -13
- package/src/archiver/archiver.ts +179 -71
- package/src/archiver/archiver_store.ts +11 -3
- package/src/archiver/archiver_store_test_suite.ts +22 -43
- package/src/archiver/config.ts +2 -2
- package/src/archiver/instrumentation.ts +14 -63
- package/src/archiver/kv_archiver_store/block_store.ts +35 -7
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +7 -3
- package/src/archiver/kv_archiver_store/log_store.ts +18 -24
- package/src/archiver/l1/calldata_retriever.ts +2 -2
- package/src/archiver/l1/validate_trace.ts +1 -1
- package/src/archiver/validation.ts +6 -6
- package/src/test/mock_l1_to_l2_message_source.ts +10 -4
- package/src/test/mock_l2_block_source.ts +76 -18
|
@@ -20,10 +20,9 @@ import {
|
|
|
20
20
|
EthAddress,
|
|
21
21
|
L2BlockHash,
|
|
22
22
|
L2BlockNew,
|
|
23
|
-
type
|
|
24
|
-
randomBlockInfo,
|
|
23
|
+
type ValidateCheckpointResult,
|
|
25
24
|
} from '@aztec/stdlib/block';
|
|
26
|
-
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
25
|
+
import { Checkpoint, L1PublishedData, PublishedCheckpoint, randomCheckpointInfo } from '@aztec/stdlib/checkpoint';
|
|
27
26
|
import {
|
|
28
27
|
type ContractClassPublic,
|
|
29
28
|
type ContractInstanceWithAddress,
|
|
@@ -2276,17 +2275,13 @@ export function describeArchiverDataStore(
|
|
|
2276
2275
|
[
|
|
2277
2276
|
expect.objectContaining({
|
|
2278
2277
|
blockNumber: 2,
|
|
2279
|
-
|
|
2280
|
-
log: makePrivateLog(tags[0]),
|
|
2281
|
-
isFromPublic: false,
|
|
2278
|
+
logData: makePrivateLog(tags[0]).getEmittedFields(),
|
|
2282
2279
|
}),
|
|
2283
2280
|
],
|
|
2284
2281
|
[
|
|
2285
2282
|
expect.objectContaining({
|
|
2286
2283
|
blockNumber: 1,
|
|
2287
|
-
|
|
2288
|
-
log: makePrivateLog(tags[1]),
|
|
2289
|
-
isFromPublic: false,
|
|
2284
|
+
logData: makePrivateLog(tags[1]).getEmittedFields(),
|
|
2290
2285
|
}),
|
|
2291
2286
|
],
|
|
2292
2287
|
]);
|
|
@@ -2312,15 +2307,11 @@ export function describeArchiverDataStore(
|
|
|
2312
2307
|
[
|
|
2313
2308
|
expect.objectContaining({
|
|
2314
2309
|
blockNumber: 1,
|
|
2315
|
-
|
|
2316
|
-
log: makePrivateLog(tags[0]),
|
|
2317
|
-
isFromPublic: false,
|
|
2310
|
+
logData: makePrivateLog(tags[0]).getEmittedFields(),
|
|
2318
2311
|
}),
|
|
2319
2312
|
expect.objectContaining({
|
|
2320
2313
|
blockNumber: newBlockNumber,
|
|
2321
|
-
|
|
2322
|
-
log: newLog,
|
|
2323
|
-
isFromPublic: false,
|
|
2314
|
+
logData: newLog.getEmittedFields(),
|
|
2324
2315
|
}),
|
|
2325
2316
|
],
|
|
2326
2317
|
]);
|
|
@@ -2338,9 +2329,7 @@ export function describeArchiverDataStore(
|
|
|
2338
2329
|
[
|
|
2339
2330
|
expect.objectContaining({
|
|
2340
2331
|
blockNumber: 1,
|
|
2341
|
-
|
|
2342
|
-
log: makePrivateLog(tags[1]),
|
|
2343
|
-
isFromPublic: false,
|
|
2332
|
+
logData: makePrivateLog(tags[1]).getEmittedFields(),
|
|
2344
2333
|
}),
|
|
2345
2334
|
],
|
|
2346
2335
|
]);
|
|
@@ -2425,17 +2414,13 @@ export function describeArchiverDataStore(
|
|
|
2425
2414
|
[
|
|
2426
2415
|
expect.objectContaining({
|
|
2427
2416
|
blockNumber: 2,
|
|
2428
|
-
|
|
2429
|
-
log: makePublicLog(tags[0]),
|
|
2430
|
-
isFromPublic: true,
|
|
2417
|
+
logData: makePublicLog(tags[0]).getEmittedFields(),
|
|
2431
2418
|
}),
|
|
2432
2419
|
],
|
|
2433
2420
|
[
|
|
2434
2421
|
expect.objectContaining({
|
|
2435
2422
|
blockNumber: 1,
|
|
2436
|
-
|
|
2437
|
-
log: makePublicLog(tags[1]),
|
|
2438
|
-
isFromPublic: true,
|
|
2423
|
+
logData: makePublicLog(tags[1]).getEmittedFields(),
|
|
2439
2424
|
}),
|
|
2440
2425
|
],
|
|
2441
2426
|
]);
|
|
@@ -2461,15 +2446,11 @@ export function describeArchiverDataStore(
|
|
|
2461
2446
|
[
|
|
2462
2447
|
expect.objectContaining({
|
|
2463
2448
|
blockNumber: 1,
|
|
2464
|
-
|
|
2465
|
-
log: makePublicLog(tags[0]),
|
|
2466
|
-
isFromPublic: true,
|
|
2449
|
+
logData: makePublicLog(tags[0]).getEmittedFields(),
|
|
2467
2450
|
}),
|
|
2468
2451
|
expect.objectContaining({
|
|
2469
2452
|
blockNumber: newBlockNumber,
|
|
2470
|
-
|
|
2471
|
-
log: newLog,
|
|
2472
|
-
isFromPublic: true,
|
|
2453
|
+
logData: newLog.getEmittedFields(),
|
|
2473
2454
|
}),
|
|
2474
2455
|
],
|
|
2475
2456
|
]);
|
|
@@ -2487,9 +2468,7 @@ export function describeArchiverDataStore(
|
|
|
2487
2468
|
[
|
|
2488
2469
|
expect.objectContaining({
|
|
2489
2470
|
blockNumber: 1,
|
|
2490
|
-
|
|
2491
|
-
log: makePublicLog(tags[1]),
|
|
2492
|
-
isFromPublic: true,
|
|
2471
|
+
logData: makePublicLog(tags[1]).getEmittedFields(),
|
|
2493
2472
|
}),
|
|
2494
2473
|
],
|
|
2495
2474
|
]);
|
|
@@ -2776,7 +2755,7 @@ export function describeArchiverDataStore(
|
|
|
2776
2755
|
});
|
|
2777
2756
|
|
|
2778
2757
|
it('should store and retrieve a valid validation status', async () => {
|
|
2779
|
-
const validStatus:
|
|
2758
|
+
const validStatus: ValidateCheckpointResult = { valid: true };
|
|
2780
2759
|
|
|
2781
2760
|
await store.setPendingChainValidationStatus(validStatus);
|
|
2782
2761
|
const retrievedStatus = await store.getPendingChainValidationStatus();
|
|
@@ -2785,9 +2764,9 @@ export function describeArchiverDataStore(
|
|
|
2785
2764
|
});
|
|
2786
2765
|
|
|
2787
2766
|
it('should store and retrieve an invalid validation status with insufficient attestations', async () => {
|
|
2788
|
-
const invalidStatus:
|
|
2767
|
+
const invalidStatus: ValidateCheckpointResult = {
|
|
2789
2768
|
valid: false,
|
|
2790
|
-
|
|
2769
|
+
checkpoint: randomCheckpointInfo(1),
|
|
2791
2770
|
committee: [EthAddress.random(), EthAddress.random()],
|
|
2792
2771
|
epoch: EpochNumber(123),
|
|
2793
2772
|
seed: 456n,
|
|
@@ -2803,9 +2782,9 @@ export function describeArchiverDataStore(
|
|
|
2803
2782
|
});
|
|
2804
2783
|
|
|
2805
2784
|
it('should store and retrieve an invalid validation status with invalid attestation', async () => {
|
|
2806
|
-
const invalidStatus:
|
|
2785
|
+
const invalidStatus: ValidateCheckpointResult = {
|
|
2807
2786
|
valid: false,
|
|
2808
|
-
|
|
2787
|
+
checkpoint: randomCheckpointInfo(2),
|
|
2809
2788
|
committee: [EthAddress.random()],
|
|
2810
2789
|
attestors: [EthAddress.random()],
|
|
2811
2790
|
epoch: EpochNumber(789),
|
|
@@ -2822,10 +2801,10 @@ export function describeArchiverDataStore(
|
|
|
2822
2801
|
});
|
|
2823
2802
|
|
|
2824
2803
|
it('should overwrite existing status when setting a new one', async () => {
|
|
2825
|
-
const firstStatus:
|
|
2826
|
-
const secondStatus:
|
|
2804
|
+
const firstStatus: ValidateCheckpointResult = { valid: true };
|
|
2805
|
+
const secondStatus: ValidateCheckpointResult = {
|
|
2827
2806
|
valid: false,
|
|
2828
|
-
|
|
2807
|
+
checkpoint: randomCheckpointInfo(3),
|
|
2829
2808
|
committee: [EthAddress.random()],
|
|
2830
2809
|
epoch: EpochNumber(999),
|
|
2831
2810
|
seed: 888n,
|
|
@@ -2842,9 +2821,9 @@ export function describeArchiverDataStore(
|
|
|
2842
2821
|
});
|
|
2843
2822
|
|
|
2844
2823
|
it('should handle empty committee and attestations arrays', async () => {
|
|
2845
|
-
const statusWithEmptyArrays:
|
|
2824
|
+
const statusWithEmptyArrays: ValidateCheckpointResult = {
|
|
2846
2825
|
valid: false,
|
|
2847
|
-
|
|
2826
|
+
checkpoint: randomCheckpointInfo(4),
|
|
2848
2827
|
committee: [],
|
|
2849
2828
|
epoch: EpochNumber(0),
|
|
2850
2829
|
seed: 0n,
|
package/src/archiver/config.ts
CHANGED
|
@@ -46,8 +46,8 @@ export const archiverConfigMappings: ConfigMappingsType<ArchiverConfig> = {
|
|
|
46
46
|
parseEnv: (val: string | undefined) => (val ? +val : undefined),
|
|
47
47
|
description: 'The maximum possible size of the archiver DB in KB. Overwrites the general dataStoreMapSizeKb.',
|
|
48
48
|
},
|
|
49
|
-
|
|
50
|
-
description: '
|
|
49
|
+
skipValidateCheckpointAttestations: {
|
|
50
|
+
description: 'Skip validating checkpoint attestations (for testing purposes only)',
|
|
51
51
|
...booleanConfigHelper(false),
|
|
52
52
|
},
|
|
53
53
|
maxAllowedEthClientDriftSeconds: {
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
type TelemetryClient,
|
|
11
11
|
type Tracer,
|
|
12
12
|
type UpDownCounter,
|
|
13
|
-
ValueType,
|
|
14
13
|
} from '@aztec/telemetry-client';
|
|
15
14
|
|
|
16
15
|
export class ArchiverInstrumentation {
|
|
@@ -45,81 +44,33 @@ export class ArchiverInstrumentation {
|
|
|
45
44
|
this.tracer = telemetry.getTracer('Archiver');
|
|
46
45
|
const meter = telemetry.getMeter('Archiver');
|
|
47
46
|
|
|
48
|
-
this.blockHeight = meter.createGauge(Metrics.ARCHIVER_BLOCK_HEIGHT
|
|
49
|
-
description: 'The height of the latest block processed by the archiver',
|
|
50
|
-
valueType: ValueType.INT,
|
|
51
|
-
});
|
|
47
|
+
this.blockHeight = meter.createGauge(Metrics.ARCHIVER_BLOCK_HEIGHT);
|
|
52
48
|
|
|
53
|
-
this.l1BlockHeight = meter.createGauge(Metrics.ARCHIVER_L1_BLOCK_HEIGHT
|
|
54
|
-
description: 'The height of the latest L1 block processed by the archiver',
|
|
55
|
-
valueType: ValueType.INT,
|
|
56
|
-
});
|
|
49
|
+
this.l1BlockHeight = meter.createGauge(Metrics.ARCHIVER_L1_BLOCK_HEIGHT);
|
|
57
50
|
|
|
58
|
-
this.txCount = meter.createUpDownCounter(Metrics.ARCHIVER_TOTAL_TXS
|
|
59
|
-
description: 'The total number of transactions',
|
|
60
|
-
valueType: ValueType.INT,
|
|
61
|
-
});
|
|
51
|
+
this.txCount = meter.createUpDownCounter(Metrics.ARCHIVER_TOTAL_TXS);
|
|
62
52
|
|
|
63
|
-
this.proofsSubmittedCount = meter.createUpDownCounter(Metrics.ARCHIVER_ROLLUP_PROOF_COUNT
|
|
64
|
-
description: 'Number of proofs submitted',
|
|
65
|
-
valueType: ValueType.INT,
|
|
66
|
-
});
|
|
53
|
+
this.proofsSubmittedCount = meter.createUpDownCounter(Metrics.ARCHIVER_ROLLUP_PROOF_COUNT);
|
|
67
54
|
|
|
68
|
-
this.proofsSubmittedDelay = meter.createHistogram(Metrics.ARCHIVER_ROLLUP_PROOF_DELAY
|
|
69
|
-
unit: 'ms',
|
|
70
|
-
description: 'Time after a block is submitted until its proof is published',
|
|
71
|
-
valueType: ValueType.INT,
|
|
72
|
-
});
|
|
55
|
+
this.proofsSubmittedDelay = meter.createHistogram(Metrics.ARCHIVER_ROLLUP_PROOF_DELAY);
|
|
73
56
|
|
|
74
|
-
this.syncDurationPerBlock = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_BLOCK
|
|
75
|
-
unit: 'ms',
|
|
76
|
-
description: 'Duration to sync a block',
|
|
77
|
-
valueType: ValueType.INT,
|
|
78
|
-
});
|
|
57
|
+
this.syncDurationPerBlock = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_BLOCK);
|
|
79
58
|
|
|
80
|
-
this.syncBlockCount = meter.createUpDownCounter(Metrics.ARCHIVER_SYNC_BLOCK_COUNT
|
|
81
|
-
description: 'Number of blocks synced from L1',
|
|
82
|
-
valueType: ValueType.INT,
|
|
83
|
-
});
|
|
59
|
+
this.syncBlockCount = meter.createUpDownCounter(Metrics.ARCHIVER_SYNC_BLOCK_COUNT);
|
|
84
60
|
|
|
85
|
-
this.manaPerBlock = meter.createHistogram(Metrics.ARCHIVER_MANA_PER_BLOCK
|
|
86
|
-
description: 'The mana consumed by blocks',
|
|
87
|
-
valueType: ValueType.DOUBLE,
|
|
88
|
-
unit: 'Mmana',
|
|
89
|
-
});
|
|
61
|
+
this.manaPerBlock = meter.createHistogram(Metrics.ARCHIVER_MANA_PER_BLOCK);
|
|
90
62
|
|
|
91
|
-
this.txsPerBlock = meter.createHistogram(Metrics.ARCHIVER_TXS_PER_BLOCK
|
|
92
|
-
description: 'The block tx count',
|
|
93
|
-
valueType: ValueType.INT,
|
|
94
|
-
unit: 'tx',
|
|
95
|
-
});
|
|
63
|
+
this.txsPerBlock = meter.createHistogram(Metrics.ARCHIVER_TXS_PER_BLOCK);
|
|
96
64
|
|
|
97
|
-
this.syncDurationPerMessage = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_MESSAGE
|
|
98
|
-
unit: 'ms',
|
|
99
|
-
description: 'Duration to sync a message',
|
|
100
|
-
valueType: ValueType.INT,
|
|
101
|
-
});
|
|
65
|
+
this.syncDurationPerMessage = meter.createHistogram(Metrics.ARCHIVER_SYNC_PER_MESSAGE);
|
|
102
66
|
|
|
103
|
-
this.syncMessageCount = meter.createUpDownCounter(Metrics.ARCHIVER_SYNC_MESSAGE_COUNT
|
|
104
|
-
description: 'Number of L1 to L2 messages synced',
|
|
105
|
-
valueType: ValueType.INT,
|
|
106
|
-
});
|
|
67
|
+
this.syncMessageCount = meter.createUpDownCounter(Metrics.ARCHIVER_SYNC_MESSAGE_COUNT);
|
|
107
68
|
|
|
108
|
-
this.pruneDuration = meter.createHistogram(Metrics.ARCHIVER_PRUNE_DURATION
|
|
109
|
-
unit: 'ms',
|
|
110
|
-
description: 'Duration to sync a message',
|
|
111
|
-
valueType: ValueType.INT,
|
|
112
|
-
});
|
|
69
|
+
this.pruneDuration = meter.createHistogram(Metrics.ARCHIVER_PRUNE_DURATION);
|
|
113
70
|
|
|
114
|
-
this.pruneCount = meter.createUpDownCounter(Metrics.ARCHIVER_PRUNE_COUNT
|
|
115
|
-
description: 'Number of prunes detected',
|
|
116
|
-
valueType: ValueType.INT,
|
|
117
|
-
});
|
|
71
|
+
this.pruneCount = meter.createUpDownCounter(Metrics.ARCHIVER_PRUNE_COUNT);
|
|
118
72
|
|
|
119
|
-
this.blockProposalTxTargetCount = meter.createUpDownCounter(Metrics.ARCHIVER_BLOCK_PROPOSAL_TX_TARGET_COUNT
|
|
120
|
-
description: 'Number of block proposals by tx target',
|
|
121
|
-
valueType: ValueType.INT,
|
|
122
|
-
});
|
|
73
|
+
this.blockProposalTxTargetCount = meter.createUpDownCounter(Metrics.ARCHIVER_BLOCK_PROPOSAL_TX_TARGET_COUNT);
|
|
123
74
|
|
|
124
75
|
this.dbMetrics = new LmdbMetrics(
|
|
125
76
|
meter,
|
|
@@ -14,9 +14,9 @@ import {
|
|
|
14
14
|
CommitteeAttestation,
|
|
15
15
|
L2BlockHash,
|
|
16
16
|
L2BlockNew,
|
|
17
|
-
type
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
type ValidateCheckpointResult,
|
|
18
|
+
deserializeValidateCheckpointResult,
|
|
19
|
+
serializeValidateCheckpointResult,
|
|
20
20
|
} from '@aztec/stdlib/block';
|
|
21
21
|
import { L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
22
22
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
@@ -503,6 +503,34 @@ export class BlockStore {
|
|
|
503
503
|
);
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
+
/**
|
|
507
|
+
* Gets up to `limit` amount of Checkpointed L2 blocks starting from `from`.
|
|
508
|
+
* @param start - Number of the first block to return (inclusive).
|
|
509
|
+
* @param limit - The number of blocks to return.
|
|
510
|
+
* @returns The requested L2 blocks
|
|
511
|
+
*/
|
|
512
|
+
async *getCheckpointedBlocks(start: BlockNumber, limit: number): AsyncIterableIterator<CheckpointedL2Block> {
|
|
513
|
+
const checkpointCache = new Map<CheckpointNumber, CheckpointStorage>();
|
|
514
|
+
for await (const [blockNumber, blockStorage] of this.getBlockStorages(start, limit)) {
|
|
515
|
+
const block = await this.getBlockFromBlockStorage(blockNumber, blockStorage);
|
|
516
|
+
if (block) {
|
|
517
|
+
const checkpoint =
|
|
518
|
+
checkpointCache.get(CheckpointNumber(blockStorage.checkpointNumber)) ??
|
|
519
|
+
(await this.#checkpoints.getAsync(blockStorage.checkpointNumber));
|
|
520
|
+
if (checkpoint) {
|
|
521
|
+
checkpointCache.set(CheckpointNumber(blockStorage.checkpointNumber), checkpoint);
|
|
522
|
+
const checkpointedBlock = new CheckpointedL2Block(
|
|
523
|
+
CheckpointNumber(checkpoint.checkpointNumber),
|
|
524
|
+
block,
|
|
525
|
+
L1PublishedData.fromBuffer(checkpoint.l1),
|
|
526
|
+
checkpoint.attestations.map(buf => CommitteeAttestation.fromBuffer(buf)),
|
|
527
|
+
);
|
|
528
|
+
yield checkpointedBlock;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
506
534
|
async getCheckpointedBlockByHash(blockHash: Fr): Promise<CheckpointedL2Block | undefined> {
|
|
507
535
|
const blockNumber = await this.#blockHashIndex.getAsync(blockHash.toString());
|
|
508
536
|
if (blockNumber === undefined) {
|
|
@@ -799,21 +827,21 @@ export class BlockStore {
|
|
|
799
827
|
* Gets the pending chain validation status.
|
|
800
828
|
* @returns The validation status or undefined if not set.
|
|
801
829
|
*/
|
|
802
|
-
async getPendingChainValidationStatus(): Promise<
|
|
830
|
+
async getPendingChainValidationStatus(): Promise<ValidateCheckpointResult | undefined> {
|
|
803
831
|
const buffer = await this.#pendingChainValidationStatus.getAsync();
|
|
804
832
|
if (!buffer) {
|
|
805
833
|
return undefined;
|
|
806
834
|
}
|
|
807
|
-
return
|
|
835
|
+
return deserializeValidateCheckpointResult(buffer);
|
|
808
836
|
}
|
|
809
837
|
|
|
810
838
|
/**
|
|
811
839
|
* Sets the pending chain validation status.
|
|
812
840
|
* @param status - The validation status to store.
|
|
813
841
|
*/
|
|
814
|
-
async setPendingChainValidationStatus(status:
|
|
842
|
+
async setPendingChainValidationStatus(status: ValidateCheckpointResult | undefined): Promise<void> {
|
|
815
843
|
if (status) {
|
|
816
|
-
const buffer =
|
|
844
|
+
const buffer = serializeValidateCheckpointResult(status);
|
|
817
845
|
await this.#pendingChainValidationStatus.set(buffer);
|
|
818
846
|
} else {
|
|
819
847
|
await this.#pendingChainValidationStatus.delete();
|
|
@@ -6,7 +6,7 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
6
6
|
import type { AztecAsyncKVStore, CustomRange, StoreSize } from '@aztec/kv-store';
|
|
7
7
|
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
8
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
-
import { CheckpointedL2Block, L2BlockHash, L2BlockNew, type
|
|
9
|
+
import { CheckpointedL2Block, L2BlockHash, L2BlockNew, type ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
10
10
|
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
11
11
|
import type {
|
|
12
12
|
ContractClassPublic,
|
|
@@ -234,6 +234,10 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
234
234
|
return toArray(this.#blockStore.getBlocks(from, limit));
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
+
getCheckpointedBlocks(from: BlockNumber, limit: number): Promise<CheckpointedL2Block[]> {
|
|
238
|
+
return toArray(this.#blockStore.getCheckpointedBlocks(from, limit));
|
|
239
|
+
}
|
|
240
|
+
|
|
237
241
|
/**
|
|
238
242
|
* Gets up to `limit` amount of L2 blocks headers starting from `from`.
|
|
239
243
|
*
|
|
@@ -410,11 +414,11 @@ export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSourc
|
|
|
410
414
|
return this.#messageStore.removeL1ToL2Messages(startIndex);
|
|
411
415
|
}
|
|
412
416
|
|
|
413
|
-
public getPendingChainValidationStatus(): Promise<
|
|
417
|
+
public getPendingChainValidationStatus(): Promise<ValidateCheckpointResult | undefined> {
|
|
414
418
|
return this.#blockStore.getPendingChainValidationStatus();
|
|
415
419
|
}
|
|
416
420
|
|
|
417
|
-
public setPendingChainValidationStatus(status:
|
|
421
|
+
public setPendingChainValidationStatus(status: ValidateCheckpointResult | undefined): Promise<void> {
|
|
418
422
|
return this.#blockStore.setPendingChainValidationStatus(status);
|
|
419
423
|
}
|
|
420
424
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INITIAL_L2_BLOCK_NUM
|
|
1
|
+
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -57,21 +57,16 @@ export class LogStore {
|
|
|
57
57
|
* @param block - The L2 block to extract logs from.
|
|
58
58
|
* @returns An object containing the private and public tagged logs for the block.
|
|
59
59
|
*/
|
|
60
|
-
|
|
61
|
-
const blockHash = L2BlockHash.fromField(await block.hash());
|
|
60
|
+
#extractTaggedLogsFromBlock(block: L2BlockNew) {
|
|
62
61
|
// SiloedTag (as string) -> array of log buffers.
|
|
63
62
|
const privateTaggedLogs = new Map<string, Buffer[]>();
|
|
64
63
|
// "{contractAddress}_{tag}" (as string) -> array of log buffers.
|
|
65
64
|
const publicTaggedLogs = new Map<string, Buffer[]>();
|
|
66
|
-
const dataStartIndexForBlock =
|
|
67
|
-
block.header.state.partial.noteHashTree.nextAvailableLeafIndex -
|
|
68
|
-
block.body.txEffects.length * MAX_NOTE_HASHES_PER_TX;
|
|
69
65
|
|
|
70
|
-
block.body.txEffects.forEach(
|
|
66
|
+
block.body.txEffects.forEach(txEffect => {
|
|
71
67
|
const txHash = txEffect.txHash;
|
|
72
|
-
const dataStartIndexForTx = dataStartIndexForBlock + txIndex * MAX_NOTE_HASHES_PER_TX;
|
|
73
68
|
|
|
74
|
-
txEffect.privateLogs.forEach(
|
|
69
|
+
txEffect.privateLogs.forEach(log => {
|
|
75
70
|
// Private logs use SiloedTag (already siloed by kernel)
|
|
76
71
|
const tag = log.fields[0];
|
|
77
72
|
this.#log.debug(`Found private log with tag ${tag.toString()} in block ${block.number}`);
|
|
@@ -80,18 +75,17 @@ export class LogStore {
|
|
|
80
75
|
currentLogs.push(
|
|
81
76
|
new TxScopedL2Log(
|
|
82
77
|
txHash,
|
|
83
|
-
dataStartIndexForTx,
|
|
84
|
-
logIndex,
|
|
85
78
|
block.number,
|
|
86
|
-
blockHash,
|
|
87
79
|
block.timestamp,
|
|
88
|
-
log,
|
|
80
|
+
log.getEmittedFields(),
|
|
81
|
+
txEffect.noteHashes,
|
|
82
|
+
txEffect.nullifiers[0],
|
|
89
83
|
).toBuffer(),
|
|
90
84
|
);
|
|
91
85
|
privateTaggedLogs.set(tag.toString(), currentLogs);
|
|
92
86
|
});
|
|
93
87
|
|
|
94
|
-
txEffect.publicLogs.forEach(
|
|
88
|
+
txEffect.publicLogs.forEach(log => {
|
|
95
89
|
// Public logs use Tag directly (not siloed) and are stored with contract address
|
|
96
90
|
const tag = log.fields[0];
|
|
97
91
|
const contractAddress = log.contractAddress;
|
|
@@ -104,12 +98,11 @@ export class LogStore {
|
|
|
104
98
|
currentLogs.push(
|
|
105
99
|
new TxScopedL2Log(
|
|
106
100
|
txHash,
|
|
107
|
-
dataStartIndexForTx,
|
|
108
|
-
logIndex,
|
|
109
101
|
block.number,
|
|
110
|
-
blockHash,
|
|
111
102
|
block.timestamp,
|
|
112
|
-
log,
|
|
103
|
+
log.getEmittedFields(),
|
|
104
|
+
txEffect.noteHashes,
|
|
105
|
+
txEffect.nullifiers[0],
|
|
113
106
|
).toBuffer(),
|
|
114
107
|
);
|
|
115
108
|
publicTaggedLogs.set(key, currentLogs);
|
|
@@ -125,10 +118,11 @@ export class LogStore {
|
|
|
125
118
|
* @returns A map from tag (as string) to an array of serialized private logs belonging to that tag, and a map from
|
|
126
119
|
* "{contractAddress}_{tag}" (as string) to an array of serialized public logs belonging to that key.
|
|
127
120
|
*/
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
121
|
+
#extractTaggedLogs(blocks: L2BlockNew[]): {
|
|
122
|
+
privateTaggedLogs: Map<string, Buffer[]>;
|
|
123
|
+
publicTaggedLogs: Map<string, Buffer[]>;
|
|
124
|
+
} {
|
|
125
|
+
const taggedLogsInBlocks = blocks.map(block => this.#extractTaggedLogsFromBlock(block));
|
|
132
126
|
|
|
133
127
|
// Now we merge the maps from each block into a single map.
|
|
134
128
|
const privateTaggedLogs = taggedLogsInBlocks.reduce((acc, { privateTaggedLogs }) => {
|
|
@@ -155,8 +149,8 @@ export class LogStore {
|
|
|
155
149
|
* @param blocks - The blocks for which to add the logs.
|
|
156
150
|
* @returns True if the operation is successful.
|
|
157
151
|
*/
|
|
158
|
-
|
|
159
|
-
const { privateTaggedLogs, publicTaggedLogs } =
|
|
152
|
+
addLogs(blocks: L2BlockNew[]): Promise<boolean> {
|
|
153
|
+
const { privateTaggedLogs, publicTaggedLogs } = this.#extractTaggedLogs(blocks);
|
|
160
154
|
|
|
161
155
|
const keysOfPrivateLogsToUpdate = Array.from(privateTaggedLogs.keys());
|
|
162
156
|
const keysOfPublicLogsToUpdate = Array.from(publicTaggedLogs.keys());
|
|
@@ -72,7 +72,7 @@ export class CalldataRetriever {
|
|
|
72
72
|
*/
|
|
73
73
|
async getCheckpointFromRollupTx(
|
|
74
74
|
txHash: `0x${string}`,
|
|
75
|
-
|
|
75
|
+
_blobHashes: Buffer[],
|
|
76
76
|
checkpointNumber: CheckpointNumber,
|
|
77
77
|
expectedHashes: {
|
|
78
78
|
attestationsHash?: Hex;
|
|
@@ -459,7 +459,7 @@ export class CalldataRetriever {
|
|
|
459
459
|
// Use ConsensusPayload to compute the digest - this ensures we match the exact logic
|
|
460
460
|
// used by the network for signing and verification
|
|
461
461
|
const consensusPayload = new ConsensusPayload(header, archiveRoot);
|
|
462
|
-
const payloadToSign = consensusPayload.getPayloadToSign(SignatureDomainSeparator.
|
|
462
|
+
const payloadToSign = consensusPayload.getPayloadToSign(SignatureDomainSeparator.checkpointAttestation);
|
|
463
463
|
const computedPayloadDigest = keccak256(payloadToSign);
|
|
464
464
|
|
|
465
465
|
// Compare as buffers to avoid case-sensitivity and string comparison issues
|
|
@@ -165,7 +165,7 @@ export async function validateAndLogTraceAvailability(
|
|
|
165
165
|
client: ViemPublicDebugClient,
|
|
166
166
|
ethereumAllowNoDebugHosts: boolean,
|
|
167
167
|
): Promise<void> {
|
|
168
|
-
logger.
|
|
168
|
+
logger.debug('Validating trace/debug method availability...');
|
|
169
169
|
|
|
170
170
|
const availability = await validateTraceAvailability(client);
|
|
171
171
|
|
|
@@ -4,15 +4,15 @@ import { compactArray } from '@aztec/foundation/collection';
|
|
|
4
4
|
import type { Logger } from '@aztec/foundation/log';
|
|
5
5
|
import {
|
|
6
6
|
type AttestationInfo,
|
|
7
|
-
type
|
|
8
|
-
type
|
|
7
|
+
type ValidateCheckpointNegativeResult,
|
|
8
|
+
type ValidateCheckpointResult,
|
|
9
9
|
getAttestationInfoFromPayload,
|
|
10
10
|
} from '@aztec/stdlib/block';
|
|
11
11
|
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
12
12
|
import { type L1RollupConstants, getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
|
|
13
13
|
import { ConsensusPayload } from '@aztec/stdlib/p2p';
|
|
14
14
|
|
|
15
|
-
export type {
|
|
15
|
+
export type { ValidateCheckpointResult };
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Extracts attestation information from a published checkpoint.
|
|
@@ -35,7 +35,7 @@ export async function validateCheckpointAttestations(
|
|
|
35
35
|
epochCache: EpochCache,
|
|
36
36
|
constants: Pick<L1RollupConstants, 'epochDuration'>,
|
|
37
37
|
logger?: Logger,
|
|
38
|
-
): Promise<
|
|
38
|
+
): Promise<ValidateCheckpointResult> {
|
|
39
39
|
const attestorInfos = getAttestationInfoFromPublishedCheckpoint(publishedCheckpoint);
|
|
40
40
|
const attestors = compactArray(attestorInfos.map(info => ('address' in info ? info.address : undefined)));
|
|
41
41
|
const { checkpoint, attestations } = publishedCheckpoint;
|
|
@@ -63,10 +63,10 @@ export async function validateCheckpointAttestations(
|
|
|
63
63
|
|
|
64
64
|
const requiredAttestationCount = Math.floor((committee.length * 2) / 3) + 1;
|
|
65
65
|
|
|
66
|
-
const failedValidationResult = <TReason extends
|
|
66
|
+
const failedValidationResult = <TReason extends ValidateCheckpointNegativeResult['reason']>(reason: TReason) => ({
|
|
67
67
|
valid: false as const,
|
|
68
68
|
reason,
|
|
69
|
-
|
|
69
|
+
checkpoint: checkpoint.toCheckpointInfo(),
|
|
70
70
|
committee,
|
|
71
71
|
seed,
|
|
72
72
|
epoch,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BlockNumber,
|
|
1
|
+
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
2
2
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
-
import type { L2Tips } from '@aztec/stdlib/block';
|
|
3
|
+
import type { CheckpointId, L2BlockId, L2TipId, L2Tips } from '@aztec/stdlib/block';
|
|
4
4
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -33,9 +33,15 @@ export class MockL1ToL2MessageSource implements L1ToL2MessageSource {
|
|
|
33
33
|
|
|
34
34
|
getL2Tips(): Promise<L2Tips> {
|
|
35
35
|
const number = this.blockNumber;
|
|
36
|
-
const
|
|
36
|
+
const blockId: L2BlockId = { number: BlockNumber(number), hash: new Fr(number).toString() };
|
|
37
|
+
const checkpointId: CheckpointId = {
|
|
38
|
+
number: CheckpointNumber(number),
|
|
39
|
+
hash: new Fr(number + 1).toString(),
|
|
40
|
+
};
|
|
41
|
+
const tip: L2TipId = { block: blockId, checkpoint: checkpointId };
|
|
37
42
|
return Promise.resolve({
|
|
38
|
-
|
|
43
|
+
proposed: blockId,
|
|
44
|
+
checkpointed: tip,
|
|
39
45
|
proven: tip,
|
|
40
46
|
finalized: tip,
|
|
41
47
|
});
|