@aztec/world-state 0.23.0 → 0.26.1

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.
@@ -0,0 +1,50 @@
1
+ import { MAX_NEW_NULLIFIERS_PER_TX, MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX } from '@aztec/circuits.js';
2
+ import { IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree';
3
+
4
+ import { MerkleTreeOperations } from './merkle_tree_operations.js';
5
+
6
+ /**
7
+ *
8
+ * @remarks Short explanation:
9
+ * The nullifier tree must be initially padded as the pre-populated 0 index prevents efficient subtree insertion.
10
+ * Padding with some values solves this issue.
11
+ *
12
+ * @remarks Thorough explanation:
13
+ * There needs to be an initial (0,0,0) leaf in the tree, so that when we insert the first 'proper' leaf, we can
14
+ * prove that any value greater than 0 doesn't exist in the tree yet. We prefill/pad the tree with "the number of
15
+ * leaves that are added by one block" so that the first 'proper' block can insert a full subtree.
16
+ *
17
+ * Without this padding, there would be a leaf (0,0,0) at leaf index 0, making it really difficult to insert e.g.
18
+ * 1024 leaves for the first block, because there's only neat space for 1023 leaves after 0. By padding with 1023
19
+ * more leaves, we can then insert the first block of 1024 leaves into indices 1024:2047.
20
+ */
21
+ export const INITIAL_NULLIFIER_TREE_SIZE = 2 * MAX_NEW_NULLIFIERS_PER_TX;
22
+
23
+ export const INITIAL_PUBLIC_DATA_TREE_SIZE = 2 * MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX;
24
+
25
+ /**
26
+ * Adds a last boolean flag in each function on the type.
27
+ */
28
+ type WithIncludeUncommitted<F> = F extends (...args: [...infer Rest]) => infer Return
29
+ ? (...args: [...Rest, boolean]) => Return
30
+ : F;
31
+
32
+ /**
33
+ * Defines the names of the setters on Merkle Trees.
34
+ */
35
+ type MerkleTreeSetters = 'appendLeaves' | 'updateLeaf' | 'commit' | 'rollback' | 'handleL2Block' | 'batchInsert';
36
+
37
+ /**
38
+ * Defines the interface for operations on a set of Merkle Trees configuring whether to return committed or uncommitted data.
39
+ */
40
+ export type MerkleTreeDb = {
41
+ [Property in keyof MerkleTreeOperations as Exclude<Property, MerkleTreeSetters>]: WithIncludeUncommitted<
42
+ MerkleTreeOperations[Property]
43
+ >;
44
+ } & Pick<MerkleTreeOperations, MerkleTreeSetters> & {
45
+ /**
46
+ * Returns a snapshot of the current state of the trees.
47
+ * @param block - The block number to take the snapshot at.
48
+ */
49
+ getSnapshot(block: number): Promise<ReadonlyArray<TreeSnapshot | IndexedTreeSnapshot>>;
50
+ };
@@ -0,0 +1,178 @@
1
+ import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/circuit-types';
2
+ import { Header, NullifierLeafPreimage, StateReference } from '@aztec/circuits.js';
3
+ import { createDebugLogger } from '@aztec/foundation/log';
4
+ import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
5
+ import { BatchInsertionResult } from '@aztec/merkle-tree';
6
+
7
+ /**
8
+ * Type alias for the nullifier tree ID.
9
+ */
10
+ export type IndexedTreeId = MerkleTreeId.NULLIFIER_TREE | MerkleTreeId.PUBLIC_DATA_TREE;
11
+
12
+ /**
13
+ * Defines tree information.
14
+ */
15
+ export interface TreeInfo {
16
+ /**
17
+ * The tree ID.
18
+ */
19
+ treeId: MerkleTreeId;
20
+ /**
21
+ * The tree root.
22
+ */
23
+ root: Buffer;
24
+ /**
25
+ * The number of leaves in the tree.
26
+ */
27
+ size: bigint;
28
+
29
+ /**
30
+ * The depth of the tree.
31
+ */
32
+ depth: number;
33
+ }
34
+
35
+ /**
36
+ * Defines the interface for operations on a set of Merkle Trees.
37
+ */
38
+ export interface MerkleTreeOperations {
39
+ /**
40
+ * Appends leaves to a given tree.
41
+ * @param treeId - The tree to be updated.
42
+ * @param leaves - The set of leaves to be appended.
43
+ */
44
+ appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise<void>;
45
+
46
+ /**
47
+ * Returns information about the given tree.
48
+ * @param treeId - The tree to be queried.
49
+ */
50
+ getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo>;
51
+
52
+ /**
53
+ * Gets the current state reference.
54
+ */
55
+ getStateReference(): Promise<StateReference>;
56
+
57
+ /**
58
+ * Builds the initial header.
59
+ */
60
+ buildInitialHeader(): Promise<Header>;
61
+
62
+ /**
63
+ * Gets sibling path for a leaf.
64
+ * @param treeId - The tree to be queried for a sibling path.
65
+ * @param index - The index of the leaf for which a sibling path should be returned.
66
+ */
67
+ getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>>;
68
+
69
+ /**
70
+ * Returns the previous index for a given value in an indexed tree.
71
+ * @param treeId - The tree for which the previous value index is required.
72
+ * @param value - The value to be queried.
73
+ */
74
+ getPreviousValueIndex(
75
+ treeId: IndexedTreeId,
76
+ value: bigint,
77
+ ): Promise<
78
+ | {
79
+ /**
80
+ * The index of the found leaf.
81
+ */
82
+ index: bigint;
83
+ /**
84
+ * A flag indicating if the corresponding leaf's value is equal to `newValue`.
85
+ */
86
+ alreadyPresent: boolean;
87
+ }
88
+ | undefined
89
+ >;
90
+
91
+ /**
92
+ * Returns the data at a specific leaf.
93
+ * @param treeId - The tree for which leaf data should be returned.
94
+ * @param index - The index of the leaf required.
95
+ */
96
+ getLeafPreimage(treeId: IndexedTreeId, index: bigint): Promise<IndexedTreeLeafPreimage | undefined>;
97
+
98
+ /**
99
+ * Update the leaf data at the given index.
100
+ * @param treeId - The tree for which leaf data should be edited.
101
+ * @param leaf - The updated leaf value.
102
+ * @param index - The index of the leaf to be updated.
103
+ */
104
+ updateLeaf(treeId: IndexedTreeId, leaf: NullifierLeafPreimage | Buffer, index: bigint): Promise<void>;
105
+
106
+ /**
107
+ * Returns the index containing a leaf value.
108
+ * @param treeId - The tree for which the index should be returned.
109
+ * @param value - The value to search for in the tree.
110
+ */
111
+ findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined>;
112
+
113
+ /**
114
+ * Gets the value for a leaf in the tree.
115
+ * @param treeId - The tree for which the index should be returned.
116
+ * @param index - The index of the leaf.
117
+ */
118
+ getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined>;
119
+
120
+ /**
121
+ * Inserts the block hash into the archive.
122
+ * This includes all of the current roots of all of the data trees and the current blocks global vars.
123
+ * @param header - The header to insert into the archive.
124
+ */
125
+ updateArchive(header: Header): Promise<void>;
126
+
127
+ /**
128
+ * Batch insert multiple leaves into the tree.
129
+ * @param leaves - Leaves to insert into the tree.
130
+ * @param treeId - The tree on which to insert.
131
+ * @param subtreeHeight - Height of the subtree.
132
+ * @returns The witness data for the leaves to be updated when inserting the new ones.
133
+ */
134
+ batchInsert<TreeHeight extends number, SubtreeSiblingPathHeight extends number>(
135
+ treeId: MerkleTreeId,
136
+ leaves: Buffer[],
137
+ subtreeHeight: number,
138
+ ): Promise<BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>>;
139
+
140
+ /**
141
+ * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
142
+ * @param block - The L2 block to handle.
143
+ */
144
+ handleL2Block(block: L2Block): Promise<HandleL2BlockResult>;
145
+
146
+ /**
147
+ * Commits pending changes to the underlying store.
148
+ */
149
+ commit(): Promise<void>;
150
+
151
+ /**
152
+ * Rolls back pending changes.
153
+ */
154
+ rollback(): Promise<void>;
155
+ }
156
+
157
+ /** Return type for handleL2Block */
158
+ export type HandleL2BlockResult = {
159
+ /** Whether the block processed was emitted by our sequencer */ isBlockOurs: boolean;
160
+ };
161
+
162
+ /**
163
+ * Outputs a tree leaves using for debugging purposes.
164
+ */
165
+ export async function inspectTree(
166
+ db: MerkleTreeOperations,
167
+ treeId: MerkleTreeId,
168
+ log = createDebugLogger('aztec:inspect-tree'),
169
+ ) {
170
+ const info = await db.getTreeInfo(treeId);
171
+ const output = [`Tree id=${treeId} size=${info.size} root=0x${info.root.toString('hex')}`];
172
+ for (let i = 0; i < info.size; i++) {
173
+ output.push(
174
+ ` Leaf ${i}: ${await db.getLeafValue(treeId, BigInt(i)).then(x => x?.toString('hex') ?? '[undefined]')}`,
175
+ );
176
+ }
177
+ log(output.join('\n'));
178
+ }
@@ -0,0 +1,182 @@
1
+ import { L2Block, MerkleTreeId, SiblingPath } from '@aztec/circuit-types';
2
+ import { Header, NullifierLeafPreimage, StateReference } from '@aztec/circuits.js';
3
+ import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
4
+ import { BatchInsertionResult } from '@aztec/merkle-tree';
5
+
6
+ import { MerkleTreeDb } from './merkle_tree_db.js';
7
+ import { HandleL2BlockResult, MerkleTreeOperations, TreeInfo } from './merkle_tree_operations.js';
8
+
9
+ /**
10
+ * Wraps a MerkleTreeDbOperations to call all functions with a preset includeUncommitted flag.
11
+ */
12
+ export class MerkleTreeOperationsFacade implements MerkleTreeOperations {
13
+ constructor(private trees: MerkleTreeDb, private includeUncommitted: boolean) {}
14
+
15
+ /**
16
+ * Returns the tree info for the specified tree id.
17
+ * @param treeId - Id of the tree to get information from.
18
+ * @param includeUncommitted - Indicates whether to include uncommitted data.
19
+ * @returns The tree info for the specified tree.
20
+ */
21
+ getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo> {
22
+ return this.trees.getTreeInfo(treeId, this.includeUncommitted);
23
+ }
24
+
25
+ /**
26
+ * Get the current state reference.
27
+ * @returns The current state reference.
28
+ */
29
+ getStateReference(): Promise<StateReference> {
30
+ return this.trees.getStateReference(this.includeUncommitted);
31
+ }
32
+
33
+ /**
34
+ * Builds the initial header.
35
+ * @returns The initial header.
36
+ */
37
+ buildInitialHeader(): Promise<Header> {
38
+ return this.trees.buildInitialHeader(this.includeUncommitted);
39
+ }
40
+
41
+ /**
42
+ * Appends a set of leaf values to the tree.
43
+ * @param treeId - Id of the tree to append leaves to.
44
+ * @param leaves - The set of leaves to be appended.
45
+ * @returns The tree info of the specified tree.
46
+ */
47
+ appendLeaves(treeId: MerkleTreeId, leaves: Buffer[]): Promise<void> {
48
+ return this.trees.appendLeaves(treeId, leaves);
49
+ }
50
+
51
+ /**
52
+ * Returns the sibling path for a requested leaf index.
53
+ * @param treeId - Id of the tree to get the sibling path from.
54
+ * @param index - The index of the leaf for which a sibling path is required.
55
+ * @returns A promise with the sibling path of the specified leaf index.
56
+ */
57
+ async getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>> {
58
+ const path = await this.trees.getSiblingPath(treeId, index, this.includeUncommitted);
59
+ return path as unknown as SiblingPath<N>;
60
+ }
61
+
62
+ /**
63
+ * Finds the index of the largest leaf whose value is less than or equal to the provided value.
64
+ * @param treeId - The ID of the tree to search.
65
+ * @param value - The value to be inserted into the tree.
66
+ * @param includeUncommitted - If true, the uncommitted changes are included in the search.
67
+ * @returns The found leaf index and a flag indicating if the corresponding leaf's value is equal to `newValue`.
68
+ */
69
+ getPreviousValueIndex(
70
+ treeId: MerkleTreeId.NULLIFIER_TREE,
71
+ value: bigint,
72
+ ): Promise<
73
+ | {
74
+ /**
75
+ * The index of the found leaf.
76
+ */
77
+ index: bigint;
78
+ /**
79
+ * A flag indicating if the corresponding leaf's value is equal to `newValue`.
80
+ */
81
+ alreadyPresent: boolean;
82
+ }
83
+ | undefined
84
+ > {
85
+ return this.trees.getPreviousValueIndex(treeId, value, this.includeUncommitted);
86
+ }
87
+
88
+ /**
89
+ * Updates a leaf in a tree at a given index.
90
+ * @param treeId - The ID of the tree.
91
+ * @param leaf - The new leaf value.
92
+ * @param index - The index to insert into.
93
+ * @returns Empty promise.
94
+ */
95
+ updateLeaf(treeId: MerkleTreeId.NULLIFIER_TREE, leaf: NullifierLeafPreimage, index: bigint): Promise<void> {
96
+ return this.trees.updateLeaf(treeId, leaf, index);
97
+ }
98
+
99
+ /**
100
+ * Gets the leaf data at a given index and tree.
101
+ * @param treeId - The ID of the tree get the leaf from.
102
+ * @param index - The index of the leaf to get.
103
+ * @returns Leaf preimage.
104
+ */
105
+ async getLeafPreimage(
106
+ treeId: MerkleTreeId.NULLIFIER_TREE,
107
+ index: bigint,
108
+ ): Promise<IndexedTreeLeafPreimage | undefined> {
109
+ const preimage = await this.trees.getLeafPreimage(treeId, index, this.includeUncommitted);
110
+ return preimage as IndexedTreeLeafPreimage | undefined;
111
+ }
112
+
113
+ /**
114
+ * Returns the index of a leaf given its value, or undefined if no leaf with that value is found.
115
+ * @param treeId - The ID of the tree.
116
+ * @param value - The leaf value to look for.
117
+ * @returns The index of the first leaf found with a given value (undefined if not found).
118
+ */
119
+ findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined> {
120
+ return this.trees.findLeafIndex(treeId, value, this.includeUncommitted);
121
+ }
122
+
123
+ /**
124
+ * Gets the value at the given index.
125
+ * @param treeId - The ID of the tree to get the leaf value from.
126
+ * @param index - The index of the leaf.
127
+ * @param includeUncommitted - Indicates whether to include uncommitted changes.
128
+ * @returns Leaf value at the given index (undefined if not found).
129
+ */
130
+ getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined> {
131
+ return this.trees.getLeafValue(treeId, index, this.includeUncommitted);
132
+ }
133
+
134
+ /**
135
+ * Inserts the new block hash into the archive.
136
+ * This includes all of the current roots of all of the data trees and the current blocks global vars.
137
+ * @param header - The header to insert into the archive.
138
+ */
139
+ public updateArchive(header: Header): Promise<void> {
140
+ return this.trees.updateArchive(header, this.includeUncommitted);
141
+ }
142
+
143
+ /**
144
+ * Handles a single L2 block (i.e. Inserts the new note hashes into the merkle tree).
145
+ * @param block - The L2 block to handle.
146
+ * @returns Whether the block handled was produced by this same node.
147
+ */
148
+ public handleL2Block(block: L2Block): Promise<HandleL2BlockResult> {
149
+ return this.trees.handleL2Block(block);
150
+ }
151
+
152
+ /**
153
+ * Commits all pending updates.
154
+ * @returns Empty promise.
155
+ */
156
+ public async commit(): Promise<void> {
157
+ return await this.trees.commit();
158
+ }
159
+
160
+ /**
161
+ * Rolls back all pending updates.
162
+ * @returns Empty promise.
163
+ */
164
+ public async rollback(): Promise<void> {
165
+ return await this.trees.rollback();
166
+ }
167
+
168
+ /**
169
+ * Batch insert multiple leaves into the tree.
170
+ * @param treeId - The ID of the tree.
171
+ * @param leaves - Leaves to insert into the tree.
172
+ * @param subtreeHeight - Height of the subtree.
173
+ * @returns The data for the leaves to be updated when inserting the new ones.
174
+ */
175
+ public batchInsert<TreeHeight extends number, SubtreeSiblingPathHeight extends number>(
176
+ treeId: MerkleTreeId,
177
+ leaves: Buffer[],
178
+ subtreeHeight: number,
179
+ ): Promise<BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>> {
180
+ return this.trees.batchInsert(treeId, leaves, subtreeHeight);
181
+ }
182
+ }
@@ -0,0 +1,157 @@
1
+ import { MerkleTreeId, SiblingPath } from '@aztec/circuit-types';
2
+ import { AppendOnlyTreeSnapshot, Fr, Header, PartialStateReference, StateReference } from '@aztec/circuits.js';
3
+ import { IndexedTreeLeafPreimage } from '@aztec/foundation/trees';
4
+ import { BatchInsertionResult, IndexedTreeSnapshot, TreeSnapshot } from '@aztec/merkle-tree';
5
+
6
+ import { MerkleTreeDb } from './merkle_tree_db.js';
7
+ import { HandleL2BlockResult, MerkleTreeOperations, TreeInfo } from './merkle_tree_operations.js';
8
+
9
+ /**
10
+ * Merkle tree operations on readonly tree snapshots.
11
+ */
12
+ export class MerkleTreeSnapshotOperationsFacade implements MerkleTreeOperations {
13
+ #treesDb: MerkleTreeDb;
14
+ #blockNumber: number;
15
+ #treeSnapshots: ReadonlyArray<TreeSnapshot | IndexedTreeSnapshot> = [];
16
+
17
+ constructor(trees: MerkleTreeDb, blockNumber: number) {
18
+ this.#treesDb = trees;
19
+ this.#blockNumber = blockNumber;
20
+ }
21
+
22
+ async #getTreeSnapshot(merkleTreeId: number): Promise<TreeSnapshot | IndexedTreeSnapshot> {
23
+ if (this.#treeSnapshots[merkleTreeId]) {
24
+ return this.#treeSnapshots[merkleTreeId];
25
+ }
26
+
27
+ this.#treeSnapshots = await this.#treesDb.getSnapshot(this.#blockNumber);
28
+ return this.#treeSnapshots[merkleTreeId]!;
29
+ }
30
+
31
+ async findLeafIndex(treeId: MerkleTreeId, value: Buffer): Promise<bigint | undefined> {
32
+ const tree = await this.#getTreeSnapshot(treeId);
33
+ return tree.findLeafIndex(value);
34
+ }
35
+
36
+ async getLeafPreimage(
37
+ treeId: MerkleTreeId.NULLIFIER_TREE,
38
+ index: bigint,
39
+ ): Promise<IndexedTreeLeafPreimage | undefined> {
40
+ const snapshot = (await this.#getTreeSnapshot(treeId)) as IndexedTreeSnapshot;
41
+ return snapshot.getLatestLeafPreimageCopy(BigInt(index));
42
+ }
43
+
44
+ async getLeafValue(treeId: MerkleTreeId, index: bigint): Promise<Buffer | undefined> {
45
+ const snapshot = await this.#getTreeSnapshot(treeId);
46
+ return snapshot.getLeafValue(BigInt(index));
47
+ }
48
+
49
+ async getPreviousValueIndex(
50
+ treeId: MerkleTreeId.NULLIFIER_TREE,
51
+ value: bigint,
52
+ ): Promise<
53
+ | {
54
+ /**
55
+ * The index of the found leaf.
56
+ */
57
+ index: bigint;
58
+ /**
59
+ * A flag indicating if the corresponding leaf's value is equal to `newValue`.
60
+ */
61
+ alreadyPresent: boolean;
62
+ }
63
+ | undefined
64
+ > {
65
+ const snapshot = (await this.#getTreeSnapshot(treeId)) as IndexedTreeSnapshot;
66
+ return snapshot.findIndexOfPreviousKey(value);
67
+ }
68
+
69
+ async getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>> {
70
+ const snapshot = await this.#getTreeSnapshot(treeId);
71
+ return snapshot.getSiblingPath(index);
72
+ }
73
+
74
+ async getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo> {
75
+ const snapshot = await this.#getTreeSnapshot(treeId);
76
+ return {
77
+ depth: snapshot.getDepth(),
78
+ root: snapshot.getRoot(),
79
+ size: snapshot.getNumLeaves(),
80
+ treeId,
81
+ };
82
+ }
83
+
84
+ async getStateReference(): Promise<StateReference> {
85
+ const snapshots = await Promise.all([
86
+ this.#getTreeSnapshot(MerkleTreeId.CONTRACT_TREE),
87
+ this.#getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE),
88
+ this.#getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE),
89
+ this.#getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE),
90
+ this.#getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGE_TREE),
91
+ this.#getTreeSnapshot(MerkleTreeId.ARCHIVE),
92
+ ]);
93
+
94
+ return new StateReference(
95
+ new AppendOnlyTreeSnapshot(
96
+ Fr.fromBuffer(snapshots[MerkleTreeId.L1_TO_L2_MESSAGE_TREE].getRoot()),
97
+ Number(snapshots[MerkleTreeId.L1_TO_L2_MESSAGE_TREE].getNumLeaves()),
98
+ ),
99
+ new PartialStateReference(
100
+ new AppendOnlyTreeSnapshot(
101
+ Fr.fromBuffer(snapshots[MerkleTreeId.NOTE_HASH_TREE].getRoot()),
102
+ Number(snapshots[MerkleTreeId.NOTE_HASH_TREE].getNumLeaves()),
103
+ ),
104
+ new AppendOnlyTreeSnapshot(
105
+ Fr.fromBuffer(snapshots[MerkleTreeId.NULLIFIER_TREE].getRoot()),
106
+ Number(snapshots[MerkleTreeId.NULLIFIER_TREE].getNumLeaves()),
107
+ ),
108
+ new AppendOnlyTreeSnapshot(
109
+ Fr.fromBuffer(snapshots[MerkleTreeId.CONTRACT_TREE].getRoot()),
110
+ Number(snapshots[MerkleTreeId.CONTRACT_TREE].getNumLeaves()),
111
+ ),
112
+ new AppendOnlyTreeSnapshot(
113
+ Fr.fromBuffer(snapshots[MerkleTreeId.PUBLIC_DATA_TREE].getRoot()),
114
+ Number(snapshots[MerkleTreeId.PUBLIC_DATA_TREE].getNumLeaves()),
115
+ ),
116
+ ),
117
+ );
118
+ }
119
+
120
+ appendLeaves(): Promise<void> {
121
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
122
+ }
123
+
124
+ batchInsert<TreeHeight extends number, SubtreeSiblingPathHeight extends number>(): Promise<
125
+ BatchInsertionResult<TreeHeight, SubtreeSiblingPathHeight>
126
+ > {
127
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
128
+ }
129
+
130
+ updateArchive(): Promise<void> {
131
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
132
+ }
133
+
134
+ commit(): Promise<void> {
135
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
136
+ }
137
+
138
+ handleL2Block(): Promise<HandleL2BlockResult> {
139
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
140
+ }
141
+
142
+ rollback(): Promise<void> {
143
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
144
+ }
145
+
146
+ updateHistoricArchive(): Promise<void> {
147
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
148
+ }
149
+
150
+ updateLeaf(): Promise<void> {
151
+ return Promise.reject(new Error('Tree snapshot operations are read-only'));
152
+ }
153
+
154
+ buildInitialHeader(): Promise<Header> {
155
+ throw new Error('Building initial header not supported on snapshot.');
156
+ }
157
+ }