@aztec/archiver 0.0.0-test.1 → 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
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
ContractClassPublic,
|
|
8
8
|
ContractClassPublicWithBlockNumber,
|
|
9
9
|
ExecutablePrivateFunctionWithMembershipProof,
|
|
10
|
-
|
|
10
|
+
UtilityFunctionWithMembershipProof,
|
|
11
11
|
} from '@aztec/stdlib/contract';
|
|
12
12
|
import { Vector } from '@aztec/stdlib/types';
|
|
13
13
|
|
|
@@ -60,7 +60,7 @@ export class ContractClassStore {
|
|
|
60
60
|
async addFunctions(
|
|
61
61
|
contractClassId: Fr,
|
|
62
62
|
newPrivateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
|
|
63
|
-
|
|
63
|
+
newUtilityFunctions: UtilityFunctionWithMembershipProof[],
|
|
64
64
|
): Promise<boolean> {
|
|
65
65
|
await this.db.transactionAsync(async () => {
|
|
66
66
|
const existingClassBuffer = await this.#contractClasses.getAsync(contractClassId.toString());
|
|
@@ -69,7 +69,7 @@ export class ContractClassStore {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const existingClass = deserializeContractClassPublic(existingClassBuffer);
|
|
72
|
-
const { privateFunctions: existingPrivateFns,
|
|
72
|
+
const { privateFunctions: existingPrivateFns, utilityFunctions: existingUtilityFns } = existingClass;
|
|
73
73
|
|
|
74
74
|
const updatedClass: Omit<ContractClassPublicWithBlockNumber, 'id'> = {
|
|
75
75
|
...existingClass,
|
|
@@ -77,11 +77,9 @@ export class ContractClassStore {
|
|
|
77
77
|
...existingPrivateFns,
|
|
78
78
|
...newPrivateFunctions.filter(newFn => !existingPrivateFns.some(f => f.selector.equals(newFn.selector))),
|
|
79
79
|
],
|
|
80
|
-
|
|
81
|
-
...
|
|
82
|
-
...
|
|
83
|
-
newFn => !existingUnconstrainedFns.some(f => f.selector.equals(newFn.selector)),
|
|
84
|
-
),
|
|
80
|
+
utilityFunctions: [
|
|
81
|
+
...existingUtilityFns,
|
|
82
|
+
...newUtilityFunctions.filter(newFn => !existingUtilityFns.some(f => f.selector.equals(newFn.selector))),
|
|
85
83
|
],
|
|
86
84
|
};
|
|
87
85
|
await this.#contractClasses.set(contractClassId.toString(), serializeContractClassPublic(updatedClass));
|
|
@@ -96,12 +94,10 @@ function serializeContractClassPublic(contractClass: Omit<ContractClassPublicWit
|
|
|
96
94
|
contractClass.l2BlockNumber,
|
|
97
95
|
numToUInt8(contractClass.version),
|
|
98
96
|
contractClass.artifactHash,
|
|
99
|
-
contractClass.publicFunctions.length,
|
|
100
|
-
contractClass.publicFunctions?.map(f => serializeToBuffer(f.selector, f.bytecode.length, f.bytecode)) ?? [],
|
|
101
97
|
contractClass.privateFunctions.length,
|
|
102
98
|
contractClass.privateFunctions.map(serializePrivateFunction),
|
|
103
|
-
contractClass.
|
|
104
|
-
contractClass.
|
|
99
|
+
contractClass.utilityFunctions.length,
|
|
100
|
+
contractClass.utilityFunctions.map(serializeUtilityFunction),
|
|
105
101
|
contractClass.packedBytecode.length,
|
|
106
102
|
contractClass.packedBytecode,
|
|
107
103
|
contractClass.privateFunctionsRoot,
|
|
@@ -116,7 +112,7 @@ function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipPro
|
|
|
116
112
|
fn.bytecode,
|
|
117
113
|
fn.functionMetadataHash,
|
|
118
114
|
fn.artifactMetadataHash,
|
|
119
|
-
fn.
|
|
115
|
+
fn.utilityFunctionsTreeRoot,
|
|
120
116
|
new Vector(fn.privateFunctionTreeSiblingPath),
|
|
121
117
|
fn.privateFunctionTreeLeafIndex,
|
|
122
118
|
new Vector(fn.artifactTreeSiblingPath),
|
|
@@ -124,7 +120,7 @@ function serializePrivateFunction(fn: ExecutablePrivateFunctionWithMembershipPro
|
|
|
124
120
|
);
|
|
125
121
|
}
|
|
126
122
|
|
|
127
|
-
function
|
|
123
|
+
function serializeUtilityFunction(fn: UtilityFunctionWithMembershipProof): Buffer {
|
|
128
124
|
return serializeToBuffer(
|
|
129
125
|
fn.selector,
|
|
130
126
|
fn.bytecode.length,
|
|
@@ -143,14 +139,8 @@ function deserializeContractClassPublic(buffer: Buffer): Omit<ContractClassPubli
|
|
|
143
139
|
l2BlockNumber: reader.readNumber(),
|
|
144
140
|
version: reader.readUInt8() as 1,
|
|
145
141
|
artifactHash: reader.readObject(Fr),
|
|
146
|
-
publicFunctions: reader.readVector({
|
|
147
|
-
fromBuffer: reader => ({
|
|
148
|
-
selector: reader.readObject(FunctionSelector),
|
|
149
|
-
bytecode: reader.readBuffer(),
|
|
150
|
-
}),
|
|
151
|
-
}),
|
|
152
142
|
privateFunctions: reader.readVector({ fromBuffer: deserializePrivateFunction }),
|
|
153
|
-
|
|
143
|
+
utilityFunctions: reader.readVector({ fromBuffer: deserializeUtilityFunction }),
|
|
154
144
|
packedBytecode: reader.readBuffer(),
|
|
155
145
|
privateFunctionsRoot: reader.readObject(Fr),
|
|
156
146
|
};
|
|
@@ -164,7 +154,7 @@ function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePr
|
|
|
164
154
|
bytecode: reader.readBuffer(),
|
|
165
155
|
functionMetadataHash: reader.readObject(Fr),
|
|
166
156
|
artifactMetadataHash: reader.readObject(Fr),
|
|
167
|
-
|
|
157
|
+
utilityFunctionsTreeRoot: reader.readObject(Fr),
|
|
168
158
|
privateFunctionTreeSiblingPath: reader.readVector(Fr),
|
|
169
159
|
privateFunctionTreeLeafIndex: reader.readNumber(),
|
|
170
160
|
artifactTreeSiblingPath: reader.readVector(Fr),
|
|
@@ -172,7 +162,7 @@ function deserializePrivateFunction(buffer: Buffer | BufferReader): ExecutablePr
|
|
|
172
162
|
};
|
|
173
163
|
}
|
|
174
164
|
|
|
175
|
-
function
|
|
165
|
+
function deserializeUtilityFunction(buffer: Buffer | BufferReader): UtilityFunctionWithMembershipProof {
|
|
176
166
|
const reader = BufferReader.asReader(buffer);
|
|
177
167
|
return {
|
|
178
168
|
selector: reader.readObject(FunctionSelector),
|
|
@@ -7,71 +7,75 @@ import {
|
|
|
7
7
|
SerializableContractInstance,
|
|
8
8
|
SerializableContractInstanceUpdate,
|
|
9
9
|
} from '@aztec/stdlib/contract';
|
|
10
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
10
11
|
|
|
11
|
-
type ContractInstanceUpdateKey = [string,
|
|
12
|
+
type ContractInstanceUpdateKey = [string, string] | [string, string, number];
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* LMDB implementation of the ArchiverDataStore interface.
|
|
15
16
|
*/
|
|
16
17
|
export class ContractInstanceStore {
|
|
17
18
|
#contractInstances: AztecAsyncMap<string, Buffer>;
|
|
19
|
+
#contractInstancePublishedAt: AztecAsyncMap<string, number>;
|
|
18
20
|
#contractInstanceUpdates: AztecAsyncMap<ContractInstanceUpdateKey, Buffer>;
|
|
19
21
|
|
|
20
|
-
constructor(db: AztecAsyncKVStore) {
|
|
22
|
+
constructor(private db: AztecAsyncKVStore) {
|
|
21
23
|
this.#contractInstances = db.openMap('archiver_contract_instances');
|
|
24
|
+
this.#contractInstancePublishedAt = db.openMap('archiver_contract_instances_publication_block_number');
|
|
22
25
|
this.#contractInstanceUpdates = db.openMap('archiver_contract_instance_updates');
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
addContractInstance(contractInstance: ContractInstanceWithAddress): Promise<void> {
|
|
26
|
-
return this
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
addContractInstance(contractInstance: ContractInstanceWithAddress, blockNumber: number): Promise<void> {
|
|
29
|
+
return this.db.transactionAsync(async () => {
|
|
30
|
+
await this.#contractInstances.set(
|
|
31
|
+
contractInstance.address.toString(),
|
|
32
|
+
new SerializableContractInstance(contractInstance).toBuffer(),
|
|
33
|
+
);
|
|
34
|
+
await this.#contractInstancePublishedAt.set(contractInstance.address.toString(), blockNumber);
|
|
35
|
+
});
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
deleteContractInstance(contractInstance: ContractInstanceWithAddress): Promise<void> {
|
|
33
|
-
return this
|
|
39
|
+
return this.db.transactionAsync(async () => {
|
|
40
|
+
await this.#contractInstances.delete(contractInstance.address.toString());
|
|
41
|
+
await this.#contractInstancePublishedAt.delete(contractInstance.address.toString());
|
|
42
|
+
});
|
|
34
43
|
}
|
|
35
44
|
|
|
36
|
-
getUpdateKey(contractAddress: AztecAddress,
|
|
45
|
+
getUpdateKey(contractAddress: AztecAddress, timestamp: UInt64, logIndex?: number): ContractInstanceUpdateKey {
|
|
37
46
|
if (logIndex === undefined) {
|
|
38
|
-
return [contractAddress.toString(),
|
|
47
|
+
return [contractAddress.toString(), timestamp.toString()];
|
|
39
48
|
} else {
|
|
40
|
-
return [contractAddress.toString(),
|
|
49
|
+
return [contractAddress.toString(), timestamp.toString(), logIndex];
|
|
41
50
|
}
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
addContractInstanceUpdate(
|
|
45
54
|
contractInstanceUpdate: ContractInstanceUpdateWithAddress,
|
|
46
|
-
|
|
55
|
+
timestamp: UInt64,
|
|
47
56
|
logIndex: number,
|
|
48
57
|
): Promise<void> {
|
|
49
58
|
return this.#contractInstanceUpdates.set(
|
|
50
|
-
this.getUpdateKey(contractInstanceUpdate.address,
|
|
59
|
+
this.getUpdateKey(contractInstanceUpdate.address, timestamp, logIndex),
|
|
51
60
|
new SerializableContractInstanceUpdate(contractInstanceUpdate).toBuffer(),
|
|
52
61
|
);
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
deleteContractInstanceUpdate(
|
|
56
65
|
contractInstanceUpdate: ContractInstanceUpdateWithAddress,
|
|
57
|
-
|
|
66
|
+
timestamp: UInt64,
|
|
58
67
|
logIndex: number,
|
|
59
68
|
): Promise<void> {
|
|
60
|
-
return this.#contractInstanceUpdates.delete(
|
|
61
|
-
this.getUpdateKey(contractInstanceUpdate.address, blockNumber, logIndex),
|
|
62
|
-
);
|
|
69
|
+
return this.#contractInstanceUpdates.delete(this.getUpdateKey(contractInstanceUpdate.address, timestamp, logIndex));
|
|
63
70
|
}
|
|
64
71
|
|
|
65
|
-
async getCurrentContractInstanceClassId(
|
|
66
|
-
|
|
67
|
-
blockNumber: number,
|
|
68
|
-
originalClassId: Fr,
|
|
69
|
-
): Promise<Fr> {
|
|
70
|
-
// We need to find the last update before the given block number
|
|
72
|
+
async getCurrentContractInstanceClassId(address: AztecAddress, timestamp: UInt64, originalClassId: Fr): Promise<Fr> {
|
|
73
|
+
// We need to find the last update before the given timestamp
|
|
71
74
|
const queryResult = await this.#contractInstanceUpdates
|
|
72
75
|
.valuesAsync({
|
|
73
76
|
reverse: true,
|
|
74
|
-
|
|
77
|
+
start: this.getUpdateKey(address, 0n), // Make sure we only look at updates for this contract
|
|
78
|
+
end: this.getUpdateKey(address, timestamp + 1n), // No update can match this key since it doesn't have a log index. We want the highest key <= timestamp
|
|
75
79
|
limit: 1,
|
|
76
80
|
})
|
|
77
81
|
.next();
|
|
@@ -81,7 +85,7 @@ export class ContractInstanceStore {
|
|
|
81
85
|
|
|
82
86
|
const serializedUpdate = queryResult.value;
|
|
83
87
|
const update = SerializableContractInstanceUpdate.fromBuffer(serializedUpdate);
|
|
84
|
-
if (
|
|
88
|
+
if (timestamp < update.timestampOfChange) {
|
|
85
89
|
return update.prevContractClassId.isZero() ? originalClassId : update.prevContractClassId;
|
|
86
90
|
}
|
|
87
91
|
return update.newContractClassId;
|
|
@@ -89,7 +93,7 @@ export class ContractInstanceStore {
|
|
|
89
93
|
|
|
90
94
|
async getContractInstance(
|
|
91
95
|
address: AztecAddress,
|
|
92
|
-
|
|
96
|
+
timestamp: UInt64,
|
|
93
97
|
): Promise<ContractInstanceWithAddress | undefined> {
|
|
94
98
|
const contractInstance = await this.#contractInstances.getAsync(address.toString());
|
|
95
99
|
if (!contractInstance) {
|
|
@@ -99,9 +103,13 @@ export class ContractInstanceStore {
|
|
|
99
103
|
const instance = SerializableContractInstance.fromBuffer(contractInstance).withAddress(address);
|
|
100
104
|
instance.currentContractClassId = await this.getCurrentContractInstanceClassId(
|
|
101
105
|
address,
|
|
102
|
-
|
|
106
|
+
timestamp,
|
|
103
107
|
instance.originalContractClassId,
|
|
104
108
|
);
|
|
105
109
|
return instance;
|
|
106
110
|
}
|
|
111
|
+
|
|
112
|
+
getContractInstanceDeploymentBlockNumber(address: AztecAddress): Promise<number | undefined> {
|
|
113
|
+
return this.#contractInstancePublishedAt.getAsync(address.toString());
|
|
114
|
+
}
|
|
107
115
|
}
|
|
@@ -1,69 +1,104 @@
|
|
|
1
|
+
import type { L1BlockId } from '@aztec/ethereum';
|
|
1
2
|
import type { Fr } from '@aztec/foundation/fields';
|
|
2
3
|
import { toArray } from '@aztec/foundation/iterable';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import type { AztecAsyncKVStore, StoreSize } from '@aztec/kv-store';
|
|
5
|
+
import type { AztecAsyncKVStore, CustomRange, StoreSize } from '@aztec/kv-store';
|
|
5
6
|
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
7
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
-
import type
|
|
8
|
+
import { type L2Block, L2BlockHash, type ValidateBlockResult } from '@aztec/stdlib/block';
|
|
8
9
|
import type {
|
|
9
10
|
ContractClassPublic,
|
|
11
|
+
ContractDataSource,
|
|
10
12
|
ContractInstanceUpdateWithAddress,
|
|
11
13
|
ContractInstanceWithAddress,
|
|
12
14
|
ExecutablePrivateFunctionWithMembershipProof,
|
|
13
|
-
|
|
15
|
+
UtilityFunctionWithMembershipProof,
|
|
14
16
|
} from '@aztec/stdlib/contract';
|
|
15
17
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
16
18
|
import { type LogFilter, PrivateLog, type TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
17
|
-
import type { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
18
19
|
import type { BlockHeader, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
20
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
21
|
+
|
|
22
|
+
import { join } from 'path';
|
|
19
23
|
|
|
20
24
|
import type { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
21
|
-
import type {
|
|
22
|
-
import type {
|
|
25
|
+
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
26
|
+
import type { PublishedL2Block } from '../structs/published.js';
|
|
23
27
|
import { BlockStore } from './block_store.js';
|
|
24
28
|
import { ContractClassStore } from './contract_class_store.js';
|
|
25
29
|
import { ContractInstanceStore } from './contract_instance_store.js';
|
|
26
30
|
import { LogStore } from './log_store.js';
|
|
27
31
|
import { MessageStore } from './message_store.js';
|
|
28
|
-
|
|
32
|
+
|
|
33
|
+
export const ARCHIVER_DB_VERSION = 3;
|
|
34
|
+
export const MAX_FUNCTION_SIGNATURES = 1000;
|
|
35
|
+
export const MAX_FUNCTION_NAME_LEN = 256;
|
|
29
36
|
|
|
30
37
|
/**
|
|
31
38
|
* LMDB implementation of the ArchiverDataStore interface.
|
|
32
39
|
*/
|
|
33
|
-
export class KVArchiverDataStore implements ArchiverDataStore {
|
|
34
|
-
public static readonly SCHEMA_VERSION =
|
|
40
|
+
export class KVArchiverDataStore implements ArchiverDataStore, ContractDataSource {
|
|
41
|
+
public static readonly SCHEMA_VERSION = ARCHIVER_DB_VERSION;
|
|
35
42
|
|
|
36
43
|
#blockStore: BlockStore;
|
|
37
44
|
#logStore: LogStore;
|
|
38
|
-
#nullifierStore: NullifierStore;
|
|
39
45
|
#messageStore: MessageStore;
|
|
40
46
|
#contractClassStore: ContractClassStore;
|
|
41
47
|
#contractInstanceStore: ContractInstanceStore;
|
|
48
|
+
|
|
42
49
|
private functionNames = new Map<string, string>();
|
|
43
50
|
|
|
44
51
|
#log = createLogger('archiver:data-store');
|
|
45
52
|
|
|
46
|
-
constructor(
|
|
53
|
+
constructor(
|
|
54
|
+
private db: AztecAsyncKVStore,
|
|
55
|
+
logsMaxPageSize: number = 1000,
|
|
56
|
+
) {
|
|
47
57
|
this.#blockStore = new BlockStore(db);
|
|
48
58
|
this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
|
|
49
59
|
this.#messageStore = new MessageStore(db);
|
|
50
60
|
this.#contractClassStore = new ContractClassStore(db);
|
|
51
61
|
this.#contractInstanceStore = new ContractInstanceStore(db);
|
|
52
|
-
this.#nullifierStore = new NullifierStore(db);
|
|
53
62
|
}
|
|
54
63
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
public transactionAsync<T>(callback: () => Promise<T>): Promise<T> {
|
|
65
|
+
return this.db.transactionAsync(callback);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public getBlockNumber(): Promise<number> {
|
|
69
|
+
return this.getSynchedL2BlockNumber();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public async getContract(
|
|
73
|
+
address: AztecAddress,
|
|
74
|
+
maybeTimestamp?: UInt64,
|
|
75
|
+
): Promise<ContractInstanceWithAddress | undefined> {
|
|
76
|
+
const [header] = await this.getBlockHeaders(await this.getBlockNumber(), 1);
|
|
77
|
+
const timestamp = maybeTimestamp ?? header!.globalVariables.timestamp;
|
|
78
|
+
return this.getContractInstance(address, timestamp);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public async backupTo(path: string, compress = true): Promise<string> {
|
|
82
|
+
await this.db.backupTo(path, compress);
|
|
83
|
+
return join(path, 'data.mdb');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public close() {
|
|
87
|
+
return this.db.close();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getDebugFunctionName(_address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
|
|
59
91
|
return Promise.resolve(this.functionNames.get(selector.toString()));
|
|
60
92
|
}
|
|
61
93
|
|
|
62
|
-
async registerContractFunctionSignatures(
|
|
94
|
+
async registerContractFunctionSignatures(signatures: string[]): Promise<void> {
|
|
63
95
|
for (const sig of signatures) {
|
|
96
|
+
if (this.functionNames.size > MAX_FUNCTION_SIGNATURES) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
64
99
|
try {
|
|
65
100
|
const selector = await FunctionSelector.fromSignature(sig);
|
|
66
|
-
this.functionNames.set(selector.toString(), sig.slice(0, sig.indexOf('(')));
|
|
101
|
+
this.functionNames.set(selector.toString(), sig.slice(0, sig.indexOf('(')).slice(0, MAX_FUNCTION_NAME_LEN));
|
|
67
102
|
} catch {
|
|
68
103
|
this.#log.warn(`Failed to parse signature: ${sig}. Ignoring`);
|
|
69
104
|
}
|
|
@@ -78,9 +113,12 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
78
113
|
return this.#contractClassStore.getContractClassIds();
|
|
79
114
|
}
|
|
80
115
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
116
|
+
getContractInstance(address: AztecAddress, timestamp: UInt64): Promise<ContractInstanceWithAddress | undefined> {
|
|
117
|
+
return this.#contractInstanceStore.getContractInstance(address, timestamp);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getContractInstanceDeploymentBlockNumber(address: AztecAddress): Promise<number | undefined> {
|
|
121
|
+
return this.#contractInstanceStore.getContractInstanceDeploymentBlockNumber(address);
|
|
84
122
|
}
|
|
85
123
|
|
|
86
124
|
async addContractClasses(
|
|
@@ -108,36 +146,35 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
108
146
|
addFunctions(
|
|
109
147
|
contractClassId: Fr,
|
|
110
148
|
privateFunctions: ExecutablePrivateFunctionWithMembershipProof[],
|
|
111
|
-
|
|
149
|
+
utilityFunctions: UtilityFunctionWithMembershipProof[],
|
|
112
150
|
): Promise<boolean> {
|
|
113
|
-
return this.#contractClassStore.addFunctions(contractClassId, privateFunctions,
|
|
151
|
+
return this.#contractClassStore.addFunctions(contractClassId, privateFunctions, utilityFunctions);
|
|
114
152
|
}
|
|
115
153
|
|
|
116
|
-
async addContractInstances(data: ContractInstanceWithAddress[],
|
|
117
|
-
return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c)))).every(
|
|
154
|
+
async addContractInstances(data: ContractInstanceWithAddress[], blockNumber: number): Promise<boolean> {
|
|
155
|
+
return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c, blockNumber)))).every(
|
|
156
|
+
Boolean,
|
|
157
|
+
);
|
|
118
158
|
}
|
|
119
159
|
|
|
120
160
|
async deleteContractInstances(data: ContractInstanceWithAddress[], _blockNumber: number): Promise<boolean> {
|
|
121
161
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.deleteContractInstance(c)))).every(Boolean);
|
|
122
162
|
}
|
|
123
163
|
|
|
124
|
-
async addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[],
|
|
164
|
+
async addContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], timestamp: UInt64): Promise<boolean> {
|
|
125
165
|
return (
|
|
126
166
|
await Promise.all(
|
|
127
167
|
data.map((update, logIndex) =>
|
|
128
|
-
this.#contractInstanceStore.addContractInstanceUpdate(update,
|
|
168
|
+
this.#contractInstanceStore.addContractInstanceUpdate(update, timestamp, logIndex),
|
|
129
169
|
),
|
|
130
170
|
)
|
|
131
171
|
).every(Boolean);
|
|
132
172
|
}
|
|
133
|
-
async deleteContractInstanceUpdates(
|
|
134
|
-
data: ContractInstanceUpdateWithAddress[],
|
|
135
|
-
blockNumber: number,
|
|
136
|
-
): Promise<boolean> {
|
|
173
|
+
async deleteContractInstanceUpdates(data: ContractInstanceUpdateWithAddress[], timestamp: UInt64): Promise<boolean> {
|
|
137
174
|
return (
|
|
138
175
|
await Promise.all(
|
|
139
176
|
data.map((update, logIndex) =>
|
|
140
|
-
this.#contractInstanceStore.deleteContractInstanceUpdate(update,
|
|
177
|
+
this.#contractInstanceStore.deleteContractInstanceUpdate(update, timestamp, logIndex),
|
|
141
178
|
),
|
|
142
179
|
)
|
|
143
180
|
).every(Boolean);
|
|
@@ -148,8 +185,8 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
148
185
|
* @param blocks - The L2 blocks to be added to the store and the last processed L1 block.
|
|
149
186
|
* @returns True if the operation is successful.
|
|
150
187
|
*/
|
|
151
|
-
addBlocks(blocks:
|
|
152
|
-
return this.#blockStore.addBlocks(blocks);
|
|
188
|
+
addBlocks(blocks: PublishedL2Block[], opts: { force?: boolean } = {}): Promise<boolean> {
|
|
189
|
+
return this.#blockStore.addBlocks(blocks, opts);
|
|
153
190
|
}
|
|
154
191
|
|
|
155
192
|
/**
|
|
@@ -163,6 +200,18 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
163
200
|
return this.#blockStore.unwindBlocks(from, blocksToUnwind);
|
|
164
201
|
}
|
|
165
202
|
|
|
203
|
+
getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
|
|
204
|
+
return this.#blockStore.getBlock(number);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
getPublishedBlockByHash(blockHash: Fr): Promise<PublishedL2Block | undefined> {
|
|
208
|
+
return this.#blockStore.getBlockByHash(L2BlockHash.fromField(blockHash));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
getPublishedBlockByArchive(archive: Fr): Promise<PublishedL2Block | undefined> {
|
|
212
|
+
return this.#blockStore.getBlockByArchive(archive);
|
|
213
|
+
}
|
|
214
|
+
|
|
166
215
|
/**
|
|
167
216
|
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
168
217
|
*
|
|
@@ -170,7 +219,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
170
219
|
* @param limit - The number of blocks to return.
|
|
171
220
|
* @returns The requested L2 blocks
|
|
172
221
|
*/
|
|
173
|
-
|
|
222
|
+
getPublishedBlocks(start: number, limit: number): Promise<PublishedL2Block[]> {
|
|
174
223
|
return toArray(this.#blockStore.getBlocks(start, limit));
|
|
175
224
|
}
|
|
176
225
|
|
|
@@ -185,10 +234,18 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
185
234
|
return toArray(this.#blockStore.getBlockHeaders(start, limit));
|
|
186
235
|
}
|
|
187
236
|
|
|
237
|
+
getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
|
|
238
|
+
return this.#blockStore.getBlockHeaderByHash(L2BlockHash.fromField(blockHash));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
|
|
242
|
+
return this.#blockStore.getBlockHeaderByArchive(archive);
|
|
243
|
+
}
|
|
244
|
+
|
|
188
245
|
/**
|
|
189
246
|
* Gets a tx effect.
|
|
190
|
-
* @param txHash - The
|
|
191
|
-
* @returns The requested tx effect (or undefined if not found).
|
|
247
|
+
* @param txHash - The hash of the tx corresponding to the tx effect.
|
|
248
|
+
* @returns The requested tx effect with block info (or undefined if not found).
|
|
192
249
|
*/
|
|
193
250
|
getTxEffect(txHash: TxHash) {
|
|
194
251
|
return this.#blockStore.getTxEffect(txHash);
|
|
@@ -216,33 +273,19 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
216
273
|
return this.#logStore.deleteLogs(blocks);
|
|
217
274
|
}
|
|
218
275
|
|
|
219
|
-
/**
|
|
220
|
-
* Append new nullifiers to the store's list.
|
|
221
|
-
* @param blocks - The blocks for which to add the nullifiers.
|
|
222
|
-
* @returns True if the operation is successful.
|
|
223
|
-
*/
|
|
224
|
-
addNullifiers(blocks: L2Block[]): Promise<boolean> {
|
|
225
|
-
return this.#nullifierStore.addNullifiers(blocks);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
deleteNullifiers(blocks: L2Block[]): Promise<boolean> {
|
|
229
|
-
return this.#nullifierStore.deleteNullifiers(blocks);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
findNullifiersIndexesWithBlock(blockNumber: number, nullifiers: Fr[]): Promise<(InBlock<bigint> | undefined)[]> {
|
|
233
|
-
return this.#nullifierStore.findNullifiersIndexesWithBlock(blockNumber, nullifiers);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
276
|
getTotalL1ToL2MessageCount(): Promise<bigint> {
|
|
237
277
|
return this.#messageStore.getTotalL1ToL2MessageCount();
|
|
238
278
|
}
|
|
239
279
|
|
|
280
|
+
getLastL1ToL2Message(): Promise<InboxMessage | undefined> {
|
|
281
|
+
return this.#messageStore.getLastMessage();
|
|
282
|
+
}
|
|
283
|
+
|
|
240
284
|
/**
|
|
241
285
|
* Append L1 to L2 messages to the store.
|
|
242
|
-
* @param messages - The L1 to L2 messages to be added to the store
|
|
243
|
-
* @returns True if the operation is successful.
|
|
286
|
+
* @param messages - The L1 to L2 messages to be added to the store.
|
|
244
287
|
*/
|
|
245
|
-
addL1ToL2Messages(messages:
|
|
288
|
+
addL1ToL2Messages(messages: InboxMessage[]): Promise<void> {
|
|
246
289
|
return this.#messageStore.addL1ToL2Messages(messages);
|
|
247
290
|
}
|
|
248
291
|
|
|
@@ -260,7 +303,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
260
303
|
* @param blockNumber - L2 block number to get messages for.
|
|
261
304
|
* @returns The L1 to L2 messages/leaves of the messages subtree (throws if not found).
|
|
262
305
|
*/
|
|
263
|
-
getL1ToL2Messages(blockNumber:
|
|
306
|
+
getL1ToL2Messages(blockNumber: number): Promise<Fr[]> {
|
|
264
307
|
return this.#messageStore.getL1ToL2Messages(blockNumber);
|
|
265
308
|
}
|
|
266
309
|
|
|
@@ -277,12 +320,13 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
277
320
|
/**
|
|
278
321
|
* Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
|
|
279
322
|
* @param tags - The tags to filter the logs by.
|
|
323
|
+
* @param logsPerTag - How many logs to return per tag. Default returns everything
|
|
280
324
|
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
|
|
281
325
|
* that tag.
|
|
282
326
|
*/
|
|
283
|
-
getLogsByTags(tags: Fr[]): Promise<TxScopedL2Log[][]> {
|
|
327
|
+
getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
|
|
284
328
|
try {
|
|
285
|
-
return this.#logStore.getLogsByTags(tags);
|
|
329
|
+
return this.#logStore.getLogsByTags(tags, logsPerTag);
|
|
286
330
|
} catch (err) {
|
|
287
331
|
return Promise.reject(err);
|
|
288
332
|
}
|
|
@@ -334,8 +378,8 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
334
378
|
await this.#blockStore.setSynchedL1BlockNumber(l1BlockNumber);
|
|
335
379
|
}
|
|
336
380
|
|
|
337
|
-
async
|
|
338
|
-
await this.#messageStore.
|
|
381
|
+
async setMessageSynchedL1Block(l1Block: L1BlockId) {
|
|
382
|
+
await this.#messageStore.setSynchedL1Block(l1Block);
|
|
339
383
|
}
|
|
340
384
|
|
|
341
385
|
/**
|
|
@@ -344,7 +388,7 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
344
388
|
async getSynchPoint(): Promise<ArchiverL1SynchPoint> {
|
|
345
389
|
const [blocksSynchedTo, messagesSynchedTo] = await Promise.all([
|
|
346
390
|
this.#blockStore.getSynchedL1BlockNumber(),
|
|
347
|
-
this.#messageStore.
|
|
391
|
+
this.#messageStore.getSynchedL1Block(),
|
|
348
392
|
]);
|
|
349
393
|
return {
|
|
350
394
|
blocksSynchedTo,
|
|
@@ -355,4 +399,24 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
355
399
|
public estimateSize(): Promise<StoreSize> {
|
|
356
400
|
return this.db.estimateSize();
|
|
357
401
|
}
|
|
402
|
+
|
|
403
|
+
public rollbackL1ToL2MessagesToL2Block(targetBlockNumber: number): Promise<void> {
|
|
404
|
+
return this.#messageStore.rollbackL1ToL2MessagesToL2Block(targetBlockNumber);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
public iterateL1ToL2Messages(range: CustomRange<bigint> = {}): AsyncIterableIterator<InboxMessage> {
|
|
408
|
+
return this.#messageStore.iterateL1ToL2Messages(range);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
public removeL1ToL2Messages(startIndex: bigint): Promise<void> {
|
|
412
|
+
return this.#messageStore.removeL1ToL2Messages(startIndex);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
public getPendingChainValidationStatus(): Promise<ValidateBlockResult | undefined> {
|
|
416
|
+
return this.#blockStore.getPendingChainValidationStatus();
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
public setPendingChainValidationStatus(status: ValidateBlockResult | undefined): Promise<void> {
|
|
420
|
+
return this.#blockStore.setPendingChainValidationStatus(status);
|
|
421
|
+
}
|
|
358
422
|
}
|