@aztec/p2p 0.0.1-commit.993d240 → 0.0.1-commit.9a89641
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 +7 -6
- package/dest/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +20 -12
- package/dest/client/factory.d.ts +2 -2
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +10 -5
- package/dest/client/interface.d.ts +40 -9
- package/dest/client/interface.d.ts.map +1 -1
- package/dest/client/p2p_client.d.ts +23 -12
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +38 -35
- package/dest/config.d.ts +19 -13
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +27 -26
- package/dest/errors/reqresp.error.d.ts +13 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.js +14 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -2
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +9 -2
- 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 +43 -0
- package/dest/mem_pools/instrumentation.d.ts +9 -4
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +11 -8
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts +1 -5
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/archive/tx_archive.js +1 -7
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts +3 -3
- package/dest/mem_pools/tx_pool_v2/deleted_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/deleted_pool.js +6 -6
- 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 +3 -3
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +3 -1
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +3 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.js +3 -4
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +4 -5
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +6 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +30 -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_pool_indices.d.ts +15 -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 +31 -0
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +9 -3
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +19 -8
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +17 -4
- 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 +133 -34
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +6 -5
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +24 -26
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +4 -4
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +2 -2
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +4 -3
- package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/block_proposal_validator.js +2 -2
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +4 -3
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +8 -2
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +19 -5
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +66 -30
- package/dest/msg_validators/tx_validator/factory.d.ts +9 -11
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +15 -6
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +12 -7
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +15 -15
- package/dest/msg_validators/tx_validator/phases_validator.js +2 -2
- package/dest/msg_validators/tx_validator/timestamp_validator.js +1 -1
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts +2 -2
- package/dest/msg_validators/tx_validator/tx_validation_cache.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/tx_validation_cache.js +6 -7
- package/dest/services/discv5/discV5_service.d.ts +12 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +84 -15
- package/dest/services/discv5/persisted_enr_store.d.ts +38 -0
- package/dest/services/discv5/persisted_enr_store.d.ts.map +1 -0
- package/dest/services/discv5/persisted_enr_store.js +145 -0
- package/dest/services/dummy_service.d.ts +6 -2
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +3 -0
- package/dest/services/encoding.d.ts +19 -6
- package/dest/services/encoding.d.ts.map +1 -1
- package/dest/services/encoding.js +25 -15
- package/dest/services/gossipsub/topic_score_params.d.ts +6 -23
- package/dest/services/gossipsub/topic_score_params.d.ts.map +1 -1
- package/dest/services/gossipsub/topic_score_params.js +4 -31
- package/dest/services/libp2p/libp2p_service.d.ts +12 -3
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +204 -114
- package/dest/services/peer-manager/peer_manager.d.ts +15 -2
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +46 -18
- package/dest/services/peer-manager/peer_scoring.d.ts +28 -1
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_scoring.js +70 -3
- package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -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 +21 -39
- package/dest/services/reqresp/config.d.ts +13 -1
- package/dest/services/reqresp/config.d.ts.map +1 -1
- package/dest/services/reqresp/config.js +11 -0
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts +4 -3
- package/dest/services/reqresp/protocols/block_txs/bitvector.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/bitvector.js +3 -2
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_handler.js +29 -28
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts +12 -7
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/protocols/block_txs/block_txs_reqresp.js +42 -24
- package/dest/services/reqresp/rate-limiter/rate_limits.js +3 -3
- 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 +34 -3
- package/dest/services/service.d.ts +21 -1
- package/dest/services/service.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.d.ts +1 -1
- package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
- package/dest/services/tx_collection/tx_source.js +4 -1
- package/dest/test-helpers/testbench-utils.d.ts +4 -1
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +11 -3
- package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
- package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
- package/dest/testbench/p2p_client_testbench_worker.js +19 -2
- package/package.json +15 -17
- package/src/bootstrap/bootstrap.ts +15 -9
- package/src/client/factory.ts +9 -5
- package/src/client/interface.ts +33 -7
- package/src/client/p2p_client.ts +46 -48
- package/src/config.ts +50 -38
- package/src/errors/reqresp.error.ts +19 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +12 -2
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +40 -1
- package/src/mem_pools/instrumentation.ts +13 -11
- package/src/mem_pools/tx_pool_v2/archive/tx_archive.ts +1 -9
- package/src/mem_pools/tx_pool_v2/deleted_pool.ts +7 -7
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +2 -4
- package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -2
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +3 -1
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_mining_rule.ts +1 -3
- package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -4
- package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +5 -6
- package/src/mem_pools/tx_pool_v2/interfaces.ts +28 -4
- package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +35 -0
- package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +22 -8
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +158 -33
- package/src/msg_validators/attestation_validator/attestation_validator.ts +26 -26
- package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +4 -3
- package/src/msg_validators/proposal_validator/block_proposal_validator.ts +4 -2
- package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +10 -2
- package/src/msg_validators/proposal_validator/proposal_validator.ts +69 -30
- package/src/msg_validators/tx_validator/README.md +2 -0
- package/src/msg_validators/tx_validator/factory.ts +19 -13
- package/src/msg_validators/tx_validator/gas_validator.ts +16 -20
- package/src/msg_validators/tx_validator/phases_validator.ts +2 -2
- package/src/msg_validators/tx_validator/timestamp_validator.ts +1 -1
- package/src/msg_validators/tx_validator/tx_validation_cache.ts +6 -7
- package/src/services/discv5/discV5_service.ts +88 -9
- package/src/services/discv5/persisted_enr_store.ts +158 -0
- package/src/services/dummy_service.ts +6 -0
- package/src/services/encoding.ts +28 -20
- package/src/services/gossipsub/README.md +33 -11
- package/src/services/gossipsub/topic_score_params.ts +9 -50
- package/src/services/libp2p/libp2p_service.ts +234 -125
- package/src/services/peer-manager/peer_manager.ts +48 -17
- package/src/services/peer-manager/peer_scoring.ts +75 -3
- package/src/services/reqresp/README.md +2 -23
- package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +21 -45
- package/src/services/reqresp/config.ts +17 -0
- package/src/services/reqresp/protocols/block_txs/bitvector.ts +3 -2
- package/src/services/reqresp/protocols/block_txs/block_txs_handler.ts +33 -31
- package/src/services/reqresp/protocols/block_txs/block_txs_reqresp.ts +47 -20
- package/src/services/reqresp/rate-limiter/rate_limits.ts +3 -3
- package/src/services/reqresp/reqresp.ts +42 -2
- package/src/services/service.ts +23 -0
- package/src/services/tx_collection/tx_source.ts +2 -1
- package/src/test-helpers/testbench-utils.ts +13 -2
- package/src/testbench/p2p_client_testbench_worker.ts +22 -2
- package/dest/msg_validators/clock_tolerance.d.ts +0 -32
- package/dest/msg_validators/clock_tolerance.d.ts.map +0 -1
- package/dest/msg_validators/clock_tolerance.js +0 -95
- package/src/msg_validators/clock_tolerance.ts +0 -127
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE/E,OAAO,EAAE,KAAK,MAAM,EAA6C,MAAM,uBAAuB,CAAC;AAG/F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE/E,OAAO,EAAE,KAAK,MAAM,EAA6C,MAAM,uBAAuB,CAAC;AAG/F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,KAAK,oBAAoB,EAAkC,MAAM,mBAAmB,CAAC;AAC9F,OAAO,KAAK,EAAE,6BAA6B,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EAEf,iBAAiB,EAEjB,SAAS,EAIV,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,EAAE,EAA2B,MAAM,kBAAkB,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAIL,KAAK,eAAe,EACpB,UAAU,EAEX,MAAM,yBAAyB,CAAC;AAcjC,OAAO,EAAE,KAAK,OAAO,EAA4B,KAAK,MAAM,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAK9G,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAGzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAU7D,OAAO,EACL,KAAK,oBAAoB,EAI1B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0DAA0D,CAAC;AAE7F,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,eAAe,CAAC;AAOtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGzE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,4CAA4C,CAAC;AAChG,OAAO,EAAE,KAAK,gBAAgB,EAAgC,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EACL,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,yBAAyB,EAE9B,aAAa,EAOd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EACV,wBAAwB,EACxB,gCAAgC,EAChC,6BAA6B,EAC7B,+BAA+B,EAC/B,4BAA4B,EAC5B,UAAU,EACV,oBAAoB,EACrB,MAAM,eAAe,CAAC;AA8BvB,KAAK,+BAA+B,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,IACjD;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;CAAE,GAC5F;IAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAEhG;;GAEG;AACH,qBAAa,aAAc,SAAQ,UAAW,YAAW,UAAU;IA4D/D,OAAO,CAAC,MAAM;IACd,SAAS,CAAC,IAAI,EAAE,YAAY;IAC5B,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,OAAO;IACf,SAAS,CAAC,WAAW,EAAE,oBAAoB;IAC3C,SAAS,CAAC,QAAQ,EAAE,QAAQ;IAC5B,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,kBAAkB;IACtD,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,oBAAoB;IAG5B,OAAO,CAAC,iBAAiB,CAAC;IAxE5B,OAAO,CAAC,uBAAuB,CAAC,CAAiB;IACjD,OAAO,CAAC,mBAAmB,CAA0F;IAGrH,OAAO,CAAC,sBAAsB,CAAyB;IACvD,OAAO,CAAC,2BAA2B,CAA8B;IACjE,OAAO,CAAC,8BAA8B,CAAiC;IAEvE,OAAO,CAAC,eAAe,CAAM;IAC7B,OAAO,CAAC,YAAY,CAA8D;IAElF,kFAAkF;IAClF,OAAO,CAAC,yBAAyB,CAAC,CAIvB;IAEX,4GAA4G;IAC5G,OAAO,CAAC,yBAAyB,CAAC,CAA+B;IAEjE,qFAAqF;IACrF,OAAO,CAAC,4BAA4B,CAAC,CAAkC;IAEvE,sFAAsF;IACtF,OAAO,CAAC,6BAA6B,CAAC,CAAmC;IAEzE;;;;OAIG;IACH,OAAO,CAAC,qBAAqB,CAA2B;IAExD;;;;OAIG;IACH,OAAO,CAAC,kCAAkC,CAAgC;IAC1E;;;;OAIG;IACH,OAAO,CAAC,mCAAmC,CAAgC;IAE3E,OAAO,CAAC,qBAAqB,CAA6C;IAE1E,OAAO,CAAC,gBAAgB,CAAC,CAAuB;IAChD,OAAO,CAAC,eAAe,CAAC,CAAS;IAEjC,OAAO,CAAC,eAAe,CAAqB;IAE5C,OAAO,CAAC,SAAS,CAAkB;IAEnC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC;IAEzB,YACU,MAAM,EAAE,SAAS,EACf,IAAI,EAAE,YAAY,EACpB,oBAAoB,EAAE,oBAAoB,EAC1C,OAAO,EAAE,gBAAgB,EACvB,WAAW,EAAE,oBAAoB,EACjC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,aAAa,GAAG,kBAAkB,EAC9C,UAAU,EAAE,mBAAmB,EAC/B,aAAa,EAAE,6BAA6B,EAC5C,sBAAsB,EAAE,sBAAsB,EAC9C,oBAAoB,EAAE,oBAAoB,EAClD,SAAS,EAAE,eAAe,EAC1B,MAAM,GAAE,MAA2C,EAC3C,iBAAiB,CAAC,+BAAmB,EAqF9C;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC,QAG/F;IAED;;;;;OAKG;IACH,OAAoB,GAAG,CACrB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;QACJ,QAAQ,EAAE,QAAQ,CAAC;QACnB,aAAa,EAAE,aAAa,GAAG,kBAAkB,CAAC;QAClD,UAAU,EAAE,mBAAmB,CAAC;QAChC,aAAa,EAAE,6BAA6B,CAAC;QAC7C,sBAAsB,EAAE,sBAAsB,CAAC;QAC/C,SAAS,EAAE,iBAAiB,CAAC;QAC7B,oBAAoB,EAAE,oBAAoB,CAAC;QAC3C,SAAS,EAAE,eAAe,CAAC;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;KACvC,0BAiPF;IAED;;;OAGG;IACU,KAAK,kBAqGjB;IAED;;;OAGG;IACU,IAAI,kBAqBhB;IAED,qBAAqB,CAAC,WAAW,EAAE,kBAAkB,EAAE,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAExG;IAEM,8BAA8B,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAEjE;IAEM,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,CAEpD;IAEM,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAE1D;IAED,OAAO,CAAC,oBAAoB;IAarB,iBAAiB,CACtB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC,CAE1B;IAED;;;OAGG;IACI,MAAM,IAAI,GAAG,GAAG,SAAS,CAE/B;IAEM,6BAA6B,CAAC,QAAQ,EAAE,wBAAwB,QAEtE;IAEM,2CAA2C,CAAC,QAAQ,EAAE,6BAA6B,QAEzF;IAEM,0CAA0C,CAAC,QAAQ,EAAE,6BAA6B,QAExF;IAED;;;OAGG;IACI,iCAAiC,CACtC,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAA;KAAE,KAAK,IAAI,GACjG,IAAI,CAEN;IAED;;OAEG;IACI,iCAAiC,CAAC,QAAQ,EAAE,4BAA4B,GAAG,IAAI,CAErF;IAED;;;;OAIG;IACI,oCAAoC,CAAC,QAAQ,EAAE,+BAA+B,GAAG,IAAI,CAE3F;IAEM,qCAAqC,CAAC,QAAQ,EAAE,gCAAgC,GAAG,IAAI,CAE7F;IAED;;;OAGG;IACH,OAAO,CAAC,gBAAgB;YAaV,cAAc;IAY5B;;;;OAIG;IACH,SAAS,CAAC,0BAA0B,CAClC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,CAAA;KAAE,CAmC5C;IAED;;;;;;OAMG;IACH,OAAO,CAAC,2BAA2B;IAcnC;;;;OAIG;IACH,UAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBA6FjF;IAED,UAAgB,uBAAuB,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,EACtD,cAAc,EAAE,MAAM,OAAO,CAAC,+BAA+B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EACpE,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,+BAA+B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAyChD;IAED,OAAO,CAAC,cAAc;IAatB,UAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBA+FlF;YAMa,oCAAoC;IAoClD,0GAA0G;IAC1G,UAGgB,qCAAqC,CACnD,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,qBAAqB,GACjC,OAAO,CAAC,+BAA+B,CAAC,qBAAqB,CAAC,CAAC,CA6DjE;IAED,UAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBtG;IAED,6HAA6H;IAC7H,UAIgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,+BAA+B,CAAC,aAAa,EAAE;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAmF3G;IAID,UAKgB,yBAAyB,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,iBAgB7E;YAQa,wBAAwB;IAatC;;;OAGG;IACH,UAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ClH;IAED;;;OAGG;IACH,UAGgB,kCAAkC,CAChD,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CACR,+BAA+B,CAC7B,kBAAkB,EAClB;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CACxE,CACF,CAwGA;IAED;;;OAGG;IACH,UAKgB,8BAA8B,CAAC,UAAU,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,iBAqBhG;IAED;;;OAGG;IACU,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC,iBAMtD;IAED;;;;;;;OAOG;IACH,UAGgB,oCAAoC,CAClD,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA6ElB;IAED,OAAO,CAAC,UAAU;IAIlB;;OAEG;IACI,0BAA0B,IAAI,6BAA6B,CAajE;IAEY,kCAAkC,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBxE;IAED,2EAA2E;IAC3E,UAAgB,iCAAiC,CAC/C,kBAAkB,EAAE,WAAW,EAC/B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CA2B/C;IAED,oGAAoG;IACpG,SAAS,CAAC,kCAAkC,IAAI,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAEnF;YAQa,cAAc;YAyCd,wBAAwB;IA0B/B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1C;IAEM,yBAAyB,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAEjG;YAEa,WAAW;YAcX,UAAU;CAYzB"}
|
|
@@ -372,14 +372,18 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
|
372
372
|
}
|
|
373
373
|
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _initProto;
|
|
374
374
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
375
|
-
import { maxBy, merge } from '@aztec/foundation/collection';
|
|
375
|
+
import { compactArray, maxBy, merge } from '@aztec/foundation/collection';
|
|
376
376
|
import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
|
|
377
377
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
378
378
|
import { Timer } from '@aztec/foundation/timer';
|
|
379
379
|
import { protocolContractsHash } from '@aztec/protocol-contracts';
|
|
380
|
+
import { DEFAULT_MAX_BLOCKS_PER_CHECKPOINT } from '@aztec/stdlib/config';
|
|
381
|
+
import { getNetworkTxGasLimits } from '@aztec/stdlib/gas';
|
|
380
382
|
import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PMessage, PeerErrorSeverity, PeerErrorSeverityByHarshness, TopicType, createTopicString, getTopicsForConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
|
|
383
|
+
import { ConsensusTimetable, getDefaultCheckpointProposalSyncGrace } from '@aztec/stdlib/timetable';
|
|
381
384
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
382
385
|
import { Tx } from '@aztec/stdlib/tx';
|
|
386
|
+
import { InvalidBlockProposalTxsError } from '@aztec/stdlib/validators';
|
|
383
387
|
import { compressComponentVersions } from '@aztec/stdlib/versioning';
|
|
384
388
|
import { Attributes, OtelMetricsAdapter, SpanStatusCode, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
385
389
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
@@ -404,14 +408,27 @@ import { convertToMultiaddr } from '../../util.js';
|
|
|
404
408
|
import { getVersions } from '../../versioning.js';
|
|
405
409
|
import { AztecDatastore } from '../data_store.js';
|
|
406
410
|
import { DiscV5Service } from '../discv5/discV5_service.js';
|
|
407
|
-
import { SnappyTransform,
|
|
411
|
+
import { SnappyTransform, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
408
412
|
import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring.js';
|
|
409
413
|
import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
|
|
410
414
|
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
411
415
|
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
416
|
+
import { YAMUX_MAX_MESSAGE_SIZE_BYTES } from '../reqresp/config.js';
|
|
412
417
|
import { ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
|
|
413
418
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
414
419
|
import { P2PInstrumentation } from './instrumentation.js';
|
|
420
|
+
/**
|
|
421
|
+
* Builds the {@link ConsensusTimetable} shared by the gossip validators for proposal/attestation receive-window
|
|
422
|
+
* bounds. Derived purely from protocol slot-timing constants plus the block sub-slot duration and the consensus
|
|
423
|
+
* materialization grace, so every node agrees on these bounds without depending on proposer operational budgets.
|
|
424
|
+
*/ function buildConsensusTimetable(config, l1Constants) {
|
|
425
|
+
const blockDuration = config.blockDurationMs / 1000;
|
|
426
|
+
return new ConsensusTimetable({
|
|
427
|
+
l1Constants,
|
|
428
|
+
blockDuration,
|
|
429
|
+
checkpointProposalSyncGrace: config.checkpointProposalSyncGraceSeconds ?? getDefaultCheckpointProposalSyncGrace(blockDuration)
|
|
430
|
+
});
|
|
431
|
+
}
|
|
415
432
|
_dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
|
|
416
433
|
[Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber.toString()
|
|
417
434
|
})), _dec1 = trackSpan('Libp2pService.validateAndStoreBlockProposal', (_peerId, block)=>({
|
|
@@ -488,6 +505,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
488
505
|
protocolVersion;
|
|
489
506
|
topicStrings;
|
|
490
507
|
/** Callback invoked when a duplicate proposal is detected (triggers slashing). */ duplicateProposalCallback;
|
|
508
|
+
/** Callback invoked when an oversized block proposal is stored as slashing evidence (triggers slashing). */ oversizedProposalCallback;
|
|
491
509
|
/** Callback invoked when a duplicate attestation is detected (triggers slashing). */ duplicateAttestationCallback;
|
|
492
510
|
/** Callback invoked when a valid checkpoint attestation is accepted into the pool. */ checkpointAttestationCallback;
|
|
493
511
|
/**
|
|
@@ -528,26 +546,27 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
528
546
|
this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
|
|
529
547
|
this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
|
|
530
548
|
this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
|
|
531
|
-
|
|
549
|
+
// Build the consensus timetable once from protocol slot-timing constants and inject it into every
|
|
550
|
+
// validator so they share one set of receive-window bounds, independent of proposer operational budgets.
|
|
551
|
+
const consensusTimetable = buildConsensusTimetable(config, epochCache.getL1Constants());
|
|
532
552
|
const proposalValidatorOpts = {
|
|
533
553
|
txsPermitted: !config.disableTransactions,
|
|
534
554
|
maxTxsPerBlock: config.validateMaxTxsPerBlock ?? config.validateMaxTxsPerCheckpoint,
|
|
535
555
|
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint,
|
|
536
|
-
p2pPropagationTime,
|
|
537
556
|
skipSlotValidation: config.skipProposalSlotValidation,
|
|
538
557
|
signatureContext: {
|
|
539
558
|
chainId: config.l1ChainId,
|
|
540
559
|
rollupAddress: config.rollupAddress
|
|
541
|
-
}
|
|
560
|
+
},
|
|
561
|
+
clockDisparityMs: config.maxGossipClockDisparityMs
|
|
542
562
|
};
|
|
543
|
-
this.blockProposalValidator = new BlockProposalValidator(epochCache, proposalValidatorOpts);
|
|
544
|
-
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, proposalValidatorOpts);
|
|
563
|
+
this.blockProposalValidator = new BlockProposalValidator(epochCache, consensusTimetable, proposalValidatorOpts);
|
|
564
|
+
this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, consensusTimetable, proposalValidatorOpts);
|
|
545
565
|
const attestationValidatorOpts = {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
signatureContext: proposalValidatorOpts.signatureContext
|
|
566
|
+
signatureContext: proposalValidatorOpts.signatureContext,
|
|
567
|
+
clockDisparityMs: config.maxGossipClockDisparityMs
|
|
549
568
|
};
|
|
550
|
-
this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry, attestationValidatorOpts) : new CheckpointAttestationValidator(epochCache, attestationValidatorOpts);
|
|
569
|
+
this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, consensusTimetable, mempools.attestationPool, telemetry, attestationValidatorOpts) : new CheckpointAttestationValidator(epochCache, consensusTimetable, attestationValidatorOpts);
|
|
551
570
|
this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
|
|
552
571
|
this.blockReceivedCallback = async (block)=>{
|
|
553
572
|
this.logger.warn(`Handler for block received not yet registered on P2P service. Received block ${block.blockNumber} for slot ${block.slotNumber} from peer.`, {
|
|
@@ -577,7 +596,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
577
596
|
const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
|
|
578
597
|
const datastore = new AztecDatastore(peerStore);
|
|
579
598
|
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry, logger.getBindings());
|
|
580
|
-
const peerDiscoveryService = new DiscV5Service(peerId, config, packageVersion, telemetry, createLogger(`${logger.module}:discv5_service`, logger.getBindings()));
|
|
599
|
+
const peerDiscoveryService = new DiscV5Service(peerId, config, packageVersion, telemetry, createLogger(`${logger.module}:discv5_service`, logger.getBindings()), peerStore);
|
|
581
600
|
// Seed libp2p's bootstrap discovery with private and trusted peers
|
|
582
601
|
const bootstrapNodes = [
|
|
583
602
|
...config.privatePeers,
|
|
@@ -592,34 +611,45 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
592
611
|
const versions = getVersions(config);
|
|
593
612
|
const protocolVersion = compressComponentVersions(versions);
|
|
594
613
|
const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
595
|
-
const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
614
|
+
const directPeers = compactArray(await Promise.all(preferredPeersEnrs.map(async (enr)=>{
|
|
615
|
+
try {
|
|
616
|
+
const peerId = await enr.peerId();
|
|
617
|
+
const address = enr.getLocationMultiaddr('tcp');
|
|
618
|
+
if (address === undefined) {
|
|
619
|
+
throw new Error(`Direct peer ${peerId.toString()} has no TCP address, ENR: ${enr.encodeTxt()}`);
|
|
620
|
+
}
|
|
621
|
+
return {
|
|
622
|
+
id: peerId,
|
|
623
|
+
addrs: [
|
|
624
|
+
address
|
|
625
|
+
]
|
|
626
|
+
};
|
|
627
|
+
} catch (err) {
|
|
628
|
+
// A malformed configured ENR shouldn't abort node setup — skip it and log.
|
|
629
|
+
logger.warn(`Skipping preferred peer with invalid ENR`, {
|
|
630
|
+
err
|
|
631
|
+
});
|
|
632
|
+
return undefined;
|
|
600
633
|
}
|
|
601
|
-
|
|
602
|
-
id: peerId,
|
|
603
|
-
addrs: [
|
|
604
|
-
address
|
|
605
|
-
]
|
|
606
|
-
};
|
|
607
|
-
}))).filter((peer)=>peer !== undefined);
|
|
634
|
+
})));
|
|
608
635
|
const announceTcpMultiaddr = config.p2pIp ? [
|
|
609
636
|
convertToMultiaddr(config.p2pIp, p2pPort, 'tcp')
|
|
610
637
|
] : [];
|
|
611
|
-
// Create dynamic topic score params based on network configuration
|
|
638
|
+
// Create dynamic topic score params based on network configuration. Scoring uses the network-wide
|
|
639
|
+
// max-blocks-per-checkpoint config value directly to size expected per-slot message rates; these are
|
|
640
|
+
// peer-rate thresholds, not consensus deadlines, so they need no proposer operational budgets.
|
|
612
641
|
const l1Constants = epochCache.getL1Constants();
|
|
613
642
|
const topicScoreParams = createAllTopicScoreParams(protocolVersion, {
|
|
614
643
|
slotDurationMs: l1Constants.slotDuration * 1000,
|
|
615
|
-
ethereumSlotDuration: l1Constants.ethereumSlotDuration,
|
|
616
644
|
heartbeatIntervalMs: config.gossipsubInterval,
|
|
617
645
|
targetCommitteeSize: l1Constants.targetCommitteeSize,
|
|
618
|
-
|
|
619
|
-
l1PublishingTime: config.l1PublishingTime,
|
|
620
|
-
p2pPropagationTime: config.attestationPropagationTime,
|
|
646
|
+
maxBlocksPerCheckpoint: config.maxBlocksPerCheckpoint ?? DEFAULT_MAX_BLOCKS_PER_CHECKPOINT,
|
|
621
647
|
expectedBlockProposalsPerSlot: config.expectedBlockProposalsPerSlot
|
|
622
648
|
});
|
|
649
|
+
// Restrict gossipsub to exactly the topics we subscribe to. Without this, an arbitrary-topic
|
|
650
|
+
// message is transformed, msg-id'd and inserted into the seenCache before the subscription check,
|
|
651
|
+
// so a crafted topic colliding on msg id can suppress a real message as a duplicate.
|
|
652
|
+
const allowedTopics = getTopicsForConfig(config.disableTransactions).map((topic)=>createTopicString(topic, protocolVersion));
|
|
623
653
|
const node = await createLibp2p({
|
|
624
654
|
start: false,
|
|
625
655
|
peerId,
|
|
@@ -653,8 +683,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
653
683
|
],
|
|
654
684
|
datastore,
|
|
655
685
|
peerDiscovery,
|
|
686
|
+
// Pin the yamux frame size: MAX_REQRESP_REQUEST_SIZE_BYTES relies on a reqresp request fitting in one frame.
|
|
656
687
|
streamMuxers: [
|
|
657
|
-
yamux(
|
|
688
|
+
yamux({
|
|
689
|
+
maxMessageSize: YAMUX_MAX_MESSAGE_SIZE_BYTES
|
|
690
|
+
}),
|
|
658
691
|
mplex()
|
|
659
692
|
],
|
|
660
693
|
connectionEncryption: [
|
|
@@ -672,7 +705,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
672
705
|
},
|
|
673
706
|
connectionGater: {
|
|
674
707
|
denyInboundConnection: (maConn)=>{
|
|
675
|
-
const allowed = peerManager.
|
|
708
|
+
const allowed = peerManager.isAddressAllowedToConnect(maConn.remoteAddr.nodeAddress().address);
|
|
676
709
|
if (allowed) {
|
|
677
710
|
return false;
|
|
678
711
|
}
|
|
@@ -682,7 +715,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
682
715
|
denyInboundEncryptedConnection: (peerId, _maConn)=>{
|
|
683
716
|
//NOTE: it is not necessary to check address here because this was already done by
|
|
684
717
|
// denyInboundConnection
|
|
685
|
-
const allowed = peerManager.
|
|
718
|
+
const allowed = peerManager.isPeerAllowedToConnect(peerId);
|
|
686
719
|
if (allowed) {
|
|
687
720
|
return false;
|
|
688
721
|
}
|
|
@@ -709,9 +742,13 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
709
742
|
mcacheLength: config.gossipsubMcacheLength,
|
|
710
743
|
mcacheGossip: config.gossipsubMcacheGossip,
|
|
711
744
|
seenTTL: config.gossipsubSeenTTL,
|
|
745
|
+
allowedTopics,
|
|
746
|
+
// No fastMsgIdFn: the fast-path dedup cache keys on a non-cryptographic 64-bit hash of the
|
|
747
|
+
// raw data only (no topic), so a collision — accidental or engineered via a weak seed — drops
|
|
748
|
+
// a different message with no fallback to the full id. Dedup instead rests solely on the
|
|
749
|
+
// cryptographic, topic-framed msgIdFn below.
|
|
712
750
|
msgIdFn: getMsgIdFn,
|
|
713
751
|
msgIdToStrFn: msgIdToStrFn,
|
|
714
|
-
fastMsgIdFn: fastMsgIdFn,
|
|
715
752
|
dataTransform: new SnappyTransform(),
|
|
716
753
|
metricsRegister: otelMetricsAdapter,
|
|
717
754
|
metricsTopicStrToLabel: metricsTopicStrToLabels(protocolVersion),
|
|
@@ -896,6 +933,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
896
933
|
this.duplicateProposalCallback = callback;
|
|
897
934
|
}
|
|
898
935
|
/**
|
|
936
|
+
* Registers a callback to be invoked when an oversized block proposal is stored as slashing evidence.
|
|
937
|
+
*/ registerOversizedProposalCallback(callback) {
|
|
938
|
+
this.oversizedProposalCallback = callback;
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
899
941
|
* Registers a callback to be invoked when a duplicate attestation is detected.
|
|
900
942
|
* A validator signing attestations for different proposals at the same slot.
|
|
901
943
|
* This callback is triggered on the first duplicate (when count goes from 1 to 2).
|
|
@@ -1342,9 +1384,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1342
1384
|
};
|
|
1343
1385
|
}
|
|
1344
1386
|
async processBlockFromPeer(payloadData, msgId, source) {
|
|
1345
|
-
const { result, obj: block, metadata: { isEquivocated } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreBlockProposal(source, BlockProposal.fromBuffer(payloadData)), msgId, source, TopicType.block_proposal);
|
|
1346
|
-
// If not accepted or
|
|
1347
|
-
|
|
1387
|
+
const { result, obj: block, metadata: { isEquivocated, isOversized } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreBlockProposal(source, BlockProposal.fromBuffer(payloadData)), msgId, source, TopicType.block_proposal);
|
|
1388
|
+
// If not accepted, equivocated, or oversized, return. Oversized proposals are re-broadcast as
|
|
1389
|
+
// slashing evidence but never attested or processed.
|
|
1390
|
+
if (result !== TopicValidatorResult.Accept || !block || isEquivocated || isOversized) {
|
|
1348
1391
|
return;
|
|
1349
1392
|
}
|
|
1350
1393
|
await this.processValidBlockProposal(block, source);
|
|
@@ -1367,6 +1410,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1367
1410
|
// Try to add the proposal: this handles existence check, cap check, and adding in one call
|
|
1368
1411
|
const { added, alreadyExists, count } = await this.mempools.attestationPool.tryAddBlockProposal(block);
|
|
1369
1412
|
const isEquivocated = count !== undefined && count > 1;
|
|
1413
|
+
// An oversized proposal (index at or beyond the consensus per-checkpoint limit) is structurally valid
|
|
1414
|
+
// proposer misbehavior: it is stored and re-broadcast as slashing evidence but never processed or
|
|
1415
|
+
// attested to. No-ops when maxBlocksPerCheckpoint is unset (local/test).
|
|
1416
|
+
const isOversized = this.config.maxBlocksPerCheckpoint !== undefined && block.indexWithinCheckpoint >= this.config.maxBlocksPerCheckpoint;
|
|
1370
1417
|
// Duplicate proposal received, no need to re-broadcast
|
|
1371
1418
|
if (alreadyExists) {
|
|
1372
1419
|
this.logger.debug(`Ignoring duplicate block proposal received`, {
|
|
@@ -1379,7 +1426,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1379
1426
|
result: TopicValidatorResult.Ignore,
|
|
1380
1427
|
obj: block,
|
|
1381
1428
|
metadata: {
|
|
1382
|
-
isEquivocated
|
|
1429
|
+
isEquivocated,
|
|
1430
|
+
isOversized
|
|
1383
1431
|
}
|
|
1384
1432
|
};
|
|
1385
1433
|
}
|
|
@@ -1395,11 +1443,30 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1395
1443
|
return {
|
|
1396
1444
|
result: TopicValidatorResult.Reject,
|
|
1397
1445
|
metadata: {
|
|
1398
|
-
isEquivocated
|
|
1446
|
+
isEquivocated,
|
|
1447
|
+
isOversized
|
|
1399
1448
|
},
|
|
1400
1449
|
severity: PeerErrorSeverity.HighToleranceError
|
|
1401
1450
|
};
|
|
1402
1451
|
}
|
|
1452
|
+
// The proposal was stored: if oversized, invoke the oversized callback so the proposer can be
|
|
1453
|
+
// slashed. Fired alongside (not instead of) equivocation detection below.
|
|
1454
|
+
if (isOversized) {
|
|
1455
|
+
const proposer = block.getSender();
|
|
1456
|
+
if (proposer) {
|
|
1457
|
+
this.logger.warn(`Detected oversized block proposal at slot ${block.slotNumber}`, {
|
|
1458
|
+
...block.toBlockInfo(),
|
|
1459
|
+
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
1460
|
+
maxBlocksPerCheckpoint: this.config.maxBlocksPerCheckpoint,
|
|
1461
|
+
source: peerId.toString(),
|
|
1462
|
+
proposer: proposer.toString()
|
|
1463
|
+
});
|
|
1464
|
+
this.oversizedProposalCallback?.({
|
|
1465
|
+
slot: block.slotNumber,
|
|
1466
|
+
proposer
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1403
1470
|
// If this was a duplicate proposal, do not process it, but do invoke the duplicate callback,
|
|
1404
1471
|
// and do re-broadcast it so other nodes in the network know to slash the proposer
|
|
1405
1472
|
if (isEquivocated) {
|
|
@@ -1421,14 +1488,19 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1421
1488
|
result: TopicValidatorResult.Accept,
|
|
1422
1489
|
obj: block,
|
|
1423
1490
|
metadata: {
|
|
1424
|
-
isEquivocated
|
|
1491
|
+
isEquivocated,
|
|
1492
|
+
isOversized
|
|
1425
1493
|
}
|
|
1426
1494
|
};
|
|
1427
1495
|
}
|
|
1428
1496
|
// Otherwise, we're good to go!
|
|
1429
1497
|
return {
|
|
1430
1498
|
result: TopicValidatorResult.Accept,
|
|
1431
|
-
obj: block
|
|
1499
|
+
obj: block,
|
|
1500
|
+
metadata: {
|
|
1501
|
+
isEquivocated: false,
|
|
1502
|
+
isOversized
|
|
1503
|
+
}
|
|
1432
1504
|
};
|
|
1433
1505
|
}
|
|
1434
1506
|
// REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
|
|
@@ -1442,20 +1514,37 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1442
1514
|
});
|
|
1443
1515
|
// Mark the txs in this proposal as protected
|
|
1444
1516
|
await this.mempools.txPool.protectTxs(block.txHashes, block.blockHeader);
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1517
|
+
if (!await this.tryBlockReceivedCallback(block, sender)) {
|
|
1518
|
+
// Release the protections this proposal created so its txs return to pending. Only entries still
|
|
1519
|
+
// keyed to this slot are cleared, so a tx referenced by a live proposal at another slot stays protected.
|
|
1520
|
+
await this.mempools.txPool.unprotectTxs(block.txHashes, slot);
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
/**
|
|
1524
|
+
* Runs the block received callback to validate a proposal, and returns whether it was accepted.
|
|
1525
|
+
* A callback that throws is reported as a rejection: the proposal is no more usable than one explicitly
|
|
1526
|
+
* rejected, and letting the error escape would leave the proposal's tx protections in place.
|
|
1527
|
+
* Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
|
|
1528
|
+
*/ async tryBlockReceivedCallback(block, sender) {
|
|
1529
|
+
try {
|
|
1530
|
+
const isValid = await this.blockReceivedCallback(block, sender);
|
|
1531
|
+
if (!isValid) {
|
|
1532
|
+
this.logger.info(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
|
|
1533
|
+
}
|
|
1534
|
+
return isValid;
|
|
1535
|
+
} catch (err) {
|
|
1536
|
+
this.logger.error(`Error validating block proposal for block ${block.blockNumber}`, err, block.toBlockInfo());
|
|
1537
|
+
return false;
|
|
1450
1538
|
}
|
|
1451
1539
|
}
|
|
1452
1540
|
/**
|
|
1453
1541
|
* Handle a gossiped checkpoint proposal.
|
|
1454
1542
|
* Validates and processes the checkpoint proposal, then triggers the callback for attestation.
|
|
1455
1543
|
*/ async handleGossipedCheckpointProposal(payloadData, msgId, source) {
|
|
1456
|
-
const { result, obj: checkpoint, metadata: { isEquivocated, processBlock } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointProposal(source, CheckpointProposal.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_proposal);
|
|
1457
|
-
//
|
|
1458
|
-
|
|
1544
|
+
const { result, obj: checkpoint, metadata: { isEquivocated, processBlock, isOversized } = {} } = await this.validateReceivedMessage(()=>this.validateAndStoreCheckpointProposal(source, CheckpointProposal.fromBuffer(payloadData)), msgId, source, TopicType.checkpoint_proposal);
|
|
1545
|
+
// An oversized checkpoint is re-broadcast as slashing evidence but never attested or processed.
|
|
1546
|
+
// Process checkpoint proposal if valid and neither equivocated nor oversized.
|
|
1547
|
+
const processCheckpointFn = ()=>result === TopicValidatorResult.Accept && checkpoint && !isEquivocated && !isOversized ? this.processValidCheckpointProposal(checkpoint.toCore(), source) : Promise.resolve();
|
|
1459
1548
|
// If the checkpoint contained a valid last block, we process it even if the checkpoint itself is to be rejected
|
|
1460
1549
|
// TODO(palla/mbps): Is this ok? Should we be considering a block from a checkpoint that was equivocated?
|
|
1461
1550
|
const processBlockFn = ()=>processBlock && checkpoint && checkpoint.getBlockProposal() ? this.processValidBlockProposal(checkpoint.getBlockProposal(), source) : Promise.resolve();
|
|
@@ -1494,13 +1583,15 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1494
1583
|
// Extract and try to add the block proposal first if present
|
|
1495
1584
|
const blockProposal = checkpoint.getBlockProposal();
|
|
1496
1585
|
let processBlock = false;
|
|
1586
|
+
let isOversized = false;
|
|
1497
1587
|
if (blockProposal) {
|
|
1498
1588
|
this.logger.debug(`Validating block proposal from propagated checkpoint`, {
|
|
1499
1589
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
1500
1590
|
[Attributes.P2P_ID]: peerId.toString()
|
|
1501
1591
|
});
|
|
1502
1592
|
const blockProposalResult = await this.validateAndStoreBlockProposal(peerId, blockProposal);
|
|
1503
|
-
const { obj, metadata: { isEquivocated } = {} } = blockProposalResult;
|
|
1593
|
+
const { obj, metadata: { isEquivocated, isOversized: blockIsOversized } = {} } = blockProposalResult;
|
|
1594
|
+
isOversized = blockIsOversized ?? false;
|
|
1504
1595
|
if (blockProposalResult.result === TopicValidatorResult.Reject || !obj || isEquivocated) {
|
|
1505
1596
|
this.logger.debug(`Rejecting checkpoint due to invalid last block proposal`, {
|
|
1506
1597
|
[Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
|
|
@@ -1512,7 +1603,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1512
1603
|
result: TopicValidatorResult.Reject,
|
|
1513
1604
|
severity: 'severity' in blockProposalResult ? blockProposalResult.severity : PeerErrorSeverity.MidToleranceError
|
|
1514
1605
|
};
|
|
1515
|
-
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated) {
|
|
1606
|
+
} else if (blockProposalResult.result === TopicValidatorResult.Accept && obj && !isEquivocated && !isOversized) {
|
|
1607
|
+
// An oversized terminal block is re-broadcast as slashing evidence but never processed.
|
|
1516
1608
|
processBlock = true;
|
|
1517
1609
|
}
|
|
1518
1610
|
}
|
|
@@ -1532,11 +1624,12 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1532
1624
|
obj: checkpoint,
|
|
1533
1625
|
metadata: {
|
|
1534
1626
|
isEquivocated,
|
|
1535
|
-
processBlock
|
|
1627
|
+
processBlock,
|
|
1628
|
+
isOversized
|
|
1536
1629
|
}
|
|
1537
1630
|
};
|
|
1538
1631
|
}
|
|
1539
|
-
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast
|
|
1632
|
+
// Too many checkpoint proposals received for this slot, penalize peer and do not re-broadcast.
|
|
1540
1633
|
// Note: We still return the checkpoint obj so the lastBlock can be processed if valid
|
|
1541
1634
|
if (!added) {
|
|
1542
1635
|
this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
|
|
@@ -1549,7 +1642,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1549
1642
|
obj: checkpoint,
|
|
1550
1643
|
metadata: {
|
|
1551
1644
|
isEquivocated,
|
|
1552
|
-
processBlock
|
|
1645
|
+
processBlock,
|
|
1646
|
+
isOversized
|
|
1553
1647
|
},
|
|
1554
1648
|
severity: PeerErrorSeverity.HighToleranceError
|
|
1555
1649
|
};
|
|
@@ -1576,7 +1670,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1576
1670
|
obj: checkpoint,
|
|
1577
1671
|
metadata: {
|
|
1578
1672
|
isEquivocated,
|
|
1579
|
-
processBlock
|
|
1673
|
+
processBlock,
|
|
1674
|
+
isOversized
|
|
1580
1675
|
}
|
|
1581
1676
|
};
|
|
1582
1677
|
}
|
|
@@ -1586,7 +1681,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1586
1681
|
obj: checkpoint,
|
|
1587
1682
|
metadata: {
|
|
1588
1683
|
processBlock,
|
|
1589
|
-
isEquivocated
|
|
1684
|
+
isEquivocated,
|
|
1685
|
+
isOversized
|
|
1590
1686
|
}
|
|
1591
1687
|
};
|
|
1592
1688
|
}
|
|
@@ -1636,70 +1732,58 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1636
1732
|
* @returns True if the request-response is consistent, false otherwise.
|
|
1637
1733
|
*/ async validateRequestedBlockTxsConsistency(request, response, peerId) {
|
|
1638
1734
|
try {
|
|
1639
|
-
//
|
|
1640
|
-
|
|
1641
|
-
// attestation pool and archiver, but matched the requested hashes against its tx pool and
|
|
1642
|
-
// shipped what it found. This is legitimate behaviour, not misbehaviour — we just can't verify
|
|
1643
|
-
// membership/order without the block, so we drop the response without penalising the peer.
|
|
1644
|
-
if (response.archiveRoot.isZero()) {
|
|
1645
|
-
this.logger.debug(`Peer ${peerId.toString()} signalled missing block with Fr.zero archive root`);
|
|
1646
|
-
return false;
|
|
1647
|
-
}
|
|
1648
|
-
if (!response.archiveRoot.equals(request.archiveRoot)) {
|
|
1649
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1650
|
-
throw new ValidationError(`Received block txs for unexpected archive root: expected ${request.archiveRoot.toString()}, got ${response.archiveRoot.toString()}`);
|
|
1651
|
-
}
|
|
1652
|
-
if (response.txIndices.getLength() !== request.txIndices.getLength()) {
|
|
1653
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1654
|
-
throw new ValidationError(`Received block txs with mismatched bitvector length: expected ${request.txIndices.getLength()}, got ${response.txIndices.getLength()}`);
|
|
1655
|
-
}
|
|
1656
|
-
// Check no duplicates and not exceeding returnable count
|
|
1657
|
-
const requestedIndices = new Set(request.txIndices.getTrueIndices());
|
|
1658
|
-
const availableIndices = new Set(response.txIndices.getTrueIndices());
|
|
1659
|
-
const maxReturnable = [
|
|
1660
|
-
...requestedIndices
|
|
1661
|
-
].filter((i)=>availableIndices.has(i)).length;
|
|
1662
|
-
const returnedHashes = await Promise.all(response.txs.map((tx)=>tx.getTxHash().toString()));
|
|
1735
|
+
// Check for duplicates txs (or hashes) in the response.
|
|
1736
|
+
const returnedHashes = response.txs.map((tx)=>tx.getTxHash().toString());
|
|
1663
1737
|
const uniqueReturned = new Set(returnedHashes.map((h)=>h.toString()));
|
|
1664
1738
|
if (uniqueReturned.size !== returnedHashes.length) {
|
|
1665
1739
|
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1666
1740
|
throw new ValidationError(`Received duplicate txs in block txs response`);
|
|
1667
1741
|
}
|
|
1668
|
-
|
|
1669
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1670
|
-
throw new ValidationError(`Received more txs (${response.txs.length}) than requested-and-available (${maxReturnable})`);
|
|
1671
|
-
}
|
|
1672
|
-
// To verify membership/order of the returned txs we need the canonical tx hash list for the
|
|
1673
|
-
// block. Prefer the block proposal (held while a block is in flight), but fall back to the
|
|
1674
|
-
// archiver for blocks we only know as mined — e.g. a prover collecting txs to prove a block it
|
|
1675
|
-
// never received a proposal for. This mirrors the responder side (reqRespBlockTxsHandler),
|
|
1676
|
-
// which serves from proposal-or-archiver.
|
|
1742
|
+
// We get the block tx hashes from the proposal or the archiver.
|
|
1677
1743
|
const proposal = await this.mempools.attestationPool.getBlockProposalByArchive(request.archiveRoot.toString());
|
|
1678
1744
|
const blockTxHashes = proposal?.txHashes ?? (await this.archiver.getBlock({
|
|
1679
1745
|
archive: request.archiveRoot
|
|
1680
1746
|
}))?.body.txEffects.map((e)=>e.txHash);
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
// Enforce subset membership and preserve increasing order by index.
|
|
1685
|
-
const hashToIndexInBlock = new Map(blockTxHashes.map((h, i)=>[
|
|
1686
|
-
h.toString(),
|
|
1687
|
-
i
|
|
1688
|
-
]));
|
|
1689
|
-
const allowedIndexSet = new Set(intersectIdx);
|
|
1690
|
-
const indices = returnedHashes.map((h)=>hashToIndexInBlock.get(h));
|
|
1691
|
-
const allAllowed = indices.every((idx)=>idx !== undefined && allowedIndexSet.has(idx));
|
|
1692
|
-
const strictlyIncreasing = indices.every((idx, i)=>i === 0 ? idx !== undefined : idx > indices[i - 1]);
|
|
1693
|
-
if (!allAllowed || !strictlyIncreasing) {
|
|
1694
|
-
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1695
|
-
throw new ValidationError('Returned txs do not match expected subset/order for requested indices');
|
|
1696
|
-
}
|
|
1697
|
-
} else {
|
|
1747
|
+
// If we don't have the block, we can't verify membership/order of the returned txs.
|
|
1748
|
+
if (!blockTxHashes) {
|
|
1749
|
+
// This shouldn't happen, since we asked for the block (proposal).
|
|
1698
1750
|
// Neither a local proposal nor an archived block: we cannot verify membership/order of the
|
|
1699
1751
|
// returned txs. This is a local-state gap, not a peer fault, so we do not penalize.
|
|
1700
1752
|
this.logger.warn(`Block ${request.archiveRoot.toString()} not found in attestation pool or archiver; cannot validate membership/order of returned txs`);
|
|
1753
|
+
// NOTE: We mark the response as invalid, given the limitations of a true/false return value.
|
|
1701
1754
|
return false;
|
|
1702
1755
|
}
|
|
1756
|
+
// Verify that the returned tx hashes are a subset of (tx hashes by index) U (explicitly requested tx hashes).
|
|
1757
|
+
const uniqueRequestedHashes = new Set([
|
|
1758
|
+
// tx hashes requested by index.
|
|
1759
|
+
...request.txIndices.getTrueIndices().map((i)=>blockTxHashes[i].toString()),
|
|
1760
|
+
// explicitly requested tx hashes.
|
|
1761
|
+
...request.txHashes.map((h)=>h.toString())
|
|
1762
|
+
]);
|
|
1763
|
+
if (!returnedHashes.every((h)=>uniqueRequestedHashes.has(h))) {
|
|
1764
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1765
|
+
throw new ValidationError('Returned txs should be a subset of (tx hashes by index) U (explicitly requested tx hashes)');
|
|
1766
|
+
}
|
|
1767
|
+
// Tx indices information is optional, but if present, we need to verify a few things.
|
|
1768
|
+
if (!response.peerHasBlock()) {
|
|
1769
|
+
this.logger.debug(`Peer ${peerId.toString()} signalled missing block`);
|
|
1770
|
+
return true;
|
|
1771
|
+
}
|
|
1772
|
+
// If the response has a non-empty bitvector, it needs to be consistent with the number of txs in the block.
|
|
1773
|
+
if (response.txIndices.getLength() !== blockTxHashes.length) {
|
|
1774
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
1775
|
+
throw new ValidationError(`Received block txs with mismatched bitvector length: expected ${blockTxHashes.length}, got ${response.txIndices.getLength()}`);
|
|
1776
|
+
}
|
|
1777
|
+
// For every index we requested that the peer claims to have (per its bitvector), the
|
|
1778
|
+
// corresponding tx must be present in the response. A peer advertising availability but
|
|
1779
|
+
// withholding the tx is inconsistent.
|
|
1780
|
+
const returnedHashSet = new Set(returnedHashes);
|
|
1781
|
+
const expectedIndices = request.txIndices.getTrueIndices().filter((i)=>response.txIndices.isSet(i));
|
|
1782
|
+
const missingExpected = expectedIndices.some((i)=>!returnedHashSet.has(blockTxHashes[i].toString()));
|
|
1783
|
+
if (missingExpected) {
|
|
1784
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
|
|
1785
|
+
throw new ValidationError('Peer advertised requested txs via indices but did not return them');
|
|
1786
|
+
}
|
|
1703
1787
|
return true;
|
|
1704
1788
|
} catch (e) {
|
|
1705
1789
|
if (e instanceof ValidationError) {
|
|
@@ -1734,12 +1818,18 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1734
1818
|
l1ChainId: this.config.l1ChainId,
|
|
1735
1819
|
rollupVersion: this.config.rollupVersion
|
|
1736
1820
|
}, this.logger.getBindings(), this.txValidationCache);
|
|
1737
|
-
const results = await Promise.all(txs.map(async (tx)=>{
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1821
|
+
const results = await Promise.all(txs.map(async (tx)=>({
|
|
1822
|
+
txHash: tx.getTxHash(),
|
|
1823
|
+
result: await validator.validateTx(tx)
|
|
1824
|
+
})));
|
|
1825
|
+
const invalidTxs = results.flatMap(({ txHash, result })=>result.result === 'invalid' ? [
|
|
1826
|
+
{
|
|
1827
|
+
txHash,
|
|
1828
|
+
reasons: result.reason
|
|
1829
|
+
}
|
|
1830
|
+
] : []);
|
|
1831
|
+
if (invalidTxs.length > 0) {
|
|
1832
|
+
throw new InvalidBlockProposalTxsError(invalidTxs);
|
|
1743
1833
|
}
|
|
1744
1834
|
}
|
|
1745
1835
|
/** Creates the first stage (fast) validators for gossiped transactions. */ async createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp) {
|
|
@@ -1750,10 +1840,10 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
|
|
|
1750
1840
|
];
|
|
1751
1841
|
const blockNumber = BlockNumber(currentBlockNumber + 1);
|
|
1752
1842
|
const l1Constants = await this.archiver.getL1Constants();
|
|
1843
|
+
const networkTxGasLimits = getNetworkTxGasLimits(this.config, l1Constants);
|
|
1753
1844
|
return createFirstStageTxValidationsForGossipedTransactions(nextSlotTimestamp, blockNumber, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings(), {
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
maxBlockDAGas: this.config.validateMaxDABlockGas
|
|
1845
|
+
maxTxL2Gas: networkTxGasLimits.l2Gas,
|
|
1846
|
+
maxTxDAGas: networkTxGasLimits.daGas
|
|
1757
1847
|
});
|
|
1758
1848
|
}
|
|
1759
1849
|
/** Creates the second stage (expensive proof verification) validators for gossiped transactions. */ createSecondStageMessageValidators() {
|