@aztec/p2p 0.0.1-commit.cf93bcc56 → 0.0.1-commit.d1cd2107c
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/client/factory.d.ts +5 -6
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +16 -26
- package/dest/client/interface.d.ts +8 -13
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +7 -13
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +29 -86
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +6 -7
- package/dest/config.d.ts +22 -15
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +66 -37
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +5 -1
- package/dest/mem_pools/instrumentation.d.ts +4 -2
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +16 -14
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +7 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.js +8 -6
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.js +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
- package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/index.js +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +12 -6
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +3 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +40 -10
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.js +74 -16
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +26 -44
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +5 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +5 -2
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +6 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +178 -140
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +10 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +6 -4
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +16 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -8
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +48 -36
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +2 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +24 -20
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts +17 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_setup_helpers.js +24 -0
- package/dest/msg_validators/tx_validator/factory.d.ts +114 -6
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +219 -58
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/fee_payer_balance.js +6 -2
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +58 -3
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +73 -36
- package/dest/msg_validators/tx_validator/index.d.ts +3 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +2 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +44 -23
- package/dest/services/dummy_service.d.ts +4 -4
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +4 -4
- package/dest/services/encoding.d.ts +2 -2
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -7
- package/dest/services/gossipsub/topic_score_params.d.ts +18 -6
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +32 -10
- package/dest/services/libp2p/libp2p_service.d.ts +16 -13
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +84 -90
- package/dest/services/peer-manager/metrics.d.ts +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +6 -0
- 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 +2 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +4 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +19 -46
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -6
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +10 -13
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +25 -46
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +17 -11
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +49 -15
- package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
- package/dest/services/reqresp/reqresp.d.ts +1 -1
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +2 -1
- package/dest/services/service.d.ts +5 -3
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +39 -33
- package/dest/services/tx_collection/file_store_tx_collection.d.ts +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_collection.js +4 -2
- package/dest/services/tx_collection/file_store_tx_source.d.ts +4 -4
- package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/file_store_tx_source.js +27 -16
- package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +5 -4
- package/dest/services/tx_collection/slow_tx_collection.d.ts +2 -2
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/slow_tx_collection.js +10 -8
- package/dest/services/tx_collection/tx_collection.d.ts +5 -4
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.d.ts +6 -5
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_collection_sink.js +13 -22
- package/dest/services/tx_collection/tx_source.d.ts +8 -3
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +19 -2
- package/dest/services/tx_provider.d.ts +3 -3
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +4 -4
- package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +1 -2
- package/dest/test-helpers/mock-pubsub.d.ts +4 -4
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +8 -2
- package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +2 -2
- package/dest/test-helpers/testbench-utils.d.ts +5 -3
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +1 -1
- package/dest/testbench/p2p_client_testbench_worker.d.ts +2 -2
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +13 -12
- package/dest/testbench/worker_client_manager.d.ts +3 -1
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +6 -2
- package/dest/util.d.ts +3 -3
- package/dest/util.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client/factory.ts +24 -47
- package/src/client/interface.ts +8 -13
- package/src/client/p2p_client.ts +34 -113
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +20 -11
- package/src/config.ts +92 -43
- package/src/mem_pools/attestation_pool/attestation_pool.ts +5 -4
- package/src/mem_pools/instrumentation.ts +17 -13
- package/src/mem_pools/tx_pool_v2/README.md +9 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -2
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_pre_add_rule.ts +15 -6
- package/src/mem_pools/tx_pool_v2/eviction/nullifier_conflict_rule.ts +2 -1
- package/src/mem_pools/tx_pool_v2/index.ts +1 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +11 -5
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +104 -19
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +6 -3
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +189 -141
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +14 -4
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +20 -7
- package/src/msg_validators/proposal_validator/proposal_validator.ts +63 -40
- package/src/msg_validators/tx_validator/README.md +115 -0
- package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +22 -27
- package/src/msg_validators/tx_validator/allowed_setup_helpers.ts +31 -0
- package/src/msg_validators/tx_validator/factory.ts +353 -77
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +90 -27
- package/src/msg_validators/tx_validator/index.ts +2 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
- package/src/msg_validators/tx_validator/phases_validator.ts +51 -26
- package/src/services/dummy_service.ts +6 -6
- package/src/services/encoding.ts +5 -6
- package/src/services/gossipsub/README.md +29 -14
- package/src/services/gossipsub/topic_score_params.ts +49 -13
- package/src/services/libp2p/libp2p_service.ts +95 -96
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +2 -1
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +20 -48
- package/src/services/reqresp/batch-tx-requester/interface.ts +1 -5
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +23 -71
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +63 -24
- package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
- package/src/services/reqresp/reqresp.ts +3 -1
- package/src/services/service.ts +11 -2
- package/src/services/tx_collection/fast_tx_collection.ts +51 -30
- package/src/services/tx_collection/file_store_tx_collection.ts +7 -3
- package/src/services/tx_collection/file_store_tx_source.ts +32 -19
- package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -7
- package/src/services/tx_collection/slow_tx_collection.ts +8 -9
- package/src/services/tx_collection/tx_collection.ts +4 -3
- package/src/services/tx_collection/tx_collection_sink.ts +15 -29
- package/src/services/tx_collection/tx_source.ts +22 -3
- package/src/services/tx_provider.ts +2 -2
- package/src/test-helpers/make-test-p2p-clients.ts +1 -3
- package/src/test-helpers/mock-pubsub.ts +13 -6
- package/src/test-helpers/reqresp-nodes.ts +3 -6
- package/src/test-helpers/testbench-utils.ts +2 -2
- package/src/testbench/p2p_client_testbench_worker.ts +22 -18
- package/src/testbench/worker_client_manager.ts +13 -5
- package/src/util.ts +8 -2
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +0 -23
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +0 -1
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +0 -212
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
|
@@ -45,6 +45,7 @@ import { TxPoolIndices } from './tx_pool_indices.js';
|
|
|
45
45
|
export interface TxPoolV2Callbacks {
|
|
46
46
|
onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
|
|
47
47
|
onTxsRemoved: (txHashes: string[] | bigint[]) => void;
|
|
48
|
+
onTxsMined: (txHashes: string[]) => void;
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -187,9 +188,35 @@ export class TxPoolV2Impl {
|
|
|
187
188
|
const errors = new Map<string, TxPoolRejectionError>();
|
|
188
189
|
const acceptedPending = new Set<string>();
|
|
189
190
|
|
|
191
|
+
// Phase 1: Pre-compute all throwable I/O outside the transaction.
|
|
192
|
+
// If any pre-computation throws, the entire call fails before mutations happen.
|
|
193
|
+
const precomputed = new Map<string, { meta: TxMetaData; minedBlockId: L2BlockId | undefined; isValid: boolean }>();
|
|
194
|
+
|
|
195
|
+
const validator = await this.#createTxValidator();
|
|
196
|
+
|
|
197
|
+
for (const tx of txs) {
|
|
198
|
+
const txHash = tx.getTxHash();
|
|
199
|
+
const txHashStr = txHash.toString();
|
|
200
|
+
|
|
201
|
+
const meta = await buildTxMetaData(tx);
|
|
202
|
+
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
203
|
+
|
|
204
|
+
// Validate non-mined txs (mined and pre-protected txs bypass validation inside the transaction)
|
|
205
|
+
let isValid = true;
|
|
206
|
+
if (!minedBlockId) {
|
|
207
|
+
isValid = await this.#validateMeta(meta, validator);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
precomputed.set(txHashStr, { meta, minedBlockId, isValid });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Phase 2: Apply mutations inside the transaction using only pre-computed results,
|
|
214
|
+
// in-memory reads, and buffered DB writes. Nothing here can throw an unhandled exception.
|
|
190
215
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
191
216
|
const preAddContext: PreAddContext | undefined =
|
|
192
|
-
opts.feeComparisonOnly !== undefined
|
|
217
|
+
opts.feeComparisonOnly !== undefined
|
|
218
|
+
? { feeComparisonOnly: opts.feeComparisonOnly, priceBumpPercentage: this.#config.priceBumpPercentage }
|
|
219
|
+
: undefined;
|
|
193
220
|
|
|
194
221
|
await this.#store.transactionAsync(async () => {
|
|
195
222
|
for (const tx of txs) {
|
|
@@ -202,22 +229,25 @@ export class TxPoolV2Impl {
|
|
|
202
229
|
continue;
|
|
203
230
|
}
|
|
204
231
|
|
|
205
|
-
|
|
206
|
-
const minedBlockId = await this.#getMinedBlockId(txHash);
|
|
232
|
+
const { meta, minedBlockId, isValid } = precomputed.get(txHashStr)!;
|
|
207
233
|
const preProtectedSlot = this.#indices.getProtectionSlot(txHashStr);
|
|
208
234
|
|
|
209
235
|
if (minedBlockId) {
|
|
210
236
|
// Already mined - add directly (protection already set if pre-protected)
|
|
211
|
-
await this.#addTx(tx, { mined: minedBlockId }, opts);
|
|
237
|
+
await this.#addTx(tx, { mined: minedBlockId }, opts, meta);
|
|
212
238
|
accepted.push(txHash);
|
|
213
239
|
} else if (preProtectedSlot !== undefined) {
|
|
214
240
|
// Pre-protected and not mined - add as protected (bypass validation)
|
|
215
|
-
await this.#addTx(tx, { protected: preProtectedSlot }, opts);
|
|
241
|
+
await this.#addTx(tx, { protected: preProtectedSlot }, opts, meta);
|
|
216
242
|
accepted.push(txHash);
|
|
243
|
+
} else if (!isValid) {
|
|
244
|
+
// Failed pre-computed validation
|
|
245
|
+
rejected.push(txHash);
|
|
217
246
|
} else {
|
|
218
|
-
// Regular pending tx -
|
|
247
|
+
// Regular pending tx - run pre-add rules using pre-computed metadata
|
|
219
248
|
const result = await this.#tryAddRegularPendingTx(
|
|
220
249
|
tx,
|
|
250
|
+
meta,
|
|
221
251
|
opts,
|
|
222
252
|
poolAccess,
|
|
223
253
|
acceptedPending,
|
|
@@ -227,13 +257,18 @@ export class TxPoolV2Impl {
|
|
|
227
257
|
);
|
|
228
258
|
if (result.status === 'accepted') {
|
|
229
259
|
acceptedPending.add(txHashStr);
|
|
230
|
-
} else if (result.status === 'rejected') {
|
|
231
|
-
rejected.push(txHash);
|
|
232
260
|
} else {
|
|
233
261
|
ignored.push(txHash);
|
|
234
262
|
}
|
|
235
263
|
}
|
|
236
264
|
}
|
|
265
|
+
|
|
266
|
+
// Run post-add eviction rules for pending txs (inside transaction for atomicity)
|
|
267
|
+
if (acceptedPending.size > 0) {
|
|
268
|
+
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
269
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
270
|
+
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
271
|
+
}
|
|
237
272
|
});
|
|
238
273
|
|
|
239
274
|
// Build final accepted list for pending txs (excludes intra-batch evictions)
|
|
@@ -249,37 +284,24 @@ export class TxPoolV2Impl {
|
|
|
249
284
|
this.#instrumentation.recordRejected(rejected.length);
|
|
250
285
|
}
|
|
251
286
|
|
|
252
|
-
// Run post-add eviction rules for pending txs
|
|
253
|
-
if (acceptedPending.size > 0) {
|
|
254
|
-
const feePayers = Array.from(acceptedPending).map(txHash => this.#indices.getMetadata(txHash)!.feePayer);
|
|
255
|
-
const uniqueFeePayers = new Set<string>(feePayers);
|
|
256
|
-
await this.#evictionManager.evictAfterNewTxs(Array.from(acceptedPending), [...uniqueFeePayers]);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
287
|
return { accepted, ignored, rejected, ...(errors.size > 0 ? { errors } : {}) };
|
|
260
288
|
}
|
|
261
289
|
|
|
262
|
-
/**
|
|
290
|
+
/** Adds a validated pending tx, running pre-add rules and evicting conflicts. */
|
|
263
291
|
async #tryAddRegularPendingTx(
|
|
264
292
|
tx: Tx,
|
|
293
|
+
precomputedMeta: TxMetaData,
|
|
265
294
|
opts: { source?: string },
|
|
266
295
|
poolAccess: PreAddPoolAccess,
|
|
267
296
|
acceptedPending: Set<string>,
|
|
268
297
|
ignored: TxHash[],
|
|
269
298
|
errors: Map<string, TxPoolRejectionError>,
|
|
270
299
|
preAddContext?: PreAddContext,
|
|
271
|
-
): Promise<{ status: 'accepted' | 'ignored'
|
|
272
|
-
const
|
|
273
|
-
const txHashStr = txHash.toString();
|
|
274
|
-
|
|
275
|
-
// Build metadata and validate using metadata
|
|
276
|
-
const meta = await buildTxMetaData(tx);
|
|
277
|
-
if (!(await this.#validateMeta(meta))) {
|
|
278
|
-
return { status: 'rejected' };
|
|
279
|
-
}
|
|
300
|
+
): Promise<{ status: 'accepted' | 'ignored' }> {
|
|
301
|
+
const txHashStr = tx.getTxHash().toString();
|
|
280
302
|
|
|
281
303
|
// Run pre-add rules
|
|
282
|
-
const preAddResult = await this.#evictionManager.runPreAddRules(
|
|
304
|
+
const preAddResult = await this.#evictionManager.runPreAddRules(precomputedMeta, poolAccess, preAddContext);
|
|
283
305
|
|
|
284
306
|
if (preAddResult.shouldIgnore) {
|
|
285
307
|
this.#log.debug(`Ignoring tx ${txHashStr}: ${preAddResult.reason?.message ?? 'unknown reason'}`);
|
|
@@ -316,12 +338,18 @@ export class TxPoolV2Impl {
|
|
|
316
338
|
}
|
|
317
339
|
}
|
|
318
340
|
|
|
341
|
+
// Randomly drop the transaction for testing purposes (report as accepted so it propagates)
|
|
342
|
+
if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
|
|
343
|
+
this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
|
|
344
|
+
return { status: 'accepted' };
|
|
345
|
+
}
|
|
346
|
+
|
|
319
347
|
// Add the transaction
|
|
320
|
-
await this.#addTx(tx, 'pending', opts);
|
|
348
|
+
await this.#addTx(tx, 'pending', opts, precomputedMeta);
|
|
321
349
|
return { status: 'accepted' };
|
|
322
350
|
}
|
|
323
351
|
|
|
324
|
-
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'
|
|
352
|
+
async canAddPendingTx(tx: Tx): Promise<'accepted' | 'ignored'> {
|
|
325
353
|
const txHashStr = tx.getTxHash().toString();
|
|
326
354
|
|
|
327
355
|
// Check if already in pool
|
|
@@ -329,14 +357,8 @@ export class TxPoolV2Impl {
|
|
|
329
357
|
return 'ignored';
|
|
330
358
|
}
|
|
331
359
|
|
|
332
|
-
// Build metadata and
|
|
360
|
+
// Build metadata and check pre-add rules
|
|
333
361
|
const meta = await buildTxMetaData(tx);
|
|
334
|
-
const validationResult = await this.#validateMeta(meta, undefined, 'can add pending');
|
|
335
|
-
if (validationResult !== true) {
|
|
336
|
-
return 'rejected';
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Use pre-add rules
|
|
340
362
|
const poolAccess = this.#createPreAddPoolAccess();
|
|
341
363
|
const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
|
|
342
364
|
|
|
@@ -379,33 +401,35 @@ export class TxPoolV2Impl {
|
|
|
379
401
|
let softDeletedHits = 0;
|
|
380
402
|
let missingPreviouslyEvicted = 0;
|
|
381
403
|
|
|
382
|
-
|
|
383
|
-
const
|
|
404
|
+
await this.#store.transactionAsync(async () => {
|
|
405
|
+
for (const txHash of txHashes) {
|
|
406
|
+
const txHashStr = txHash.toString();
|
|
384
407
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
408
|
+
if (this.#indices.has(txHashStr)) {
|
|
409
|
+
// Update protection for existing tx
|
|
410
|
+
this.#indices.updateProtection(txHashStr, slotNumber);
|
|
411
|
+
} else if (this.#deletedPool.isSoftDeleted(txHashStr)) {
|
|
412
|
+
// Resurrect soft-deleted tx as protected
|
|
413
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
414
|
+
if (buffer) {
|
|
415
|
+
const tx = Tx.fromBuffer(buffer);
|
|
416
|
+
await this.#addTx(tx, { protected: slotNumber });
|
|
417
|
+
softDeletedHits++;
|
|
418
|
+
} else {
|
|
419
|
+
// Data missing despite soft-delete flag — treat as truly missing
|
|
420
|
+
this.#indices.setProtection(txHashStr, slotNumber);
|
|
421
|
+
missing.push(txHash);
|
|
422
|
+
}
|
|
395
423
|
} else {
|
|
396
|
-
//
|
|
424
|
+
// Truly missing — pre-record protection for tx we don't have yet
|
|
397
425
|
this.#indices.setProtection(txHashStr, slotNumber);
|
|
398
426
|
missing.push(txHash);
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
this.#indices.setProtection(txHashStr, slotNumber);
|
|
403
|
-
missing.push(txHash);
|
|
404
|
-
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
405
|
-
missingPreviouslyEvicted++;
|
|
427
|
+
if (this.#evictedTxHashes.has(txHashStr)) {
|
|
428
|
+
missingPreviouslyEvicted++;
|
|
429
|
+
}
|
|
406
430
|
}
|
|
407
431
|
}
|
|
408
|
-
}
|
|
432
|
+
});
|
|
409
433
|
|
|
410
434
|
// Record metrics
|
|
411
435
|
if (softDeletedHits > 0) {
|
|
@@ -466,59 +490,67 @@ export class TxPoolV2Impl {
|
|
|
466
490
|
}
|
|
467
491
|
}
|
|
468
492
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
493
|
+
await this.#store.transactionAsync(async () => {
|
|
494
|
+
// Step 4: Mark txs as mined (only those we have in the pool)
|
|
495
|
+
for (const meta of found) {
|
|
496
|
+
this.#indices.markAsMined(meta, blockId);
|
|
497
|
+
await this.#deletedPool.clearIfMinedHigher(meta.txHash, blockId.number);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Step 5: Run post-event eviction rules (inside transaction for atomicity)
|
|
501
|
+
await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
|
|
502
|
+
});
|
|
474
503
|
|
|
475
|
-
|
|
476
|
-
|
|
504
|
+
if (found.length > 0) {
|
|
505
|
+
this.#callbacks.onTxsMined(found.map(m => m.txHash));
|
|
506
|
+
}
|
|
477
507
|
|
|
478
508
|
this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
|
|
479
509
|
}
|
|
480
510
|
|
|
481
511
|
async prepareForSlot(slotNumber: SlotNumber): Promise<void> {
|
|
482
|
-
|
|
483
|
-
|
|
512
|
+
await this.#store.transactionAsync(async () => {
|
|
513
|
+
// Step 0: Clean up slot-deleted txs from previous slots
|
|
514
|
+
await this.#deletedPool.cleanupSlotDeleted(slotNumber);
|
|
484
515
|
|
|
485
|
-
|
|
486
|
-
|
|
516
|
+
// Step 1: Find expired protected txs
|
|
517
|
+
const expiredProtected = this.#indices.findExpiredProtectedTxs(slotNumber);
|
|
487
518
|
|
|
488
|
-
|
|
489
|
-
|
|
519
|
+
// Step 2: Clear protection for all expired entries (including those without metadata)
|
|
520
|
+
this.#indices.clearProtection(expiredProtected);
|
|
490
521
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
522
|
+
// Step 3: Filter to only txs that have metadata and are not mined
|
|
523
|
+
const txsToRestore = this.#indices.filterRestorable(expiredProtected);
|
|
524
|
+
if (txsToRestore.length === 0) {
|
|
525
|
+
this.#log.debug(`Preparing for slot ${slotNumber}, no txs to unprotect`);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
497
528
|
|
|
498
|
-
|
|
529
|
+
this.#log.info(`Preparing for slot ${slotNumber}: unprotecting ${txsToRestore.length} txs`);
|
|
499
530
|
|
|
500
|
-
|
|
501
|
-
|
|
531
|
+
// Step 4: Validate for pending pool
|
|
532
|
+
const { valid, invalid } = await this.#revalidateMetadata(txsToRestore, 'during prepareForSlot');
|
|
502
533
|
|
|
503
|
-
|
|
504
|
-
|
|
534
|
+
// Step 5: Resolve nullifier conflicts and add winners to pending indices
|
|
535
|
+
const { added, toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
505
536
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
537
|
+
// Step 6: Delete invalid txs and evict conflict losers
|
|
538
|
+
await this.#deleteTxsBatch(invalid);
|
|
539
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
509
540
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
541
|
+
// Step 7: Run eviction rules (enforce pool size limit)
|
|
542
|
+
if (added.length > 0) {
|
|
543
|
+
const feePayers = added.map(meta => meta.feePayer);
|
|
544
|
+
const uniqueFeePayers = new Set<string>(feePayers);
|
|
545
|
+
await this.#evictionManager.evictAfterNewTxs(
|
|
546
|
+
added.map(m => m.txHash),
|
|
547
|
+
[...uniqueFeePayers],
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
});
|
|
519
551
|
}
|
|
520
552
|
|
|
521
|
-
async handlePrunedBlocks(latestBlock: L2BlockId): Promise<void> {
|
|
553
|
+
async handlePrunedBlocks(latestBlock: L2BlockId, options?: { deleteAllTxs?: boolean }): Promise<void> {
|
|
522
554
|
// Step 1: Find transactions mined after the prune point
|
|
523
555
|
const txsToUnmine = this.#indices.findTxsMinedAfter(latestBlock.number);
|
|
524
556
|
if (txsToUnmine.length === 0) {
|
|
@@ -528,47 +560,60 @@ export class TxPoolV2Impl {
|
|
|
528
560
|
|
|
529
561
|
this.#log.info(`Handling prune to block ${latestBlock.number}: un-mining ${txsToUnmine.length} txs`);
|
|
530
562
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
563
|
+
await this.#store.transactionAsync(async () => {
|
|
564
|
+
// Step 2: Mark ALL un-mined txs with their original mined block number
|
|
565
|
+
// This ensures they get soft-deleted if removed later, and only hard-deleted
|
|
566
|
+
// when their original mined block is finalized
|
|
567
|
+
await this.#deletedPool.markFromPrunedBlock(
|
|
568
|
+
txsToUnmine.map(m => ({
|
|
569
|
+
txHash: m.txHash,
|
|
570
|
+
minedAtBlock: BlockNumber(m.minedL2BlockId!.number),
|
|
571
|
+
})),
|
|
572
|
+
);
|
|
540
573
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
574
|
+
// Step 3: Unmine - clear mined status from metadata
|
|
575
|
+
for (const meta of txsToUnmine) {
|
|
576
|
+
this.#indices.markAsUnmined(meta);
|
|
577
|
+
}
|
|
545
578
|
|
|
546
|
-
|
|
547
|
-
|
|
579
|
+
// If deleteAllTxs is set (epoch prune), delete all un-mined txs and return early
|
|
580
|
+
if (options?.deleteAllTxs) {
|
|
581
|
+
const allTxHashes = txsToUnmine.map(m => m.txHash);
|
|
582
|
+
await this.#deleteTxsBatch(allTxHashes);
|
|
583
|
+
this.#log.info(
|
|
584
|
+
`Handled prune to block ${latestBlock.number} with deleteAllTxs: deleted ${allTxHashes.length} txs`,
|
|
585
|
+
);
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
548
588
|
|
|
549
|
-
|
|
550
|
-
|
|
589
|
+
// Step 4: Filter out protected txs (they'll be handled by prepareForSlot)
|
|
590
|
+
const unprotectedTxs = this.#indices.filterUnprotected(txsToUnmine);
|
|
551
591
|
|
|
552
|
-
|
|
553
|
-
|
|
592
|
+
// Step 5: Validate for pending pool
|
|
593
|
+
const { valid, invalid } = await this.#revalidateMetadata(unprotectedTxs, 'during handlePrunedBlocks');
|
|
554
594
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
595
|
+
// Step 6: Resolve nullifier conflicts and add winners to pending indices
|
|
596
|
+
const { toEvict } = this.#applyNullifierConflictResolution(valid);
|
|
558
597
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
598
|
+
// Step 7: Delete invalid txs and evict conflict losers
|
|
599
|
+
await this.#deleteTxsBatch(invalid);
|
|
600
|
+
await this.#evictTxs(toEvict, 'NullifierConflict');
|
|
601
|
+
|
|
602
|
+
this.#log.info(
|
|
603
|
+
`Handled prune to block ${latestBlock.number}: ${valid.length} txs restored to pending, ${invalid.length} invalid, ${toEvict.length} evicted due to nullifier conflicts`,
|
|
604
|
+
{ txHashesRestored: valid.map(m => m.txHash), txHashesInvalid: invalid, txHashesEvicted: toEvict },
|
|
605
|
+
);
|
|
563
606
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
607
|
+
// Step 8: Run eviction rules for ALL pending txs (not just restored ones)
|
|
608
|
+
// This handles cases like existing pending txs with invalid fee payer balances
|
|
609
|
+
await this.#evictionManager.evictAfterChainPrune(latestBlock.number);
|
|
610
|
+
});
|
|
567
611
|
}
|
|
568
612
|
|
|
569
613
|
async handleFailedExecution(txHashes: TxHash[]): Promise<void> {
|
|
570
|
-
|
|
571
|
-
|
|
614
|
+
await this.#store.transactionAsync(async () => {
|
|
615
|
+
await this.#deleteTxsBatch(txHashes.map(h => h.toString()));
|
|
616
|
+
});
|
|
572
617
|
|
|
573
618
|
this.#log.info(`Deleted ${txHashes.length} failed txs`, { txHashes: txHashes.map(h => h.toString()) });
|
|
574
619
|
}
|
|
@@ -579,27 +624,29 @@ export class TxPoolV2Impl {
|
|
|
579
624
|
// Step 1: Find mined txs at or before finalized block
|
|
580
625
|
const minedTxsToFinalize = this.#indices.findTxsMinedAtOrBefore(blockNumber);
|
|
581
626
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
627
|
+
await this.#store.transactionAsync(async () => {
|
|
628
|
+
// Step 2: Collect mined txs for archiving (before deletion)
|
|
629
|
+
const txsToArchive: Tx[] = [];
|
|
630
|
+
if (this.#archive.isEnabled()) {
|
|
631
|
+
for (const txHashStr of minedTxsToFinalize) {
|
|
632
|
+
const buffer = await this.#txsDB.getAsync(txHashStr);
|
|
633
|
+
if (buffer) {
|
|
634
|
+
txsToArchive.push(Tx.fromBuffer(buffer));
|
|
635
|
+
}
|
|
589
636
|
}
|
|
590
637
|
}
|
|
591
|
-
}
|
|
592
638
|
|
|
593
|
-
|
|
594
|
-
|
|
639
|
+
// Step 3: Delete mined txs from active pool
|
|
640
|
+
await this.#deleteTxsBatch(minedTxsToFinalize);
|
|
595
641
|
|
|
596
|
-
|
|
597
|
-
|
|
642
|
+
// Step 4: Finalize soft-deleted txs
|
|
643
|
+
await this.#deletedPool.finalizeBlock(blockNumber);
|
|
598
644
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
645
|
+
// Step 5: Archive mined txs
|
|
646
|
+
if (txsToArchive.length > 0) {
|
|
647
|
+
await this.#archive.archiveTxs(txsToArchive);
|
|
648
|
+
}
|
|
649
|
+
});
|
|
603
650
|
|
|
604
651
|
if (minedTxsToFinalize.length > 0) {
|
|
605
652
|
this.#log.info(`Finalized ${minedTxsToFinalize.length} mined txs from blocks up to ${blockNumber}`, {
|
|
@@ -744,9 +791,10 @@ export class TxPoolV2Impl {
|
|
|
744
791
|
tx: Tx,
|
|
745
792
|
state: 'pending' | { protected: SlotNumber } | { mined: L2BlockId },
|
|
746
793
|
opts: { source?: string } = {},
|
|
794
|
+
precomputedMeta?: TxMetaData,
|
|
747
795
|
): Promise<TxMetaData> {
|
|
748
796
|
const txHashStr = tx.getTxHash().toString();
|
|
749
|
-
const meta = await buildTxMetaData(tx);
|
|
797
|
+
const meta = precomputedMeta ?? (await buildTxMetaData(tx));
|
|
750
798
|
meta.receivedAt = this.#dateProvider.now();
|
|
751
799
|
|
|
752
800
|
await this.#txsDB.set(txHashStr, tx.toBuffer());
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
-
import type { BlockProposal, P2PValidator } from '@aztec/stdlib/p2p';
|
|
2
|
+
import type { BlockProposal, P2PValidator, ValidationResult } from '@aztec/stdlib/p2p';
|
|
3
3
|
|
|
4
4
|
import { ProposalValidator } from '../proposal_validator/proposal_validator.js';
|
|
5
5
|
|
|
6
|
-
export class BlockProposalValidator
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export class BlockProposalValidator implements P2PValidator<BlockProposal> {
|
|
7
|
+
private proposalValidator: ProposalValidator;
|
|
8
|
+
|
|
9
|
+
constructor(epochCache: EpochCacheInterface, opts: { txsPermitted: boolean; maxTxsPerBlock?: number }) {
|
|
10
|
+
this.proposalValidator = new ProposalValidator(epochCache, opts, 'p2p:block_proposal_validator');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async validate(proposal: BlockProposal): Promise<ValidationResult> {
|
|
14
|
+
const headerResult = await this.proposalValidator.validate(proposal);
|
|
15
|
+
if (headerResult.result !== 'accept') {
|
|
16
|
+
return headerResult;
|
|
17
|
+
}
|
|
18
|
+
return this.proposalValidator.validateTxs(proposal);
|
|
9
19
|
}
|
|
10
20
|
}
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import type { EpochCacheInterface } from '@aztec/epoch-cache';
|
|
2
|
-
import type { CheckpointProposal, P2PValidator } from '@aztec/stdlib/p2p';
|
|
2
|
+
import type { CheckpointProposal, P2PValidator, ValidationResult } from '@aztec/stdlib/p2p';
|
|
3
3
|
|
|
4
4
|
import { ProposalValidator } from '../proposal_validator/proposal_validator.js';
|
|
5
5
|
|
|
6
|
-
export class CheckpointProposalValidator
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
export class CheckpointProposalValidator implements P2PValidator<CheckpointProposal> {
|
|
7
|
+
private proposalValidator: ProposalValidator;
|
|
8
|
+
|
|
9
|
+
constructor(epochCache: EpochCacheInterface, opts: { txsPermitted: boolean; maxTxsPerBlock?: number }) {
|
|
10
|
+
this.proposalValidator = new ProposalValidator(epochCache, opts, 'p2p:checkpoint_proposal_validator');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async validate(proposal: CheckpointProposal): Promise<ValidationResult> {
|
|
14
|
+
const headerResult = await this.proposalValidator.validate(proposal);
|
|
15
|
+
if (headerResult.result !== 'accept') {
|
|
16
|
+
return headerResult;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const blockProposal = proposal.getBlockProposal();
|
|
20
|
+
if (blockProposal) {
|
|
21
|
+
return this.proposalValidator.validateTxs(blockProposal);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return { result: 'accept' };
|
|
12
25
|
}
|
|
13
26
|
}
|