@aztec/archiver 0.24.0 → 0.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/archiver/archiver.d.ts +15 -11
- package/dest/archiver/archiver.d.ts.map +1 -1
- package/dest/archiver/archiver.js +67 -72
- package/dest/archiver/archiver_store.d.ts +37 -15
- 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 +70 -54
- package/dest/archiver/data_retrieval.d.ts +18 -8
- package/dest/archiver/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/data_retrieval.js +39 -14
- package/dest/archiver/eth_log_handlers.d.ts +25 -23
- package/dest/archiver/eth_log_handlers.d.ts.map +1 -1
- package/dest/archiver/eth_log_handlers.js +98 -57
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts +27 -0
- package/dest/archiver/kv_archiver_store/block_body_store.d.ts.map +1 -0
- package/dest/archiver/kv_archiver_store/block_body_store.js +47 -0
- package/dest/archiver/kv_archiver_store/block_store.d.ts +19 -11
- package/dest/archiver/kv_archiver_store/block_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/block_store.js +58 -30
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts +1 -0
- package/dest/archiver/kv_archiver_store/contract_class_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_class_store.js +4 -1
- package/dest/archiver/kv_archiver_store/contract_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/contract_store.js +6 -3
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +36 -16
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +52 -22
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +4 -3
- package/dest/archiver/kv_archiver_store/message_store.d.ts +9 -9
- package/dest/archiver/kv_archiver_store/message_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/message_store.js +34 -31
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts +6 -6
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/l1_to_l2_message_store.js +18 -18
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts +41 -16
- package/dest/archiver/memory_archiver_store/memory_archiver_store.d.ts.map +1 -1
- package/dest/archiver/memory_archiver_store/memory_archiver_store.js +78 -29
- package/dest/index.js +2 -2
- package/dest/rpc/archiver_client.d.ts.map +1 -1
- package/dest/rpc/archiver_client.js +3 -3
- package/dest/rpc/archiver_server.d.ts.map +1 -1
- package/dest/rpc/archiver_server.js +4 -3
- package/package.json +10 -10
- package/src/archiver/archiver.ts +95 -92
- package/src/archiver/archiver_store.ts +42 -15
- package/src/archiver/archiver_store_test_suite.ts +73 -58
- package/src/archiver/data_retrieval.ts +61 -16
- package/src/archiver/eth_log_handlers.ts +142 -68
- package/src/archiver/kv_archiver_store/block_body_store.ts +54 -0
- package/src/archiver/kv_archiver_store/block_store.ts +71 -36
- package/src/archiver/kv_archiver_store/contract_class_store.ts +4 -0
- package/src/archiver/kv_archiver_store/contract_store.ts +7 -2
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +56 -20
- package/src/archiver/kv_archiver_store/log_store.ts +2 -2
- package/src/archiver/kv_archiver_store/message_store.ts +34 -30
- package/src/archiver/memory_archiver_store/l1_to_l2_message_store.ts +17 -17
- package/src/archiver/memory_archiver_store/memory_archiver_store.ts +91 -29
- package/src/index.ts +1 -0
- package/src/rpc/archiver_client.ts +3 -1
- package/src/rpc/archiver_server.ts +5 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Body,
|
|
2
3
|
ContractData,
|
|
3
4
|
ExtendedContractData,
|
|
4
5
|
GetUnencryptedLogsResponse,
|
|
5
6
|
L1ToL2Message,
|
|
6
7
|
L2Block,
|
|
7
8
|
L2BlockL2Logs,
|
|
8
|
-
L2Tx,
|
|
9
9
|
LogFilter,
|
|
10
10
|
LogType,
|
|
11
|
+
TxEffect,
|
|
11
12
|
TxHash,
|
|
13
|
+
TxReceipt,
|
|
12
14
|
} from '@aztec/circuit-types';
|
|
13
15
|
import { Fr } from '@aztec/circuits.js';
|
|
14
16
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
@@ -17,6 +19,7 @@ import { AztecKVStore } from '@aztec/kv-store';
|
|
|
17
19
|
import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
18
20
|
|
|
19
21
|
import { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
22
|
+
import { BlockBodyStore } from './block_body_store.js';
|
|
20
23
|
import { BlockStore } from './block_store.js';
|
|
21
24
|
import { ContractClassStore } from './contract_class_store.js';
|
|
22
25
|
import { ContractInstanceStore } from './contract_instance_store.js';
|
|
@@ -29,6 +32,7 @@ import { MessageStore } from './message_store.js';
|
|
|
29
32
|
*/
|
|
30
33
|
export class KVArchiverDataStore implements ArchiverDataStore {
|
|
31
34
|
#blockStore: BlockStore;
|
|
35
|
+
#blockBodyStore: BlockBodyStore;
|
|
32
36
|
#logStore: LogStore;
|
|
33
37
|
#contractStore: ContractStore;
|
|
34
38
|
#messageStore: MessageStore;
|
|
@@ -38,7 +42,8 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
38
42
|
#log = createDebugLogger('aztec:archiver:data-store');
|
|
39
43
|
|
|
40
44
|
constructor(db: AztecKVStore, logsMaxPageSize: number = 1000) {
|
|
41
|
-
this.#
|
|
45
|
+
this.#blockBodyStore = new BlockBodyStore(db);
|
|
46
|
+
this.#blockStore = new BlockStore(db, this.#blockBodyStore);
|
|
42
47
|
this.#logStore = new LogStore(db, this.#blockStore, logsMaxPageSize);
|
|
43
48
|
this.#contractStore = new ContractStore(db, this.#blockStore);
|
|
44
49
|
this.#messageStore = new MessageStore(db);
|
|
@@ -50,6 +55,10 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
50
55
|
return Promise.resolve(this.#contractClassStore.getContractClass(id));
|
|
51
56
|
}
|
|
52
57
|
|
|
58
|
+
getContractClassIds(): Promise<Fr[]> {
|
|
59
|
+
return Promise.resolve(this.#contractClassStore.getContractClassIds());
|
|
60
|
+
}
|
|
61
|
+
|
|
53
62
|
getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
54
63
|
return Promise.resolve(this.#contractInstanceStore.getContractInstance(address));
|
|
55
64
|
}
|
|
@@ -62,6 +71,25 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
62
71
|
return (await Promise.all(data.map(c => this.#contractInstanceStore.addContractInstance(c)))).every(Boolean);
|
|
63
72
|
}
|
|
64
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Append new block bodies to the store's list.
|
|
76
|
+
* @param blockBodies - The L2 block bodies to be added to the store.
|
|
77
|
+
* @returns True if the operation is successful.
|
|
78
|
+
*/
|
|
79
|
+
addBlockBodies(blockBodies: Body[]): Promise<boolean> {
|
|
80
|
+
return this.#blockBodyStore.addBlockBodies(blockBodies);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Gets block bodies that have the same txHashes as we supply.
|
|
85
|
+
*
|
|
86
|
+
* @param txsHashes - A list of txsHashes (body hashes).
|
|
87
|
+
* @returns The requested L2 block bodies
|
|
88
|
+
*/
|
|
89
|
+
getBlockBodies(txsHashes: Buffer[]): Promise<Body[]> {
|
|
90
|
+
return this.#blockBodyStore.getBlockBodies(txsHashes);
|
|
91
|
+
}
|
|
92
|
+
|
|
65
93
|
/**
|
|
66
94
|
* Append new blocks to the store's list.
|
|
67
95
|
* @param blocks - The L2 blocks to be added to the store.
|
|
@@ -73,11 +101,10 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
73
101
|
|
|
74
102
|
/**
|
|
75
103
|
* Gets up to `limit` amount of L2 blocks starting from `from`.
|
|
76
|
-
* The blocks returned do not contain any logs.
|
|
77
104
|
*
|
|
78
105
|
* @param start - Number of the first block to return (inclusive).
|
|
79
106
|
* @param limit - The number of blocks to return.
|
|
80
|
-
* @returns The requested L2 blocks
|
|
107
|
+
* @returns The requested L2 blocks
|
|
81
108
|
*/
|
|
82
109
|
getBlocks(start: number, limit: number): Promise<L2Block[]> {
|
|
83
110
|
try {
|
|
@@ -89,12 +116,21 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
89
116
|
}
|
|
90
117
|
|
|
91
118
|
/**
|
|
92
|
-
* Gets
|
|
93
|
-
* @param txHash - The txHash of the
|
|
94
|
-
* @returns The requested
|
|
119
|
+
* Gets a tx effect.
|
|
120
|
+
* @param txHash - The txHash of the tx corresponding to the tx effect.
|
|
121
|
+
* @returns The requested tx effect (or undefined if not found).
|
|
122
|
+
*/
|
|
123
|
+
getTxEffect(txHash: TxHash): Promise<TxEffect | undefined> {
|
|
124
|
+
return Promise.resolve(this.#blockStore.getTxEffect(txHash));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Gets a receipt of a settled tx.
|
|
129
|
+
* @param txHash - The hash of a tx we try to get the receipt for.
|
|
130
|
+
* @returns The requested tx receipt (or undefined if not found).
|
|
95
131
|
*/
|
|
96
|
-
|
|
97
|
-
return Promise.resolve(this.#blockStore.
|
|
132
|
+
getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined> {
|
|
133
|
+
return Promise.resolve(this.#blockStore.getSettledTxReceipt(txHash));
|
|
98
134
|
}
|
|
99
135
|
|
|
100
136
|
/**
|
|
@@ -124,42 +160,42 @@ export class KVArchiverDataStore implements ArchiverDataStore {
|
|
|
124
160
|
|
|
125
161
|
/**
|
|
126
162
|
* Remove pending L1 to L2 messages from the store (if they were cancelled).
|
|
127
|
-
* @param messages - The
|
|
163
|
+
* @param messages - The entry keys to be removed from the store.
|
|
128
164
|
* @param l1BlockNumber - The L1 block number for which to remove the messages.
|
|
129
165
|
* @returns True if the operation is successful.
|
|
130
166
|
*/
|
|
131
|
-
|
|
167
|
+
cancelPendingL1ToL2EntryKeys(messages: Fr[], l1BlockNumber: bigint): Promise<boolean> {
|
|
132
168
|
return Promise.resolve(this.#messageStore.cancelPendingMessages(messages, l1BlockNumber));
|
|
133
169
|
}
|
|
134
170
|
|
|
135
171
|
/**
|
|
136
172
|
* Messages that have been published in an L2 block are confirmed.
|
|
137
173
|
* Add them to the confirmed store, also remove them from the pending store.
|
|
138
|
-
* @param entryKeys - The
|
|
174
|
+
* @param entryKeys - The entry keys to be removed from the store.
|
|
139
175
|
* @param blockNumber - The block for which to add the messages.
|
|
140
176
|
* @returns True if the operation is successful.
|
|
141
177
|
*/
|
|
142
|
-
|
|
178
|
+
confirmL1ToL2EntryKeys(entryKeys: Fr[]): Promise<boolean> {
|
|
143
179
|
return this.#messageStore.confirmPendingMessages(entryKeys);
|
|
144
180
|
}
|
|
145
181
|
|
|
146
182
|
/**
|
|
147
183
|
* Gets up to `limit` amount of pending L1 to L2 messages, sorted by fee
|
|
148
184
|
* @param limit - The number of messages to return (by default NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).
|
|
149
|
-
* @returns The requested L1 to L2
|
|
185
|
+
* @returns The requested L1 to L2 entry keys.
|
|
150
186
|
*/
|
|
151
|
-
|
|
152
|
-
return Promise.resolve(this.#messageStore.
|
|
187
|
+
getPendingL1ToL2EntryKeys(limit: number): Promise<Fr[]> {
|
|
188
|
+
return Promise.resolve(this.#messageStore.getPendingEntryKeysByFee(limit));
|
|
153
189
|
}
|
|
154
190
|
|
|
155
191
|
/**
|
|
156
|
-
* Gets the confirmed L1 to L2 message corresponding to the given
|
|
157
|
-
* @param
|
|
192
|
+
* Gets the confirmed L1 to L2 message corresponding to the given entry key.
|
|
193
|
+
* @param entryKey - The entry key to look up.
|
|
158
194
|
* @returns The requested L1 to L2 message or throws if not found.
|
|
159
195
|
*/
|
|
160
|
-
getConfirmedL1ToL2Message(
|
|
196
|
+
getConfirmedL1ToL2Message(entryKey: Fr): Promise<L1ToL2Message> {
|
|
161
197
|
try {
|
|
162
|
-
return Promise.resolve(this.#messageStore.getConfirmedMessage(
|
|
198
|
+
return Promise.resolve(this.#messageStore.getConfirmedMessage(entryKey));
|
|
163
199
|
} catch (err) {
|
|
164
200
|
return Promise.reject(err);
|
|
165
201
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExtendedUnencryptedL2Log,
|
|
3
3
|
GetUnencryptedLogsResponse,
|
|
4
|
-
INITIAL_L2_BLOCK_NUM,
|
|
5
4
|
L2BlockL2Logs,
|
|
6
5
|
LogFilter,
|
|
7
6
|
LogId,
|
|
8
7
|
LogType,
|
|
9
8
|
UnencryptedL2Log,
|
|
10
9
|
} from '@aztec/circuit-types';
|
|
10
|
+
import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
|
|
11
11
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
12
12
|
import { AztecKVStore, AztecMap } from '@aztec/kv-store';
|
|
13
13
|
|
|
@@ -88,7 +88,7 @@ export class LogStore {
|
|
|
88
88
|
throw new Error('Missing txHash');
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
const [blockNumber, txIndex] = this.blockStore.
|
|
91
|
+
const [blockNumber, txIndex] = this.blockStore.getTxLocation(filter.txHash) ?? [];
|
|
92
92
|
if (typeof blockNumber !== 'number' || typeof txIndex !== 'number') {
|
|
93
93
|
return { logs: [], maxLogsHit: false };
|
|
94
94
|
}
|
|
@@ -60,18 +60,18 @@ export class MessageStore {
|
|
|
60
60
|
void this.#lastL1BlockAddingMessages.set(l1BlockNumber);
|
|
61
61
|
|
|
62
62
|
for (const message of messages) {
|
|
63
|
-
const
|
|
64
|
-
if (!
|
|
63
|
+
const entryKey = message.entryKey?.toString();
|
|
64
|
+
if (!entryKey) {
|
|
65
65
|
throw new Error('Message does not have an entry key');
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
void this.#messages.setIfNotExists(
|
|
68
|
+
void this.#messages.setIfNotExists(entryKey, {
|
|
69
69
|
message: message.toBuffer(),
|
|
70
70
|
fee: message.fee,
|
|
71
71
|
confirmed: false,
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
void this.#pendingMessagesByFee.update([message.fee,
|
|
74
|
+
void this.#pendingMessagesByFee.update([message.fee, entryKey], 1);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
return true;
|
|
@@ -80,11 +80,11 @@ export class MessageStore {
|
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
82
|
* Remove pending L1 to L2 messages from the store (if they were cancelled).
|
|
83
|
-
* @param
|
|
83
|
+
* @param entryKeys - The entry keys to be removed from the store.
|
|
84
84
|
* @param l1BlockNumber - The L1 block number for which to remove the messages.
|
|
85
85
|
* @returns True if the operation is successful.
|
|
86
86
|
*/
|
|
87
|
-
cancelPendingMessages(
|
|
87
|
+
cancelPendingMessages(entryKeys: Fr[], l1BlockNumber: bigint): Promise<boolean> {
|
|
88
88
|
return this.db.transaction(() => {
|
|
89
89
|
const lastL1BlockNumber = this.#lastL1BlockCancellingMessages.get() ?? 0n;
|
|
90
90
|
if (lastL1BlockNumber >= l1BlockNumber) {
|
|
@@ -93,13 +93,13 @@ export class MessageStore {
|
|
|
93
93
|
|
|
94
94
|
void this.#lastL1BlockCancellingMessages.set(l1BlockNumber);
|
|
95
95
|
|
|
96
|
-
for (const
|
|
97
|
-
const messageCtx = this.#messages.get(
|
|
96
|
+
for (const entryKey of entryKeys) {
|
|
97
|
+
const messageCtx = this.#messages.get(entryKey.toString());
|
|
98
98
|
if (!messageCtx) {
|
|
99
|
-
throw new Error(`Message ${
|
|
99
|
+
throw new Error(`Message ${entryKey.toString()} not found`);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
void this.#pendingMessagesByFee.update([messageCtx.fee,
|
|
102
|
+
void this.#pendingMessagesByFee.update([messageCtx.fee, entryKey.toString()], -1);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
return true;
|
|
@@ -109,20 +109,24 @@ export class MessageStore {
|
|
|
109
109
|
/**
|
|
110
110
|
* Messages that have been published in an L2 block are confirmed.
|
|
111
111
|
* Add them to the confirmed store, also remove them from the pending store.
|
|
112
|
-
* @param
|
|
112
|
+
* @param entryKeys - The entry keys to be removed from the store.
|
|
113
113
|
* @returns True if the operation is successful.
|
|
114
114
|
*/
|
|
115
|
-
confirmPendingMessages(
|
|
115
|
+
confirmPendingMessages(entryKeys: Fr[]): Promise<boolean> {
|
|
116
116
|
return this.db.transaction(() => {
|
|
117
|
-
for (const
|
|
118
|
-
|
|
117
|
+
for (const entryKey of entryKeys) {
|
|
118
|
+
if (entryKey.equals(Fr.ZERO)) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const messageCtx = this.#messages.get(entryKey.toString());
|
|
119
123
|
if (!messageCtx) {
|
|
120
|
-
throw new Error(`Message ${
|
|
124
|
+
throw new Error(`Message ${entryKey.toString()} not found`);
|
|
121
125
|
}
|
|
122
126
|
messageCtx.confirmed = true;
|
|
123
127
|
|
|
124
|
-
void this.#messages.set(
|
|
125
|
-
void this.#pendingMessagesByFee.update([messageCtx.fee,
|
|
128
|
+
void this.#messages.set(entryKey.toString(), messageCtx);
|
|
129
|
+
void this.#pendingMessagesByFee.update([messageCtx.fee, entryKey.toString()], -1);
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
return true;
|
|
@@ -130,18 +134,18 @@ export class MessageStore {
|
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/**
|
|
133
|
-
* Gets the confirmed L1 to L2 message corresponding to the given
|
|
134
|
-
* @param
|
|
137
|
+
* Gets the confirmed L1 to L2 message corresponding to the given entry key.
|
|
138
|
+
* @param entryKey - The entry key to look up.
|
|
135
139
|
* @returns The requested L1 to L2 message or throws if not found.
|
|
136
140
|
*/
|
|
137
|
-
getConfirmedMessage(
|
|
138
|
-
const messageCtx = this.#messages.get(
|
|
141
|
+
getConfirmedMessage(entryKey: Fr): L1ToL2Message {
|
|
142
|
+
const messageCtx = this.#messages.get(entryKey.toString());
|
|
139
143
|
if (!messageCtx) {
|
|
140
|
-
throw new Error(`Message ${
|
|
144
|
+
throw new Error(`Message ${entryKey.toString()} not found`);
|
|
141
145
|
}
|
|
142
146
|
|
|
143
147
|
if (!messageCtx.confirmed) {
|
|
144
|
-
throw new Error(`Message ${
|
|
148
|
+
throw new Error(`Message ${entryKey.toString()} not confirmed`);
|
|
145
149
|
}
|
|
146
150
|
|
|
147
151
|
return L1ToL2Message.fromBuffer(messageCtx.message);
|
|
@@ -150,21 +154,21 @@ export class MessageStore {
|
|
|
150
154
|
/**
|
|
151
155
|
* Gets up to `limit` amount of pending L1 to L2 messages, sorted by fee
|
|
152
156
|
* @param limit - The number of messages to return (by default NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).
|
|
153
|
-
* @returns The requested L1 to L2
|
|
157
|
+
* @returns The requested L1 to L2 entry keys.
|
|
154
158
|
*/
|
|
155
|
-
|
|
156
|
-
const
|
|
159
|
+
getPendingEntryKeysByFee(limit: number): Fr[] {
|
|
160
|
+
const entryKeys: Fr[] = [];
|
|
157
161
|
|
|
158
|
-
for (const [[_,
|
|
162
|
+
for (const [[_, entryKey], count] of this.#pendingMessagesByFee.entries({
|
|
159
163
|
reverse: true,
|
|
160
164
|
})) {
|
|
161
165
|
// put `count` copies of this message in the result list
|
|
162
|
-
|
|
163
|
-
if (
|
|
166
|
+
entryKeys.push(...Array(count).fill(Fr.fromString(entryKey)));
|
|
167
|
+
if (entryKeys.length >= limit) {
|
|
164
168
|
break;
|
|
165
169
|
}
|
|
166
170
|
}
|
|
167
171
|
|
|
168
|
-
return
|
|
172
|
+
return entryKeys;
|
|
169
173
|
}
|
|
170
174
|
}
|
|
@@ -7,29 +7,29 @@ import { Fr } from '@aztec/foundation/fields';
|
|
|
7
7
|
*/
|
|
8
8
|
export class L1ToL2MessageStore {
|
|
9
9
|
/**
|
|
10
|
-
* A map containing the
|
|
10
|
+
* A map containing the entry key to the corresponding L1 to L2
|
|
11
11
|
* messages (and the number of times the message has been seen).
|
|
12
12
|
*/
|
|
13
13
|
protected store: Map<bigint, L1ToL2MessageAndCount> = new Map();
|
|
14
14
|
|
|
15
15
|
constructor() {}
|
|
16
16
|
|
|
17
|
-
addMessage(
|
|
18
|
-
const
|
|
19
|
-
const msgAndCount = this.store.get(
|
|
17
|
+
addMessage(entryKey: Fr, message: L1ToL2Message) {
|
|
18
|
+
const entryKeyBigInt = entryKey.toBigInt();
|
|
19
|
+
const msgAndCount = this.store.get(entryKeyBigInt);
|
|
20
20
|
if (msgAndCount) {
|
|
21
21
|
msgAndCount.count++;
|
|
22
22
|
} else {
|
|
23
|
-
this.store.set(
|
|
23
|
+
this.store.set(entryKeyBigInt, { message, count: 1 });
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
getMessage(
|
|
28
|
-
return this.store.get(
|
|
27
|
+
getMessage(entryKey: Fr): L1ToL2Message | undefined {
|
|
28
|
+
return this.store.get(entryKey.value)?.message;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
getMessageAndCount(
|
|
32
|
-
return this.store.get(
|
|
31
|
+
getMessageAndCount(entryKey: Fr): L1ToL2MessageAndCount | undefined {
|
|
32
|
+
return this.store.get(entryKey.value);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ export class L1ToL2MessageStore {
|
|
|
38
38
|
* for removing messages or fetching multiple messages.
|
|
39
39
|
*/
|
|
40
40
|
export class PendingL1ToL2MessageStore extends L1ToL2MessageStore {
|
|
41
|
-
|
|
41
|
+
getEntryKeys(limit: number): Fr[] {
|
|
42
42
|
if (limit < 1) {
|
|
43
43
|
return [];
|
|
44
44
|
}
|
|
@@ -57,21 +57,21 @@ export class PendingL1ToL2MessageStore extends L1ToL2MessageStore {
|
|
|
57
57
|
return messages;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
removeMessage(
|
|
61
|
-
// ignore 0 -
|
|
62
|
-
if (
|
|
60
|
+
removeMessage(entryKey: Fr) {
|
|
61
|
+
// ignore 0 - entryKey is a hash, so a 0 can probabilistically never occur. It is best to skip it.
|
|
62
|
+
if (entryKey.equals(Fr.ZERO)) {
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
const
|
|
67
|
-
const msgAndCount = this.store.get(
|
|
66
|
+
const entryKeyBigInt = entryKey.value;
|
|
67
|
+
const msgAndCount = this.store.get(entryKeyBigInt);
|
|
68
68
|
if (!msgAndCount) {
|
|
69
|
-
throw new Error(`Unable to remove message: L1 to L2 Message with key ${
|
|
69
|
+
throw new Error(`Unable to remove message: L1 to L2 Message with key ${entryKeyBigInt} not found in store`);
|
|
70
70
|
}
|
|
71
71
|
if (msgAndCount.count > 1) {
|
|
72
72
|
msgAndCount.count--;
|
|
73
73
|
} else {
|
|
74
|
-
this.store.delete(
|
|
74
|
+
this.store.delete(entryKeyBigInt);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Body,
|
|
2
3
|
ContractData,
|
|
3
4
|
ExtendedContractData,
|
|
4
5
|
ExtendedUnencryptedL2Log,
|
|
5
6
|
GetUnencryptedLogsResponse,
|
|
6
|
-
INITIAL_L2_BLOCK_NUM,
|
|
7
7
|
L1ToL2Message,
|
|
8
8
|
L2Block,
|
|
9
9
|
L2BlockContext,
|
|
10
10
|
L2BlockL2Logs,
|
|
11
|
-
L2Tx,
|
|
12
11
|
LogFilter,
|
|
13
12
|
LogId,
|
|
14
13
|
LogType,
|
|
14
|
+
TxEffect,
|
|
15
15
|
TxHash,
|
|
16
|
+
TxReceipt,
|
|
17
|
+
TxStatus,
|
|
16
18
|
UnencryptedL2Log,
|
|
17
19
|
} from '@aztec/circuit-types';
|
|
18
|
-
import { Fr, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js';
|
|
20
|
+
import { Fr, INITIAL_L2_BLOCK_NUM, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/circuits.js';
|
|
19
21
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
20
22
|
import { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
21
23
|
|
|
@@ -32,9 +34,14 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
32
34
|
private l2BlockContexts: L2BlockContext[] = [];
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
|
-
*
|
|
37
|
+
* A mapping of body hash to body
|
|
36
38
|
*/
|
|
37
|
-
private
|
|
39
|
+
private l2BlockBodies: Map<string, Body> = new Map();
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* An array containing all the the tx effects in the L2 blocks that have been fetched so far.
|
|
43
|
+
*/
|
|
44
|
+
private txEffects: TxEffect[] = [];
|
|
38
45
|
|
|
39
46
|
/**
|
|
40
47
|
* An array containing all the encrypted logs that have been fetched so far.
|
|
@@ -85,6 +92,10 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
85
92
|
return Promise.resolve(this.contractClasses.get(id.toString()));
|
|
86
93
|
}
|
|
87
94
|
|
|
95
|
+
public getContractClassIds(): Promise<Fr[]> {
|
|
96
|
+
return Promise.resolve(Array.from(this.contractClasses.keys()).map(key => Fr.fromString(key)));
|
|
97
|
+
}
|
|
98
|
+
|
|
88
99
|
public getContractInstance(address: AztecAddress): Promise<ContractInstanceWithAddress | undefined> {
|
|
89
100
|
return Promise.resolve(this.contractInstances.get(address.toString()));
|
|
90
101
|
}
|
|
@@ -110,10 +121,39 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
110
121
|
*/
|
|
111
122
|
public addBlocks(blocks: L2Block[]): Promise<boolean> {
|
|
112
123
|
this.l2BlockContexts.push(...blocks.map(block => new L2BlockContext(block)));
|
|
113
|
-
this.
|
|
124
|
+
this.txEffects.push(...blocks.flatMap(b => b.getTxs()));
|
|
125
|
+
return Promise.resolve(true);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Append new block bodies to the store's list.
|
|
130
|
+
* @param blockBodies - The L2 block bodies to be added to the store.
|
|
131
|
+
* @returns True if the operation is successful.
|
|
132
|
+
*/
|
|
133
|
+
addBlockBodies(blockBodies: Body[]): Promise<boolean> {
|
|
134
|
+
for (const body of blockBodies) {
|
|
135
|
+
void this.l2BlockBodies.set(body.getCalldataHash().toString('hex'), body);
|
|
136
|
+
}
|
|
137
|
+
|
|
114
138
|
return Promise.resolve(true);
|
|
115
139
|
}
|
|
116
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Gets block bodies that have the same txHashes as we supply.
|
|
143
|
+
*
|
|
144
|
+
* @param txsHashes - A list of txsHashes (body hashes).
|
|
145
|
+
* @returns The requested L2 block bodies
|
|
146
|
+
*/
|
|
147
|
+
getBlockBodies(txsHashes: Buffer[]): Promise<Body[]> {
|
|
148
|
+
const blockBodies = txsHashes.map(txsHash => this.l2BlockBodies.get(txsHash.toString('hex')));
|
|
149
|
+
|
|
150
|
+
if (blockBodies.some(bodyBuffer => bodyBuffer === undefined)) {
|
|
151
|
+
throw new Error('Block body is undefined');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return Promise.resolve(blockBodies as Body[]);
|
|
155
|
+
}
|
|
156
|
+
|
|
117
157
|
/**
|
|
118
158
|
* Append new logs to the store's list.
|
|
119
159
|
* @param encryptedLogs - The encrypted logs to be added to the store.
|
|
@@ -153,11 +193,11 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
153
193
|
|
|
154
194
|
/**
|
|
155
195
|
* Remove pending L1 to L2 messages from the store (if they were cancelled).
|
|
156
|
-
* @param messages - The
|
|
196
|
+
* @param messages - The entry keys to be removed from the store.
|
|
157
197
|
* @param l1BlockNumber - The L1 block number for which to remove the messages.
|
|
158
198
|
* @returns True if the operation is successful (always in this implementation).
|
|
159
199
|
*/
|
|
160
|
-
public
|
|
200
|
+
public cancelPendingL1ToL2EntryKeys(messages: Fr[], l1BlockNumber: bigint): Promise<boolean> {
|
|
161
201
|
if (l1BlockNumber <= this.lastL1BlockCancelledMessages) {
|
|
162
202
|
return Promise.resolve(false);
|
|
163
203
|
}
|
|
@@ -172,13 +212,17 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
172
212
|
/**
|
|
173
213
|
* Messages that have been published in an L2 block are confirmed.
|
|
174
214
|
* Add them to the confirmed store, also remove them from the pending store.
|
|
175
|
-
* @param
|
|
215
|
+
* @param entryKeys - The entry keys to be removed from the store.
|
|
176
216
|
* @returns True if the operation is successful (always in this implementation).
|
|
177
217
|
*/
|
|
178
|
-
public
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
218
|
+
public confirmL1ToL2EntryKeys(entryKeys: Fr[]): Promise<boolean> {
|
|
219
|
+
entryKeys.forEach(entryKey => {
|
|
220
|
+
if (entryKey.equals(Fr.ZERO)) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
this.confirmedL1ToL2Messages.addMessage(entryKey, this.pendingL1ToL2Messages.getMessage(entryKey)!);
|
|
225
|
+
this.pendingL1ToL2Messages.removeMessage(entryKey);
|
|
182
226
|
});
|
|
183
227
|
return Promise.resolve(true);
|
|
184
228
|
}
|
|
@@ -228,33 +272,51 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
228
272
|
}
|
|
229
273
|
|
|
230
274
|
/**
|
|
231
|
-
* Gets
|
|
232
|
-
* @param txHash - The txHash of the
|
|
233
|
-
* @returns The requested
|
|
275
|
+
* Gets a tx effect.
|
|
276
|
+
* @param txHash - The txHash of the tx effect.
|
|
277
|
+
* @returns The requested tx effect.
|
|
278
|
+
*/
|
|
279
|
+
public getTxEffect(txHash: TxHash): Promise<TxEffect | undefined> {
|
|
280
|
+
const txEffect = this.txEffects.find(tx => tx.txHash.equals(txHash));
|
|
281
|
+
return Promise.resolve(txEffect);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Gets a receipt of a settled tx.
|
|
286
|
+
* @param txHash - The hash of a tx we try to get the receipt for.
|
|
287
|
+
* @returns The requested tx receipt (or undefined if not found).
|
|
234
288
|
*/
|
|
235
|
-
public
|
|
236
|
-
const
|
|
237
|
-
|
|
289
|
+
public getSettledTxReceipt(txHash: TxHash): Promise<TxReceipt | undefined> {
|
|
290
|
+
for (const blockContext of this.l2BlockContexts) {
|
|
291
|
+
for (const currentTxHash of blockContext.getTxHashes()) {
|
|
292
|
+
if (currentTxHash.equals(txHash)) {
|
|
293
|
+
return Promise.resolve(
|
|
294
|
+
new TxReceipt(txHash, TxStatus.MINED, '', blockContext.block.hash().toBuffer(), blockContext.block.number),
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return Promise.resolve(undefined);
|
|
238
300
|
}
|
|
239
301
|
|
|
240
302
|
/**
|
|
241
303
|
* Gets up to `limit` amount of pending L1 to L2 messages, sorted by fee
|
|
242
304
|
* @param limit - The number of messages to return (by default NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).
|
|
243
|
-
* @returns The requested L1 to L2
|
|
305
|
+
* @returns The requested L1 to L2 entry keys.
|
|
244
306
|
*/
|
|
245
|
-
public
|
|
246
|
-
return Promise.resolve(this.pendingL1ToL2Messages.
|
|
307
|
+
public getPendingL1ToL2EntryKeys(limit: number = NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP): Promise<Fr[]> {
|
|
308
|
+
return Promise.resolve(this.pendingL1ToL2Messages.getEntryKeys(limit));
|
|
247
309
|
}
|
|
248
310
|
|
|
249
311
|
/**
|
|
250
|
-
* Gets the confirmed L1 to L2 message corresponding to the given
|
|
251
|
-
* @param
|
|
312
|
+
* Gets the confirmed L1 to L2 message corresponding to the given entry key.
|
|
313
|
+
* @param entryKey - The entry key to look up.
|
|
252
314
|
* @returns The requested L1 to L2 message or throws if not found.
|
|
253
315
|
*/
|
|
254
|
-
public getConfirmedL1ToL2Message(
|
|
255
|
-
const message = this.confirmedL1ToL2Messages.getMessage(
|
|
316
|
+
public getConfirmedL1ToL2Message(entryKey: Fr): Promise<L1ToL2Message> {
|
|
317
|
+
const message = this.confirmedL1ToL2Messages.getMessage(entryKey);
|
|
256
318
|
if (!message) {
|
|
257
|
-
throw new Error(`L1 to L2 Message with key ${
|
|
319
|
+
throw new Error(`L1 to L2 Message with key ${entryKey.toString()} not found in the confirmed messages store`);
|
|
258
320
|
}
|
|
259
321
|
return Promise.resolve(message);
|
|
260
322
|
}
|
|
@@ -396,7 +458,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
396
458
|
return Promise.resolve(undefined);
|
|
397
459
|
}
|
|
398
460
|
for (const blockContext of this.l2BlockContexts) {
|
|
399
|
-
for (const contractData of blockContext.block.
|
|
461
|
+
for (const contractData of blockContext.block.body.txEffects.flatMap(txEffect => txEffect.contractData)) {
|
|
400
462
|
if (contractData.contractAddress.equals(contractAddress)) {
|
|
401
463
|
return Promise.resolve(contractData);
|
|
402
464
|
}
|
|
@@ -416,7 +478,7 @@ export class MemoryArchiverStore implements ArchiverDataStore {
|
|
|
416
478
|
return Promise.resolve([]);
|
|
417
479
|
}
|
|
418
480
|
const block: L2Block | undefined = this.l2BlockContexts[l2BlockNum - INITIAL_L2_BLOCK_NUM]?.block;
|
|
419
|
-
return Promise.resolve(block?.
|
|
481
|
+
return Promise.resolve(block?.body.txEffects.flatMap(txEffect => txEffect.contractData));
|
|
420
482
|
}
|
|
421
483
|
|
|
422
484
|
/**
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
L1ToL2Message,
|
|
7
7
|
L2Block,
|
|
8
8
|
L2BlockL2Logs,
|
|
9
|
+
NullifierMembershipWitness,
|
|
10
|
+
TxReceipt,
|
|
9
11
|
} from '@aztec/circuit-types';
|
|
10
12
|
import { EthAddress, Fr } from '@aztec/circuits.js';
|
|
11
13
|
import { createJsonRpcClient, makeFetch } from '@aztec/foundation/json-rpc/client';
|
|
@@ -26,7 +28,7 @@ export const createArchiverClient = (url: string, fetch = makeFetch([1, 2, 3], t
|
|
|
26
28
|
L2Block,
|
|
27
29
|
L2BlockL2Logs,
|
|
28
30
|
},
|
|
29
|
-
{},
|
|
31
|
+
{ TxReceipt, NullifierMembershipWitness },
|
|
30
32
|
false,
|
|
31
33
|
'archiver',
|
|
32
34
|
fetch,
|