@aztec/archiver 2.0.3 → 2.1.0-rc.10

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.
@@ -21,9 +21,9 @@ import { L2BlockSourceEvents } from '@aztec/stdlib/block';
21
21
  import { computePublicBytecodeCommitment, isValidPrivateFunctionMembershipProof, isValidUtilityFunctionMembershipProof } from '@aztec/stdlib/contract';
22
22
  import { getEpochAtSlot, getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
23
23
  import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
24
+ import { createPublicClient, fallback, http } from '@spalladino/viem';
24
25
  import { EventEmitter } from 'events';
25
26
  import groupBy from 'lodash.groupby';
26
- import { createPublicClient, fallback, http } from 'viem';
27
27
  import { retrieveBlocksFromRollup, retrieveL1ToL2Message, retrieveL1ToL2Messages, retrievedBlockToPublishedL2Block } from './data_retrieval.js';
28
28
  import { InitialBlockNumberNotSequentialError, NoBlobBodiesFoundError } from './errors.js';
29
29
  import { ArchiverInstrumentation } from './instrumentation.js';
@@ -7,7 +7,7 @@ import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
7
7
  import { Body, CommitteeAttestation, PublishedL2Block } from '@aztec/stdlib/block';
8
8
  import { Proof } from '@aztec/stdlib/proofs';
9
9
  import { ProposedBlockHeader, StateReference } from '@aztec/stdlib/tx';
10
- import { type GetContractReturnType, type Hex } from 'viem';
10
+ import { type GetContractReturnType, type Hex } from '@spalladino/viem';
11
11
  import type { DataRetrieval } from './structs/data_retrieval.js';
12
12
  import type { InboxMessage } from './structs/inbox_message.js';
13
13
  import type { L1PublishedData } from './structs/published.js';
@@ -1 +1 @@
1
- {"version":3,"file":"data_retrieval.d.ts","sourceRoot":"","sources":["../../src/archiver/data_retrieval.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data_retrieval.d.ts","sourceRoot":"","sources":["../../src/archiver/data_retrieval.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import { Body, CommitteeAttestation, L2Block, PublishedL2Block } from '@aztec/st
8
8
  import { Proof } from '@aztec/stdlib/proofs';
9
9
  import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
10
10
  import { BlockHeader, GlobalVariables, ProposedBlockHeader, StateReference } from '@aztec/stdlib/tx';
11
- import { decodeFunctionData, getAbiItem, hexToBytes, multicall3Abi } from 'viem';
11
+ import { decodeFunctionData, getAbiItem, hexToBytes, multicall3Abi } from '@spalladino/viem';
12
12
  import { NoBlobBodiesFoundError } from './errors.js';
13
13
  export function retrievedBlockToPublishedL2Block(retrievedBlock) {
14
14
  const { l2BlockNumber, archiveRoot, stateReference, header: proposedHeader, body, l1, chainId, version, attestations } = retrievedBlock;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/archiver/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,iBAAiB,EAAkB,MAAM,6BAA6B,CAAC;AAErF,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,cAAc,EAAE,gBAAgB,EAChC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,EACnD,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,CAAC,CAqE9B"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/archiver/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,iBAAiB,EAAkB,MAAM,6BAA6B,CAAC;AAErF,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,cAAc,EAAE,gBAAgB,EAChC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,EACnD,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,mBAAmB,CAAC,CAoF9B"}
@@ -1,3 +1,4 @@
1
+ import { compactArray } from '@aztec/foundation/collection';
1
2
  import { getAttestationsFromPublishedL2Block } from '@aztec/stdlib/block';
2
3
  import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
3
4
  /**
@@ -5,7 +6,7 @@ import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
5
6
  * Returns true if the attestations are valid and sufficient, false otherwise.
6
7
  */ export async function validateBlockAttestations(publishedBlock, epochCache, constants, logger) {
7
8
  const attestations = getAttestationsFromPublishedL2Block(publishedBlock);
8
- const attestors = attestations.map((a)=>a.getSender());
9
+ const attestors = compactArray(attestations.map((a)=>a?.tryGetSender()));
9
10
  const { block } = publishedBlock;
10
11
  const blockHash = await block.hash().then((hash)=>hash.toString());
11
12
  const archiveRoot = block.archive.root.toString();
@@ -21,8 +22,9 @@ import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
21
22
  };
22
23
  logger?.debug(`Validating attestations for block ${block.number} at slot ${slot} in epoch ${epoch}`, {
23
24
  committee: (committee ?? []).map((member)=>member.toString()),
24
- recoveredAttestors: attestations.map((a)=>a.getSender().toString()),
25
- postedAttestations: publishedBlock.attestations.map((a)=>a.address.isZero() ? a.signature.toString() : a.address.toString()),
25
+ recoveredAttestors: attestors.map((member)=>member.toString()),
26
+ invalidAttestations: attestations.filter((a)=>a !== undefined && a.tryGetSender() === undefined).map((a)=>a?.toInspect()),
27
+ postedAttestations: publishedBlock.attestations.map((a)=>(a.address.isZero() ? a.signature : a.address).toString()),
26
28
  ...logData
27
29
  });
28
30
  if (!committee || committee.length === 0) {
@@ -35,29 +37,43 @@ import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
35
37
  const requiredAttestationCount = Math.floor(committee.length * 2 / 3) + 1;
36
38
  for(let i = 0; i < attestations.length; i++){
37
39
  const attestation = attestations[i];
38
- const signer = attestation.getSender().toString();
39
- if (!committeeSet.has(signer)) {
40
- logger?.warn(`Attestation from non-committee member ${signer} at slot ${slot}`, {
41
- committee
40
+ // Skip empty signatures (undefined entries)
41
+ if (attestation === undefined) {
42
+ continue;
43
+ }
44
+ const signer = attestation.tryGetSender()?.toString();
45
+ if (signer !== undefined && committeeSet.has(signer)) {
46
+ continue;
47
+ }
48
+ if (signer === undefined) {
49
+ logger?.warn(`Attestation with invalid signature at slot ${slot}`, {
50
+ committee,
51
+ ...logData
42
52
  });
43
- const reason = 'invalid-attestation';
44
- return {
45
- valid: false,
46
- reason,
47
- invalidIndex: i,
48
- block: publishedBlock.block.toBlockInfo(),
53
+ } else {
54
+ logger?.warn(`Attestation from non-committee member ${signer} at slot ${slot}`, {
49
55
  committee,
50
- seed,
51
- epoch,
52
- attestors,
53
- attestations: publishedBlock.attestations
54
- };
56
+ ...logData
57
+ });
55
58
  }
59
+ const reason = 'invalid-attestation';
60
+ return {
61
+ valid: false,
62
+ reason,
63
+ invalidIndex: i,
64
+ block: publishedBlock.block.toBlockInfo(),
65
+ committee,
66
+ seed,
67
+ epoch,
68
+ attestors,
69
+ attestations: publishedBlock.attestations
70
+ };
56
71
  }
57
- if (attestations.length < requiredAttestationCount) {
72
+ const validAttestationCount = compactArray(attestations).length;
73
+ if (validAttestationCount < requiredAttestationCount) {
58
74
  logger?.warn(`Insufficient attestations for block at slot ${slot}`, {
59
75
  requiredAttestations: requiredAttestationCount,
60
- actualAttestations: attestations.length,
76
+ actualAttestations: validAttestationCount,
61
77
  ...logData
62
78
  });
63
79
  const reason = 'insufficient-attestations';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/archiver",
3
- "version": "2.0.3",
3
+ "version": "2.1.0-rc.10",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -66,23 +66,23 @@
66
66
  ]
67
67
  },
68
68
  "dependencies": {
69
- "@aztec/blob-lib": "2.0.3",
70
- "@aztec/blob-sink": "2.0.3",
71
- "@aztec/constants": "2.0.3",
72
- "@aztec/epoch-cache": "2.0.3",
73
- "@aztec/ethereum": "2.0.3",
74
- "@aztec/foundation": "2.0.3",
75
- "@aztec/kv-store": "2.0.3",
76
- "@aztec/l1-artifacts": "2.0.3",
77
- "@aztec/noir-protocol-circuits-types": "2.0.3",
78
- "@aztec/protocol-contracts": "2.0.3",
79
- "@aztec/stdlib": "2.0.3",
80
- "@aztec/telemetry-client": "2.0.3",
69
+ "@aztec/blob-lib": "2.1.0-rc.10",
70
+ "@aztec/blob-sink": "2.1.0-rc.10",
71
+ "@aztec/constants": "2.1.0-rc.10",
72
+ "@aztec/epoch-cache": "2.1.0-rc.10",
73
+ "@aztec/ethereum": "2.1.0-rc.10",
74
+ "@aztec/foundation": "2.1.0-rc.10",
75
+ "@aztec/kv-store": "2.1.0-rc.10",
76
+ "@aztec/l1-artifacts": "2.1.0-rc.10",
77
+ "@aztec/noir-protocol-circuits-types": "2.1.0-rc.10",
78
+ "@aztec/protocol-contracts": "2.1.0-rc.10",
79
+ "@aztec/stdlib": "2.1.0-rc.10",
80
+ "@aztec/telemetry-client": "2.1.0-rc.10",
81
+ "@spalladino/viem": "2.38.2-eip7594.0",
81
82
  "lodash.groupby": "^4.6.0",
82
83
  "lodash.omit": "^4.5.0",
83
84
  "tsc-watch": "^6.0.0",
84
- "tslib": "^2.5.0",
85
- "viem": "2.23.7"
85
+ "tslib": "^2.5.0"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@jest/globals": "^30.0.0",
@@ -72,9 +72,9 @@ import {
72
72
  trackSpan,
73
73
  } from '@aztec/telemetry-client';
74
74
 
75
+ import { type GetContractReturnType, createPublicClient, fallback, http } from '@spalladino/viem';
75
76
  import { EventEmitter } from 'events';
76
77
  import groupBy from 'lodash.groupby';
77
- import { type GetContractReturnType, createPublicClient, fallback, http } from 'viem';
78
78
 
79
79
  import type { ArchiverDataStore, ArchiverL1SynchPoint } from './archiver_store.js';
80
80
  import type { ArchiverConfig } from './config.js';
@@ -11,6 +11,7 @@ import type {
11
11
  import { asyncPool } from '@aztec/foundation/async-pool';
12
12
  import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
13
13
  import type { EthAddress } from '@aztec/foundation/eth-address';
14
+ import type { ViemSignature } from '@aztec/foundation/eth-signature';
14
15
  import { Fr } from '@aztec/foundation/fields';
15
16
  import { type Logger, createLogger } from '@aztec/foundation/log';
16
17
  import { type InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
@@ -27,7 +28,7 @@ import {
27
28
  getAbiItem,
28
29
  hexToBytes,
29
30
  multicall3Abi,
30
- } from 'viem';
31
+ } from '@spalladino/viem';
31
32
 
32
33
  import { NoBlobBodiesFoundError } from './errors.js';
33
34
  import type { DataRetrieval } from './structs/data_retrieval.js';
@@ -319,6 +320,7 @@ async function getBlockFromRollupTx(
319
320
  },
320
321
  ViemCommitteeAttestations,
321
322
  Hex[],
323
+ ViemSignature,
322
324
  Hex,
323
325
  ];
324
326
 
@@ -1,4 +1,5 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
+ import { compactArray } from '@aztec/foundation/collection';
2
3
  import type { Logger } from '@aztec/foundation/log';
3
4
  import {
4
5
  type PublishedL2Block,
@@ -20,7 +21,7 @@ export async function validateBlockAttestations(
20
21
  logger?: Logger,
21
22
  ): Promise<ValidateBlockResult> {
22
23
  const attestations = getAttestationsFromPublishedL2Block(publishedBlock);
23
- const attestors = attestations.map(a => a.getSender());
24
+ const attestors = compactArray(attestations.map(a => a?.tryGetSender()));
24
25
  const { block } = publishedBlock;
25
26
  const blockHash = await block.hash().then(hash => hash.toString());
26
27
  const archiveRoot = block.archive.root.toString();
@@ -31,10 +32,11 @@ export async function validateBlockAttestations(
31
32
 
32
33
  logger?.debug(`Validating attestations for block ${block.number} at slot ${slot} in epoch ${epoch}`, {
33
34
  committee: (committee ?? []).map(member => member.toString()),
34
- recoveredAttestors: attestations.map(a => a.getSender().toString()),
35
- postedAttestations: publishedBlock.attestations.map(a =>
36
- a.address.isZero() ? a.signature.toString() : a.address.toString(),
37
- ),
35
+ recoveredAttestors: attestors.map(member => member.toString()),
36
+ invalidAttestations: attestations
37
+ .filter(a => a !== undefined && a.tryGetSender() === undefined)
38
+ .map(a => a?.toInspect()),
39
+ postedAttestations: publishedBlock.attestations.map(a => (a.address.isZero() ? a.signature : a.address).toString()),
38
40
  ...logData,
39
41
  });
40
42
 
@@ -48,28 +50,42 @@ export async function validateBlockAttestations(
48
50
 
49
51
  for (let i = 0; i < attestations.length; i++) {
50
52
  const attestation = attestations[i];
51
- const signer = attestation.getSender().toString();
52
- if (!committeeSet.has(signer)) {
53
- logger?.warn(`Attestation from non-committee member ${signer} at slot ${slot}`, { committee });
54
- const reason = 'invalid-attestation';
55
- return {
56
- valid: false,
57
- reason,
58
- invalidIndex: i,
59
- block: publishedBlock.block.toBlockInfo(),
60
- committee,
61
- seed,
62
- epoch,
63
- attestors,
64
- attestations: publishedBlock.attestations,
65
- };
53
+
54
+ // Skip empty signatures (undefined entries)
55
+ if (attestation === undefined) {
56
+ continue;
57
+ }
58
+
59
+ const signer = attestation.tryGetSender()?.toString();
60
+ if (signer !== undefined && committeeSet.has(signer)) {
61
+ continue;
62
+ }
63
+
64
+ if (signer === undefined) {
65
+ logger?.warn(`Attestation with invalid signature at slot ${slot}`, { committee, ...logData });
66
+ } else {
67
+ logger?.warn(`Attestation from non-committee member ${signer} at slot ${slot}`, { committee, ...logData });
66
68
  }
69
+
70
+ const reason = 'invalid-attestation';
71
+ return {
72
+ valid: false,
73
+ reason,
74
+ invalidIndex: i,
75
+ block: publishedBlock.block.toBlockInfo(),
76
+ committee,
77
+ seed,
78
+ epoch,
79
+ attestors,
80
+ attestations: publishedBlock.attestations,
81
+ };
67
82
  }
68
83
 
69
- if (attestations.length < requiredAttestationCount) {
84
+ const validAttestationCount = compactArray(attestations).length;
85
+ if (validAttestationCount < requiredAttestationCount) {
70
86
  logger?.warn(`Insufficient attestations for block at slot ${slot}`, {
71
87
  requiredAttestations: requiredAttestationCount,
72
- actualAttestations: attestations.length,
88
+ actualAttestations: validAttestationCount,
73
89
  ...logData,
74
90
  });
75
91
  const reason = 'insufficient-attestations';