@aztec/archiver 0.47.0 → 0.48.0
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/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +32 -17
- package/dest/archiver/archiver_store.d.ts +1 -1
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/config.d.ts +5 -15
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +30 -13
- package/dest/archiver/data_retrieval.d.ts +7 -1
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +19 -1
- package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
- package/dest/archiver/eth_log_handlers.js +35 -13
- package/dest/archiver/instrumentation.d.ts +3 -1
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +15 -6
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts +4 -3
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_body_store.js +13 -6
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +2 -2
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +3 -7
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +4 -2
- package/package.json +10 -10
- package/src/archiver/archiver.ts +36 -17
- package/src/archiver/archiver_store.ts +1 -1
- package/src/archiver/config.ts +33 -37
- package/src/archiver/data_retrieval.ts +25 -2
- package/src/archiver/eth_log_handlers.ts +43 -13
- package/src/archiver/instrumentation.ts +26 -6
- package/src/archiver/kv_archiver_store/block_body_store.ts +12 -6
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +1 -1
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +5 -9
- package/src/index.ts +4 -1
|
@@ -5,7 +5,16 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
5
5
|
import { numToUInt32BE } from '@aztec/foundation/serialize';
|
|
6
6
|
import { AvailabilityOracleAbi, InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type Hex,
|
|
10
|
+
type Log,
|
|
11
|
+
type PublicClient,
|
|
12
|
+
decodeFunctionData,
|
|
13
|
+
getAbiItem,
|
|
14
|
+
getAddress,
|
|
15
|
+
hexToBytes,
|
|
16
|
+
slice,
|
|
17
|
+
} from 'viem';
|
|
9
18
|
|
|
10
19
|
/**
|
|
11
20
|
* Processes newly received MessageSent (L1 to L2) logs.
|
|
@@ -88,7 +97,7 @@ async function getBlockMetadataFromRollupTx(
|
|
|
88
97
|
data,
|
|
89
98
|
});
|
|
90
99
|
|
|
91
|
-
if (functionName
|
|
100
|
+
if (!(functionName === 'process' || functionName === 'publishAndProcess')) {
|
|
92
101
|
throw new Error(`Unexpected method called ${functionName}`);
|
|
93
102
|
}
|
|
94
103
|
const [headerHex, archiveRootHex] = args! as readonly [Hex, Hex];
|
|
@@ -113,7 +122,7 @@ async function getBlockMetadataFromRollupTx(
|
|
|
113
122
|
|
|
114
123
|
/**
|
|
115
124
|
* Gets block bodies from calldata of an L1 transaction, and deserializes them into Body objects.
|
|
116
|
-
* Assumes that the block was published
|
|
125
|
+
* @note Assumes that the block was published using `publishAndProcess` or `publish`.
|
|
117
126
|
* TODO: Add retries and error management.
|
|
118
127
|
* @param publicClient - The viem public client to use for transaction retrieval.
|
|
119
128
|
* @param txHash - Hash of the tx that published it.
|
|
@@ -124,20 +133,41 @@ async function getBlockBodiesFromAvailabilityOracleTx(
|
|
|
124
133
|
txHash: `0x${string}`,
|
|
125
134
|
): Promise<Body> {
|
|
126
135
|
const { input: data } = await publicClient.getTransaction({ hash: txHash });
|
|
127
|
-
const
|
|
128
|
-
abi: AvailabilityOracleAbi,
|
|
129
|
-
data,
|
|
130
|
-
});
|
|
136
|
+
const DATA_INDEX = [3, 2, 0];
|
|
131
137
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
138
|
+
// @note Use `forge inspect Rollup methodIdentifiers to get this,
|
|
139
|
+
// If using `forge sig` you will get an INVALID value for the case with a struct.
|
|
140
|
+
// [
|
|
141
|
+
// "publishAndProcess(bytes calldata _header,bytes32 _archive,SignatureLib.Signature[] memory _signatures,bytes calldata _body)",
|
|
142
|
+
// "publishAndProcess(bytes calldata _header,bytes32 _archive,bytes calldata _body)",
|
|
143
|
+
// "publish(bytes calldata _body)"
|
|
144
|
+
// ]
|
|
145
|
+
const SUPPORTED_SIGS = ['0xe4e90c26', '0xe86e3595', '0x7fd28346'];
|
|
135
146
|
|
|
136
|
-
const
|
|
147
|
+
const signature = slice(data, 0, 4);
|
|
137
148
|
|
|
138
|
-
|
|
149
|
+
if (!SUPPORTED_SIGS.includes(signature)) {
|
|
150
|
+
throw new Error(`Unexpected method called ${signature}`);
|
|
151
|
+
}
|
|
139
152
|
|
|
140
|
-
|
|
153
|
+
if (signature === SUPPORTED_SIGS[2]) {
|
|
154
|
+
const { args } = decodeFunctionData({
|
|
155
|
+
abi: AvailabilityOracleAbi,
|
|
156
|
+
data,
|
|
157
|
+
});
|
|
158
|
+
const [bodyHex] = args! as [Hex];
|
|
159
|
+
const blockBody = Body.fromBuffer(Buffer.from(hexToBytes(bodyHex)));
|
|
160
|
+
return blockBody;
|
|
161
|
+
} else {
|
|
162
|
+
const { args } = decodeFunctionData({
|
|
163
|
+
abi: RollupAbi,
|
|
164
|
+
data,
|
|
165
|
+
});
|
|
166
|
+
const index = SUPPORTED_SIGS.indexOf(signature);
|
|
167
|
+
const bodyHex = args![DATA_INDEX[index]] as Hex;
|
|
168
|
+
const blockBody = Body.fromBuffer(Buffer.from(hexToBytes(bodyHex)));
|
|
169
|
+
return blockBody;
|
|
170
|
+
}
|
|
141
171
|
}
|
|
142
172
|
|
|
143
173
|
/**
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { type L2Block } from '@aztec/circuit-types';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Attributes,
|
|
4
|
+
type Gauge,
|
|
5
|
+
type Histogram,
|
|
6
|
+
Metrics,
|
|
7
|
+
type TelemetryClient,
|
|
8
|
+
ValueType,
|
|
9
|
+
exponentialBuckets,
|
|
10
|
+
} from '@aztec/telemetry-client';
|
|
3
11
|
|
|
4
12
|
export class ArchiverInstrumentation {
|
|
5
13
|
private blockHeight: Gauge;
|
|
6
|
-
private blockSize:
|
|
14
|
+
private blockSize: Gauge;
|
|
15
|
+
private syncDuration: Histogram;
|
|
7
16
|
|
|
8
17
|
constructor(telemetry: TelemetryClient) {
|
|
9
18
|
const meter = telemetry.getMeter('Archiver');
|
|
@@ -12,19 +21,30 @@ export class ArchiverInstrumentation {
|
|
|
12
21
|
valueType: ValueType.INT,
|
|
13
22
|
});
|
|
14
23
|
|
|
15
|
-
this.blockSize = meter.
|
|
16
|
-
description: 'The number of transactions
|
|
24
|
+
this.blockSize = meter.createGauge(Metrics.ARCHIVER_BLOCK_SIZE, {
|
|
25
|
+
description: 'The number of transactions in a block',
|
|
26
|
+
valueType: ValueType.INT,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
this.syncDuration = meter.createHistogram(Metrics.ARCHIVER_SYNC_DURATION, {
|
|
30
|
+
unit: 'ms',
|
|
31
|
+
description: 'Duration to sync a block',
|
|
17
32
|
valueType: ValueType.INT,
|
|
18
33
|
advice: {
|
|
19
|
-
explicitBucketBoundaries:
|
|
34
|
+
explicitBucketBoundaries: exponentialBuckets(1, 16),
|
|
20
35
|
},
|
|
21
36
|
});
|
|
22
37
|
}
|
|
23
38
|
|
|
24
|
-
public processNewBlocks(blocks: L2Block[]) {
|
|
39
|
+
public processNewBlocks(syncTimePerBlock: number, blocks: L2Block[]) {
|
|
40
|
+
this.syncDuration.record(syncTimePerBlock);
|
|
25
41
|
this.blockHeight.record(Math.max(...blocks.map(b => b.number)));
|
|
26
42
|
for (const block of blocks) {
|
|
27
43
|
this.blockSize.record(block.body.txEffects.length);
|
|
28
44
|
}
|
|
29
45
|
}
|
|
46
|
+
|
|
47
|
+
public updateLastProvenBlock(blockNumber: number) {
|
|
48
|
+
this.blockHeight.record(blockNumber, { [Attributes.STATUS]: 'proven' });
|
|
49
|
+
}
|
|
30
50
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Body } from '@aztec/circuit-types';
|
|
2
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
2
3
|
import { type AztecKVStore, type AztecMap } from '@aztec/kv-store';
|
|
3
4
|
|
|
4
5
|
export class BlockBodyStore {
|
|
5
6
|
/** Map block body hash to block body */
|
|
6
7
|
#blockBodies: AztecMap<string, Buffer>;
|
|
7
8
|
|
|
8
|
-
constructor(private db: AztecKVStore) {
|
|
9
|
+
constructor(private db: AztecKVStore, private log = createDebugLogger('aztec:archiver:block_body_store')) {
|
|
9
10
|
this.#blockBodies = db.openMap('archiver_block_bodies');
|
|
10
11
|
}
|
|
11
12
|
|
|
@@ -29,21 +30,26 @@ export class BlockBodyStore {
|
|
|
29
30
|
* @param txsEffectsHashes - The txsEffectsHashes list that corresponds to the blockBodies we want to retrieve
|
|
30
31
|
* @returns The requested L2 block bodies
|
|
31
32
|
*/
|
|
32
|
-
async getBlockBodies(txsEffectsHashes: Buffer[]): Promise<Body[]> {
|
|
33
|
+
async getBlockBodies(txsEffectsHashes: Buffer[]): Promise<(Body | undefined)[]> {
|
|
33
34
|
const blockBodiesBuffer = await this.db.transaction(() =>
|
|
34
35
|
txsEffectsHashes.map(txsEffectsHash => this.#blockBodies.get(txsEffectsHash.toString('hex'))),
|
|
35
36
|
);
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
const blockBodies: (Body | undefined)[] = [];
|
|
39
|
+
for (let i = 0; i < blockBodiesBuffer.length; i++) {
|
|
40
|
+
const blockBodyBuffer = blockBodiesBuffer[i];
|
|
41
|
+
if (blockBodyBuffer === undefined) {
|
|
42
|
+
this.log.warn(`Block body buffer is undefined for txsEffectsHash: ${txsEffectsHashes[i].toString('hex')}`);
|
|
43
|
+
}
|
|
44
|
+
blockBodies.push(blockBodyBuffer ? Body.fromBuffer(blockBodyBuffer) : undefined);
|
|
39
45
|
}
|
|
40
46
|
|
|
41
|
-
return
|
|
47
|
+
return blockBodies;
|
|
42
48
|
}
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* Gets an L2 block body.
|
|
46
|
-
* @param txsEffectsHash - The txHash of the
|
|
52
|
+
* @param txsEffectsHash - The txHash of the block body to return
|
|
47
53
|
* @returns The requested L2 block body
|
|
48
54
|
*/
|
|
49
55
|
getBlockBody(txsEffectsHash: Buffer): Body | undefined {
|
|
@@ -111,7 +111,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
111
111
|
* @param txsEffectsHashes - A list of txsEffectsHashes (body hashes).
|
|
112
112
|
* @returns The requested L2 block bodies
|
|
113
113
|
*/
|
|
114
|
-
getBlockBodies(txsEffectsHashes: Buffer[]): Promise<Body[]> {
|
|
114
|
+
getBlockBodies(txsEffectsHashes: Buffer[]): Promise<(Body | undefined)[]> {
|
|
115
115
|
return this.#blockBodyStore.getBlockBodies(txsEffectsHashes);
|
|
116
116
|
}
|
|
117
117
|
|
|
@@ -45,7 +45,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
45
45
|
private l2BlockBodies: Map<string, Body> = new Map();
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
|
-
* An array containing all the
|
|
48
|
+
* An array containing all the tx effects in the L2 blocks that have been fetched so far.
|
|
49
49
|
*/
|
|
50
50
|
private txEffects: TxEffect[] = [];
|
|
51
51
|
|
|
@@ -177,14 +177,10 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
177
177
|
* @param txsEffectsHashes - A list of txsEffectsHashes (body hashes).
|
|
178
178
|
* @returns The requested L2 block bodies
|
|
179
179
|
*/
|
|
180
|
-
getBlockBodies(txsEffectsHashes: Buffer[]): Promise<Body[]> {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
throw new Error('Block body is undefined');
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return Promise.resolve(blockBodies as Body[]);
|
|
180
|
+
getBlockBodies(txsEffectsHashes: Buffer[]): Promise<(Body | undefined)[]> {
|
|
181
|
+
return Promise.resolve(
|
|
182
|
+
txsEffectsHashes.map(txsEffectsHash => this.l2BlockBodies.get(txsEffectsHash.toString('hex'))),
|
|
183
|
+
);
|
|
188
184
|
}
|
|
189
185
|
|
|
190
186
|
/**
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,9 @@ export * from './archiver/index.js';
|
|
|
12
12
|
export * from './rpc/index.js';
|
|
13
13
|
export * from './factory.js';
|
|
14
14
|
|
|
15
|
+
// We are not storing the info from these events in the archiver for now (and we don't really need to), so we expose this query directly
|
|
16
|
+
export { retrieveL2ProofVerifiedEvents } from './archiver/data_retrieval.js';
|
|
17
|
+
|
|
15
18
|
const log = createDebugLogger('aztec:archiver');
|
|
16
19
|
|
|
17
20
|
/**
|
|
@@ -20,7 +23,7 @@ const log = createDebugLogger('aztec:archiver');
|
|
|
20
23
|
// eslint-disable-next-line require-await
|
|
21
24
|
async function main() {
|
|
22
25
|
const config = getArchiverConfigFromEnv();
|
|
23
|
-
const { rpcUrl, l1Contracts } = config;
|
|
26
|
+
const { l1RpcUrl: rpcUrl, l1Contracts } = config;
|
|
24
27
|
|
|
25
28
|
const publicClient = createPublicClient({
|
|
26
29
|
chain: localhost,
|