@aztec/archiver 0.77.0-testnet-ignition.17 → 0.77.0-testnet-ignition.23
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 +4 -2
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +14 -10
- package/dest/factory.d.ts +16 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +24 -11
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/archiver/archiver.ts +37 -5
- package/src/factory.ts +29 -12
- package/src/test/mock_l2_block_source.ts +12 -3
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
1
2
|
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
2
3
|
import { type ViemPublicClient } from '@aztec/ethereum';
|
|
3
4
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
@@ -5,7 +6,7 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
5
6
|
import { type Logger } from '@aztec/foundation/log';
|
|
6
7
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
7
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
8
|
-
import type
|
|
9
|
+
import { type InBlock, type L2Block, type L2BlockSource, type L2Tips, type NullifierWithBlockSource } from '@aztec/stdlib/block';
|
|
9
10
|
import { type ContractClassPublic, type ContractDataSource, type ContractInstanceWithAddress, type PublicFunction } from '@aztec/stdlib/contract';
|
|
10
11
|
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
11
12
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
@@ -14,6 +15,7 @@ import { type LogFilter, type PrivateLog, TxScopedL2Log } from '@aztec/stdlib/lo
|
|
|
14
15
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
15
16
|
import { type BlockHeader, TxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
16
17
|
import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
|
|
18
|
+
import { EventEmitter } from 'events';
|
|
17
19
|
import type { ArchiverDataStore } from './archiver_store.js';
|
|
18
20
|
import type { ArchiverConfig } from './config.js';
|
|
19
21
|
import { ArchiverInstrumentation } from './instrumentation.js';
|
|
@@ -26,7 +28,7 @@ export type ArchiveSource = L2BlockSource & L2LogsSource & ContractDataSource &
|
|
|
26
28
|
* Responsible for handling robust L1 polling so that other components do not need to
|
|
27
29
|
* concern themselves with it.
|
|
28
30
|
*/
|
|
29
|
-
export declare class Archiver implements ArchiveSource, Traceable {
|
|
31
|
+
export declare class Archiver extends EventEmitter implements ArchiveSource, Traceable {
|
|
30
32
|
private readonly publicClient;
|
|
31
33
|
private readonly l1Addresses;
|
|
32
34
|
readonly dataStore: ArchiverDataStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiver.d.ts","sourceRoot":"","sources":["../../src/archiver/archiver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,KAAK,gBAAgB,EAAuB,MAAM,iBAAiB,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAC9C,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAclE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"archiver.d.ts","sourceRoot":"","sources":["../../src/archiver/archiver.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,9 +13,11 @@ import { elapsed } from '@aztec/foundation/timer';
|
|
|
13
13
|
import { InboxAbi, RollupAbi } from '@aztec/l1-artifacts';
|
|
14
14
|
import { ContractClassRegisteredEvent, PrivateFunctionBroadcastedEvent, UnconstrainedFunctionBroadcastedEvent } from '@aztec/protocol-contracts/class-registerer';
|
|
15
15
|
import { ContractInstanceDeployedEvent, ContractInstanceUpdatedEvent } from '@aztec/protocol-contracts/instance-deployer';
|
|
16
|
+
import { L2BlockSourceEvents } from '@aztec/stdlib/block';
|
|
16
17
|
import { computePublicBytecodeCommitment, isValidPrivateFunctionMembershipProof, isValidUnconstrainedFunctionMembershipProof } from '@aztec/stdlib/contract';
|
|
17
|
-
import { getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
18
|
+
import { getEpochAtSlot, getEpochNumberAtTimestamp, getSlotAtTimestamp, getSlotRangeForEpoch, getTimestampRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
18
19
|
import { Attributes, trackSpan } from '@aztec/telemetry-client';
|
|
20
|
+
import { EventEmitter } from 'events';
|
|
19
21
|
import groupBy from 'lodash.groupby';
|
|
20
22
|
import { createPublicClient, fallback, getContract, http } from 'viem';
|
|
21
23
|
import { retrieveBlocksFromRollup, retrieveL1ToL2Messages } from './data_retrieval.js';
|
|
@@ -25,7 +27,7 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
25
27
|
* Pulls L2 blocks in a non-blocking manner and provides interface for their retrieval.
|
|
26
28
|
* Responsible for handling robust L1 polling so that other components do not need to
|
|
27
29
|
* concern themselves with it.
|
|
28
|
-
*/ export class Archiver {
|
|
30
|
+
*/ export class Archiver extends EventEmitter {
|
|
29
31
|
publicClient;
|
|
30
32
|
l1Addresses;
|
|
31
33
|
dataStore;
|
|
@@ -53,14 +55,7 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
53
55
|
* @param store - An archiver data store for storage & retrieval of blocks, encrypted logs & contract data.
|
|
54
56
|
* @param log - A logger.
|
|
55
57
|
*/ constructor(publicClient, l1Addresses, dataStore, config, blobSinkClient, instrumentation, l1constants, log = createLogger('archiver')){
|
|
56
|
-
this.publicClient = publicClient;
|
|
57
|
-
this.l1Addresses = l1Addresses;
|
|
58
|
-
this.dataStore = dataStore;
|
|
59
|
-
this.config = config;
|
|
60
|
-
this.blobSinkClient = blobSinkClient;
|
|
61
|
-
this.instrumentation = instrumentation;
|
|
62
|
-
this.l1constants = l1constants;
|
|
63
|
-
this.log = log;
|
|
58
|
+
super(), this.publicClient = publicClient, this.l1Addresses = l1Addresses, this.dataStore = dataStore, this.config = config, this.blobSinkClient = blobSinkClient, this.instrumentation = instrumentation, this.l1constants = l1constants, this.log = log;
|
|
64
59
|
this.tracer = instrumentation.tracer;
|
|
65
60
|
this.store = new ArchiverStoreHelper(dataStore);
|
|
66
61
|
this.rollup = getContract({
|
|
@@ -211,6 +206,15 @@ import { ArchiverInstrumentation } from './instrumentation.js';
|
|
|
211
206
|
const localPendingBlockNumber = BigInt(await this.getBlockNumber());
|
|
212
207
|
const canPrune = localPendingBlockNumber > provenBlockNumber && await this.canPrune(currentL1BlockNumber);
|
|
213
208
|
if (canPrune) {
|
|
209
|
+
const localPendingSlotNumber = await this.getL2SlotNumber();
|
|
210
|
+
const localPendingEpochNumber = getEpochAtSlot(localPendingSlotNumber, this.l1constants);
|
|
211
|
+
// Emit an event for listening services to react to the chain prune
|
|
212
|
+
this.emit(L2BlockSourceEvents.L2PruneDetected, {
|
|
213
|
+
type: L2BlockSourceEvents.L2PruneDetected,
|
|
214
|
+
blockNumber: localPendingBlockNumber,
|
|
215
|
+
slotNumber: localPendingSlotNumber,
|
|
216
|
+
epochNumber: localPendingEpochNumber
|
|
217
|
+
});
|
|
214
218
|
const blocksToUnwind = localPendingBlockNumber - provenBlockNumber;
|
|
215
219
|
this.log.debug(`L2 prune from ${provenBlockNumber + 1n} to ${localPendingBlockNumber} will occur on next block submission.`);
|
|
216
220
|
await this.store.unwindBlocks(Number(localPendingBlockNumber), Number(blocksToUnwind));
|
package/dest/factory.d.ts
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
2
|
-
import type { Maybe } from '@aztec/foundation/types';
|
|
3
2
|
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
3
|
+
import type { L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
|
|
4
4
|
import type { ArchiverApi, Service } from '@aztec/stdlib/interfaces/server';
|
|
5
5
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
6
6
|
import type { ArchiverConfig } from './archiver/config.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a local archiver.
|
|
9
|
+
* @param config - The archiver configuration.
|
|
10
|
+
* @param blobSinkClient - The blob sink client.
|
|
11
|
+
* @param opts - The options.
|
|
12
|
+
* @param telemetry - The telemetry client.
|
|
13
|
+
* @returns The local archiver.
|
|
14
|
+
*/
|
|
7
15
|
export declare function createArchiver(config: ArchiverConfig & DataStoreConfig, blobSinkClient: BlobSinkClientInterface, opts?: {
|
|
8
16
|
blockUntilSync: boolean;
|
|
9
|
-
}, telemetry?: TelemetryClient): Promise<ArchiverApi &
|
|
17
|
+
}, telemetry?: TelemetryClient): Promise<ArchiverApi & Service & L2BlockSourceEventEmitter>;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a remote archiver client.
|
|
20
|
+
* @param config - The archiver configuration.
|
|
21
|
+
* @returns The remote archiver client.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createRemoteArchiver(config: ArchiverConfig): ArchiverApi;
|
|
10
24
|
//# sourceMappingURL=factory.d.ts.map
|
package/dest/factory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAQ9D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAMrE,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAE5E,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAGnF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,GAAG,eAAe,EACxC,cAAc,EAAE,uBAAuB,EACvC,IAAI,GAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAA6B,EAC5D,SAAS,GAAE,eAAsC,GAChD,OAAO,CAAC,WAAW,GAAG,OAAO,GAAG,yBAAyB,CAAC,CAM5D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CASxE"}
|
package/dest/factory.js
CHANGED
|
@@ -12,21 +12,34 @@ import { getTelemetryClient } from '@aztec/telemetry-client';
|
|
|
12
12
|
import { Archiver } from './archiver/archiver.js';
|
|
13
13
|
import { KVArchiverDataStore } from './archiver/index.js';
|
|
14
14
|
import { createArchiverClient } from './rpc/index.js';
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Creates a local archiver.
|
|
17
|
+
* @param config - The archiver configuration.
|
|
18
|
+
* @param blobSinkClient - The blob sink client.
|
|
19
|
+
* @param opts - The options.
|
|
20
|
+
* @param telemetry - The telemetry client.
|
|
21
|
+
* @returns The local archiver.
|
|
22
|
+
*/ export async function createArchiver(config, blobSinkClient, opts = {
|
|
16
23
|
blockUntilSync: true
|
|
17
24
|
}, telemetry = getTelemetryClient()) {
|
|
25
|
+
const store = await createStore('archiver', config, createLogger('archiver:lmdb'));
|
|
26
|
+
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
|
|
27
|
+
await registerProtocolContracts(archiverStore);
|
|
28
|
+
await registerCommonContracts(archiverStore);
|
|
29
|
+
return Archiver.createAndSync(config, archiverStore, {
|
|
30
|
+
telemetry,
|
|
31
|
+
blobSinkClient
|
|
32
|
+
}, opts.blockUntilSync);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates a remote archiver client.
|
|
36
|
+
* @param config - The archiver configuration.
|
|
37
|
+
* @returns The remote archiver client.
|
|
38
|
+
*/ export function createRemoteArchiver(config) {
|
|
18
39
|
if (!config.archiverUrl) {
|
|
19
|
-
|
|
20
|
-
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
|
|
21
|
-
await registerProtocolContracts(archiverStore);
|
|
22
|
-
await registerCommonContracts(archiverStore);
|
|
23
|
-
return Archiver.createAndSync(config, archiverStore, {
|
|
24
|
-
telemetry,
|
|
25
|
-
blobSinkClient
|
|
26
|
-
}, opts.blockUntilSync);
|
|
27
|
-
} else {
|
|
28
|
-
return createArchiverClient(config.archiverUrl, getComponentsVersionsFromConfig(config, protocolContractTreeRoot, getVKTreeRoot()));
|
|
40
|
+
throw new Error('Archiver URL is required');
|
|
29
41
|
}
|
|
42
|
+
return createArchiverClient(config.archiverUrl, getComponentsVersionsFromConfig(config, protocolContractTreeRoot, getVKTreeRoot()));
|
|
30
43
|
}
|
|
31
44
|
async function registerProtocolContracts(store) {
|
|
32
45
|
const blockNumber = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mock_l2_block_source.d.ts","sourceRoot":"","sources":["../../src/test/mock_l2_block_source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,EAAE,SAAS,EAAY,MAAM,kBAAkB,CAAC;AAEjF;;GAEG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAM;IAEnC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,iBAAiB,CAAa;IAEtC,OAAO,CAAC,GAAG,CAAiD;IAE/C,YAAY,CAAC,SAAS,EAAE,MAAM;IAUpC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE;IAK3B,YAAY,CAAC,SAAS,EAAE,MAAM;IAK9B,oBAAoB,CAAC,iBAAiB,EAAE,MAAM;IAI9C,oBAAoB,CAAC,iBAAiB,EAAE,MAAM;IAIrD;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC;IAIvC;;;OAGG;IACH,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC;IAIzC;;;OAGG;IACI,cAAc;IAId,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvC,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAI5D;;;;OAIG;IACI,QAAQ,CAAC,MAAM,EAAE,MAAM;IAI9B;;;;;OAKG;IACI,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO;IAQ9D,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI3E,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAU1D;;;;OAIG;IACU,WAAW,CAAC,MAAM,EAAE,MAAM;;;;;IAWvC;;;;OAIG;IACU,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAkB1E,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"mock_l2_block_source.d.ts","sourceRoot":"","sources":["../../src/test/mock_l2_block_source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,KAAK,iBAAiB,EAAwB,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,EAAE,SAAS,EAAY,MAAM,kBAAkB,CAAC;AAEjF;;GAEG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAM;IAEnC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,iBAAiB,CAAa;IAEtC,OAAO,CAAC,GAAG,CAAiD;IAE/C,YAAY,CAAC,SAAS,EAAE,MAAM;IAUpC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE;IAK3B,YAAY,CAAC,SAAS,EAAE,MAAM;IAK9B,oBAAoB,CAAC,iBAAiB,EAAE,MAAM;IAI9C,oBAAoB,CAAC,iBAAiB,EAAE,MAAM;IAIrD;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC;IAIvC;;;OAGG;IACH,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC;IAIzC;;;OAGG;IACI,cAAc;IAId,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvC,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAI5D;;;;OAIG;IACI,QAAQ,CAAC,MAAM,EAAE,MAAM;IAI9B;;;;;OAKG;IACI,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO;IAQ9D,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAI3E,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAU1D;;;;OAIG;IACU,WAAW,CAAC,MAAM,EAAE,MAAM;;;;;IAWvC;;;;OAIG;IACU,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAkB1E,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IA2BlC,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAIlC,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI5C;;;OAGG;IACI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7B;;;OAGG;IACI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/archiver",
|
|
3
|
-
"version": "0.77.0-testnet-ignition.
|
|
3
|
+
"version": "0.77.0-testnet-ignition.23",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -64,18 +64,18 @@
|
|
|
64
64
|
]
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@aztec/blob-lib": "0.77.0-testnet-ignition.
|
|
68
|
-
"@aztec/blob-sink": "0.77.0-testnet-ignition.
|
|
69
|
-
"@aztec/constants": "0.77.0-testnet-ignition.
|
|
70
|
-
"@aztec/ethereum": "0.77.0-testnet-ignition.
|
|
71
|
-
"@aztec/foundation": "0.77.0-testnet-ignition.
|
|
72
|
-
"@aztec/kv-store": "0.77.0-testnet-ignition.
|
|
73
|
-
"@aztec/l1-artifacts": "0.77.0-testnet-ignition.
|
|
74
|
-
"@aztec/noir-contracts.js": "0.77.0-testnet-ignition.
|
|
75
|
-
"@aztec/noir-protocol-circuits-types": "0.77.0-testnet-ignition.
|
|
76
|
-
"@aztec/protocol-contracts": "0.77.0-testnet-ignition.
|
|
77
|
-
"@aztec/stdlib": "0.77.0-testnet-ignition.
|
|
78
|
-
"@aztec/telemetry-client": "0.77.0-testnet-ignition.
|
|
67
|
+
"@aztec/blob-lib": "0.77.0-testnet-ignition.23",
|
|
68
|
+
"@aztec/blob-sink": "0.77.0-testnet-ignition.23",
|
|
69
|
+
"@aztec/constants": "0.77.0-testnet-ignition.23",
|
|
70
|
+
"@aztec/ethereum": "0.77.0-testnet-ignition.23",
|
|
71
|
+
"@aztec/foundation": "0.77.0-testnet-ignition.23",
|
|
72
|
+
"@aztec/kv-store": "0.77.0-testnet-ignition.23",
|
|
73
|
+
"@aztec/l1-artifacts": "0.77.0-testnet-ignition.23",
|
|
74
|
+
"@aztec/noir-contracts.js": "0.77.0-testnet-ignition.23",
|
|
75
|
+
"@aztec/noir-protocol-circuits-types": "0.77.0-testnet-ignition.23",
|
|
76
|
+
"@aztec/protocol-contracts": "0.77.0-testnet-ignition.23",
|
|
77
|
+
"@aztec/stdlib": "0.77.0-testnet-ignition.23",
|
|
78
|
+
"@aztec/telemetry-client": "0.77.0-testnet-ignition.23",
|
|
79
79
|
"debug": "^4.3.4",
|
|
80
80
|
"lodash.groupby": "^4.6.0",
|
|
81
81
|
"lodash.omit": "^4.5.0",
|
package/src/archiver/archiver.ts
CHANGED
|
@@ -18,7 +18,15 @@ import {
|
|
|
18
18
|
} from '@aztec/protocol-contracts/instance-deployer';
|
|
19
19
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
20
20
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
21
|
-
import
|
|
21
|
+
import {
|
|
22
|
+
type InBlock,
|
|
23
|
+
type L2Block,
|
|
24
|
+
type L2BlockId,
|
|
25
|
+
type L2BlockSource,
|
|
26
|
+
L2BlockSourceEvents,
|
|
27
|
+
type L2Tips,
|
|
28
|
+
type NullifierWithBlockSource,
|
|
29
|
+
} from '@aztec/stdlib/block';
|
|
22
30
|
import {
|
|
23
31
|
type ContractClassPublic,
|
|
24
32
|
type ContractDataSource,
|
|
@@ -32,6 +40,7 @@ import {
|
|
|
32
40
|
} from '@aztec/stdlib/contract';
|
|
33
41
|
import {
|
|
34
42
|
type L1RollupConstants,
|
|
43
|
+
getEpochAtSlot,
|
|
35
44
|
getEpochNumberAtTimestamp,
|
|
36
45
|
getSlotAtTimestamp,
|
|
37
46
|
getSlotRangeForEpoch,
|
|
@@ -44,6 +53,7 @@ import type { InboxLeaf, L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
|
44
53
|
import { type BlockHeader, TxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
45
54
|
import { Attributes, type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
|
|
46
55
|
|
|
56
|
+
import { EventEmitter } from 'events';
|
|
47
57
|
import groupBy from 'lodash.groupby';
|
|
48
58
|
import { type GetContractReturnType, createPublicClient, fallback, getContract, http } from 'viem';
|
|
49
59
|
|
|
@@ -69,7 +79,7 @@ export type ArchiveSource = L2BlockSource &
|
|
|
69
79
|
* Responsible for handling robust L1 polling so that other components do not need to
|
|
70
80
|
* concern themselves with it.
|
|
71
81
|
*/
|
|
72
|
-
export class Archiver implements ArchiveSource, Traceable {
|
|
82
|
+
export class Archiver extends EventEmitter implements ArchiveSource, Traceable {
|
|
73
83
|
/**
|
|
74
84
|
* A promise in which we will be continually fetching new L2 blocks.
|
|
75
85
|
*/
|
|
@@ -105,6 +115,8 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
105
115
|
private readonly l1constants: L1RollupConstants,
|
|
106
116
|
private readonly log: Logger = createLogger('archiver'),
|
|
107
117
|
) {
|
|
118
|
+
super();
|
|
119
|
+
|
|
108
120
|
this.tracer = instrumentation.tracer;
|
|
109
121
|
this.store = new ArchiverStoreHelper(dataStore);
|
|
110
122
|
|
|
@@ -299,6 +311,17 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
299
311
|
const canPrune = localPendingBlockNumber > provenBlockNumber && (await this.canPrune(currentL1BlockNumber));
|
|
300
312
|
|
|
301
313
|
if (canPrune) {
|
|
314
|
+
const localPendingSlotNumber = await this.getL2SlotNumber();
|
|
315
|
+
const localPendingEpochNumber = getEpochAtSlot(localPendingSlotNumber, this.l1constants);
|
|
316
|
+
|
|
317
|
+
// Emit an event for listening services to react to the chain prune
|
|
318
|
+
this.emit(L2BlockSourceEvents.L2PruneDetected, {
|
|
319
|
+
type: L2BlockSourceEvents.L2PruneDetected,
|
|
320
|
+
blockNumber: localPendingBlockNumber,
|
|
321
|
+
slotNumber: localPendingSlotNumber,
|
|
322
|
+
epochNumber: localPendingEpochNumber,
|
|
323
|
+
});
|
|
324
|
+
|
|
302
325
|
const blocksToUnwind = localPendingBlockNumber - provenBlockNumber;
|
|
303
326
|
this.log.debug(
|
|
304
327
|
`L2 prune from ${provenBlockNumber + 1n} to ${localPendingBlockNumber} will occur on next block submission.`,
|
|
@@ -846,9 +869,18 @@ export class Archiver implements ArchiveSource, Traceable {
|
|
|
846
869
|
const provenBlockHeaderHash = await provenBlockHeader?.hash();
|
|
847
870
|
const finalizedBlockHeaderHash = await provenBlockHeader?.hash();
|
|
848
871
|
return {
|
|
849
|
-
latest: {
|
|
850
|
-
|
|
851
|
-
|
|
872
|
+
latest: {
|
|
873
|
+
number: latestBlockNumber,
|
|
874
|
+
hash: latestBlockHeaderHash?.toString(),
|
|
875
|
+
} as L2BlockId,
|
|
876
|
+
proven: {
|
|
877
|
+
number: provenBlockNumber,
|
|
878
|
+
hash: provenBlockHeaderHash?.toString(),
|
|
879
|
+
} as L2BlockId,
|
|
880
|
+
finalized: {
|
|
881
|
+
number: provenBlockNumber,
|
|
882
|
+
hash: finalizedBlockHeaderHash?.toString(),
|
|
883
|
+
} as L2BlockId,
|
|
852
884
|
};
|
|
853
885
|
}
|
|
854
886
|
}
|
package/src/factory.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import type { Maybe } from '@aztec/foundation/types';
|
|
4
3
|
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
5
4
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
6
5
|
import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
|
|
@@ -9,6 +8,7 @@ import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
|
9
8
|
import { protocolContractNames, protocolContractTreeRoot } from '@aztec/protocol-contracts';
|
|
10
9
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
11
10
|
import { FunctionType, decodeFunctionSignature } from '@aztec/stdlib/abi';
|
|
11
|
+
import type { L2BlockSourceEventEmitter } from '@aztec/stdlib/block';
|
|
12
12
|
import {
|
|
13
13
|
type ContractClassPublic,
|
|
14
14
|
computePublicBytecodeCommitment,
|
|
@@ -23,24 +23,41 @@ import type { ArchiverConfig } from './archiver/config.js';
|
|
|
23
23
|
import { KVArchiverDataStore } from './archiver/index.js';
|
|
24
24
|
import { createArchiverClient } from './rpc/index.js';
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Creates a local archiver.
|
|
28
|
+
* @param config - The archiver configuration.
|
|
29
|
+
* @param blobSinkClient - The blob sink client.
|
|
30
|
+
* @param opts - The options.
|
|
31
|
+
* @param telemetry - The telemetry client.
|
|
32
|
+
* @returns The local archiver.
|
|
33
|
+
*/
|
|
26
34
|
export async function createArchiver(
|
|
27
35
|
config: ArchiverConfig & DataStoreConfig,
|
|
28
36
|
blobSinkClient: BlobSinkClientInterface,
|
|
29
37
|
opts: { blockUntilSync: boolean } = { blockUntilSync: true },
|
|
30
38
|
telemetry: TelemetryClient = getTelemetryClient(),
|
|
31
|
-
): Promise<ArchiverApi &
|
|
39
|
+
): Promise<ArchiverApi & Service & L2BlockSourceEventEmitter> {
|
|
40
|
+
const store = await createStore('archiver', config, createLogger('archiver:lmdb'));
|
|
41
|
+
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
|
|
42
|
+
await registerProtocolContracts(archiverStore);
|
|
43
|
+
await registerCommonContracts(archiverStore);
|
|
44
|
+
return Archiver.createAndSync(config, archiverStore, { telemetry, blobSinkClient }, opts.blockUntilSync);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a remote archiver client.
|
|
49
|
+
* @param config - The archiver configuration.
|
|
50
|
+
* @returns The remote archiver client.
|
|
51
|
+
*/
|
|
52
|
+
export function createRemoteArchiver(config: ArchiverConfig): ArchiverApi {
|
|
32
53
|
if (!config.archiverUrl) {
|
|
33
|
-
|
|
34
|
-
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
|
|
35
|
-
await registerProtocolContracts(archiverStore);
|
|
36
|
-
await registerCommonContracts(archiverStore);
|
|
37
|
-
return Archiver.createAndSync(config, archiverStore, { telemetry, blobSinkClient }, opts.blockUntilSync);
|
|
38
|
-
} else {
|
|
39
|
-
return createArchiverClient(
|
|
40
|
-
config.archiverUrl,
|
|
41
|
-
getComponentsVersionsFromConfig(config, protocolContractTreeRoot, getVKTreeRoot()),
|
|
42
|
-
);
|
|
54
|
+
throw new Error('Archiver URL is required');
|
|
43
55
|
}
|
|
56
|
+
|
|
57
|
+
return createArchiverClient(
|
|
58
|
+
config.archiverUrl,
|
|
59
|
+
getComponentsVersionsFromConfig(config, protocolContractTreeRoot, getVKTreeRoot()),
|
|
60
|
+
);
|
|
44
61
|
}
|
|
45
62
|
|
|
46
63
|
async function registerProtocolContracts(store: KVArchiverDataStore) {
|
|
@@ -164,9 +164,18 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
164
164
|
const finalizedBlock = this.l2Blocks[finalized - 1];
|
|
165
165
|
|
|
166
166
|
return {
|
|
167
|
-
latest: {
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
latest: {
|
|
168
|
+
number: latest,
|
|
169
|
+
hash: (await latestBlock?.hash())?.toString(),
|
|
170
|
+
},
|
|
171
|
+
proven: {
|
|
172
|
+
number: proven,
|
|
173
|
+
hash: (await provenBlock?.hash())?.toString(),
|
|
174
|
+
},
|
|
175
|
+
finalized: {
|
|
176
|
+
number: finalized,
|
|
177
|
+
hash: (await finalizedBlock?.hash())?.toString(),
|
|
178
|
+
},
|
|
170
179
|
};
|
|
171
180
|
}
|
|
172
181
|
|