@aztec/archiver 0.0.0-test.0 → 0.0.1-commit.24de95ac
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 +27 -6
- package/dest/archiver/archiver.d.ts +126 -46
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +683 -261
- package/dest/archiver/archiver_store.d.ts +84 -49
- package/dest/archiver/archiver_store.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +707 -213
- package/dest/archiver/config.d.ts +4 -20
- package/dest/archiver/config.d.ts.map +1 -1
- package/dest/archiver/config.js +16 -12
- package/dest/archiver/data_retrieval.d.ts +25 -20
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +147 -68
- package/dest/archiver/errors.d.ts +8 -0
- package/dest/archiver/errors.d.ts.map +1 -1
- package/dest/archiver/errors.js +12 -0
- package/dest/archiver/index.d.ts +2 -3
- package/dest/archiver/index.d.ts.map +1 -1
- package/dest/archiver/index.js +1 -2
- package/dest/archiver/instrumentation.d.ts +9 -3
- package/dest/archiver/instrumentation.d.ts.map +1 -1
- package/dest/archiver/instrumentation.js +58 -17
- package/dest/archiver/kv_archiver_store/block_store.d.ts +47 -10
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +216 -63
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +2 -2
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +12 -18
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts +10 -7
- package/dest/archiver/kv_archiver_store/contract_instance_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_instance_store.js +30 -16
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +49 -34
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +88 -46
- 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 +18 -46
- package/dest/archiver/kv_archiver_store/message_store.d.ts +22 -16
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +150 -48
- package/dest/archiver/structs/inbox_message.d.ts +15 -0
- package/dest/archiver/structs/inbox_message.d.ts.map +1 -0
- package/dest/archiver/structs/inbox_message.js +38 -0
- package/dest/archiver/structs/published.d.ts +1 -10
- package/dest/archiver/structs/published.d.ts.map +1 -1
- package/dest/archiver/structs/published.js +1 -1
- package/dest/archiver/validation.d.ts +11 -0
- package/dest/archiver/validation.d.ts.map +1 -0
- package/dest/archiver/validation.js +90 -0
- package/dest/factory.d.ts +7 -12
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +18 -49
- package/dest/rpc/index.d.ts +1 -2
- package/dest/rpc/index.d.ts.map +1 -1
- package/dest/rpc/index.js +1 -4
- package/dest/test/mock_archiver.d.ts +1 -1
- package/dest/test/mock_l1_to_l2_message_source.d.ts +4 -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 +14 -1
- package/dest/test/mock_l2_block_source.d.ts +32 -5
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +118 -7
- package/dest/test/mock_structs.d.ts +9 -0
- package/dest/test/mock_structs.d.ts.map +1 -0
- package/dest/test/mock_structs.js +37 -0
- package/package.json +25 -27
- package/src/archiver/archiver.ts +858 -317
- package/src/archiver/archiver_store.ts +97 -55
- package/src/archiver/archiver_store_test_suite.ts +663 -210
- package/src/archiver/config.ts +23 -41
- package/src/archiver/data_retrieval.ts +215 -92
- package/src/archiver/errors.ts +21 -0
- package/src/archiver/index.ts +2 -3
- package/src/archiver/instrumentation.ts +75 -20
- package/src/archiver/kv_archiver_store/block_store.ts +270 -72
- package/src/archiver/kv_archiver_store/contract_class_store.ts +13 -23
- package/src/archiver/kv_archiver_store/contract_instance_store.ts +35 -27
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +127 -63
- package/src/archiver/kv_archiver_store/log_store.ts +24 -62
- package/src/archiver/kv_archiver_store/message_store.ts +209 -53
- package/src/archiver/structs/inbox_message.ts +41 -0
- package/src/archiver/structs/published.ts +1 -11
- package/src/archiver/validation.ts +99 -0
- package/src/factory.ts +24 -66
- package/src/rpc/index.ts +1 -5
- package/src/test/mock_archiver.ts +1 -1
- package/src/test/mock_l1_to_l2_message_source.ts +14 -3
- package/src/test/mock_l2_block_source.ts +152 -8
- package/src/test/mock_structs.ts +49 -0
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts +0 -12
- package/dest/archiver/kv_archiver_store/nullifier_store.d.ts.map +0 -1
- package/dest/archiver/kv_archiver_store/nullifier_store.js +0 -73
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +0 -23
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +0 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +0 -49
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +0 -175
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +0 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +0 -636
- package/src/archiver/kv_archiver_store/nullifier_store.ts +0 -97
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +0 -61
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +0 -801
package/src/factory.ts
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
2
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
2
|
import type { DataStoreConfig } from '@aztec/kv-store/config';
|
|
4
3
|
import { createStore } from '@aztec/kv-store/lmdb-v2';
|
|
5
|
-
import {
|
|
6
|
-
import { TokenBridgeContractArtifact } from '@aztec/noir-contracts.js/TokenBridge';
|
|
7
|
-
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
8
|
-
import { protocolContractNames, protocolContractTreeRoot } from '@aztec/protocol-contracts';
|
|
4
|
+
import { protocolContractNames } from '@aztec/protocol-contracts';
|
|
9
5
|
import { BundledProtocolContractsProvider } from '@aztec/protocol-contracts/providers/bundle';
|
|
10
6
|
import { FunctionType, decodeFunctionSignature } from '@aztec/stdlib/abi';
|
|
11
|
-
import type
|
|
12
|
-
import {
|
|
13
|
-
type ContractClassPublic,
|
|
14
|
-
computePublicBytecodeCommitment,
|
|
15
|
-
getContractClassFromArtifact,
|
|
16
|
-
} from '@aztec/stdlib/contract';
|
|
17
|
-
import type { ArchiverApi, Service } from '@aztec/stdlib/interfaces/server';
|
|
18
|
-
import { getComponentsVersionsFromConfig } from '@aztec/stdlib/versioning';
|
|
19
|
-
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
7
|
+
import { type ContractClassPublic, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
|
|
20
8
|
|
|
21
|
-
import { Archiver } from './archiver/archiver.js';
|
|
9
|
+
import { Archiver, type ArchiverDeps } from './archiver/archiver.js';
|
|
22
10
|
import type { ArchiverConfig } from './archiver/config.js';
|
|
23
|
-
import { KVArchiverDataStore } from './archiver/
|
|
24
|
-
|
|
11
|
+
import { ARCHIVER_DB_VERSION, KVArchiverDataStore } from './archiver/kv_archiver_store/kv_archiver_store.js';
|
|
12
|
+
|
|
13
|
+
export const ARCHIVER_STORE_NAME = 'archiver';
|
|
14
|
+
|
|
15
|
+
/** Creates an archiver store. */
|
|
16
|
+
export async function createArchiverStore(
|
|
17
|
+
userConfig: Pick<ArchiverConfig, 'archiverStoreMapSizeKb' | 'maxLogs'> & DataStoreConfig,
|
|
18
|
+
) {
|
|
19
|
+
const config = {
|
|
20
|
+
...userConfig,
|
|
21
|
+
dataStoreMapSizeKb: userConfig.archiverStoreMapSizeKb ?? userConfig.dataStoreMapSizeKb,
|
|
22
|
+
};
|
|
23
|
+
const store = await createStore(ARCHIVER_STORE_NAME, ARCHIVER_DB_VERSION, config, createLogger('archiver:lmdb'));
|
|
24
|
+
return new KVArchiverDataStore(store, config.maxLogs);
|
|
25
|
+
}
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Creates a local archiver.
|
|
@@ -33,36 +34,12 @@ import { createArchiverClient } from './rpc/index.js';
|
|
|
33
34
|
*/
|
|
34
35
|
export async function createArchiver(
|
|
35
36
|
config: ArchiverConfig & DataStoreConfig,
|
|
36
|
-
|
|
37
|
+
deps: ArchiverDeps,
|
|
37
38
|
opts: { blockUntilSync: boolean } = { blockUntilSync: true },
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const store = await createStore(
|
|
41
|
-
'archiver',
|
|
42
|
-
KVArchiverDataStore.SCHEMA_VERSION,
|
|
43
|
-
config,
|
|
44
|
-
createLogger('archiver:lmdb'),
|
|
45
|
-
);
|
|
46
|
-
const archiverStore = new KVArchiverDataStore(store, config.maxLogs);
|
|
39
|
+
): Promise<Archiver> {
|
|
40
|
+
const archiverStore = await createArchiverStore(config);
|
|
47
41
|
await registerProtocolContracts(archiverStore);
|
|
48
|
-
|
|
49
|
-
return Archiver.createAndSync(config, archiverStore, { telemetry, blobSinkClient }, opts.blockUntilSync);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Creates a remote archiver client.
|
|
54
|
-
* @param config - The archiver configuration.
|
|
55
|
-
* @returns The remote archiver client.
|
|
56
|
-
*/
|
|
57
|
-
export function createRemoteArchiver(config: ArchiverConfig): ArchiverApi {
|
|
58
|
-
if (!config.archiverUrl) {
|
|
59
|
-
throw new Error('Archiver URL is required');
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return createArchiverClient(
|
|
63
|
-
config.archiverUrl,
|
|
64
|
-
getComponentsVersionsFromConfig(config, protocolContractTreeRoot, getVKTreeRoot()),
|
|
65
|
-
);
|
|
42
|
+
return Archiver.createAndSync(config, archiverStore, deps, opts.blockUntilSync);
|
|
66
43
|
}
|
|
67
44
|
|
|
68
45
|
async function registerProtocolContracts(store: KVArchiverDataStore) {
|
|
@@ -73,35 +50,16 @@ async function registerProtocolContracts(store: KVArchiverDataStore) {
|
|
|
73
50
|
const contractClassPublic: ContractClassPublic = {
|
|
74
51
|
...contract.contractClass,
|
|
75
52
|
privateFunctions: [],
|
|
76
|
-
|
|
53
|
+
utilityFunctions: [],
|
|
77
54
|
};
|
|
78
55
|
|
|
79
56
|
const publicFunctionSignatures = contract.artifact.functions
|
|
80
57
|
.filter(fn => fn.functionType === FunctionType.PUBLIC)
|
|
81
58
|
.map(fn => decodeFunctionSignature(fn.name, fn.parameters));
|
|
82
59
|
|
|
83
|
-
await store.registerContractFunctionSignatures(
|
|
60
|
+
await store.registerContractFunctionSignatures(publicFunctionSignatures);
|
|
84
61
|
const bytecodeCommitment = await computePublicBytecodeCommitment(contractClassPublic.packedBytecode);
|
|
85
62
|
await store.addContractClasses([contractClassPublic], [bytecodeCommitment], blockNumber);
|
|
86
63
|
await store.addContractInstances([contract.instance], blockNumber);
|
|
87
64
|
}
|
|
88
65
|
}
|
|
89
|
-
|
|
90
|
-
// TODO(#10007): Remove this method. We are explicitly registering these contracts
|
|
91
|
-
// here to ensure they are available to all nodes and all prover nodes, since the PXE
|
|
92
|
-
// was tweaked to automatically push contract classes to the node it is registered,
|
|
93
|
-
// but other nodes in the network may require the contract classes to be registered as well.
|
|
94
|
-
// TODO(#10007): Remove the dependency on noir-contracts.js from this package once we remove this.
|
|
95
|
-
async function registerCommonContracts(store: KVArchiverDataStore) {
|
|
96
|
-
const blockNumber = 0;
|
|
97
|
-
const artifacts = [TokenBridgeContractArtifact, TokenContractArtifact];
|
|
98
|
-
const classes = await Promise.all(
|
|
99
|
-
artifacts.map(async artifact => ({
|
|
100
|
-
...(await getContractClassFromArtifact(artifact)),
|
|
101
|
-
privateFunctions: [],
|
|
102
|
-
unconstrainedFunctions: [],
|
|
103
|
-
})),
|
|
104
|
-
);
|
|
105
|
-
const bytecodeCommitments = await Promise.all(classes.map(x => computePublicBytecodeCommitment(x.packedBytecode)));
|
|
106
|
-
await store.addContractClasses(classes, bytecodeCommitments, blockNumber);
|
|
107
|
-
}
|
package/src/rpc/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createSafeJsonRpcClient } from '@aztec/foundation/json-rpc/client';
|
|
2
2
|
import { type ArchiverApi, ArchiverApiSchema } from '@aztec/stdlib/interfaces/server';
|
|
3
3
|
import { type ComponentsVersions, getVersioningResponseHandler } from '@aztec/stdlib/versioning';
|
|
4
|
-
import {
|
|
4
|
+
import { makeTracedFetch } from '@aztec/telemetry-client';
|
|
5
5
|
|
|
6
6
|
export function createArchiverClient(
|
|
7
7
|
url: string,
|
|
@@ -14,7 +14,3 @@ export function createArchiverClient(
|
|
|
14
14
|
onResponse: getVersioningResponseHandler(versions),
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
export function createArchiverRpcServer(handler: ArchiverApi) {
|
|
19
|
-
return createTracedJsonRpcServer(handler, ArchiverApiSchema);
|
|
20
|
-
}
|
|
@@ -15,7 +15,7 @@ export class MockArchiver extends MockL2BlockSource implements L2BlockSource, L1
|
|
|
15
15
|
this.messageSource.setL1ToL2Messages(blockNumber, msgs);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
getL1ToL2Messages(blockNumber:
|
|
18
|
+
getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
|
|
19
19
|
return this.messageSource.getL1ToL2Messages(blockNumber);
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import type { L2Tips } from '@aztec/stdlib/block';
|
|
2
3
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -17,8 +18,8 @@ export class MockL1ToL2MessageSource implements L1ToL2MessageSource {
|
|
|
17
18
|
this.blockNumber = blockNumber;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
getL1ToL2Messages(blockNumber:
|
|
21
|
-
return Promise.resolve(this.messagesPerBlock.get(
|
|
21
|
+
getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
|
|
22
|
+
return Promise.resolve(this.messagesPerBlock.get(blockNumber) ?? []);
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
getL1ToL2MessageIndex(_l1ToL2Message: Fr): Promise<bigint | undefined> {
|
|
@@ -28,4 +29,14 @@ export class MockL1ToL2MessageSource implements L1ToL2MessageSource {
|
|
|
28
29
|
getBlockNumber(): Promise<number> {
|
|
29
30
|
return Promise.resolve(this.blockNumber);
|
|
30
31
|
}
|
|
32
|
+
|
|
33
|
+
getL2Tips(): Promise<L2Tips> {
|
|
34
|
+
const number = this.blockNumber;
|
|
35
|
+
const tip = { number, hash: new Fr(number).toString() };
|
|
36
|
+
return Promise.resolve({
|
|
37
|
+
latest: tip,
|
|
38
|
+
proven: tip,
|
|
39
|
+
finalized: tip,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
31
42
|
}
|
|
@@ -1,17 +1,32 @@
|
|
|
1
|
+
import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
|
|
1
2
|
import { DefaultL1ContractsConfig } from '@aztec/ethereum';
|
|
3
|
+
import { Buffer32 } from '@aztec/foundation/buffer';
|
|
2
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
6
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
7
|
+
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
8
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
9
|
+
import {
|
|
10
|
+
L2Block,
|
|
11
|
+
L2BlockHash,
|
|
12
|
+
type L2BlockSource,
|
|
13
|
+
type L2Tips,
|
|
14
|
+
PublishedL2Block,
|
|
15
|
+
type ValidateBlockResult,
|
|
16
|
+
} from '@aztec/stdlib/block';
|
|
17
|
+
import type { ContractClassPublic, ContractDataSource, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
18
|
+
import { EmptyL1RollupConstants, type L1RollupConstants, getSlotRangeForEpoch } from '@aztec/stdlib/epoch-helpers';
|
|
6
19
|
import { type BlockHeader, TxHash, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
20
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
7
21
|
|
|
8
22
|
/**
|
|
9
23
|
* A mocked implementation of L2BlockSource to be used in tests.
|
|
10
24
|
*/
|
|
11
|
-
export class MockL2BlockSource implements L2BlockSource {
|
|
25
|
+
export class MockL2BlockSource implements L2BlockSource, ContractDataSource {
|
|
12
26
|
protected l2Blocks: L2Block[] = [];
|
|
13
27
|
|
|
14
28
|
private provenBlockNumber: number = 0;
|
|
29
|
+
private finalizedBlockNumber: number = 0;
|
|
15
30
|
|
|
16
31
|
private log = createLogger('archiver:mock_l2_block_source');
|
|
17
32
|
|
|
@@ -39,6 +54,13 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
39
54
|
this.provenBlockNumber = provenBlockNumber;
|
|
40
55
|
}
|
|
41
56
|
|
|
57
|
+
public setFinalizedBlockNumber(finalizedBlockNumber: number) {
|
|
58
|
+
if (finalizedBlockNumber > this.provenBlockNumber) {
|
|
59
|
+
this.provenBlockNumber = finalizedBlockNumber;
|
|
60
|
+
}
|
|
61
|
+
this.finalizedBlockNumber = finalizedBlockNumber;
|
|
62
|
+
}
|
|
63
|
+
|
|
42
64
|
/**
|
|
43
65
|
* Method to fetch the rollup contract address at the base-layer.
|
|
44
66
|
* @returns The rollup address.
|
|
@@ -90,8 +112,74 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
90
112
|
);
|
|
91
113
|
}
|
|
92
114
|
|
|
115
|
+
public async getPublishedBlocks(from: number, limit: number, proven?: boolean) {
|
|
116
|
+
const blocks = await this.getBlocks(from, limit, proven);
|
|
117
|
+
return blocks.map(block =>
|
|
118
|
+
PublishedL2Block.fromFields({
|
|
119
|
+
block,
|
|
120
|
+
l1: {
|
|
121
|
+
blockNumber: BigInt(block.number),
|
|
122
|
+
blockHash: Buffer32.random().toString(),
|
|
123
|
+
timestamp: BigInt(block.number),
|
|
124
|
+
},
|
|
125
|
+
attestations: [],
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public async getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
|
|
131
|
+
for (const block of this.l2Blocks) {
|
|
132
|
+
const hash = await block.hash();
|
|
133
|
+
if (hash.equals(blockHash)) {
|
|
134
|
+
return PublishedL2Block.fromFields({
|
|
135
|
+
block,
|
|
136
|
+
l1: {
|
|
137
|
+
blockNumber: BigInt(block.number),
|
|
138
|
+
blockHash: Buffer32.random().toString(),
|
|
139
|
+
timestamp: BigInt(block.number),
|
|
140
|
+
},
|
|
141
|
+
attestations: [],
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public getPublishedBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined> {
|
|
149
|
+
const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
|
|
150
|
+
if (!block) {
|
|
151
|
+
return Promise.resolve(undefined);
|
|
152
|
+
}
|
|
153
|
+
return Promise.resolve(
|
|
154
|
+
PublishedL2Block.fromFields({
|
|
155
|
+
block,
|
|
156
|
+
l1: {
|
|
157
|
+
blockNumber: BigInt(block.number),
|
|
158
|
+
blockHash: Buffer32.random().toString(),
|
|
159
|
+
timestamp: BigInt(block.number),
|
|
160
|
+
},
|
|
161
|
+
attestations: [],
|
|
162
|
+
}),
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
|
|
167
|
+
for (const block of this.l2Blocks) {
|
|
168
|
+
const hash = await block.hash();
|
|
169
|
+
if (hash.equals(blockHash)) {
|
|
170
|
+
return block.getBlockHeader();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
|
|
177
|
+
const block = this.l2Blocks.find(b => b.archive.root.equals(archive));
|
|
178
|
+
return Promise.resolve(block?.getBlockHeader());
|
|
179
|
+
}
|
|
180
|
+
|
|
93
181
|
getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
|
|
94
|
-
return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number - 1 : -1)?.
|
|
182
|
+
return Promise.resolve(this.l2Blocks.at(typeof number === 'number' ? number - 1 : -1)?.getBlockHeader());
|
|
95
183
|
}
|
|
96
184
|
|
|
97
185
|
getBlocksForEpoch(epochNumber: bigint): Promise<L2Block[]> {
|
|
@@ -104,10 +192,15 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
104
192
|
return Promise.resolve(blocks);
|
|
105
193
|
}
|
|
106
194
|
|
|
195
|
+
async getBlockHeadersForEpoch(epochNumber: bigint): Promise<BlockHeader[]> {
|
|
196
|
+
const blocks = await this.getBlocksForEpoch(epochNumber);
|
|
197
|
+
return blocks.map(b => b.getBlockHeader());
|
|
198
|
+
}
|
|
199
|
+
|
|
107
200
|
/**
|
|
108
201
|
* Gets a tx effect.
|
|
109
|
-
* @param txHash - The hash of
|
|
110
|
-
* @returns The requested tx effect.
|
|
202
|
+
* @param txHash - The hash of the tx corresponding to the tx effect.
|
|
203
|
+
* @returns The requested tx effect with block info (or undefined if not found).
|
|
111
204
|
*/
|
|
112
205
|
public async getTxEffect(txHash: TxHash) {
|
|
113
206
|
const match = this.l2Blocks
|
|
@@ -117,7 +210,12 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
117
210
|
return Promise.resolve(undefined);
|
|
118
211
|
}
|
|
119
212
|
const [txEffect, block] = match;
|
|
120
|
-
return {
|
|
213
|
+
return {
|
|
214
|
+
data: txEffect,
|
|
215
|
+
l2BlockNumber: block.number,
|
|
216
|
+
l2BlockHash: L2BlockHash.fromField(await block.hash()),
|
|
217
|
+
txIndexInBlock: block.body.txEffects.indexOf(txEffect),
|
|
218
|
+
};
|
|
121
219
|
}
|
|
122
220
|
|
|
123
221
|
/**
|
|
@@ -147,7 +245,7 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
147
245
|
const [latest, proven, finalized] = [
|
|
148
246
|
await this.getBlockNumber(),
|
|
149
247
|
await this.getProvenBlockNumber(),
|
|
150
|
-
|
|
248
|
+
this.finalizedBlockNumber,
|
|
151
249
|
] as const;
|
|
152
250
|
|
|
153
251
|
const latestBlock = this.l2Blocks[latest - 1];
|
|
@@ -183,6 +281,14 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
183
281
|
}
|
|
184
282
|
|
|
185
283
|
getL1Constants(): Promise<L1RollupConstants> {
|
|
284
|
+
return Promise.resolve(EmptyL1RollupConstants);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
getGenesisValues(): Promise<{ genesisArchiveRoot: Fr }> {
|
|
288
|
+
return Promise.resolve({ genesisArchiveRoot: new Fr(GENESIS_ARCHIVE_ROOT) });
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
getL1Timestamp(): Promise<bigint> {
|
|
186
292
|
throw new Error('Method not implemented.');
|
|
187
293
|
}
|
|
188
294
|
|
|
@@ -191,6 +297,7 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
191
297
|
* @returns A promise that signals the initialization of the l2 block source on completion.
|
|
192
298
|
*/
|
|
193
299
|
public start(): Promise<void> {
|
|
300
|
+
this.log.verbose('Starting mock L2 block source');
|
|
194
301
|
return Promise.resolve();
|
|
195
302
|
}
|
|
196
303
|
|
|
@@ -199,6 +306,43 @@ export class MockL2BlockSource implements L2BlockSource {
|
|
|
199
306
|
* @returns A promise that signals the l2 block source is now stopped.
|
|
200
307
|
*/
|
|
201
308
|
public stop(): Promise<void> {
|
|
309
|
+
this.log.verbose('Stopping mock L2 block source');
|
|
202
310
|
return Promise.resolve();
|
|
203
311
|
}
|
|
312
|
+
|
|
313
|
+
getContractClass(_id: Fr): Promise<ContractClassPublic | undefined> {
|
|
314
|
+
return Promise.resolve(undefined);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
getBytecodeCommitment(_id: Fr): Promise<Fr | undefined> {
|
|
318
|
+
return Promise.resolve(undefined);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
getContract(_address: AztecAddress, _timestamp?: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
322
|
+
return Promise.resolve(undefined);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
getContractClassIds(): Promise<Fr[]> {
|
|
326
|
+
return Promise.resolve([]);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
getDebugFunctionName(_address: AztecAddress, _selector: FunctionSelector): Promise<string | undefined> {
|
|
330
|
+
return Promise.resolve(undefined);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
registerContractFunctionSignatures(_signatures: string[]): Promise<void> {
|
|
334
|
+
return Promise.resolve();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
syncImmediate(): Promise<void> {
|
|
338
|
+
return Promise.resolve();
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
isPendingChainInvalid(): Promise<boolean> {
|
|
342
|
+
return Promise.resolve(false);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
getPendingChainValidationStatus(): Promise<ValidateBlockResult> {
|
|
346
|
+
return Promise.resolve({ valid: true });
|
|
347
|
+
}
|
|
204
348
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Buffer16, Buffer32 } from '@aztec/foundation/buffer';
|
|
2
|
+
import { randomBigInt, randomInt } from '@aztec/foundation/crypto';
|
|
3
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
4
|
+
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
5
|
+
|
|
6
|
+
import { type InboxMessage, updateRollingHash } from '../archiver/structs/inbox_message.js';
|
|
7
|
+
|
|
8
|
+
export function makeInboxMessage(
|
|
9
|
+
previousRollingHash = Buffer16.ZERO,
|
|
10
|
+
overrides: Partial<InboxMessage> = {},
|
|
11
|
+
): InboxMessage {
|
|
12
|
+
const { l2BlockNumber = randomInt(100) + 1 } = overrides;
|
|
13
|
+
const { l1BlockNumber = randomBigInt(100n) + 1n } = overrides;
|
|
14
|
+
const { l1BlockHash = Buffer32.random() } = overrides;
|
|
15
|
+
const { leaf = Fr.random() } = overrides;
|
|
16
|
+
const { rollingHash = updateRollingHash(previousRollingHash, leaf) } = overrides;
|
|
17
|
+
const { index = InboxLeaf.smallestIndexFromL2Block(l2BlockNumber) } = overrides;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
index,
|
|
21
|
+
leaf,
|
|
22
|
+
l2BlockNumber,
|
|
23
|
+
l1BlockNumber,
|
|
24
|
+
l1BlockHash,
|
|
25
|
+
rollingHash,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function makeInboxMessages(
|
|
30
|
+
count: number,
|
|
31
|
+
opts: {
|
|
32
|
+
initialHash?: Buffer16;
|
|
33
|
+
initialL2BlockNumber?: number;
|
|
34
|
+
overrideFn?: (msg: InboxMessage, index: number) => InboxMessage;
|
|
35
|
+
} = {},
|
|
36
|
+
): InboxMessage[] {
|
|
37
|
+
const { initialHash = Buffer16.ZERO, overrideFn = msg => msg, initialL2BlockNumber = 1 } = opts;
|
|
38
|
+
const messages: InboxMessage[] = [];
|
|
39
|
+
let rollingHash = initialHash;
|
|
40
|
+
for (let i = 0; i < count; i++) {
|
|
41
|
+
const leaf = Fr.random();
|
|
42
|
+
const l2BlockNumber = i + initialL2BlockNumber;
|
|
43
|
+
const message = overrideFn(makeInboxMessage(rollingHash, { leaf, l2BlockNumber }), i);
|
|
44
|
+
rollingHash = message.rollingHash;
|
|
45
|
+
messages.push(message);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return messages;
|
|
49
|
+
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
3
|
-
import type { InBlock, L2Block } from '@aztec/stdlib/block';
|
|
4
|
-
export declare class NullifierStore {
|
|
5
|
-
#private;
|
|
6
|
-
private db;
|
|
7
|
-
constructor(db: AztecAsyncKVStore);
|
|
8
|
-
addNullifiers(blocks: L2Block[]): Promise<boolean>;
|
|
9
|
-
deleteNullifiers(blocks: L2Block[]): Promise<boolean>;
|
|
10
|
-
findNullifiersIndexesWithBlock(blockNumber: number, nullifiers: Fr[]): Promise<(InBlock<bigint> | undefined)[]>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=nullifier_store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nullifier_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/nullifier_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE5D,qBAAa,cAAc;;IAMb,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,iBAAiB;IAMnC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BlD,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAerD,8BAA8B,CAClC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,EAAE,EAAE,GACf,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;CAkC5C"}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
|
|
2
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
export class NullifierStore {
|
|
4
|
-
db;
|
|
5
|
-
#nullifiersToBlockNumber;
|
|
6
|
-
#nullifiersToBlockHash;
|
|
7
|
-
#nullifiersToIndex;
|
|
8
|
-
#log;
|
|
9
|
-
constructor(db){
|
|
10
|
-
this.db = db;
|
|
11
|
-
this.#log = createLogger('archiver:log_store');
|
|
12
|
-
this.#nullifiersToBlockNumber = db.openMap('archiver_nullifiers_to_block_number');
|
|
13
|
-
this.#nullifiersToBlockHash = db.openMap('archiver_nullifiers_to_block_hash');
|
|
14
|
-
this.#nullifiersToIndex = db.openMap('archiver_nullifiers_to_index');
|
|
15
|
-
}
|
|
16
|
-
async addNullifiers(blocks) {
|
|
17
|
-
const blockHashes = await Promise.all(blocks.map((block)=>block.hash()));
|
|
18
|
-
await this.db.transactionAsync(async ()=>{
|
|
19
|
-
await Promise.all(blocks.map((block, i)=>{
|
|
20
|
-
const dataStartIndexForBlock = block.header.state.partial.nullifierTree.nextAvailableLeafIndex - block.body.txEffects.length * MAX_NULLIFIERS_PER_TX;
|
|
21
|
-
return Promise.all(block.body.txEffects.map((txEffects, txIndex)=>{
|
|
22
|
-
const dataStartIndexForTx = dataStartIndexForBlock + txIndex * MAX_NULLIFIERS_PER_TX;
|
|
23
|
-
return Promise.all(txEffects.nullifiers.map(async (nullifier, nullifierIndex)=>{
|
|
24
|
-
await this.#nullifiersToBlockNumber.set(nullifier.toString(), block.number);
|
|
25
|
-
await this.#nullifiersToBlockHash.set(nullifier.toString(), blockHashes[i].toString());
|
|
26
|
-
await this.#nullifiersToIndex.set(nullifier.toString(), dataStartIndexForTx + nullifierIndex);
|
|
27
|
-
}));
|
|
28
|
-
}));
|
|
29
|
-
}));
|
|
30
|
-
});
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
async deleteNullifiers(blocks) {
|
|
34
|
-
await this.db.transactionAsync(async ()=>{
|
|
35
|
-
for (const block of blocks){
|
|
36
|
-
for (const nullifier of block.body.txEffects.flatMap((tx)=>tx.nullifiers)){
|
|
37
|
-
await Promise.all([
|
|
38
|
-
this.#nullifiersToBlockNumber.delete(nullifier.toString()),
|
|
39
|
-
this.#nullifiersToBlockHash.delete(nullifier.toString()),
|
|
40
|
-
this.#nullifiersToIndex.delete(nullifier.toString())
|
|
41
|
-
]);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
async findNullifiersIndexesWithBlock(blockNumber, nullifiers) {
|
|
48
|
-
const asStrings = nullifiers.map((x)=>x.toString());
|
|
49
|
-
const maybeNullifiers = await Promise.all(asStrings.map(async (nullifier)=>{
|
|
50
|
-
const [data, l2BlockNumber, l2BlockHash] = await Promise.all([
|
|
51
|
-
this.#nullifiersToIndex.getAsync(nullifier),
|
|
52
|
-
this.#nullifiersToBlockNumber.getAsync(nullifier),
|
|
53
|
-
this.#nullifiersToBlockHash.getAsync(nullifier)
|
|
54
|
-
]);
|
|
55
|
-
return {
|
|
56
|
-
data,
|
|
57
|
-
l2BlockNumber,
|
|
58
|
-
l2BlockHash
|
|
59
|
-
};
|
|
60
|
-
}));
|
|
61
|
-
return maybeNullifiers.map(({ data, l2BlockNumber, l2BlockHash })=>{
|
|
62
|
-
if (data === undefined || l2BlockNumber === undefined || l2BlockHash === undefined || l2BlockNumber > blockNumber) {
|
|
63
|
-
return undefined;
|
|
64
|
-
} else {
|
|
65
|
-
return {
|
|
66
|
-
data: BigInt(data),
|
|
67
|
-
l2BlockNumber,
|
|
68
|
-
l2BlockHash
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { Fr } from '@aztec/foundation/fields';
|
|
2
|
-
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
3
|
-
/**
|
|
4
|
-
* A simple in-memory implementation of an L1 to L2 message store.
|
|
5
|
-
*/
|
|
6
|
-
export declare class L1ToL2MessageStore {
|
|
7
|
-
#private;
|
|
8
|
-
/**
|
|
9
|
-
* A map pointing from a key in a "messageIndex" format to the corresponding L1 to L2 message hash.
|
|
10
|
-
*/
|
|
11
|
-
protected store: Map<string, Fr>;
|
|
12
|
-
constructor();
|
|
13
|
-
getTotalL1ToL2MessageCount(): bigint;
|
|
14
|
-
addMessage(message: InboxLeaf): void;
|
|
15
|
-
getMessages(blockNumber: bigint): Fr[];
|
|
16
|
-
/**
|
|
17
|
-
* Gets the L1 to L2 message index in the L1 to L2 message tree.
|
|
18
|
-
* @param l1ToL2Message - The L1 to L2 message.
|
|
19
|
-
* @returns The index of the L1 to L2 message in the L1 to L2 message tree (undefined if not found).
|
|
20
|
-
*/
|
|
21
|
-
getMessageIndex(l1ToL2Message: Fr): bigint | undefined;
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=l1_to_l2_message_store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"l1_to_l2_message_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/memory_archiver_store/l1_to_l2_message_store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD;;GAEG;AACH,qBAAa,kBAAkB;;IAC7B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAa;;IAM7C,0BAA0B,IAAI,MAAM;IAIpC,UAAU,CAAC,OAAO,EAAE,SAAS;IAI7B,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,EAAE,EAAE;IAsBtC;;;;OAIG;IACH,eAAe,CAAC,aAAa,EAAE,EAAE,GAAG,MAAM,GAAG,SAAS;CAQvD"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/constants';
|
|
2
|
-
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
3
|
-
/**
|
|
4
|
-
* A simple in-memory implementation of an L1 to L2 message store.
|
|
5
|
-
*/ export class L1ToL2MessageStore {
|
|
6
|
-
/**
|
|
7
|
-
* A map pointing from a key in a "messageIndex" format to the corresponding L1 to L2 message hash.
|
|
8
|
-
*/ store = new Map();
|
|
9
|
-
#l1ToL2MessagesSubtreeSize = 2 ** L1_TO_L2_MSG_SUBTREE_HEIGHT;
|
|
10
|
-
constructor(){}
|
|
11
|
-
getTotalL1ToL2MessageCount() {
|
|
12
|
-
return BigInt(this.store.size);
|
|
13
|
-
}
|
|
14
|
-
addMessage(message) {
|
|
15
|
-
this.store.set(`${message.index}`, message.leaf);
|
|
16
|
-
}
|
|
17
|
-
getMessages(blockNumber) {
|
|
18
|
-
const messages = [];
|
|
19
|
-
let undefinedMessageFound = false;
|
|
20
|
-
const startIndex = Number(InboxLeaf.smallestIndexFromL2Block(blockNumber));
|
|
21
|
-
for(let i = startIndex; i < startIndex + this.#l1ToL2MessagesSubtreeSize; i++){
|
|
22
|
-
// This is inefficient but probably fine for now.
|
|
23
|
-
const message = this.store.get(`${i}`);
|
|
24
|
-
if (message) {
|
|
25
|
-
if (undefinedMessageFound) {
|
|
26
|
-
throw new Error(`L1 to L2 message gap found in block ${blockNumber}`);
|
|
27
|
-
}
|
|
28
|
-
messages.push(message);
|
|
29
|
-
} else {
|
|
30
|
-
undefinedMessageFound = true;
|
|
31
|
-
// We continue iterating over messages here to verify that there are no more messages after the undefined one.
|
|
32
|
-
// --> If this was the case this would imply there is some issue with log fetching.
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return messages;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Gets the L1 to L2 message index in the L1 to L2 message tree.
|
|
39
|
-
* @param l1ToL2Message - The L1 to L2 message.
|
|
40
|
-
* @returns The index of the L1 to L2 message in the L1 to L2 message tree (undefined if not found).
|
|
41
|
-
*/ getMessageIndex(l1ToL2Message) {
|
|
42
|
-
for (const [key, message] of this.store.entries()){
|
|
43
|
-
if (message.equals(l1ToL2Message)) {
|
|
44
|
-
return BigInt(key);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return undefined;
|
|
48
|
-
}
|
|
49
|
-
}
|