@aztec/p2p 0.86.0-starknet.1 → 0.87.0
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/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/client/factory.d.ts +1 -1
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +11 -13
- package/dest/client/interface.d.ts +10 -1
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +18 -6
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +103 -53
- package/dest/config.d.ts +5 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -11
- package/dest/enr/generate-enr.d.ts +7 -0
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +23 -2
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +3 -0
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +44 -14
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +2 -0
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +6 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +7 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +13 -5
- package/dest/msg_validators/tx_validator/block_header_validator.js +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +15 -14
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +0 -2
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +2 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +14 -0
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/factory.js +62 -0
- package/dest/msg_validators/tx_validator/gas_validator.js +3 -3
- package/dest/msg_validators/tx_validator/metadata_validator.js +5 -5
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +1 -1
- package/dest/services/discv5/discV5_service.d.ts +2 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +9 -13
- package/dest/services/dummy_service.d.ts +3 -3
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +6 -1
- package/dest/services/encoding.d.ts +1 -3
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.d.ts +4 -2
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +87 -88
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +11 -2
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +2 -2
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +41 -21
- package/dest/services/reqresp/interface.d.ts +1 -3
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/goodbye.d.ts +0 -2
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/goodbye.js +1 -1
- package/dest/services/reqresp/protocols/ping.d.ts +0 -2
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +0 -2
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.d.ts +1 -3
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +2 -2
- package/dest/services/service.d.ts +3 -2
- package/dest/services/service.d.ts.map +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +2 -2
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +9 -6
- package/dest/testbench/testbench.js +1 -1
- package/dest/testbench/worker_client_manager.d.ts +0 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +2 -2
- package/dest/types/index.d.ts +1 -0
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +1 -0
- package/dest/versioning.d.ts +2 -2
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +6 -1
- package/package.json +15 -15
- package/src/bootstrap/bootstrap.ts +1 -1
- package/src/client/factory.ts +33 -32
- package/src/client/interface.ts +13 -1
- package/src/client/p2p_client.ts +129 -55
- package/src/config.ts +11 -18
- package/src/enr/generate-enr.ts +33 -3
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +2 -2
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +4 -1
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +72 -34
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +12 -1
- package/src/mem_pools/tx_pool/tx_pool.ts +9 -0
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +9 -3
- package/src/msg_validators/tx_validator/block_header_validator.ts +1 -1
- package/src/msg_validators/tx_validator/data_validator.ts +24 -18
- package/src/msg_validators/tx_validator/double_spend_validator.ts +2 -2
- package/src/msg_validators/tx_validator/factory.ts +94 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +3 -3
- package/src/msg_validators/tx_validator/metadata_validator.ts +5 -5
- package/src/msg_validators/tx_validator/phases_validator.ts +6 -2
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +1 -1
- package/src/services/discv5/discV5_service.ts +14 -12
- package/src/services/dummy_service.ts +8 -2
- package/src/services/libp2p/libp2p_service.ts +95 -107
- package/src/services/peer-manager/metrics.ts +4 -1
- package/src/services/peer-manager/peer_manager.ts +18 -1
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +5 -1
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +42 -19
- package/src/services/reqresp/metrics.ts +4 -1
- package/src/services/reqresp/protocols/goodbye.ts +1 -1
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +4 -1
- package/src/services/reqresp/reqresp.ts +2 -1
- package/src/services/service.ts +4 -1
- package/src/test-helpers/make-test-p2p-clients.ts +2 -1
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/testbench/p2p_client_testbench_worker.ts +8 -4
- package/src/testbench/testbench.ts +1 -1
- package/src/testbench/worker_client_manager.ts +2 -2
- package/src/types/index.ts +1 -0
- package/src/versioning.ts +8 -1
|
@@ -44,9 +44,15 @@ export class AztecKVTxPool implements TxPool {
|
|
|
44
44
|
/** The cumulative tx size in bytes that the pending txs in the pool take up. */
|
|
45
45
|
#pendingTxSize: AztecAsyncSingleton<number>;
|
|
46
46
|
|
|
47
|
+
/** Count of total pending txs. */
|
|
48
|
+
#pendingTxCount: AztecAsyncSingleton<number>;
|
|
49
|
+
|
|
47
50
|
/** In-memory mapping of pending tx hashes to the hydrated pending tx in the pool. */
|
|
48
51
|
#pendingTxs: Map<string, Tx>;
|
|
49
52
|
|
|
53
|
+
/** In-memory set of txs that should not be evicted from the pool. */
|
|
54
|
+
#nonEvictableTxs: Set<string>;
|
|
55
|
+
|
|
50
56
|
/** KV store for archived txs. */
|
|
51
57
|
#archive: AztecAsyncKVStore;
|
|
52
58
|
|
|
@@ -91,8 +97,10 @@ export class AztecKVTxPool implements TxPool {
|
|
|
91
97
|
this.#pendingTxHashToSize = store.openMap('pendingTxHashToSize');
|
|
92
98
|
this.#pendingTxHashToHeaderHash = store.openMap('pendingTxHashToHeaderHash');
|
|
93
99
|
this.#pendingTxSize = store.openSingleton('pendingTxSize');
|
|
100
|
+
this.#pendingTxCount = store.openSingleton('pendingTxCount');
|
|
94
101
|
this.#maxTxPoolSize = config.maxTxPoolSize;
|
|
95
102
|
this.#pendingTxs = new Map<string, Tx>();
|
|
103
|
+
this.#nonEvictableTxs = new Set<string>();
|
|
96
104
|
|
|
97
105
|
this.#archivedTxs = archive.openMap('archivedTxs');
|
|
98
106
|
this.#archivedTxIndices = archive.openMap('archivedTxIndices');
|
|
@@ -112,7 +120,7 @@ export class AztecKVTxPool implements TxPool {
|
|
|
112
120
|
return true;
|
|
113
121
|
}
|
|
114
122
|
|
|
115
|
-
public markAsMined(txHashes: TxHash[], blockNumber: number): Promise<void> {
|
|
123
|
+
public async markAsMined(txHashes: TxHash[], blockNumber: number): Promise<void> {
|
|
116
124
|
if (txHashes.length === 0) {
|
|
117
125
|
return Promise.resolve();
|
|
118
126
|
}
|
|
@@ -120,7 +128,8 @@ export class AztecKVTxPool implements TxPool {
|
|
|
120
128
|
let deletedPending = 0;
|
|
121
129
|
const minedNullifiers = new Set<string>();
|
|
122
130
|
const minedFeePayers = new Set<string>();
|
|
123
|
-
|
|
131
|
+
|
|
132
|
+
await this.#store.transactionAsync(async () => {
|
|
124
133
|
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
125
134
|
for (const hash of txHashes) {
|
|
126
135
|
const key = hash.toString();
|
|
@@ -139,6 +148,7 @@ export class AztecKVTxPool implements TxPool {
|
|
|
139
148
|
}
|
|
140
149
|
this.#metrics.recordAddedObjects(txHashes.length, 'mined');
|
|
141
150
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
151
|
+
await this.increasePendingTxCount(-deletedPending);
|
|
142
152
|
|
|
143
153
|
const numTxsEvicted = await this.evictInvalidTxsAfterMining(
|
|
144
154
|
txHashes,
|
|
@@ -148,43 +158,44 @@ export class AztecKVTxPool implements TxPool {
|
|
|
148
158
|
);
|
|
149
159
|
this.#metrics.recordRemovedObjects(deletedPending + numTxsEvicted, 'pending');
|
|
150
160
|
});
|
|
161
|
+
// We update this after the transaction above. This ensures that the non-evictable transactions are not evicted
|
|
162
|
+
// until any that have been mined are marked as such.
|
|
163
|
+
// The non-evictable set is not considered when evicting transactions that are invalid after a block is mined.
|
|
164
|
+
this.#nonEvictableTxs.clear();
|
|
151
165
|
}
|
|
152
166
|
|
|
153
|
-
public markMinedAsPending(txHashes: TxHash[]): Promise<void> {
|
|
167
|
+
public async markMinedAsPending(txHashes: TxHash[]): Promise<void> {
|
|
154
168
|
if (txHashes.length === 0) {
|
|
155
169
|
return Promise.resolve();
|
|
156
170
|
}
|
|
157
171
|
|
|
158
172
|
let markedAsPending = 0;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
await this.#minedTxHashToBlock.delete(key);
|
|
173
|
+
await this.#store.transactionAsync(async () => {
|
|
174
|
+
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
175
|
+
for (const hash of txHashes) {
|
|
176
|
+
const key = hash.toString();
|
|
177
|
+
await this.#minedTxHashToBlock.delete(key);
|
|
165
178
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
179
|
+
// Rehydrate the tx in the in-memory pending txs mapping
|
|
180
|
+
const tx = await this.getPendingTxByHash(hash);
|
|
181
|
+
if (tx) {
|
|
182
|
+
await this.addPendingTxIndices(tx, key);
|
|
183
|
+
pendingTxSize += tx.getSize();
|
|
184
|
+
markedAsPending++;
|
|
173
185
|
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
await this.#pendingTxSize.set(pendingTxSize);
|
|
189
|
+
});
|
|
174
190
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
numInvalidTxsEvicted + numLowPriorityTxsEvicted - numNewTxsEvicted,
|
|
184
|
-
'pending',
|
|
185
|
-
);
|
|
186
|
-
this.#metrics.recordRemovedObjects(markedAsPending, 'mined');
|
|
187
|
-
});
|
|
191
|
+
const numInvalidTxsEvicted = await this.evictInvalidTxsAfterReorg(txHashes);
|
|
192
|
+
const { numLowPriorityTxsEvicted, numNewTxsEvicted } = await this.evictLowPriorityTxs(txHashes);
|
|
193
|
+
|
|
194
|
+
await this.increasePendingTxCount(markedAsPending);
|
|
195
|
+
|
|
196
|
+
this.#metrics.recordAddedObjects(markedAsPending - numNewTxsEvicted, 'pending');
|
|
197
|
+
this.#metrics.recordRemovedObjects(numInvalidTxsEvicted + numLowPriorityTxsEvicted - numNewTxsEvicted, 'pending');
|
|
198
|
+
this.#metrics.recordRemovedObjects(markedAsPending, 'mined');
|
|
188
199
|
}
|
|
189
200
|
|
|
190
201
|
public async getPendingTxHashes(): Promise<TxHash[]> {
|
|
@@ -197,6 +208,10 @@ export class AztecKVTxPool implements TxPool {
|
|
|
197
208
|
return vals.map(([txHash, blockNumber]) => [TxHash.fromString(txHash), blockNumber]);
|
|
198
209
|
}
|
|
199
210
|
|
|
211
|
+
public async getPendingTxCount(): Promise<number> {
|
|
212
|
+
return (await this.#pendingTxCount.getAsync()) ?? 0;
|
|
213
|
+
}
|
|
214
|
+
|
|
200
215
|
public async getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
|
|
201
216
|
const key = txHash.toString();
|
|
202
217
|
const [isMined, isKnown] = await Promise.all([this.#minedTxHashToBlock.hasAsync(key), this.#txs.hasAsync(key)]);
|
|
@@ -266,21 +281,26 @@ export class AztecKVTxPool implements TxPool {
|
|
|
266
281
|
txs.map(async tx => ({ txHash: await tx.getTxHash(), txStats: await tx.getStats() })),
|
|
267
282
|
);
|
|
268
283
|
await this.#store.transactionAsync(async () => {
|
|
269
|
-
let
|
|
284
|
+
let addedCount = 0;
|
|
270
285
|
let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
271
286
|
await Promise.all(
|
|
272
287
|
txs.map(async (tx, i) => {
|
|
273
288
|
const { txHash, txStats } = hashesAndStats[i];
|
|
289
|
+
const key = txHash.toString();
|
|
290
|
+
if (await this.#txs.hasAsync(key)) {
|
|
291
|
+
this.#log.debug(`Tx ${txHash.toString()} already exists in the pool`);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
274
295
|
this.#log.verbose(`Adding tx ${txHash.toString()} to pool`, {
|
|
275
296
|
eventName: 'tx-added-to-pool',
|
|
276
297
|
...txStats,
|
|
277
298
|
} satisfies TxAddedToPoolStats);
|
|
278
299
|
|
|
279
|
-
const key = txHash.toString();
|
|
280
300
|
await this.#txs.set(key, tx.toBuffer());
|
|
281
301
|
|
|
282
302
|
if (!(await this.#minedTxHashToBlock.hasAsync(key))) {
|
|
283
|
-
|
|
303
|
+
addedCount++;
|
|
284
304
|
pendingTxSize += tx.getSize();
|
|
285
305
|
await this.addPendingTxIndices(tx, key);
|
|
286
306
|
this.#metrics.recordSize(tx);
|
|
@@ -288,13 +308,13 @@ export class AztecKVTxPool implements TxPool {
|
|
|
288
308
|
}),
|
|
289
309
|
);
|
|
290
310
|
|
|
311
|
+
await this.increasePendingTxCount(addedCount);
|
|
291
312
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
292
|
-
|
|
293
313
|
const { numLowPriorityTxsEvicted, numNewTxsEvicted } = await this.evictLowPriorityTxs(
|
|
294
314
|
hashesAndStats.map(({ txHash }) => txHash),
|
|
295
315
|
);
|
|
296
316
|
|
|
297
|
-
this.#metrics.recordAddedObjects(
|
|
317
|
+
this.#metrics.recordAddedObjects(addedCount - numNewTxsEvicted, 'pending');
|
|
298
318
|
this.#metrics.recordRemovedObjects(numLowPriorityTxsEvicted - numNewTxsEvicted, 'pending');
|
|
299
319
|
});
|
|
300
320
|
}
|
|
@@ -335,6 +355,8 @@ export class AztecKVTxPool implements TxPool {
|
|
|
335
355
|
}
|
|
336
356
|
|
|
337
357
|
await this.#pendingTxSize.set(pendingTxSize);
|
|
358
|
+
await this.increasePendingTxCount(-pendingDeleted);
|
|
359
|
+
|
|
338
360
|
this.#metrics.recordRemovedObjects(pendingDeleted, 'pending');
|
|
339
361
|
this.#metrics.recordRemovedObjects(minedDeleted, 'mined');
|
|
340
362
|
});
|
|
@@ -369,6 +391,11 @@ export class AztecKVTxPool implements TxPool {
|
|
|
369
391
|
return Promise.resolve();
|
|
370
392
|
}
|
|
371
393
|
|
|
394
|
+
public markTxsAsNonEvictable(txHashes: TxHash[]): Promise<void> {
|
|
395
|
+
txHashes.forEach(txHash => this.#nonEvictableTxs.add(txHash.toString()));
|
|
396
|
+
return Promise.resolve();
|
|
397
|
+
}
|
|
398
|
+
|
|
372
399
|
/**
|
|
373
400
|
* Creates a GasTxValidator instance.
|
|
374
401
|
* @param db - DB for the validator to use
|
|
@@ -466,6 +493,9 @@ export class AztecKVTxPool implements TxPool {
|
|
|
466
493
|
let pendingTxsSize = (await this.#pendingTxSize.getAsync()) ?? 0;
|
|
467
494
|
if (pendingTxsSize > this.#maxTxPoolSize) {
|
|
468
495
|
for await (const txHash of this.#pendingTxPriorityToHash.valuesAsync()) {
|
|
496
|
+
if (this.#nonEvictableTxs.has(txHash.toString())) {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
469
499
|
this.#log.verbose(`Evicting tx ${txHash} from pool due to low priority to satisfy max tx size limit`);
|
|
470
500
|
txsToEvict.push(TxHash.fromString(txHash));
|
|
471
501
|
|
|
@@ -613,4 +643,12 @@ export class AztecKVTxPool implements TxPool {
|
|
|
613
643
|
await this.#pendingTxHashToHeaderHash.delete(txHash);
|
|
614
644
|
this.#pendingTxs.delete(txHash);
|
|
615
645
|
}
|
|
646
|
+
|
|
647
|
+
private async increasePendingTxCount(count: number): Promise<void> {
|
|
648
|
+
const pendingTxCount = (await this.#pendingTxCount.getAsync()) ?? 0;
|
|
649
|
+
this.#log.debug(
|
|
650
|
+
`Increasing pending tx count: current ${pendingTxCount} + count ${count} = ${pendingTxCount + count}`,
|
|
651
|
+
);
|
|
652
|
+
await this.#pendingTxCount.set(pendingTxCount + count);
|
|
653
|
+
}
|
|
616
654
|
}
|
|
@@ -24,7 +24,10 @@ export class InMemoryTxPool implements TxPool {
|
|
|
24
24
|
* Class constructor for in-memory TxPool. Initiates our transaction pool as a JS Map.
|
|
25
25
|
* @param log - A logger.
|
|
26
26
|
*/
|
|
27
|
-
constructor(
|
|
27
|
+
constructor(
|
|
28
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
29
|
+
private log = createLogger('p2p:tx_pool'),
|
|
30
|
+
) {
|
|
28
31
|
this.txs = new Map<bigint, Tx>();
|
|
29
32
|
this.minedTxs = new Map();
|
|
30
33
|
this.pendingTxs = new Set();
|
|
@@ -86,6 +89,10 @@ export class InMemoryTxPool implements TxPool {
|
|
|
86
89
|
);
|
|
87
90
|
}
|
|
88
91
|
|
|
92
|
+
public getPendingTxCount(): Promise<number> {
|
|
93
|
+
return Promise.resolve(this.pendingTxs.size);
|
|
94
|
+
}
|
|
95
|
+
|
|
89
96
|
public getTxStatus(txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
|
|
90
97
|
const key = txHash.toBigInt();
|
|
91
98
|
if (this.pendingTxs.has(key)) {
|
|
@@ -186,4 +193,8 @@ export class InMemoryTxPool implements TxPool {
|
|
|
186
193
|
setMaxTxPoolSize(_maxSizeBytes: number | undefined): Promise<void> {
|
|
187
194
|
return Promise.resolve();
|
|
188
195
|
}
|
|
196
|
+
|
|
197
|
+
markTxsAsNonEvictable(_: TxHash[]): Promise<void> {
|
|
198
|
+
return Promise.resolve();
|
|
199
|
+
}
|
|
189
200
|
}
|
|
@@ -75,6 +75,9 @@ export interface TxPool {
|
|
|
75
75
|
*/
|
|
76
76
|
getPendingTxHashes(): Promise<TxHash[]>;
|
|
77
77
|
|
|
78
|
+
/** Returns the number of pending txs in the pool. */
|
|
79
|
+
getPendingTxCount(): Promise<number>;
|
|
80
|
+
|
|
78
81
|
/**
|
|
79
82
|
* Gets the hashes of mined transactions currently in the tx pool.
|
|
80
83
|
* @returns An array of mined transaction hashes found in the tx pool.
|
|
@@ -96,4 +99,10 @@ export interface TxPool {
|
|
|
96
99
|
|
|
97
100
|
/** Returns whether the pool is empty. */
|
|
98
101
|
isEmpty(): Promise<boolean>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Marks transactions as non-evictible in the pool.
|
|
105
|
+
* @param txHashes - Hashes of the transactions to mark as non-evictible.
|
|
106
|
+
*/
|
|
107
|
+
markTxsAsNonEvictable(txHashes: TxHash[]): Promise<void>;
|
|
99
108
|
}
|
|
@@ -24,6 +24,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
24
24
|
expect(await poolTx!.getTxHash()).toEqual(await tx1.getTxHash());
|
|
25
25
|
await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toEqual('pending');
|
|
26
26
|
await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx1.getTxHash()]);
|
|
27
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(1);
|
|
27
28
|
});
|
|
28
29
|
|
|
29
30
|
it('Removes txs from the pool', async () => {
|
|
@@ -34,6 +35,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
34
35
|
|
|
35
36
|
await expect(pool.getTxByHash(await tx1.getTxHash())).resolves.toBeFalsy();
|
|
36
37
|
await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toBeUndefined();
|
|
38
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(0);
|
|
37
39
|
});
|
|
38
40
|
|
|
39
41
|
it('Marks txs as mined', async () => {
|
|
@@ -47,6 +49,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
47
49
|
await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toEqual('mined');
|
|
48
50
|
await expect(pool.getMinedTxHashes()).resolves.toEqual([[await tx1.getTxHash(), 1]]);
|
|
49
51
|
await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx2.getTxHash()]);
|
|
52
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(1);
|
|
50
53
|
});
|
|
51
54
|
|
|
52
55
|
it('Marks txs as pending after being mined', async () => {
|
|
@@ -61,6 +64,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
61
64
|
const pending = await pool.getPendingTxHashes();
|
|
62
65
|
expect(pending).toHaveLength(2);
|
|
63
66
|
expect(pending).toEqual(expect.arrayContaining([await tx1.getTxHash(), await tx2.getTxHash()]));
|
|
67
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(2);
|
|
64
68
|
});
|
|
65
69
|
|
|
66
70
|
it('Only marks txs as pending if they are known', async () => {
|
|
@@ -82,6 +86,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
82
86
|
await pool.markMinedAsPending([await tx1.getTxHash(), someTxHashThatThisPeerDidNotSee]);
|
|
83
87
|
await expect(pool.getMinedTxHashes()).resolves.toEqual([]);
|
|
84
88
|
await expect(pool.getPendingTxHashes()).resolves.toEqual([await tx1.getTxHash()]); // tx2 is not in the pool
|
|
89
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(1);
|
|
85
90
|
});
|
|
86
91
|
|
|
87
92
|
it('Returns all transactions in the pool', async () => {
|
|
@@ -94,6 +99,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
94
99
|
const poolTxs = await pool.getAllTxs();
|
|
95
100
|
expect(poolTxs).toHaveLength(3);
|
|
96
101
|
expect(poolTxs).toEqual(expect.arrayContaining([tx1, tx2, tx3]));
|
|
102
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(3);
|
|
97
103
|
});
|
|
98
104
|
|
|
99
105
|
it('Returns all txHashes in the pool', async () => {
|
|
@@ -104,10 +110,10 @@ export function describeTxPool(getTxPool: () => TxPool) {
|
|
|
104
110
|
await pool.addTxs([tx1, tx2, tx3]);
|
|
105
111
|
|
|
106
112
|
const poolTxHashes = await pool.getAllTxHashes();
|
|
113
|
+
const expectedHashes = await Promise.all([tx1, tx2, tx3].map(tx => tx.getTxHash()));
|
|
107
114
|
expect(poolTxHashes).toHaveLength(3);
|
|
108
|
-
expect(poolTxHashes).toEqual(
|
|
109
|
-
|
|
110
|
-
);
|
|
115
|
+
expect(poolTxHashes).toEqual(expect.arrayContaining(expectedHashes));
|
|
116
|
+
await expect(pool.getPendingTxCount()).resolves.toEqual(3);
|
|
111
117
|
});
|
|
112
118
|
|
|
113
119
|
it('Returns txs by their hash', async () => {
|
|
@@ -17,7 +17,7 @@ export class BlockHeaderTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
17
17
|
async validateTx(tx: T): Promise<TxValidationResult> {
|
|
18
18
|
const [index] = await this.#archiveSource.getArchiveIndices([await tx.data.constants.historicalHeader.hash()]);
|
|
19
19
|
if (index === undefined) {
|
|
20
|
-
this.#log.
|
|
20
|
+
this.#log.verbose(`Rejecting tx ${await Tx.getHash(tx)} for referencing an unknown block header`);
|
|
21
21
|
return { result: 'invalid', reason: [TX_ERROR_BLOCK_HEADER] };
|
|
22
22
|
}
|
|
23
23
|
return { result: 'valid' };
|
|
@@ -26,7 +26,7 @@ export class DataTxValidator implements TxValidator<Tx> {
|
|
|
26
26
|
async #hasCorrectCalldata(tx: Tx): Promise<TxValidationResult> {
|
|
27
27
|
if (tx.publicFunctionCalldata.length !== tx.numberOfPublicCalls()) {
|
|
28
28
|
const reason = TX_ERROR_CALLDATA_COUNT_MISMATCH;
|
|
29
|
-
this.#log.
|
|
29
|
+
this.#log.verbose(
|
|
30
30
|
`Rejecting tx ${await Tx.getHash(tx)}. Reason: ${reason}. Expected ${tx.numberOfPublicCalls()}. Got ${
|
|
31
31
|
tx.publicFunctionCalldata.length
|
|
32
32
|
}.`,
|
|
@@ -36,7 +36,7 @@ export class DataTxValidator implements TxValidator<Tx> {
|
|
|
36
36
|
|
|
37
37
|
if (tx.getTotalPublicCalldataCount() > MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS) {
|
|
38
38
|
const reason = TX_ERROR_CALLDATA_COUNT_TOO_LARGE;
|
|
39
|
-
this.#log.
|
|
39
|
+
this.#log.verbose(
|
|
40
40
|
`Rejecting tx ${await Tx.getHash(
|
|
41
41
|
tx,
|
|
42
42
|
)}. Reason: ${reason}. Expected no greater than ${MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS} fields. Got ${tx.getTotalPublicCalldataCount()}.`,
|
|
@@ -50,7 +50,7 @@ export class DataTxValidator implements TxValidator<Tx> {
|
|
|
50
50
|
const hash = await computeCalldataHash(calldata);
|
|
51
51
|
if (!hash.equals(request.calldataHash)) {
|
|
52
52
|
const reason = TX_ERROR_INCORRECT_CALLDATA;
|
|
53
|
-
this.#log.
|
|
53
|
+
this.#log.verbose(`Rejecting tx ${await Tx.getHash(tx)}. Reason: ${reason}. Call request index: ${i}.`);
|
|
54
54
|
return { result: 'invalid', reason: [reason] };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -60,44 +60,50 @@ export class DataTxValidator implements TxValidator<Tx> {
|
|
|
60
60
|
|
|
61
61
|
async #hasCorrectContractClassLogs(tx: Tx): Promise<TxValidationResult> {
|
|
62
62
|
const contractClassLogsHashes = tx.data.getNonEmptyContractClassLogsHashes();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.#log.warn(
|
|
63
|
+
if (contractClassLogsHashes.length !== tx.contractClassLogs.length) {
|
|
64
|
+
this.#log.verbose(
|
|
66
65
|
`Rejecting tx ${await Tx.getHash(tx)} because of mismatched number of contract class logs. Expected ${
|
|
67
66
|
contractClassLogsHashes.length
|
|
68
|
-
}. Got ${
|
|
67
|
+
}. Got ${tx.contractClassLogs.length}.`,
|
|
69
68
|
);
|
|
70
69
|
return { result: 'invalid', reason: [TX_ERROR_CONTRACT_CLASS_LOG_COUNT] };
|
|
71
70
|
}
|
|
71
|
+
|
|
72
|
+
const expectedHashes = await Promise.all(tx.contractClassLogs.map(l => l.hash()));
|
|
72
73
|
for (const [i, logHash] of contractClassLogsHashes.entries()) {
|
|
73
|
-
const
|
|
74
|
-
if (!logHash.value.equals(
|
|
75
|
-
if (
|
|
76
|
-
const matchingLogIndex =
|
|
77
|
-
this.#log.
|
|
74
|
+
const hash = expectedHashes[i];
|
|
75
|
+
if (!logHash.value.equals(hash)) {
|
|
76
|
+
if (expectedHashes.some(h => logHash.value.equals(h))) {
|
|
77
|
+
const matchingLogIndex = expectedHashes.findIndex(l => logHash.value.equals(l));
|
|
78
|
+
this.#log.verbose(
|
|
78
79
|
`Rejecting tx ${await Tx.getHash(
|
|
79
80
|
tx,
|
|
80
81
|
)} because of mismatched contract class logs indices. Expected ${i} from the kernel's log hashes. Got ${matchingLogIndex} in the tx.`,
|
|
81
82
|
);
|
|
82
83
|
return { result: 'invalid', reason: [TX_ERROR_CONTRACT_CLASS_LOG_SORTING] };
|
|
83
84
|
} else {
|
|
84
|
-
this.#log.
|
|
85
|
+
this.#log.verbose(
|
|
85
86
|
`Rejecting tx ${await Tx.getHash(tx)} because of mismatched contract class logs. Expected hash ${
|
|
86
87
|
logHash.value
|
|
87
|
-
} from the kernels. Got ${
|
|
88
|
+
} from the kernels. Got ${hash} in the tx.`,
|
|
88
89
|
);
|
|
89
90
|
return { result: 'invalid', reason: [TX_ERROR_CONTRACT_CLASS_LOGS] };
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
|
|
94
|
+
const expectedMinLength = 1 + tx.contractClassLogs[i].fields.findLastIndex(f => !f.isZero());
|
|
95
|
+
if (logHash.logHash.length < expectedMinLength) {
|
|
96
|
+
this.#log.verbose(
|
|
97
|
+
`Rejecting tx ${await Tx.getHash(
|
|
98
|
+
tx,
|
|
99
|
+
)} because of incorrect contract class log length. Expected the length to be at least ${expectedMinLength}. Got ${
|
|
95
100
|
logHash.logHash.length
|
|
96
|
-
}
|
|
101
|
+
}.`,
|
|
97
102
|
);
|
|
98
103
|
return { result: 'invalid', reason: [TX_ERROR_CONTRACT_CLASS_LOG_LENGTH] };
|
|
99
104
|
}
|
|
100
105
|
}
|
|
106
|
+
|
|
101
107
|
return { result: 'valid' };
|
|
102
108
|
}
|
|
103
109
|
}
|
|
@@ -26,12 +26,12 @@ export class DoubleSpendTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
26
26
|
// Ditch this tx if it has repeated nullifiers
|
|
27
27
|
const uniqueNullifiers = new Set(nullifiers);
|
|
28
28
|
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
29
|
-
this.#log.
|
|
29
|
+
this.#log.verbose(`Rejecting tx ${await Tx.getHash(tx)} for emitting duplicate nullifiers`);
|
|
30
30
|
return { result: 'invalid', reason: [TX_ERROR_DUPLICATE_NULLIFIER_IN_TX] };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if ((await this.#nullifierSource.nullifiersExist(nullifiers.map(n => n.toBuffer()))).some(Boolean)) {
|
|
34
|
-
this.#log.
|
|
34
|
+
this.#log.verbose(`Rejecting tx ${await Tx.getHash(tx)} for repeating a nullifier`);
|
|
35
35
|
return { result: 'invalid', reason: [TX_ERROR_EXISTING_NULLIFIER] };
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
3
|
+
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
4
|
+
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
5
|
+
import type { GasFees } from '@aztec/stdlib/gas';
|
|
6
|
+
import type {
|
|
7
|
+
AllowedElement,
|
|
8
|
+
ClientProtocolCircuitVerifier,
|
|
9
|
+
WorldStateSynchronizer,
|
|
10
|
+
} from '@aztec/stdlib/interfaces/server';
|
|
11
|
+
import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
12
|
+
import { DatabasePublicStateSource, MerkleTreeId } from '@aztec/stdlib/trees';
|
|
13
|
+
import type { Tx, TxValidationResult } from '@aztec/stdlib/tx';
|
|
14
|
+
|
|
15
|
+
import { ArchiveCache } from './archive_cache.js';
|
|
16
|
+
import { BlockHeaderTxValidator } from './block_header_validator.js';
|
|
17
|
+
import { DataTxValidator } from './data_validator.js';
|
|
18
|
+
import { DoubleSpendTxValidator } from './double_spend_validator.js';
|
|
19
|
+
import { GasTxValidator } from './gas_validator.js';
|
|
20
|
+
import { MetadataTxValidator } from './metadata_validator.js';
|
|
21
|
+
import { PhasesTxValidator } from './phases_validator.js';
|
|
22
|
+
import { TxProofValidator } from './tx_proof_validator.js';
|
|
23
|
+
|
|
24
|
+
export interface MessageValidator {
|
|
25
|
+
validator: {
|
|
26
|
+
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
27
|
+
};
|
|
28
|
+
severity: PeerErrorSeverity;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function createTxMessageValidators(
|
|
32
|
+
blockNumber: number,
|
|
33
|
+
worldStateSynchronizer: WorldStateSynchronizer,
|
|
34
|
+
gasFees: GasFees,
|
|
35
|
+
l1ChainId: number,
|
|
36
|
+
rollupVersion: number,
|
|
37
|
+
protocolContractTreeRoot: Fr,
|
|
38
|
+
contractDataSource: ContractDataSource,
|
|
39
|
+
proofVerifier: ClientProtocolCircuitVerifier,
|
|
40
|
+
allowedInSetup: AllowedElement[] = [],
|
|
41
|
+
): Record<string, MessageValidator>[] {
|
|
42
|
+
const merkleTree = worldStateSynchronizer.getCommitted();
|
|
43
|
+
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
dataValidator: {
|
|
47
|
+
validator: new DataTxValidator(),
|
|
48
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
49
|
+
},
|
|
50
|
+
metadataValidator: {
|
|
51
|
+
validator: new MetadataTxValidator({
|
|
52
|
+
l1ChainId: new Fr(l1ChainId),
|
|
53
|
+
rollupVersion: new Fr(rollupVersion),
|
|
54
|
+
blockNumber: new Fr(blockNumber),
|
|
55
|
+
protocolContractTreeRoot,
|
|
56
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
57
|
+
}),
|
|
58
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
59
|
+
},
|
|
60
|
+
doubleSpendValidator: {
|
|
61
|
+
validator: new DoubleSpendTxValidator({
|
|
62
|
+
nullifiersExist: async (nullifiers: Buffer[]) => {
|
|
63
|
+
const merkleTree = worldStateSynchronizer.getCommitted();
|
|
64
|
+
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
65
|
+
return indices.map(index => index !== undefined);
|
|
66
|
+
},
|
|
67
|
+
}),
|
|
68
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
69
|
+
},
|
|
70
|
+
gasValidator: {
|
|
71
|
+
validator: new GasTxValidator(
|
|
72
|
+
new DatabasePublicStateSource(merkleTree),
|
|
73
|
+
ProtocolContractAddress.FeeJuice,
|
|
74
|
+
gasFees,
|
|
75
|
+
),
|
|
76
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
77
|
+
},
|
|
78
|
+
phasesValidator: {
|
|
79
|
+
validator: new PhasesTxValidator(contractDataSource, allowedInSetup, blockNumber),
|
|
80
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
81
|
+
},
|
|
82
|
+
blockHeaderValidator: {
|
|
83
|
+
validator: new BlockHeaderTxValidator(new ArchiveCache(merkleTree)),
|
|
84
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
proofValidator: {
|
|
89
|
+
validator: new TxProofValidator(proofVerifier),
|
|
90
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
}
|
|
@@ -55,7 +55,7 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
55
55
|
maxFeesPerGas.feePerL2Gas.lt(this.#gasFees.feePerL2Gas);
|
|
56
56
|
|
|
57
57
|
if (notEnoughMaxFees) {
|
|
58
|
-
this.#log.
|
|
58
|
+
this.#log.verbose(`Skipping transaction ${await tx.getTxHash()} due to insufficient fee per gas`, {
|
|
59
59
|
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
60
60
|
currentGasFees: this.#gasFees.toInspect(),
|
|
61
61
|
});
|
|
@@ -71,7 +71,7 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
71
71
|
const minGasLimits = new Gas(FIXED_DA_GAS, FIXED_L2_GAS);
|
|
72
72
|
|
|
73
73
|
if (minGasLimits.gtAny(gasLimits)) {
|
|
74
|
-
this.#log.
|
|
74
|
+
this.#log.verbose(`Rejecting transaction due to the gas limit(s) not being above the minimum gas limit`, {
|
|
75
75
|
gasLimits,
|
|
76
76
|
minGasLimits,
|
|
77
77
|
});
|
|
@@ -113,7 +113,7 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
113
113
|
|
|
114
114
|
const balance = claimFunctionCall ? initialBalance.add(claimFunctionCall.args[1]) : initialBalance;
|
|
115
115
|
if (balance.lt(feeLimit)) {
|
|
116
|
-
this.#log.
|
|
116
|
+
this.#log.verbose(`Rejecting transaction due to not enough fee payer balance`, {
|
|
117
117
|
feePayer,
|
|
118
118
|
balance: balance.toBigInt(),
|
|
119
119
|
feeLimit: feeLimit.toBigInt(),
|
|
@@ -42,7 +42,7 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
42
42
|
async #hasCorrectVkTreeRoot(tx: T): Promise<boolean> {
|
|
43
43
|
// This gets implicitly tested in the proof validator, but we can get a much cheaper check here by looking early at the vk.
|
|
44
44
|
if (!tx.data.constants.vkTreeRoot.equals(this.values.vkTreeRoot)) {
|
|
45
|
-
this.#log.
|
|
45
|
+
this.#log.verbose(
|
|
46
46
|
`Rejecting tx ${await Tx.getHash(
|
|
47
47
|
tx,
|
|
48
48
|
)} because of incorrect vk tree root ${tx.data.constants.vkTreeRoot.toString()} != ${this.values.vkTreeRoot.toString()}`,
|
|
@@ -55,7 +55,7 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
55
55
|
|
|
56
56
|
async #hasCorrectProtocolContractTreeRoot(tx: T): Promise<boolean> {
|
|
57
57
|
if (!tx.data.constants.protocolContractTreeRoot.equals(this.values.protocolContractTreeRoot)) {
|
|
58
|
-
this.#log.
|
|
58
|
+
this.#log.verbose(
|
|
59
59
|
`Rejecting tx ${await Tx.getHash(
|
|
60
60
|
tx,
|
|
61
61
|
)} because of incorrect protocol contract tree root ${tx.data.constants.protocolContractTreeRoot.toString()} != ${this.values.protocolContractTreeRoot.toString()}`,
|
|
@@ -67,7 +67,7 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
67
67
|
|
|
68
68
|
async #hasCorrectL1ChainId(tx: T): Promise<boolean> {
|
|
69
69
|
if (!tx.data.constants.txContext.chainId.equals(this.values.l1ChainId)) {
|
|
70
|
-
this.#log.
|
|
70
|
+
this.#log.verbose(
|
|
71
71
|
`Rejecting tx ${await Tx.getHash(
|
|
72
72
|
tx,
|
|
73
73
|
)} because of incorrect L1 chain ${tx.data.constants.txContext.chainId.toNumber()} != ${this.values.l1ChainId.toNumber()}`,
|
|
@@ -82,7 +82,7 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
82
82
|
const maxBlockNumber = tx.data.rollupValidationRequests.maxBlockNumber;
|
|
83
83
|
|
|
84
84
|
if (maxBlockNumber.isSome && maxBlockNumber.value < this.values.blockNumber) {
|
|
85
|
-
this.#log.
|
|
85
|
+
this.#log.verbose(
|
|
86
86
|
`Rejecting tx ${await Tx.getHash(tx)} for low max block number. Tx max block number: ${
|
|
87
87
|
maxBlockNumber.value
|
|
88
88
|
}, current block number: ${this.values.blockNumber}.`,
|
|
@@ -95,7 +95,7 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
95
95
|
|
|
96
96
|
async #hasCorrectRollupVersion(tx: T): Promise<boolean> {
|
|
97
97
|
if (!tx.data.constants.txContext.version.equals(this.values.rollupVersion)) {
|
|
98
|
-
this.#log.
|
|
98
|
+
this.#log.verbose(
|
|
99
99
|
`Rejecting tx ${await Tx.getHash(
|
|
100
100
|
tx,
|
|
101
101
|
)} because of incorrect rollup version ${tx.data.constants.txContext.version.toNumber()} != ${this.values.rollupVersion.toNumber()}`,
|
|
@@ -16,7 +16,11 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
16
16
|
#log = createLogger('sequencer:tx_validator:tx_phases');
|
|
17
17
|
private contractsDB: PublicContractsDB;
|
|
18
18
|
|
|
19
|
-
constructor(
|
|
19
|
+
constructor(
|
|
20
|
+
contracts: ContractDataSource,
|
|
21
|
+
private setupAllowList: AllowedElement[],
|
|
22
|
+
private blockNumber: number,
|
|
23
|
+
) {
|
|
20
24
|
this.contractsDB = new PublicContractsDB(contracts);
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -37,7 +41,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
37
41
|
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
38
42
|
for (const setupFn of setupFns) {
|
|
39
43
|
if (!(await this.isOnAllowList(setupFn, this.setupAllowList))) {
|
|
40
|
-
this.#log.
|
|
44
|
+
this.#log.verbose(
|
|
41
45
|
`Rejecting tx ${await Tx.getHash(tx)} because it calls setup function not on allow list: ${
|
|
42
46
|
setupFn.request.contractAddress
|
|
43
47
|
}:${setupFn.functionSelector}`,
|
|
@@ -9,7 +9,7 @@ export class TxProofValidator implements TxValidator<Tx> {
|
|
|
9
9
|
|
|
10
10
|
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
11
11
|
if (!(await this.verifier.verifyProof(tx))) {
|
|
12
|
-
this.#log.
|
|
12
|
+
this.#log.verbose(`Rejecting tx ${await Tx.getHash(tx)} for invalid proof`);
|
|
13
13
|
return { result: 'invalid', reason: [TX_ERROR_INVALID_PROOF] };
|
|
14
14
|
}
|
|
15
15
|
this.#log.trace(`Accepted ${await Tx.getHash(tx)} with valid proof`);
|