@aztec/p2p 0.0.0-test.1 → 0.0.1-commit.1142ef1
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 +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +22 -9
- package/dest/client/factory.d.ts +15 -5
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +60 -25
- package/dest/client/index.d.ts +2 -1
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +1 -0
- package/dest/client/interface.d.ts +170 -0
- package/dest/client/interface.d.ts.map +1 -0
- package/dest/client/interface.js +9 -0
- package/dest/client/p2p_client.d.ts +75 -193
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +757 -228
- package/dest/config.d.ts +148 -125
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +180 -34
- package/dest/enr/generate-enr.d.ts +11 -3
- package/dest/enr/generate-enr.d.ts.map +1 -1
- package/dest/enr/generate-enr.js +27 -5
- package/dest/enr/index.d.ts +1 -1
- package/dest/errors/attestation-pool.error.d.ts +7 -0
- package/dest/errors/attestation-pool.error.d.ts.map +1 -0
- package/dest/errors/attestation-pool.error.js +12 -0
- package/dest/errors/reqresp.error.d.ts +1 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/index.d.ts +4 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +104 -25
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +288 -174
- package/dest/mem_pools/attestation_pool/index.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +29 -11
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +168 -62
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +24 -10
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +133 -82
- package/dest/mem_pools/attestation_pool/mocks.d.ts +232 -11
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +15 -20
- package/dest/mem_pools/index.d.ts +1 -1
- package/dest/mem_pools/instrumentation.d.ts +16 -12
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +55 -40
- package/dest/mem_pools/interface.d.ts +3 -4
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +70 -16
- 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 +452 -142
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +18 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +56 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +83 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +5 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts +15 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.js +88 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +17 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +84 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +19 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +76 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +26 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +1 -0
- package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +84 -0
- package/dest/mem_pools/tx_pool/index.d.ts +1 -2
- package/dest/mem_pools/tx_pool/index.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/index.js +0 -1
- package/dest/mem_pools/tx_pool/priority.d.ts +5 -1
- package/dest/mem_pools/tx_pool/priority.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/priority.js +7 -2
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +72 -11
- 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 +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 +276 -45
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +7 -5
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +48 -10
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +20 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -0
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +64 -0
- package/dest/msg_validators/attestation_validator/index.d.ts +2 -1
- package/dest/msg_validators/attestation_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/index.js +1 -0
- package/dest/msg_validators/index.d.ts +2 -2
- package/dest/msg_validators/index.d.ts.map +1 -1
- package/dest/msg_validators/index.js +1 -1
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts +10 -0
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.d.ts.map +1 -0
- package/dest/msg_validators/msg_seen_validator/msg_seen_validator.js +36 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
- package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
- package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/index.js +3 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.js +80 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
- package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +183 -0
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +3 -0
- package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/allowed_public_setup.js +27 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts +14 -0
- package/dest/msg_validators/tx_validator/archive_cache.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/archive_cache.js +22 -0
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts +2 -2
- package/dest/msg_validators/tx_validator/block_header_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/block_header_validator.js +4 -4
- 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 +56 -86
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts +1 -3
- package/dest/msg_validators/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/double_spend_validator.js +21 -27
- package/dest/msg_validators/tx_validator/factory.d.ts +16 -0
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/factory.js +74 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +11 -0
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/gas_validator.js +115 -0
- package/dest/msg_validators/tx_validator/index.d.ts +8 -1
- package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/index.js +7 -0
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts +9 -5
- package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/metadata_validator.js +39 -20
- package/dest/msg_validators/tx_validator/phases_validator.d.ts +14 -0
- package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/phases_validator.js +93 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts +17 -0
- package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/test_utils.js +22 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts +13 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/timestamp_validator.js +32 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts +8 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.d.ts.map +1 -0
- package/dest/msg_validators/tx_validator/tx_permitted_validator.js +24 -0
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_proof_validator.js +6 -5
- package/dest/services/data_store.d.ts +1 -1
- package/dest/services/data_store.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.d.ts +10 -9
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +63 -36
- package/dest/services/dummy_service.d.ts +54 -11
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +91 -5
- package/dest/services/encoding.d.ts +26 -7
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +76 -6
- package/dest/services/gossipsub/scoring.d.ts +1 -1
- package/dest/services/index.d.ts +5 -1
- package/dest/services/index.d.ts.map +1 -1
- package/dest/services/index.js +4 -0
- package/dest/services/libp2p/instrumentation.d.ts +20 -0
- package/dest/services/libp2p/instrumentation.d.ts.map +1 -0
- package/dest/services/libp2p/instrumentation.js +111 -0
- package/dest/services/libp2p/libp2p_service.d.ts +102 -96
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +1307 -301
- package/dest/services/peer-manager/interface.d.ts +23 -0
- package/dest/services/peer-manager/interface.d.ts.map +1 -0
- package/dest/services/peer-manager/interface.js +1 -0
- package/dest/services/peer-manager/metrics.d.ts +11 -2
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +29 -12
- package/dest/services/peer-manager/peer_manager.d.ts +103 -23
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +551 -82
- package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +37 -2
- package/dest/services/reqresp/config.d.ts +11 -9
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/config.js +18 -4
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +2 -2
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +10 -6
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +31 -17
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +142 -84
- package/dest/services/reqresp/index.d.ts +3 -2
- package/dest/services/reqresp/index.d.ts.map +1 -1
- package/dest/services/reqresp/index.js +2 -1
- package/dest/services/reqresp/interface.d.ts +73 -24
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +46 -27
- package/dest/services/reqresp/metrics.d.ts +1 -1
- package/dest/services/reqresp/metrics.d.ts.map +1 -1
- package/dest/services/reqresp/metrics.js +5 -21
- package/dest/services/reqresp/protocols/auth.d.ts +43 -0
- package/dest/services/reqresp/protocols/auth.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/auth.js +71 -0
- package/dest/services/reqresp/protocols/block.d.ts +6 -1
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block.js +30 -6
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +30 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +75 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +11 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +39 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +47 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +75 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts +4 -0
- package/dest/services/reqresp/protocols/block_txs/index.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block_txs/index.js +3 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts +3 -5
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/goodbye.js +7 -7
- package/dest/services/reqresp/protocols/index.d.ts +3 -1
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/index.js +2 -0
- package/dest/services/reqresp/protocols/ping.d.ts +1 -3
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.d.ts +40 -7
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/status.js +75 -5
- package/dest/services/reqresp/protocols/tx.d.ts +14 -4
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/tx.js +34 -6
- package/dest/services/reqresp/rate-limiter/index.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +6 -4
- package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -2
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
- package/dest/services/reqresp/rate-limiter/rate_limits.js +21 -1
- package/dest/services/reqresp/reqresp.d.ts +24 -66
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +699 -230
- package/dest/services/reqresp/status.d.ts +10 -4
- package/dest/services/reqresp/status.d.ts.map +1 -1
- package/dest/services/reqresp/status.js +9 -2
- package/dest/services/service.d.ts +37 -20
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/config.d.ts +25 -0
- package/dest/services/tx_collection/config.d.ts.map +1 -0
- package/dest/services/tx_collection/config.js +58 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts +51 -0
- package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/fast_tx_collection.js +300 -0
- package/dest/services/tx_collection/index.d.ts +3 -0
- package/dest/services/tx_collection/index.d.ts.map +1 -0
- package/dest/services/tx_collection/index.js +2 -0
- package/dest/services/tx_collection/instrumentation.d.ts +10 -0
- package/dest/services/tx_collection/instrumentation.d.ts.map +1 -0
- package/dest/services/tx_collection/instrumentation.js +24 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts +53 -0
- package/dest/services/tx_collection/slow_tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/slow_tx_collection.js +177 -0
- package/dest/services/tx_collection/tx_collection.d.ts +110 -0
- package/dest/services/tx_collection/tx_collection.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection.js +128 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts +30 -0
- package/dest/services/tx_collection/tx_collection_sink.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_collection_sink.js +111 -0
- package/dest/services/tx_collection/tx_source.d.ts +18 -0
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -0
- package/dest/services/tx_collection/tx_source.js +31 -0
- package/dest/services/tx_provider.d.ts +51 -0
- package/dest/services/tx_provider.d.ts.map +1 -0
- package/dest/services/tx_provider.js +219 -0
- package/dest/services/tx_provider_instrumentation.d.ts +16 -0
- package/dest/services/tx_provider_instrumentation.d.ts.map +1 -0
- package/dest/services/tx_provider_instrumentation.js +34 -0
- package/dest/test-helpers/generate-peer-id-private-keys.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts +1 -1
- package/dest/test-helpers/get-ports.d.ts.map +1 -1
- package/dest/test-helpers/index.d.ts +2 -1
- package/dest/test-helpers/index.d.ts.map +1 -1
- package/dest/test-helpers/index.js +1 -0
- package/dest/test-helpers/make-enrs.d.ts +1 -1
- package/dest/test-helpers/make-enrs.d.ts.map +1 -1
- package/dest/test-helpers/make-enrs.js +4 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts +33 -5
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +86 -16
- package/dest/test-helpers/mock-pubsub.d.ts +59 -0
- package/dest/test-helpers/mock-pubsub.d.ts.map +1 -0
- package/dest/test-helpers/mock-pubsub.js +130 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts +12 -0
- package/dest/test-helpers/mock-tx-helpers.d.ts.map +1 -0
- package/dest/test-helpers/mock-tx-helpers.js +19 -0
- package/dest/test-helpers/reqresp-nodes.d.ts +15 -11
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +62 -28
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +124 -35
- package/dest/testbench/parse_log_file.d.ts +1 -1
- package/dest/testbench/parse_log_file.js +4 -4
- package/dest/testbench/testbench.d.ts +1 -1
- package/dest/testbench/testbench.js +4 -4
- package/dest/testbench/worker_client_manager.d.ts +1 -6
- package/dest/testbench/worker_client_manager.d.ts.map +1 -1
- package/dest/testbench/worker_client_manager.js +17 -20
- package/dest/types/index.d.ts +4 -2
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +2 -0
- package/dest/util.d.ts +24 -16
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +75 -69
- package/dest/versioning.d.ts +4 -4
- package/dest/versioning.d.ts.map +1 -1
- package/dest/versioning.js +8 -3
- package/package.json +32 -27
- package/src/bootstrap/bootstrap.ts +27 -11
- package/src/client/factory.ts +139 -53
- package/src/client/index.ts +1 -0
- package/src/client/interface.ts +213 -0
- package/src/client/p2p_client.ts +471 -385
- package/src/config.ts +299 -134
- package/src/enr/generate-enr.ts +39 -6
- package/src/errors/attestation-pool.error.ts +13 -0
- package/src/index.ts +4 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +119 -24
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +344 -201
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +233 -72
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +199 -96
- package/src/mem_pools/attestation_pool/mocks.ts +21 -16
- package/src/mem_pools/instrumentation.ts +71 -48
- package/src/mem_pools/interface.ts +2 -4
- package/src/mem_pools/tx_pool/README.md +255 -0
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +537 -155
- package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +71 -0
- package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +93 -0
- package/src/mem_pools/tx_pool/eviction/insufficient_fee_payer_balance_rule.ts +108 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +104 -0
- package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +91 -0
- package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +106 -0
- package/src/mem_pools/tx_pool/index.ts +0 -1
- package/src/mem_pools/tx_pool/priority.ts +9 -2
- package/src/mem_pools/tx_pool/tx_pool.ts +75 -10
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +225 -36
- package/src/msg_validators/attestation_validator/attestation_validator.ts +60 -14
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +88 -0
- package/src/msg_validators/attestation_validator/index.ts +1 -0
- package/src/msg_validators/index.ts +1 -1
- package/src/msg_validators/msg_seen_validator/msg_seen_validator.ts +36 -0
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
- package/src/msg_validators/proposal_validator/index.ts +3 -0
- package/src/msg_validators/proposal_validator/proposal_validator.ts +92 -0
- package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +206 -0
- package/src/msg_validators/tx_validator/allowed_public_setup.ts +35 -0
- package/src/msg_validators/tx_validator/archive_cache.ts +28 -0
- package/src/msg_validators/tx_validator/block_header_validator.ts +5 -5
- package/src/msg_validators/tx_validator/data_validator.ts +89 -69
- package/src/msg_validators/tx_validator/double_spend_validator.ts +19 -17
- package/src/msg_validators/tx_validator/factory.ts +110 -0
- package/src/msg_validators/tx_validator/gas_validator.ts +134 -0
- package/src/msg_validators/tx_validator/index.ts +7 -0
- package/src/msg_validators/tx_validator/metadata_validator.ts +67 -22
- package/src/msg_validators/tx_validator/phases_validator.ts +116 -0
- package/src/msg_validators/tx_validator/test_utils.ts +43 -0
- package/src/msg_validators/tx_validator/timestamp_validator.ts +49 -0
- package/src/msg_validators/tx_validator/tx_permitted_validator.ts +17 -0
- package/src/msg_validators/tx_validator/tx_proof_validator.ts +6 -5
- package/src/services/discv5/discV5_service.ts +84 -38
- package/src/services/dummy_service.ts +153 -9
- package/src/services/encoding.ts +83 -6
- package/src/services/index.ts +4 -0
- package/src/services/libp2p/instrumentation.ts +113 -0
- package/src/services/libp2p/libp2p_service.ts +1120 -329
- package/src/services/peer-manager/interface.ts +29 -0
- package/src/services/peer-manager/metrics.ts +38 -12
- package/src/services/peer-manager/peer_manager.ts +657 -80
- package/src/services/peer-manager/peer_scoring.ts +42 -3
- package/src/services/reqresp/config.ts +26 -9
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +12 -6
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +150 -95
- package/src/services/reqresp/index.ts +2 -0
- package/src/services/reqresp/interface.ts +92 -37
- package/src/services/reqresp/metrics.ts +11 -24
- package/src/services/reqresp/protocols/auth.ts +83 -0
- package/src/services/reqresp/protocols/block.ts +26 -4
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +90 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +53 -0
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +79 -0
- package/src/services/reqresp/protocols/block_txs/index.ts +3 -0
- package/src/services/reqresp/protocols/goodbye.ts +9 -7
- package/src/services/reqresp/protocols/index.ts +2 -0
- package/src/services/reqresp/protocols/status.ts +119 -5
- package/src/services/reqresp/protocols/tx.ts +36 -8
- package/src/services/reqresp/rate-limiter/rate_limiter.ts +12 -3
- package/src/services/reqresp/rate-limiter/rate_limits.ts +21 -1
- package/src/services/reqresp/reqresp.ts +387 -256
- package/src/services/reqresp/status.ts +12 -3
- package/src/services/service.ts +61 -22
- package/src/services/tx_collection/config.ts +84 -0
- package/src/services/tx_collection/fast_tx_collection.ts +341 -0
- package/src/services/tx_collection/index.ts +2 -0
- package/src/services/tx_collection/instrumentation.ts +26 -0
- package/src/services/tx_collection/slow_tx_collection.ts +233 -0
- package/src/services/tx_collection/tx_collection.ts +216 -0
- package/src/services/tx_collection/tx_collection_sink.ts +129 -0
- package/src/services/tx_collection/tx_source.ts +37 -0
- package/src/services/tx_provider.ts +232 -0
- package/src/services/tx_provider_instrumentation.ts +48 -0
- package/src/test-helpers/index.ts +1 -0
- package/src/test-helpers/make-enrs.ts +4 -5
- package/src/test-helpers/make-test-p2p-clients.ts +111 -21
- package/src/test-helpers/mock-pubsub.ts +188 -0
- package/src/test-helpers/mock-tx-helpers.ts +24 -0
- package/src/test-helpers/reqresp-nodes.ts +87 -36
- package/src/testbench/p2p_client_testbench_worker.ts +182 -32
- package/src/testbench/parse_log_file.ts +4 -4
- package/src/testbench/testbench.ts +4 -4
- package/src/testbench/worker_client_manager.ts +23 -24
- package/src/types/index.ts +2 -0
- package/src/util.ts +105 -91
- package/src/versioning.ts +11 -4
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +0 -56
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +0 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +0 -141
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -8
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +0 -21
- package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
- package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
- package/dest/msg_validators/block_proposal_validator/index.js +0 -1
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +0 -174
- package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +0 -29
- package/src/msg_validators/block_proposal_validator/index.ts +0 -1
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type AnyTx,
|
|
4
|
+
TX_ERROR_DUPLICATE_NULLIFIER_IN_TX,
|
|
5
|
+
TX_ERROR_EXISTING_NULLIFIER,
|
|
6
|
+
Tx,
|
|
7
|
+
type TxValidationResult,
|
|
8
|
+
type TxValidator,
|
|
9
|
+
} from '@aztec/stdlib/tx';
|
|
3
10
|
|
|
4
11
|
export interface NullifierSource {
|
|
5
12
|
nullifiersExist: (nullifiers: Buffer[]) => Promise<boolean[]>;
|
|
@@ -14,25 +21,20 @@ export class DoubleSpendTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
async validateTx(tx: T): Promise<TxValidationResult> {
|
|
17
|
-
|
|
18
|
-
// because the AVM will perform merkle insertions as it goes and will fail on
|
|
19
|
-
// duplicate nullifier. In fact we CANNOT check here because the nullifiers
|
|
20
|
-
// have already been inserted, and so they will exist in nullifierSource.
|
|
21
|
-
if (!hasPublicCalls(tx)) {
|
|
22
|
-
const nullifiers = tx instanceof Tx ? tx.data.getNonEmptyNullifiers() : tx.txEffect.nullifiers;
|
|
24
|
+
const nullifiers = tx instanceof Tx ? tx.data.getNonEmptyNullifiers() : tx.txEffect.nullifiers;
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// Ditch this tx if it has repeated nullifiers
|
|
27
|
+
const uniqueNullifiers = new Set(nullifiers.map(n => n.toBigInt()));
|
|
28
|
+
if (uniqueNullifiers.size !== nullifiers.length) {
|
|
29
|
+
this.#log.verbose(`Rejecting tx ${'txHash' in tx ? tx.txHash : tx.hash} for emitting duplicate nullifiers`);
|
|
30
|
+
return { result: 'invalid', reason: [TX_ERROR_DUPLICATE_NULLIFIER_IN_TX] };
|
|
31
|
+
}
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
33
|
+
if ((await this.#nullifierSource.nullifiersExist(nullifiers.map(n => n.toBuffer()))).some(Boolean)) {
|
|
34
|
+
this.#log.verbose(`Rejecting tx ${'txHash' in tx ? tx.txHash : tx.hash} for repeating a nullifier`);
|
|
35
|
+
return { result: 'invalid', reason: [TX_ERROR_EXISTING_NULLIFIER] };
|
|
35
36
|
}
|
|
37
|
+
|
|
36
38
|
return { result: 'valid' };
|
|
37
39
|
}
|
|
38
40
|
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
|
+
import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
|
|
4
|
+
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
5
|
+
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
6
|
+
import type { GasFees } from '@aztec/stdlib/gas';
|
|
7
|
+
import type {
|
|
8
|
+
AllowedElement,
|
|
9
|
+
ClientProtocolCircuitVerifier,
|
|
10
|
+
WorldStateSynchronizer,
|
|
11
|
+
} from '@aztec/stdlib/interfaces/server';
|
|
12
|
+
import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
13
|
+
import { DatabasePublicStateSource, MerkleTreeId } from '@aztec/stdlib/trees';
|
|
14
|
+
import type { Tx, TxValidationResult } from '@aztec/stdlib/tx';
|
|
15
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
16
|
+
|
|
17
|
+
import { ArchiveCache } from './archive_cache.js';
|
|
18
|
+
import { BlockHeaderTxValidator } from './block_header_validator.js';
|
|
19
|
+
import { DataTxValidator } from './data_validator.js';
|
|
20
|
+
import { DoubleSpendTxValidator } from './double_spend_validator.js';
|
|
21
|
+
import { GasTxValidator } from './gas_validator.js';
|
|
22
|
+
import { MetadataTxValidator } from './metadata_validator.js';
|
|
23
|
+
import { PhasesTxValidator } from './phases_validator.js';
|
|
24
|
+
import { TimestampTxValidator } from './timestamp_validator.js';
|
|
25
|
+
import { TxPermittedValidator } from './tx_permitted_validator.js';
|
|
26
|
+
import { TxProofValidator } from './tx_proof_validator.js';
|
|
27
|
+
|
|
28
|
+
export interface MessageValidator {
|
|
29
|
+
validator: {
|
|
30
|
+
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
31
|
+
};
|
|
32
|
+
severity: PeerErrorSeverity;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function createTxMessageValidators(
|
|
36
|
+
timestamp: UInt64,
|
|
37
|
+
blockNumber: BlockNumber,
|
|
38
|
+
worldStateSynchronizer: WorldStateSynchronizer,
|
|
39
|
+
gasFees: GasFees,
|
|
40
|
+
l1ChainId: number,
|
|
41
|
+
rollupVersion: number,
|
|
42
|
+
protocolContractsHash: Fr,
|
|
43
|
+
contractDataSource: ContractDataSource,
|
|
44
|
+
proofVerifier: ClientProtocolCircuitVerifier,
|
|
45
|
+
txsPermitted: boolean,
|
|
46
|
+
allowedInSetup: AllowedElement[] = [],
|
|
47
|
+
): Record<string, MessageValidator>[] {
|
|
48
|
+
const merkleTree = worldStateSynchronizer.getCommitted();
|
|
49
|
+
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
txsPermittedValidator: {
|
|
53
|
+
validator: new TxPermittedValidator(txsPermitted),
|
|
54
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
55
|
+
},
|
|
56
|
+
dataValidator: {
|
|
57
|
+
validator: new DataTxValidator(),
|
|
58
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
59
|
+
},
|
|
60
|
+
metadataValidator: {
|
|
61
|
+
validator: new MetadataTxValidator({
|
|
62
|
+
l1ChainId: new Fr(l1ChainId),
|
|
63
|
+
rollupVersion: new Fr(rollupVersion),
|
|
64
|
+
protocolContractsHash,
|
|
65
|
+
vkTreeRoot: getVKTreeRoot(),
|
|
66
|
+
}),
|
|
67
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
68
|
+
},
|
|
69
|
+
timestampValidator: {
|
|
70
|
+
validator: new TimestampTxValidator<Tx>({
|
|
71
|
+
timestamp,
|
|
72
|
+
blockNumber,
|
|
73
|
+
}),
|
|
74
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
75
|
+
},
|
|
76
|
+
doubleSpendValidator: {
|
|
77
|
+
validator: new DoubleSpendTxValidator({
|
|
78
|
+
nullifiersExist: async (nullifiers: Buffer[]) => {
|
|
79
|
+
const merkleTree = worldStateSynchronizer.getCommitted();
|
|
80
|
+
const indices = await merkleTree.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, nullifiers);
|
|
81
|
+
return indices.map(index => index !== undefined);
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
85
|
+
},
|
|
86
|
+
gasValidator: {
|
|
87
|
+
validator: new GasTxValidator(
|
|
88
|
+
new DatabasePublicStateSource(merkleTree),
|
|
89
|
+
ProtocolContractAddress.FeeJuice,
|
|
90
|
+
gasFees,
|
|
91
|
+
),
|
|
92
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
93
|
+
},
|
|
94
|
+
phasesValidator: {
|
|
95
|
+
validator: new PhasesTxValidator(contractDataSource, allowedInSetup, timestamp),
|
|
96
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
97
|
+
},
|
|
98
|
+
blockHeaderValidator: {
|
|
99
|
+
validator: new BlockHeaderTxValidator(new ArchiveCache(merkleTree)),
|
|
100
|
+
severity: PeerErrorSeverity.HighToleranceError,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
proofValidator: {
|
|
105
|
+
validator: new TxProofValidator(proofVerifier),
|
|
106
|
+
severity: PeerErrorSeverity.MidToleranceError,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { AVM_MAX_PROCESSABLE_L2_GAS, FIXED_DA_GAS, FIXED_L2_GAS } from '@aztec/constants';
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
4
|
+
import { getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
5
|
+
import { FunctionSelector } from '@aztec/stdlib/abi';
|
|
6
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
+
import { Gas, GasFees } from '@aztec/stdlib/gas';
|
|
8
|
+
import type { PublicStateSource } from '@aztec/stdlib/trees';
|
|
9
|
+
import {
|
|
10
|
+
TX_ERROR_GAS_LIMIT_TOO_HIGH,
|
|
11
|
+
TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE,
|
|
12
|
+
TX_ERROR_INSUFFICIENT_FEE_PER_GAS,
|
|
13
|
+
TX_ERROR_INSUFFICIENT_GAS_LIMIT,
|
|
14
|
+
type Tx,
|
|
15
|
+
TxExecutionPhase,
|
|
16
|
+
type TxValidationResult,
|
|
17
|
+
type TxValidator,
|
|
18
|
+
} from '@aztec/stdlib/tx';
|
|
19
|
+
|
|
20
|
+
export class GasTxValidator implements TxValidator<Tx> {
|
|
21
|
+
#log = createLogger('sequencer:tx_validator:tx_gas');
|
|
22
|
+
#publicDataSource: PublicStateSource;
|
|
23
|
+
#feeJuiceAddress: AztecAddress;
|
|
24
|
+
#gasFees: GasFees;
|
|
25
|
+
|
|
26
|
+
constructor(publicDataSource: PublicStateSource, feeJuiceAddress: AztecAddress, gasFees: GasFees) {
|
|
27
|
+
this.#publicDataSource = publicDataSource;
|
|
28
|
+
this.#feeJuiceAddress = feeJuiceAddress;
|
|
29
|
+
this.#gasFees = gasFees;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
33
|
+
const gasLimitValidation = this.#validateGasLimit(tx);
|
|
34
|
+
if (gasLimitValidation.result === 'invalid') {
|
|
35
|
+
return Promise.resolve(gasLimitValidation);
|
|
36
|
+
}
|
|
37
|
+
if (this.#shouldSkip(tx)) {
|
|
38
|
+
return Promise.resolve({ result: 'skipped', reason: [TX_ERROR_INSUFFICIENT_FEE_PER_GAS] });
|
|
39
|
+
}
|
|
40
|
+
return await this.validateTxFee(tx);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Check whether the tx's max fees are valid for the current block, and skip if not.
|
|
45
|
+
* We skip instead of invalidating since the tx may become eligible later.
|
|
46
|
+
* Note that circuits check max fees even if fee payer is unset, so we
|
|
47
|
+
* keep this validation even if the tx does not pay fees.
|
|
48
|
+
*/
|
|
49
|
+
#shouldSkip(tx: Tx): boolean {
|
|
50
|
+
const gasSettings = tx.data.constants.txContext.gasSettings;
|
|
51
|
+
|
|
52
|
+
// Skip the tx if its max fees are not enough for the current block's gas fees.
|
|
53
|
+
const maxFeesPerGas = gasSettings.maxFeesPerGas;
|
|
54
|
+
const notEnoughMaxFees =
|
|
55
|
+
maxFeesPerGas.feePerDaGas < this.#gasFees.feePerDaGas || maxFeesPerGas.feePerL2Gas < this.#gasFees.feePerL2Gas;
|
|
56
|
+
|
|
57
|
+
if (notEnoughMaxFees) {
|
|
58
|
+
this.#log.verbose(`Skipping transaction ${tx.getTxHash().toString()} due to insufficient fee per gas`, {
|
|
59
|
+
txMaxFeesPerGas: maxFeesPerGas.toInspect(),
|
|
60
|
+
currentGasFees: this.#gasFees.toInspect(),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return notEnoughMaxFees;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check whether the tx's gas limit is above the minimum amount.
|
|
68
|
+
*/
|
|
69
|
+
#validateGasLimit(tx: Tx): TxValidationResult {
|
|
70
|
+
const gasLimits = tx.data.constants.txContext.gasSettings.gasLimits;
|
|
71
|
+
const minGasLimits = new Gas(FIXED_DA_GAS, FIXED_L2_GAS);
|
|
72
|
+
|
|
73
|
+
if (minGasLimits.gtAny(gasLimits)) {
|
|
74
|
+
this.#log.verbose(`Rejecting transaction due to the gas limit(s) not being above the minimum gas limit`, {
|
|
75
|
+
gasLimits,
|
|
76
|
+
minGasLimits,
|
|
77
|
+
});
|
|
78
|
+
return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_GAS_LIMIT] };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (gasLimits.l2Gas > AVM_MAX_PROCESSABLE_L2_GAS) {
|
|
82
|
+
this.#log.verbose(`Rejecting transaction due to the gas limit(s) being higher than the maximum processable gas`, {
|
|
83
|
+
gasLimits,
|
|
84
|
+
minGasLimits,
|
|
85
|
+
});
|
|
86
|
+
return { result: 'invalid', reason: [TX_ERROR_GAS_LIMIT_TOO_HIGH] };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { result: 'valid' };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public async validateTxFee(tx: Tx): Promise<TxValidationResult> {
|
|
93
|
+
const feePayer = tx.data.feePayer;
|
|
94
|
+
|
|
95
|
+
// Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
|
|
96
|
+
const feeLimit = tx.data.constants.txContext.gasSettings.getFeeLimit();
|
|
97
|
+
|
|
98
|
+
// Read current balance of the feePayer
|
|
99
|
+
const initialBalance = await this.#publicDataSource.storageRead(
|
|
100
|
+
this.#feeJuiceAddress,
|
|
101
|
+
await computeFeePayerBalanceStorageSlot(feePayer),
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// If there is a claim in this tx that increases the fee payer balance in Fee Juice, add it to balance
|
|
105
|
+
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
106
|
+
const increasePublicBalanceSelector = await FunctionSelector.fromSignature(
|
|
107
|
+
'_increase_public_balance((Field),u128)',
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Arguments of the claim function call:
|
|
111
|
+
// - args[0]: Amount recipient.
|
|
112
|
+
// - args[1]: Amount being claimed.
|
|
113
|
+
const claimFunctionCall = setupFns.find(
|
|
114
|
+
fn =>
|
|
115
|
+
fn.request.contractAddress.equals(this.#feeJuiceAddress) &&
|
|
116
|
+
fn.request.msgSender.equals(this.#feeJuiceAddress) &&
|
|
117
|
+
fn.calldata.length > 2 &&
|
|
118
|
+
fn.functionSelector.equals(increasePublicBalanceSelector) &&
|
|
119
|
+
fn.args[0].equals(feePayer.toField()) &&
|
|
120
|
+
!fn.request.isStaticCall,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const balance = claimFunctionCall ? initialBalance.add(claimFunctionCall.args[1]) : initialBalance;
|
|
124
|
+
if (balance.lt(feeLimit)) {
|
|
125
|
+
this.#log.verbose(`Rejecting transaction due to not enough fee payer balance`, {
|
|
126
|
+
feePayer,
|
|
127
|
+
balance: balance.toBigInt(),
|
|
128
|
+
feeLimit: feeLimit.toBigInt(),
|
|
129
|
+
});
|
|
130
|
+
return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE] };
|
|
131
|
+
}
|
|
132
|
+
return { result: 'valid' };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -4,3 +4,10 @@ export * from './double_spend_validator.js';
|
|
|
4
4
|
export * from './metadata_validator.js';
|
|
5
5
|
export * from './tx_proof_validator.js';
|
|
6
6
|
export * from './block_header_validator.js';
|
|
7
|
+
export * from './gas_validator.js';
|
|
8
|
+
export * from './phases_validator.js';
|
|
9
|
+
export * from './test_utils.js';
|
|
10
|
+
export * from './allowed_public_setup.js';
|
|
11
|
+
export * from './archive_cache.js';
|
|
12
|
+
export * from './tx_permitted_validator.js';
|
|
13
|
+
export * from './timestamp_validator.js';
|
|
@@ -1,29 +1,51 @@
|
|
|
1
|
-
import type { Fr } from '@aztec/foundation/
|
|
1
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
2
|
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type AnyTx,
|
|
5
|
+
TX_ERROR_INCORRECT_L1_CHAIN_ID,
|
|
6
|
+
TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH,
|
|
7
|
+
TX_ERROR_INCORRECT_ROLLUP_VERSION,
|
|
8
|
+
TX_ERROR_INCORRECT_VK_TREE_ROOT,
|
|
9
|
+
type TxValidationResult,
|
|
10
|
+
type TxValidator,
|
|
11
|
+
} from '@aztec/stdlib/tx';
|
|
4
12
|
|
|
5
13
|
export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
6
14
|
#log = createLogger('p2p:tx_validator:tx_metadata');
|
|
7
15
|
|
|
8
|
-
constructor(
|
|
16
|
+
constructor(
|
|
17
|
+
private values: {
|
|
18
|
+
l1ChainId: Fr;
|
|
19
|
+
rollupVersion: Fr;
|
|
20
|
+
vkTreeRoot: Fr;
|
|
21
|
+
protocolContractsHash: Fr;
|
|
22
|
+
},
|
|
23
|
+
) {}
|
|
9
24
|
|
|
10
|
-
|
|
25
|
+
validateTx(tx: T): Promise<TxValidationResult> {
|
|
11
26
|
const errors = [];
|
|
12
|
-
if (!
|
|
13
|
-
errors.push(
|
|
27
|
+
if (!this.#hasCorrectL1ChainId(tx)) {
|
|
28
|
+
errors.push(TX_ERROR_INCORRECT_L1_CHAIN_ID);
|
|
14
29
|
}
|
|
15
|
-
if (!
|
|
16
|
-
errors.push(
|
|
30
|
+
if (!this.#hasCorrectRollupVersion(tx)) {
|
|
31
|
+
errors.push(TX_ERROR_INCORRECT_ROLLUP_VERSION);
|
|
17
32
|
}
|
|
18
|
-
|
|
33
|
+
if (!this.#hasCorrectVkTreeRoot(tx)) {
|
|
34
|
+
errors.push(TX_ERROR_INCORRECT_VK_TREE_ROOT);
|
|
35
|
+
}
|
|
36
|
+
if (!this.#hasCorrectprotocolContractsHash(tx)) {
|
|
37
|
+
errors.push(TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH);
|
|
38
|
+
}
|
|
39
|
+
return Promise.resolve(errors.length > 0 ? { result: 'invalid', reason: errors } : { result: 'valid' });
|
|
19
40
|
}
|
|
20
41
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
42
|
+
#hasCorrectVkTreeRoot(tx: T): boolean {
|
|
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
|
+
if (!tx.data.constants.vkTreeRoot.equals(this.values.vkTreeRoot)) {
|
|
45
|
+
this.#log.verbose(
|
|
46
|
+
`Rejecting tx ${
|
|
47
|
+
'txHash' in tx ? tx.txHash : tx.hash
|
|
48
|
+
} because of incorrect vk tree root ${tx.data.constants.vkTreeRoot.toString()} != ${this.values.vkTreeRoot.toString()}`,
|
|
27
49
|
);
|
|
28
50
|
return false;
|
|
29
51
|
} else {
|
|
@@ -31,14 +53,37 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
|
31
53
|
}
|
|
32
54
|
}
|
|
33
55
|
|
|
34
|
-
|
|
35
|
-
|
|
56
|
+
#hasCorrectprotocolContractsHash(tx: T): boolean {
|
|
57
|
+
if (!tx.data.constants.protocolContractsHash.equals(this.values.protocolContractsHash)) {
|
|
58
|
+
this.#log.verbose(
|
|
59
|
+
`Rejecting tx ${
|
|
60
|
+
'txHash' in tx ? tx.txHash : tx.hash
|
|
61
|
+
} because of incorrect protocol contracts hash ${tx.data.constants.protocolContractsHash.toString()} != ${this.values.protocolContractsHash.toString()}`,
|
|
62
|
+
);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#hasCorrectL1ChainId(tx: T): boolean {
|
|
69
|
+
if (!tx.data.constants.txContext.chainId.equals(this.values.l1ChainId)) {
|
|
70
|
+
this.#log.verbose(
|
|
71
|
+
`Rejecting tx ${
|
|
72
|
+
'txHash' in tx ? tx.txHash : tx.hash
|
|
73
|
+
} because of incorrect L1 chain ${tx.data.constants.txContext.chainId.toNumber()} != ${this.values.l1ChainId.toNumber()}`,
|
|
74
|
+
);
|
|
75
|
+
return false;
|
|
76
|
+
} else {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
36
80
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
81
|
+
#hasCorrectRollupVersion(tx: T): boolean {
|
|
82
|
+
if (!tx.data.constants.txContext.version.equals(this.values.rollupVersion)) {
|
|
83
|
+
this.#log.verbose(
|
|
84
|
+
`Rejecting tx ${
|
|
85
|
+
'txHash' in tx ? tx.txHash : tx.hash
|
|
86
|
+
} because of incorrect rollup version ${tx.data.constants.txContext.version.toNumber()} != ${this.values.rollupVersion.toNumber()}`,
|
|
42
87
|
);
|
|
43
88
|
return false;
|
|
44
89
|
} else {
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import { PublicContractsDB, getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
|
|
3
|
+
import type { ContractDataSource } from '@aztec/stdlib/contract';
|
|
4
|
+
import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
|
|
5
|
+
import {
|
|
6
|
+
type PublicCallRequestWithCalldata,
|
|
7
|
+
TX_ERROR_DURING_VALIDATION,
|
|
8
|
+
TX_ERROR_SETUP_FUNCTION_NOT_ALLOWED,
|
|
9
|
+
Tx,
|
|
10
|
+
TxExecutionPhase,
|
|
11
|
+
type TxValidationResult,
|
|
12
|
+
type TxValidator,
|
|
13
|
+
} from '@aztec/stdlib/tx';
|
|
14
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
15
|
+
|
|
16
|
+
export class PhasesTxValidator implements TxValidator<Tx> {
|
|
17
|
+
#log = createLogger('sequencer:tx_validator:tx_phases');
|
|
18
|
+
private contractsDB: PublicContractsDB;
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
contracts: ContractDataSource,
|
|
22
|
+
private setupAllowList: AllowedElement[],
|
|
23
|
+
private timestamp: UInt64,
|
|
24
|
+
) {
|
|
25
|
+
this.contractsDB = new PublicContractsDB(contracts);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
29
|
+
this.contractsDB.createCheckpoint();
|
|
30
|
+
try {
|
|
31
|
+
// TODO(@spalladino): We add this just to handle public authwit-check calls during setup
|
|
32
|
+
// which are needed for public FPC flows, but fail if the account contract hasnt been deployed yet,
|
|
33
|
+
// which is what we're trying to do as part of the current txs.
|
|
34
|
+
// We only need to create/revert checkpoint here because of this addNewContracts call.
|
|
35
|
+
await this.contractsDB.addNewContracts(tx);
|
|
36
|
+
|
|
37
|
+
if (!tx.data.forPublic) {
|
|
38
|
+
this.#log.debug(
|
|
39
|
+
`Tx ${tx.getTxHash().toString()} does not contain enqueued public functions. Skipping phases validation.`,
|
|
40
|
+
);
|
|
41
|
+
return { result: 'valid' };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
|
|
45
|
+
for (const setupFn of setupFns) {
|
|
46
|
+
if (!(await this.isOnAllowList(setupFn, this.setupAllowList))) {
|
|
47
|
+
this.#log.verbose(
|
|
48
|
+
`Rejecting tx ${tx.getTxHash().toString()} because it calls setup function not on allow list: ${
|
|
49
|
+
setupFn.request.contractAddress
|
|
50
|
+
}:${setupFn.functionSelector}`,
|
|
51
|
+
{ allowList: this.setupAllowList },
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
return { result: 'invalid', reason: [TX_ERROR_SETUP_FUNCTION_NOT_ALLOWED] };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { result: 'valid' };
|
|
59
|
+
} catch (err) {
|
|
60
|
+
this.#log.error(`Error validating phases for tx`, err);
|
|
61
|
+
return { result: 'invalid', reason: [TX_ERROR_DURING_VALIDATION] };
|
|
62
|
+
} finally {
|
|
63
|
+
this.contractsDB.revertCheckpoint();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private async isOnAllowList(
|
|
68
|
+
publicCall: PublicCallRequestWithCalldata,
|
|
69
|
+
allowList: AllowedElement[],
|
|
70
|
+
): Promise<boolean> {
|
|
71
|
+
if (publicCall.isEmpty()) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const contractAddress = publicCall.request.contractAddress;
|
|
76
|
+
const functionSelector = publicCall.functionSelector;
|
|
77
|
+
|
|
78
|
+
// do these checks first since they don't require the contract class
|
|
79
|
+
for (const entry of allowList) {
|
|
80
|
+
if ('address' in entry && !('selector' in entry)) {
|
|
81
|
+
if (contractAddress.equals(entry.address)) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if ('address' in entry && 'selector' in entry) {
|
|
87
|
+
if (contractAddress.equals(entry.address) && entry.selector.equals(functionSelector)) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const contractClass = await this.contractsDB.getContractInstance(contractAddress, this.timestamp);
|
|
93
|
+
|
|
94
|
+
if (!contractClass) {
|
|
95
|
+
throw new Error(`Contract not found: ${contractAddress}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if ('classId' in entry && !('selector' in entry)) {
|
|
99
|
+
if (contractClass.currentContractClassId.equals(entry.classId)) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if ('classId' in entry && 'selector' in entry) {
|
|
105
|
+
if (
|
|
106
|
+
contractClass.currentContractClassId.equals(entry.classId) &&
|
|
107
|
+
(entry.selector === undefined || entry.selector.equals(functionSelector))
|
|
108
|
+
) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
|
+
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
|
+
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
import { HashedValues, type Tx } from '@aztec/stdlib/tx';
|
|
5
|
+
|
|
6
|
+
export function patchNonRevertibleFn(
|
|
7
|
+
tx: Tx,
|
|
8
|
+
index: number,
|
|
9
|
+
overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
|
|
10
|
+
): Promise<AztecAddress> {
|
|
11
|
+
return patchFn('nonRevertibleAccumulatedData', tx, index, overrides);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function patchRevertibleFn(
|
|
15
|
+
tx: Tx,
|
|
16
|
+
index: number,
|
|
17
|
+
overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
|
|
18
|
+
): Promise<AztecAddress> {
|
|
19
|
+
return patchFn('revertibleAccumulatedData', tx, index, overrides);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function patchFn(
|
|
23
|
+
where: 'revertibleAccumulatedData' | 'nonRevertibleAccumulatedData',
|
|
24
|
+
tx: Tx,
|
|
25
|
+
index: number,
|
|
26
|
+
overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
|
|
27
|
+
): Promise<AztecAddress> {
|
|
28
|
+
const calldataIndex =
|
|
29
|
+
where === 'nonRevertibleAccumulatedData'
|
|
30
|
+
? index
|
|
31
|
+
: index + tx.data.forPublic!.nonRevertibleAccumulatedData.publicCallRequests.length;
|
|
32
|
+
const calldata = [overrides.selector.toField(), ...(overrides.args ?? [])];
|
|
33
|
+
const hashedCalldata = await HashedValues.fromCalldata(calldata);
|
|
34
|
+
tx.publicFunctionCalldata[calldataIndex] = hashedCalldata;
|
|
35
|
+
|
|
36
|
+
const request = tx.data.forPublic![where].publicCallRequests[index];
|
|
37
|
+
request.contractAddress = overrides.address ?? request.contractAddress;
|
|
38
|
+
request.msgSender = overrides.msgSender ?? request.msgSender;
|
|
39
|
+
request.calldataHash = hashedCalldata.hash;
|
|
40
|
+
tx.data.forPublic![where].publicCallRequests[index] = request;
|
|
41
|
+
|
|
42
|
+
return request.contractAddress;
|
|
43
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import {
|
|
4
|
+
type AnyTx,
|
|
5
|
+
TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP,
|
|
6
|
+
type TxValidationResult,
|
|
7
|
+
type TxValidator,
|
|
8
|
+
getTxHash,
|
|
9
|
+
} from '@aztec/stdlib/tx';
|
|
10
|
+
import type { UInt64 } from '@aztec/stdlib/types';
|
|
11
|
+
|
|
12
|
+
export class TimestampTxValidator<T extends AnyTx> implements TxValidator<T> {
|
|
13
|
+
#log = createLogger('p2p:tx_validator:timestamp');
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private values: {
|
|
17
|
+
// Timestamp at which we will validate that the tx is not expired. This is typically the timestamp of the block
|
|
18
|
+
// being built.
|
|
19
|
+
timestamp: UInt64;
|
|
20
|
+
// Block number in which the tx is considered to be included.
|
|
21
|
+
blockNumber: BlockNumber;
|
|
22
|
+
},
|
|
23
|
+
) {}
|
|
24
|
+
|
|
25
|
+
validateTx(tx: T): Promise<TxValidationResult> {
|
|
26
|
+
const includeByTimestamp = tx.data.includeByTimestamp;
|
|
27
|
+
// If building block 1, we skip the expiration check. For details on why see the `validate_include_by_timestamp`
|
|
28
|
+
// function in `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
|
|
29
|
+
const buildingBlock1 = this.values.blockNumber === 1;
|
|
30
|
+
|
|
31
|
+
if (!buildingBlock1 && includeByTimestamp < this.values.timestamp) {
|
|
32
|
+
if (tx.data.constants.anchorBlockHeader.globalVariables.blockNumber === 0) {
|
|
33
|
+
this.#log.warn(
|
|
34
|
+
`A tx built against a genesis block failed to be included in block 1 which is the only block in which txs built against a genesis block are allowed to be included.`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
this.#log.verbose(
|
|
38
|
+
`Rejecting tx ${getTxHash(
|
|
39
|
+
tx,
|
|
40
|
+
)} for low expiration timestamp. Tx expiration timestamp: ${includeByTimestamp}, timestamp: ${
|
|
41
|
+
this.values.timestamp
|
|
42
|
+
}.`,
|
|
43
|
+
);
|
|
44
|
+
return Promise.resolve({ result: 'invalid', reason: [TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP] });
|
|
45
|
+
} else {
|
|
46
|
+
return Promise.resolve({ result: 'valid' });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
+
import type { Tx, TxValidationResult, TxValidator } from '@aztec/stdlib/tx';
|
|
3
|
+
|
|
4
|
+
export class TxPermittedValidator implements TxValidator<Tx> {
|
|
5
|
+
#log = createLogger('p2p:tx_validator:tx_permitted');
|
|
6
|
+
|
|
7
|
+
constructor(private permitted: boolean) {}
|
|
8
|
+
|
|
9
|
+
validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
10
|
+
if (!this.permitted) {
|
|
11
|
+
const txHash = tx.getTxHash();
|
|
12
|
+
this.#log.verbose(`Rejecting tx ${txHash.toString()}. Reason: Transactions are not permitted`);
|
|
13
|
+
return Promise.resolve({ result: 'invalid', reason: ['Transactions are not permitted'] });
|
|
14
|
+
}
|
|
15
|
+
return Promise.resolve({ result: 'valid' });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
2
|
import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
|
|
3
|
-
import { Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
3
|
+
import { TX_ERROR_INVALID_PROOF, Tx, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
|
|
4
4
|
|
|
5
5
|
export class TxProofValidator implements TxValidator<Tx> {
|
|
6
6
|
#log = createLogger('p2p:tx_validator:private_proof');
|
|
@@ -8,11 +8,12 @@ export class TxProofValidator implements TxValidator<Tx> {
|
|
|
8
8
|
constructor(private verifier: ClientProtocolCircuitVerifier) {}
|
|
9
9
|
|
|
10
10
|
async validateTx(tx: Tx): Promise<TxValidationResult> {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const result = await this.verifier.verifyProof(tx);
|
|
12
|
+
if (!result.valid) {
|
|
13
|
+
this.#log.verbose(`Rejecting tx ${tx.getTxHash().toString()} for invalid proof`);
|
|
14
|
+
return { result: 'invalid', reason: [TX_ERROR_INVALID_PROOF] };
|
|
14
15
|
}
|
|
15
|
-
this.#log.trace(`Accepted ${
|
|
16
|
+
this.#log.trace(`Accepted ${tx.getTxHash().toString()} with valid proof`);
|
|
16
17
|
return { result: 'valid' };
|
|
17
18
|
}
|
|
18
19
|
}
|