@aztec/p2p 0.0.1-commit.c0b82b2 → 0.0.1-commit.c2eed6949
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -3
- package/dest/client/factory.d.ts +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +22 -9
- package/dest/client/p2p_client.d.ts +1 -1
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +22 -34
- package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +3 -3
- package/dest/config.d.ts +32 -11
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +86 -32
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +8 -4
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
- 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/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +2 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +2 -2
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +4 -4
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +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 +3 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +2 -1
- 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/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/interfaces.d.ts +9 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
- package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +25 -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 +33 -10
- 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 -43
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +4 -2
- 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 +6 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -1
- 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 +24 -6
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +5 -4
- package/dest/msg_validators/clock_tolerance.d.ts +1 -1
- package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
- package/dest/msg_validators/clock_tolerance.js +4 -3
- 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 +53 -41
- 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/contract_instance_validator.d.ts +9 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +35 -2
- package/dest/msg_validators/tx_validator/factory.d.ts +23 -4
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +36 -10
- 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 +13 -4
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +39 -9
- package/dest/msg_validators/tx_validator/index.d.ts +2 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +1 -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/phases_validator.d.ts +22 -2
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/phases_validator.js +72 -24
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +4 -2
- package/dest/services/encoding.d.ts +5 -1
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +7 -1
- package/dest/services/libp2p/libp2p_service.d.ts +7 -9
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +166 -72
- 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 +6 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +11 -8
- 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 +69 -65
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts +3 -2
- package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +5 -4
- package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/missing_txs.js +13 -7
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +3 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
- package/dest/services/reqresp/batch-tx-requester/peer_collection.js +3 -0
- 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 +17 -9
- package/dest/services/service.d.ts +7 -1
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.d.ts +1 -4
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
- package/dest/services/tx_collection/fast_tx_collection.js +57 -73
- package/dest/services/tx_collection/proposal_tx_collector.d.ts +6 -7
- package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
- package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
- package/dest/services/tx_collection/request_tracker.d.ts +53 -0
- package/dest/services/tx_collection/request_tracker.d.ts.map +1 -0
- package/dest/services/tx_collection/request_tracker.js +84 -0
- package/dest/services/tx_collection/slow_tx_collection.js +1 -1
- package/dest/services/tx_collection/tx_collection.d.ts +3 -6
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.d.ts +6 -1
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
- package/dest/test-helpers/mock-pubsub.js +9 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.d.ts +1 -1
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +22 -3
- package/dest/testbench/p2p_client_testbench_worker.js +5 -4
- 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 +9 -4
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +2 -9
- package/package.json +14 -14
- package/src/client/factory.ts +37 -13
- package/src/client/p2p_client.ts +22 -34
- package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +4 -6
- package/src/config.ts +124 -34
- package/src/mem_pools/attestation_pool/attestation_pool.ts +8 -7
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
- package/src/mem_pools/instrumentation.ts +17 -13
- package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +2 -1
- package/src/mem_pools/tx_pool/priority.ts +4 -4
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +3 -1
- 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 +2 -1
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +11 -1
- 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/interfaces.ts +9 -4
- package/src/mem_pools/tx_pool_v2/tx_metadata.ts +52 -12
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +29 -43
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +16 -1
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +28 -6
- package/src/msg_validators/attestation_validator/README.md +49 -0
- package/src/msg_validators/attestation_validator/attestation_validator.ts +5 -4
- package/src/msg_validators/clock_tolerance.ts +4 -3
- package/src/msg_validators/proposal_validator/README.md +123 -0
- 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 +69 -45
- package/src/msg_validators/tx_validator/README.md +5 -1
- 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/contract_instance_validator.ts +56 -0
- package/src/msg_validators/tx_validator/data_validator.ts +42 -1
- package/src/msg_validators/tx_validator/factory.ts +43 -3
- package/src/msg_validators/tx_validator/fee_payer_balance.ts +6 -2
- package/src/msg_validators/tx_validator/gas_validator.ts +41 -8
- package/src/msg_validators/tx_validator/index.ts +1 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +12 -4
- package/src/msg_validators/tx_validator/phases_validator.ts +82 -27
- package/src/services/discv5/discV5_service.ts +4 -2
- package/src/services/encoding.ts +9 -1
- package/src/services/libp2p/libp2p_service.ts +164 -80
- package/src/services/peer-manager/metrics.ts +7 -0
- package/src/services/peer-manager/peer_manager.ts +7 -3
- package/src/services/reqresp/README.md +229 -0
- package/src/services/reqresp/batch-tx-requester/README.md +46 -7
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +64 -69
- package/src/services/reqresp/batch-tx-requester/interface.ts +2 -1
- package/src/services/reqresp/batch-tx-requester/missing_txs.ts +13 -6
- package/src/services/reqresp/batch-tx-requester/peer_collection.ts +5 -0
- package/src/services/reqresp/reqresp.ts +19 -11
- package/src/services/service.ts +7 -0
- package/src/services/tx_collection/fast_tx_collection.ts +57 -83
- package/src/services/tx_collection/proposal_tx_collector.ts +8 -13
- package/src/services/tx_collection/request_tracker.ts +127 -0
- package/src/services/tx_collection/slow_tx_collection.ts +1 -1
- package/src/services/tx_collection/tx_collection.ts +3 -5
- package/src/test-helpers/make-test-p2p-clients.ts +1 -1
- package/src/test-helpers/mock-pubsub.ts +9 -0
- package/src/test-helpers/reqresp-nodes.ts +1 -1
- package/src/test-helpers/testbench-utils.ts +29 -3
- package/src/testbench/p2p_client_testbench_worker.ts +5 -6
- package/src/testbench/worker_client_manager.ts +13 -5
- package/src/util.ts +9 -13
- 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/dest/services/tx_collection/missing_txs_tracker.d.ts +0 -32
- package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +0 -1
- package/dest/services/tx_collection/missing_txs_tracker.js +0 -27
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +0 -230
- package/src/services/tx_collection/missing_txs_tracker.ts +0 -52
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { ContractInstancePublishedEvent } from '@aztec/protocol-contracts/instance-registry';
|
|
3
|
+
import { computeContractAddressFromInstance } from '@aztec/stdlib/contract';
|
|
4
|
+
import {
|
|
5
|
+
TX_ERROR_INCORRECT_CONTRACT_ADDRESS,
|
|
6
|
+
TX_ERROR_MALFORMED_CONTRACT_INSTANCE_LOG,
|
|
7
|
+
type Tx,
|
|
8
|
+
type TxValidationResult,
|
|
9
|
+
type TxValidator,
|
|
10
|
+
} from '@aztec/stdlib/tx';
|
|
11
|
+
|
|
12
|
+
/** Validates that contract instance deployment logs contain correct addresses. */
|
|
13
|
+
export class ContractInstanceTxValidator implements TxValidator<Tx> {
|
|
14
|
+
#log: Logger;
|
|
15
|
+
|
|
16
|
+
constructor(bindings?: LoggerBindings) {
|
|
17
|
+
this.#log = createLogger('p2p:tx_validator:contract_instance', bindings);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
21
|
+
const reason = await this.#hasCorrectContractInstanceAddresses(tx);
|
|
22
|
+
return reason ? { result: 'invalid', reason: [reason] } : { result: 'valid' };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async #hasCorrectContractInstanceAddresses(tx: Tx): Promise<string | undefined> {
|
|
26
|
+
const privateLogs = tx.data.getNonEmptyPrivateLogs();
|
|
27
|
+
for (const log of privateLogs) {
|
|
28
|
+
if (!ContractInstancePublishedEvent.isContractInstancePublishedEvent(log)) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let event;
|
|
33
|
+
try {
|
|
34
|
+
event = ContractInstancePublishedEvent.fromLog(log);
|
|
35
|
+
} catch (e) {
|
|
36
|
+
this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to parse contract instance event: ${e}`);
|
|
37
|
+
return TX_ERROR_MALFORMED_CONTRACT_INSTANCE_LOG;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const instance = event.toContractInstance();
|
|
42
|
+
const computedAddress = await computeContractAddressFromInstance(instance);
|
|
43
|
+
if (!computedAddress.equals(instance.address)) {
|
|
44
|
+
this.#log.warn(
|
|
45
|
+
`Rejecting tx ${tx.getTxHash()}: contract instance address mismatch. Claimed ${instance.address}, computed ${computedAddress}`,
|
|
46
|
+
);
|
|
47
|
+
return TX_ERROR_INCORRECT_CONTRACT_ADDRESS;
|
|
48
|
+
}
|
|
49
|
+
} catch (e) {
|
|
50
|
+
this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to compute contract instance address: ${e}`);
|
|
51
|
+
return TX_ERROR_MALFORMED_CONTRACT_INSTANCE_LOG;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS } from '@aztec/constants';
|
|
2
2
|
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
|
|
4
|
+
import { computeContractClassId } from '@aztec/stdlib/contract';
|
|
3
5
|
import { computeCalldataHash } from '@aztec/stdlib/hash';
|
|
4
6
|
import {
|
|
5
7
|
TX_ERROR_CALLDATA_COUNT_MISMATCH,
|
|
@@ -9,7 +11,9 @@ import {
|
|
|
9
11
|
TX_ERROR_CONTRACT_CLASS_LOG_LENGTH,
|
|
10
12
|
TX_ERROR_CONTRACT_CLASS_LOG_SORTING,
|
|
11
13
|
TX_ERROR_INCORRECT_CALLDATA,
|
|
14
|
+
TX_ERROR_INCORRECT_CONTRACT_CLASS_ID,
|
|
12
15
|
TX_ERROR_INCORRECT_HASH,
|
|
16
|
+
TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG,
|
|
13
17
|
Tx,
|
|
14
18
|
type TxValidationResult,
|
|
15
19
|
type TxValidator,
|
|
@@ -26,7 +30,8 @@ export class DataTxValidator implements TxValidator<Tx> {
|
|
|
26
30
|
const reason =
|
|
27
31
|
(await this.#hasCorrectHash(tx)) ??
|
|
28
32
|
(await this.#hasCorrectCalldata(tx)) ??
|
|
29
|
-
(await this.#hasCorrectContractClassLogs(tx))
|
|
33
|
+
(await this.#hasCorrectContractClassLogs(tx)) ??
|
|
34
|
+
(await this.#hasCorrectContractClassIds(tx));
|
|
30
35
|
return reason ? { result: 'invalid', reason: [reason] } : { result: 'valid' };
|
|
31
36
|
}
|
|
32
37
|
|
|
@@ -127,4 +132,40 @@ export class DataTxValidator implements TxValidator<Tx> {
|
|
|
127
132
|
|
|
128
133
|
return undefined;
|
|
129
134
|
}
|
|
135
|
+
|
|
136
|
+
async #hasCorrectContractClassIds(tx: Tx): Promise<string | undefined> {
|
|
137
|
+
const contractClassLogs = tx.getContractClassLogs();
|
|
138
|
+
for (const log of contractClassLogs) {
|
|
139
|
+
if (!ContractClassPublishedEvent.isContractClassPublishedEvent(log)) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let event;
|
|
144
|
+
try {
|
|
145
|
+
event = ContractClassPublishedEvent.fromLog(log);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to parse contract class event: ${e}`);
|
|
148
|
+
return TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
const { publicBytecodeCommitment } = await event.toContractClassPublicWithBytecodeCommitment();
|
|
153
|
+
const computedClassId = await computeContractClassId({
|
|
154
|
+
artifactHash: event.artifactHash,
|
|
155
|
+
privateFunctionsRoot: event.privateFunctionsRoot,
|
|
156
|
+
publicBytecodeCommitment,
|
|
157
|
+
});
|
|
158
|
+
if (!computedClassId.equals(event.contractClassId)) {
|
|
159
|
+
this.#log.warn(
|
|
160
|
+
`Rejecting tx ${tx.getTxHash()}: contract class id mismatch. Claimed ${event.contractClassId}, computed ${computedClassId}`,
|
|
161
|
+
);
|
|
162
|
+
return TX_ERROR_INCORRECT_CONTRACT_CLASS_ID;
|
|
163
|
+
}
|
|
164
|
+
} catch (e) {
|
|
165
|
+
this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to compute contract class id: ${e}`);
|
|
166
|
+
return TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
130
171
|
}
|
|
@@ -53,12 +53,13 @@ import type { TxMetaData } from '../../mem_pools/tx_pool_v2/tx_metadata.js';
|
|
|
53
53
|
import { AggregateTxValidator } from './aggregate_tx_validator.js';
|
|
54
54
|
import { ArchiveCache } from './archive_cache.js';
|
|
55
55
|
import { type ArchiveSource, BlockHeaderTxValidator } from './block_header_validator.js';
|
|
56
|
+
import { ContractInstanceTxValidator } from './contract_instance_validator.js';
|
|
56
57
|
import { DataTxValidator } from './data_validator.js';
|
|
57
58
|
import { DoubleSpendTxValidator, type NullifierSource } from './double_spend_validator.js';
|
|
58
59
|
import { GasLimitsValidator, GasTxValidator } from './gas_validator.js';
|
|
59
60
|
import { MetadataTxValidator } from './metadata_validator.js';
|
|
60
61
|
import { NullifierCache } from './nullifier_cache.js';
|
|
61
|
-
import { PhasesTxValidator } from './phases_validator.js';
|
|
62
|
+
import { AllowedSetupCallsMetaValidator, PhasesTxValidator } from './phases_validator.js';
|
|
62
63
|
import { SizeTxValidator } from './size_validator.js';
|
|
63
64
|
import { TimestampTxValidator } from './timestamp_validator.js';
|
|
64
65
|
import { TxPermittedValidator } from './tx_permitted_validator.js';
|
|
@@ -97,6 +98,7 @@ export function createFirstStageTxValidationsForGossipedTransactions(
|
|
|
97
98
|
txsPermitted: boolean,
|
|
98
99
|
allowedInSetup: AllowedElement[] = [],
|
|
99
100
|
bindings?: LoggerBindings,
|
|
101
|
+
gasLimitOpts?: { rollupManaLimit?: number; maxBlockL2Gas?: number; maxBlockDAGas?: number },
|
|
100
102
|
): Record<string, TransactionValidator> {
|
|
101
103
|
const merkleTree = worldStateSynchronizer.getCommitted();
|
|
102
104
|
|
|
@@ -158,6 +160,7 @@ export function createFirstStageTxValidationsForGossipedTransactions(
|
|
|
158
160
|
ProtocolContractAddress.FeeJuice,
|
|
159
161
|
gasFees,
|
|
160
162
|
bindings,
|
|
163
|
+
gasLimitOpts,
|
|
161
164
|
),
|
|
162
165
|
severity: PeerErrorSeverity.MidToleranceError,
|
|
163
166
|
},
|
|
@@ -165,6 +168,10 @@ export function createFirstStageTxValidationsForGossipedTransactions(
|
|
|
165
168
|
validator: new DataTxValidator(bindings),
|
|
166
169
|
severity: PeerErrorSeverity.MidToleranceError,
|
|
167
170
|
},
|
|
171
|
+
contractInstanceValidator: {
|
|
172
|
+
validator: new ContractInstanceTxValidator(bindings),
|
|
173
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
174
|
+
},
|
|
168
175
|
};
|
|
169
176
|
}
|
|
170
177
|
|
|
@@ -216,6 +223,7 @@ function createTxValidatorForMinimumTxIntegrityChecks(
|
|
|
216
223
|
),
|
|
217
224
|
new SizeTxValidator(bindings),
|
|
218
225
|
new DataTxValidator(bindings),
|
|
226
|
+
new ContractInstanceTxValidator(bindings),
|
|
219
227
|
new TxProofValidator(verifier, bindings),
|
|
220
228
|
);
|
|
221
229
|
}
|
|
@@ -278,6 +286,9 @@ export function createTxValidatorForAcceptingTxsOverRPC(
|
|
|
278
286
|
timestamp,
|
|
279
287
|
blockNumber,
|
|
280
288
|
txsPermitted,
|
|
289
|
+
rollupManaLimit,
|
|
290
|
+
maxBlockL2Gas,
|
|
291
|
+
maxBlockDAGas,
|
|
281
292
|
}: {
|
|
282
293
|
l1ChainId: number;
|
|
283
294
|
rollupVersion: number;
|
|
@@ -287,6 +298,9 @@ export function createTxValidatorForAcceptingTxsOverRPC(
|
|
|
287
298
|
timestamp: UInt64;
|
|
288
299
|
blockNumber: BlockNumber;
|
|
289
300
|
txsPermitted: boolean;
|
|
301
|
+
rollupManaLimit: number;
|
|
302
|
+
maxBlockL2Gas?: number;
|
|
303
|
+
maxBlockDAGas?: number;
|
|
290
304
|
},
|
|
291
305
|
bindings?: LoggerBindings,
|
|
292
306
|
): TxValidator<Tx> {
|
|
@@ -313,11 +327,16 @@ export function createTxValidatorForAcceptingTxsOverRPC(
|
|
|
313
327
|
new BlockHeaderTxValidator(new ArchiveCache(db), bindings),
|
|
314
328
|
new DoubleSpendTxValidator(new NullifierCache(db), bindings),
|
|
315
329
|
new DataTxValidator(bindings),
|
|
330
|
+
new ContractInstanceTxValidator(bindings),
|
|
316
331
|
];
|
|
317
332
|
|
|
318
333
|
if (!skipFeeEnforcement) {
|
|
319
334
|
validators.push(
|
|
320
|
-
new GasTxValidator(new DatabasePublicStateSource(db), ProtocolContractAddress.FeeJuice, gasFees, bindings
|
|
335
|
+
new GasTxValidator(new DatabasePublicStateSource(db), ProtocolContractAddress.FeeJuice, gasFees, bindings, {
|
|
336
|
+
rollupManaLimit,
|
|
337
|
+
maxBlockL2Gas,
|
|
338
|
+
maxBlockDAGas,
|
|
339
|
+
}),
|
|
321
340
|
);
|
|
322
341
|
}
|
|
323
342
|
|
|
@@ -403,6 +422,7 @@ export async function createTxValidatorForTransactionsEnteringPendingTxPool(
|
|
|
403
422
|
worldStateSynchronizer: WorldStateSynchronizer,
|
|
404
423
|
timestamp: bigint,
|
|
405
424
|
blockNumber: BlockNumber,
|
|
425
|
+
gasLimitOpts: { rollupManaLimit?: number; maxBlockL2Gas?: number; maxBlockDAGas?: number },
|
|
406
426
|
bindings?: LoggerBindings,
|
|
407
427
|
): Promise<TxValidator<TxMetaData>> {
|
|
408
428
|
await worldStateSynchronizer.syncImmediate();
|
|
@@ -419,9 +439,29 @@ export async function createTxValidatorForTransactionsEnteringPendingTxPool(
|
|
|
419
439
|
},
|
|
420
440
|
};
|
|
421
441
|
return new AggregateTxValidator<TxMetaData>(
|
|
422
|
-
new GasLimitsValidator<TxMetaData>(bindings),
|
|
442
|
+
new GasLimitsValidator<TxMetaData>({ ...gasLimitOpts, bindings }),
|
|
423
443
|
new TimestampTxValidator<TxMetaData>({ timestamp, blockNumber }, bindings),
|
|
424
444
|
new DoubleSpendTxValidator<TxMetaData>(nullifierSource, bindings),
|
|
425
445
|
new BlockHeaderTxValidator<TxMetaData>(archiveSource, bindings),
|
|
446
|
+
new AllowedSetupCallsMetaValidator<TxMetaData>(bindings),
|
|
426
447
|
);
|
|
427
448
|
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Creates a function that checks whether a tx's setup-phase calls are on the allow list.
|
|
452
|
+
*
|
|
453
|
+
* Uses the `PhasesTxValidator` on the full Tx. The result is stored as a boolean
|
|
454
|
+
* flag in `TxMetaData.allowedSetupCalls` at receipt time, so the pending pool
|
|
455
|
+
* migration validator can check it without needing the full Tx or its dependencies.
|
|
456
|
+
*/
|
|
457
|
+
export function createCheckAllowedSetupCalls(
|
|
458
|
+
contractDataSource: ContractDataSource,
|
|
459
|
+
setupAllowList: AllowedElement[],
|
|
460
|
+
getTimestamp: () => UInt64,
|
|
461
|
+
): (tx: Tx) => Promise<boolean> {
|
|
462
|
+
return async (tx: Tx) => {
|
|
463
|
+
const validator = new PhasesTxValidator(contractDataSource, setupAllowList, getTimestamp());
|
|
464
|
+
const result = await validator.validateTx(tx);
|
|
465
|
+
return result.result === 'valid';
|
|
466
|
+
};
|
|
467
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { FeeJuiceArtifact } from '@aztec/protocol-contracts/fee-juice';
|
|
1
2
|
import { getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
2
|
-
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
|
+
import { FunctionSelector, getAllFunctionAbis } from '@aztec/stdlib/abi';
|
|
3
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
5
|
import { type Tx, TxExecutionPhase } from '@aztec/stdlib/tx';
|
|
5
6
|
|
|
@@ -8,7 +9,10 @@ export type FeePayerBalanceDelta = {
|
|
|
8
9
|
claimAmount: bigint;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
const increasePublicBalanceSelectorPromise =
|
|
12
|
+
const increasePublicBalanceSelectorPromise = (() => {
|
|
13
|
+
const fn = getAllFunctionAbis(FeeJuiceArtifact).find(f => f.name === '_increase_public_balance')!;
|
|
14
|
+
return FunctionSelector.fromNameAndParameters(fn.name, fn.parameters);
|
|
15
|
+
})();
|
|
12
16
|
|
|
13
17
|
export function getTxFeeLimit(tx: Tx): bigint {
|
|
14
18
|
return tx.data.constants.txContext.gasSettings.getFeeLimit().toBigInt();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT,
|
|
2
3
|
MAX_PROCESSABLE_L2_GAS,
|
|
3
4
|
PRIVATE_TX_L2_GAS_OVERHEAD,
|
|
4
5
|
PUBLIC_TX_L2_GAS_OVERHEAD,
|
|
@@ -49,16 +50,31 @@ export interface HasGasLimitData {
|
|
|
49
50
|
*/
|
|
50
51
|
export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidator<T> {
|
|
51
52
|
#log: Logger;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
#effectiveMaxL2Gas: number;
|
|
54
|
+
#effectiveMaxDAGas: number;
|
|
55
|
+
#rollupManaLimit: number;
|
|
56
|
+
#maxBlockL2Gas: number;
|
|
57
|
+
#maxBlockDAGas: number;
|
|
58
|
+
|
|
59
|
+
constructor(opts?: {
|
|
60
|
+
rollupManaLimit?: number;
|
|
61
|
+
maxBlockL2Gas?: number;
|
|
62
|
+
maxBlockDAGas?: number;
|
|
63
|
+
bindings?: LoggerBindings;
|
|
64
|
+
}) {
|
|
65
|
+
this.#log = createLogger('sequencer:tx_validator:tx_gas', opts?.bindings);
|
|
66
|
+
this.#rollupManaLimit = opts?.rollupManaLimit ?? Infinity;
|
|
67
|
+
this.#maxBlockL2Gas = opts?.maxBlockL2Gas ?? Infinity;
|
|
68
|
+
this.#maxBlockDAGas = opts?.maxBlockDAGas ?? Infinity;
|
|
69
|
+
this.#effectiveMaxL2Gas = Math.min(MAX_PROCESSABLE_L2_GAS, this.#rollupManaLimit, this.#maxBlockL2Gas);
|
|
70
|
+
this.#effectiveMaxDAGas = Math.min(MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT, this.#maxBlockDAGas);
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
validateTx(tx: T): Promise<TxValidationResult> {
|
|
58
74
|
return Promise.resolve(this.validateGasLimit(tx));
|
|
59
75
|
}
|
|
60
76
|
|
|
61
|
-
/** Checks gas limits are >= fixed minimums and <=
|
|
77
|
+
/** Checks gas limits are >= fixed minimums and <= effective max gas (L2 and DA). */
|
|
62
78
|
validateGasLimit(tx: T): TxValidationResult {
|
|
63
79
|
const gasLimits = tx.data.constants.txContext.gasSettings.gasLimits;
|
|
64
80
|
const minGasLimits = new Gas(
|
|
@@ -74,10 +90,21 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
|
|
|
74
90
|
return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_GAS_LIMIT] };
|
|
75
91
|
}
|
|
76
92
|
|
|
77
|
-
if (gasLimits.l2Gas >
|
|
78
|
-
this.#log.verbose(`Rejecting transaction due to the gas limit
|
|
93
|
+
if (gasLimits.l2Gas > this.#effectiveMaxL2Gas) {
|
|
94
|
+
this.#log.verbose(`Rejecting transaction due to the L2 gas limit being higher than the effective maximum`, {
|
|
79
95
|
gasLimits,
|
|
80
|
-
|
|
96
|
+
effectiveMaxL2Gas: this.#effectiveMaxL2Gas,
|
|
97
|
+
rollupManaLimit: this.#rollupManaLimit,
|
|
98
|
+
maxBlockL2Gas: this.#maxBlockL2Gas,
|
|
99
|
+
});
|
|
100
|
+
return { result: 'invalid', reason: [TX_ERROR_GAS_LIMIT_TOO_HIGH] };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (gasLimits.daGas > this.#effectiveMaxDAGas) {
|
|
104
|
+
this.#log.verbose(`Rejecting transaction due to the DA gas limit being higher than the effective maximum`, {
|
|
105
|
+
gasLimits,
|
|
106
|
+
effectiveMaxDAGas: this.#effectiveMaxDAGas,
|
|
107
|
+
maxBlockDAGas: this.#maxBlockDAGas,
|
|
81
108
|
});
|
|
82
109
|
return { result: 'invalid', reason: [TX_ERROR_GAS_LIMIT_TOO_HIGH] };
|
|
83
110
|
}
|
|
@@ -106,21 +133,27 @@ export class GasTxValidator implements TxValidator<Tx> {
|
|
|
106
133
|
#publicDataSource: PublicStateSource;
|
|
107
134
|
#feeJuiceAddress: AztecAddress;
|
|
108
135
|
#gasFees: GasFees;
|
|
136
|
+
#gasLimitOpts?: { rollupManaLimit?: number; maxBlockL2Gas?: number; maxBlockDAGas?: number };
|
|
109
137
|
|
|
110
138
|
constructor(
|
|
111
139
|
publicDataSource: PublicStateSource,
|
|
112
140
|
feeJuiceAddress: AztecAddress,
|
|
113
141
|
gasFees: GasFees,
|
|
114
142
|
private bindings?: LoggerBindings,
|
|
143
|
+
opts?: { rollupManaLimit?: number; maxBlockL2Gas?: number; maxBlockDAGas?: number },
|
|
115
144
|
) {
|
|
116
145
|
this.#log = createLogger('sequencer:tx_validator:tx_gas', bindings);
|
|
117
146
|
this.#publicDataSource = publicDataSource;
|
|
118
147
|
this.#feeJuiceAddress = feeJuiceAddress;
|
|
119
148
|
this.#gasFees = gasFees;
|
|
149
|
+
this.#gasLimitOpts = opts;
|
|
120
150
|
}
|
|
121
151
|
|
|
122
152
|
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
123
|
-
const gasLimitValidation = new GasLimitsValidator(
|
|
153
|
+
const gasLimitValidation = new GasLimitsValidator({
|
|
154
|
+
...this.#gasLimitOpts,
|
|
155
|
+
bindings: this.bindings,
|
|
156
|
+
}).validateGasLimit(tx);
|
|
124
157
|
if (gasLimitValidation.result === 'invalid') {
|
|
125
158
|
return Promise.resolve(gasLimitValidation);
|
|
126
159
|
}
|
|
@@ -8,6 +8,7 @@ export * from './gas_validator.js';
|
|
|
8
8
|
export * from './phases_validator.js';
|
|
9
9
|
export * from './test_utils.js';
|
|
10
10
|
export * from './allowed_public_setup.js';
|
|
11
|
+
export * from './allowed_setup_helpers.js';
|
|
11
12
|
export * from './archive_cache.js';
|
|
12
13
|
export * from './tx_permitted_validator.js';
|
|
13
14
|
export * from './timestamp_validator.js';
|
|
@@ -28,16 +28,24 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
28
28
|
validateTx(tx: T): Promise<TxValidationResult> {
|
|
29
29
|
const errors = [];
|
|
30
30
|
if (!this.#hasCorrectL1ChainId(tx)) {
|
|
31
|
-
errors.push(
|
|
31
|
+
errors.push(
|
|
32
|
+
`${TX_ERROR_INCORRECT_L1_CHAIN_ID} (tx: ${tx.data.constants.txContext.chainId.toNumber()}, expected: ${this.values.l1ChainId.toNumber()})`,
|
|
33
|
+
);
|
|
32
34
|
}
|
|
33
35
|
if (!this.#hasCorrectRollupVersion(tx)) {
|
|
34
|
-
errors.push(
|
|
36
|
+
errors.push(
|
|
37
|
+
`${TX_ERROR_INCORRECT_ROLLUP_VERSION} (tx: ${tx.data.constants.txContext.version.toNumber()}, expected: ${this.values.rollupVersion.toNumber()})`,
|
|
38
|
+
);
|
|
35
39
|
}
|
|
36
40
|
if (!this.#hasCorrectVkTreeRoot(tx)) {
|
|
37
|
-
errors.push(
|
|
41
|
+
errors.push(
|
|
42
|
+
`${TX_ERROR_INCORRECT_VK_TREE_ROOT} (tx: ${tx.data.constants.vkTreeRoot.toString()}, expected: ${this.values.vkTreeRoot.toString()})`,
|
|
43
|
+
);
|
|
38
44
|
}
|
|
39
45
|
if (!this.#hasCorrectprotocolContractsHash(tx)) {
|
|
40
|
-
errors.push(
|
|
46
|
+
errors.push(
|
|
47
|
+
`${TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH} (tx: ${tx.data.constants.protocolContractsHash.toString()}, expected: ${this.values.protocolContractsHash.toString()})`,
|
|
48
|
+
);
|
|
41
49
|
}
|
|
42
50
|
return Promise.resolve(errors.length > 0 ? { result: 'invalid', reason: errors } : { result: 'valid' });
|
|
43
51
|
}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
import { NULL_MSG_SENDER_CONTRACT_ADDRESS } from '@aztec/constants';
|
|
1
2
|
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
2
3
|
import { PublicContractsDB, getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
4
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
5
|
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
4
6
|
import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
|
|
5
7
|
import {
|
|
6
8
|
type PublicCallRequestWithCalldata,
|
|
7
9
|
TX_ERROR_DURING_VALIDATION,
|
|
8
10
|
TX_ERROR_SETUP_FUNCTION_NOT_ALLOWED,
|
|
11
|
+
TX_ERROR_SETUP_FUNCTION_UNKNOWN_CONTRACT,
|
|
12
|
+
TX_ERROR_SETUP_NULL_MSG_SENDER,
|
|
13
|
+
TX_ERROR_SETUP_ONLY_SELF_WRONG_SENDER,
|
|
14
|
+
TX_ERROR_SETUP_WRONG_CALLDATA_LENGTH,
|
|
9
15
|
Tx,
|
|
10
16
|
TxExecutionPhase,
|
|
11
17
|
type TxValidationResult,
|
|
@@ -34,7 +40,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
34
40
|
// which are needed for public FPC flows, but fail if the account contract hasnt been deployed yet,
|
|
35
41
|
// which is what we're trying to do as part of the current txs.
|
|
36
42
|
// We only need to create/revert checkpoint here because of this addNewContracts call.
|
|
37
|
-
|
|
43
|
+
this.contractsDB.addNewContracts(tx);
|
|
38
44
|
|
|
39
45
|
if (!tx.data.forPublic) {
|
|
40
46
|
this.#log.debug(
|
|
@@ -45,7 +51,8 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
45
51
|
|
|
46
52
|
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
47
53
|
for (const setupFn of setupFns) {
|
|
48
|
-
|
|
54
|
+
const rejectionReason = await this.checkAllowList(setupFn, this.setupAllowList);
|
|
55
|
+
if (rejectionReason) {
|
|
49
56
|
this.#log.verbose(
|
|
50
57
|
`Rejecting tx ${tx.getTxHash().toString()} because it calls setup function not on allow list: ${
|
|
51
58
|
setupFn.request.contractAddress
|
|
@@ -53,7 +60,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
53
60
|
{ allowList: this.setupAllowList },
|
|
54
61
|
);
|
|
55
62
|
|
|
56
|
-
return { result: 'invalid', reason: [
|
|
63
|
+
return { result: 'invalid', reason: [rejectionReason] };
|
|
57
64
|
}
|
|
58
65
|
}
|
|
59
66
|
|
|
@@ -66,53 +73,101 @@ export class PhasesTxValidator implements TxValidator<Tx> {
|
|
|
66
73
|
}
|
|
67
74
|
}
|
|
68
75
|
|
|
69
|
-
|
|
76
|
+
/** Returns a rejection reason if the call is not on the allow list, or undefined if it is allowed. */
|
|
77
|
+
private async checkAllowList(
|
|
70
78
|
publicCall: PublicCallRequestWithCalldata,
|
|
71
79
|
allowList: AllowedElement[],
|
|
72
|
-
): Promise<
|
|
80
|
+
): Promise<string | undefined> {
|
|
73
81
|
if (publicCall.isEmpty()) {
|
|
74
|
-
return
|
|
82
|
+
return undefined;
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
const contractAddress = publicCall.request.contractAddress;
|
|
78
86
|
const functionSelector = publicCall.functionSelector;
|
|
79
87
|
|
|
80
|
-
//
|
|
88
|
+
// Check address-based entries first since they don't require the contract class.
|
|
81
89
|
for (const entry of allowList) {
|
|
82
|
-
if ('address' in entry
|
|
83
|
-
if (contractAddress.equals(entry.address)) {
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if ('address' in entry && 'selector' in entry) {
|
|
90
|
+
if ('address' in entry) {
|
|
89
91
|
if (contractAddress.equals(entry.address) && entry.selector.equals(functionSelector)) {
|
|
90
|
-
|
|
92
|
+
if (entry.calldataLength !== undefined && publicCall.calldata.length !== entry.calldataLength) {
|
|
93
|
+
return TX_ERROR_SETUP_WRONG_CALLDATA_LENGTH;
|
|
94
|
+
}
|
|
95
|
+
if (entry.onlySelf && !publicCall.request.msgSender.equals(contractAddress)) {
|
|
96
|
+
return TX_ERROR_SETUP_ONLY_SELF_WRONG_SENDER;
|
|
97
|
+
}
|
|
98
|
+
if (
|
|
99
|
+
entry.rejectNullMsgSender &&
|
|
100
|
+
publicCall.request.msgSender.equals(AztecAddress.fromBigInt(NULL_MSG_SENDER_CONTRACT_ADDRESS))
|
|
101
|
+
) {
|
|
102
|
+
return TX_ERROR_SETUP_NULL_MSG_SENDER;
|
|
103
|
+
}
|
|
104
|
+
return undefined;
|
|
91
105
|
}
|
|
92
106
|
}
|
|
107
|
+
}
|
|
93
108
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
109
|
+
// Check class-based entries. Fetch the contract instance lazily (only once).
|
|
110
|
+
let contractClassId: undefined | { value: string | undefined };
|
|
111
|
+
for (const entry of allowList) {
|
|
112
|
+
if (!('classId' in entry)) {
|
|
113
|
+
continue;
|
|
98
114
|
}
|
|
99
115
|
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
116
|
+
if (contractClassId === undefined) {
|
|
117
|
+
const instance = await this.contractsDB.getContractInstance(contractAddress, this.timestamp);
|
|
118
|
+
contractClassId = { value: instance?.currentContractClassId.toString() };
|
|
119
|
+
if (!contractClassId.value) {
|
|
120
|
+
return TX_ERROR_SETUP_FUNCTION_UNKNOWN_CONTRACT;
|
|
103
121
|
}
|
|
104
122
|
}
|
|
105
123
|
|
|
106
|
-
if (
|
|
124
|
+
if (contractClassId.value === entry.classId.toString() && entry.selector.equals(functionSelector)) {
|
|
125
|
+
if (entry.calldataLength !== undefined && publicCall.calldata.length !== entry.calldataLength) {
|
|
126
|
+
return TX_ERROR_SETUP_WRONG_CALLDATA_LENGTH;
|
|
127
|
+
}
|
|
128
|
+
if (entry.onlySelf && !publicCall.request.msgSender.equals(contractAddress)) {
|
|
129
|
+
return TX_ERROR_SETUP_ONLY_SELF_WRONG_SENDER;
|
|
130
|
+
}
|
|
107
131
|
if (
|
|
108
|
-
|
|
109
|
-
|
|
132
|
+
entry.rejectNullMsgSender &&
|
|
133
|
+
publicCall.request.msgSender.equals(AztecAddress.fromBigInt(NULL_MSG_SENDER_CONTRACT_ADDRESS))
|
|
110
134
|
) {
|
|
111
|
-
return
|
|
135
|
+
return TX_ERROR_SETUP_NULL_MSG_SENDER;
|
|
112
136
|
}
|
|
137
|
+
return undefined;
|
|
113
138
|
}
|
|
114
139
|
}
|
|
115
140
|
|
|
116
|
-
return
|
|
141
|
+
return TX_ERROR_SETUP_FUNCTION_NOT_ALLOWED;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Structural interface for the allowed-setup-calls flag check. */
|
|
146
|
+
export interface HasAllowedSetupCallsData {
|
|
147
|
+
txHash: { toString(): string };
|
|
148
|
+
allowedSetupCalls: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Validates that a transaction's setup-phase calls were allowed at receipt time.
|
|
153
|
+
*
|
|
154
|
+
* Checks the precomputed `allowedSetupCalls` flag on TxMetaData. The flag is
|
|
155
|
+
* computed by running the PhasesTxValidator on the full Tx when it first enters
|
|
156
|
+
* the pool. This lightweight validator is used during pending pool migration to
|
|
157
|
+
* reject txs whose setup calls are not on the allow list.
|
|
158
|
+
*/
|
|
159
|
+
export class AllowedSetupCallsMetaValidator<T extends HasAllowedSetupCallsData> implements TxValidator<T> {
|
|
160
|
+
#log: Logger;
|
|
161
|
+
|
|
162
|
+
constructor(bindings?: LoggerBindings) {
|
|
163
|
+
this.#log = createLogger('sequencer:tx_validator:tx_phases_meta', bindings);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
validateTx(tx: T): Promise<TxValidationResult> {
|
|
167
|
+
if (!tx.allowedSetupCalls) {
|
|
168
|
+
this.#log.verbose(`Rejecting tx ${tx.txHash} because its setup calls are not on the allow list`);
|
|
169
|
+
return Promise.resolve({ result: 'invalid', reason: [TX_ERROR_SETUP_FUNCTION_NOT_ALLOWED] });
|
|
170
|
+
}
|
|
171
|
+
return Promise.resolve({ result: 'valid' });
|
|
117
172
|
}
|
|
118
173
|
}
|
|
@@ -96,7 +96,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
96
96
|
lookupTimeout: 2000,
|
|
97
97
|
requestTimeout: 2000,
|
|
98
98
|
allowUnverifiedSessions: true,
|
|
99
|
-
enrUpdate: !p2pIp
|
|
99
|
+
enrUpdate: config.queryForIp && !p2pIp, // Enable native ENR IP discovery when no static IP is configured
|
|
100
100
|
...configOverrides.config,
|
|
101
101
|
},
|
|
102
102
|
metricsRegistry,
|
|
@@ -129,9 +129,11 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
129
129
|
private onMultiaddrUpdated(m: Multiaddr) {
|
|
130
130
|
// We want to update our tcp port to match the udp port
|
|
131
131
|
// p2pBroadcastPort is optional on config, however it is set to default within the p2p client factory
|
|
132
|
-
const
|
|
132
|
+
const address = m.nodeAddress().address;
|
|
133
|
+
const multiAddrTcp = multiaddr(convertToMultiaddr(address, this.config.p2pBroadcastPort!, 'tcp'));
|
|
133
134
|
this.enr.setLocationMultiaddr(multiAddrTcp);
|
|
134
135
|
this.logger.info('Multiaddr updated', { multiaddr: multiAddrTcp.toString() });
|
|
136
|
+
this.emit('ip:changed', address);
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
public async start(): Promise<void> {
|
package/src/services/encoding.ts
CHANGED
|
@@ -9,6 +9,14 @@ import { webcrypto } from 'node:crypto';
|
|
|
9
9
|
import { compressSync, uncompressSync } from 'snappy';
|
|
10
10
|
import xxhashFactory from 'xxhash-wasm';
|
|
11
11
|
|
|
12
|
+
/** Thrown when a Snappy-compressed response exceeds the allowed decompressed size. */
|
|
13
|
+
export class OversizedSnappyResponseError extends Error {
|
|
14
|
+
constructor(decompressedSize: number, maxSizeKb: number) {
|
|
15
|
+
super(`Decompressed size ${decompressedSize} exceeds maximum allowed size of ${maxSizeKb}kb`);
|
|
16
|
+
this.name = 'OversizedSnappyResponseError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
// Load WASM
|
|
13
21
|
const xxhash = await xxhashFactory();
|
|
14
22
|
|
|
@@ -86,7 +94,7 @@ export class SnappyTransform implements DataTransform {
|
|
|
86
94
|
const { decompressedSize } = readSnappyPreamble(data);
|
|
87
95
|
if (decompressedSize > maxSizeKb * 1024) {
|
|
88
96
|
this.logger.warn(`Decompressed size ${decompressedSize} exceeds maximum allowed size of ${maxSizeKb}kb`);
|
|
89
|
-
throw new
|
|
97
|
+
throw new OversizedSnappyResponseError(decompressedSize, maxSizeKb);
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
return Buffer.from(uncompressSync(data, { asBuffer: true }));
|