chia-blockchain 2.5.0rc2__py3-none-any.whl → 2.5.1rc2__py3-none-any.whl
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.
- chia/_tests/README.md +1 -1
- chia/_tests/blockchain/blockchain_test_utils.py +24 -26
- chia/_tests/blockchain/test_augmented_chain.py +6 -8
- chia/_tests/blockchain/test_blockchain.py +409 -307
- chia/_tests/blockchain/test_blockchain_transactions.py +56 -75
- chia/_tests/blockchain/test_build_chains.py +11 -13
- chia/_tests/blockchain/test_get_block_generator.py +8 -8
- chia/_tests/blockchain/test_lookup_fork_chain.py +3 -4
- chia/_tests/build-init-files.py +3 -4
- chia/_tests/build-job-matrix.py +9 -9
- chia/_tests/check_sql_statements.py +2 -3
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +7 -5
- chia/_tests/clvm/test_chialisp_deserialization.py +8 -8
- chia/_tests/clvm/test_condition_codes.py +2 -2
- chia/_tests/clvm/test_curry_and_treehash.py +2 -4
- chia/_tests/clvm/test_message_conditions.py +184 -0
- chia/_tests/clvm/test_puzzle_compression.py +1 -2
- chia/_tests/clvm/test_puzzle_drivers.py +3 -3
- chia/_tests/clvm/test_puzzles.py +13 -18
- chia/_tests/clvm/test_singletons.py +17 -17
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +42 -45
- chia/_tests/cmds/conftest.py +2 -2
- chia/_tests/cmds/test_click_types.py +21 -16
- chia/_tests/cmds/test_cmd_framework.py +255 -35
- chia/_tests/cmds/test_cmds_util.py +2 -2
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_dev_gh.py +131 -0
- chia/_tests/cmds/test_farm_cmd.py +1 -2
- chia/_tests/cmds/test_show.py +6 -6
- chia/_tests/cmds/test_tx_config_args.py +2 -1
- chia/_tests/cmds/wallet/test_dao.py +23 -23
- chia/_tests/cmds/wallet/test_did.py +29 -29
- chia/_tests/cmds/wallet/test_nft.py +24 -23
- chia/_tests/cmds/wallet/test_notifications.py +8 -8
- chia/_tests/cmds/wallet/test_tx_decorators.py +3 -3
- chia/_tests/cmds/wallet/test_vcs.py +97 -73
- chia/_tests/cmds/wallet/test_wallet.py +74 -75
- chia/_tests/cmds/wallet/test_wallet_check.py +5 -7
- chia/_tests/conftest.py +153 -38
- chia/_tests/connection_utils.py +7 -6
- chia/_tests/core/cmds/test_beta.py +3 -3
- chia/_tests/core/cmds/test_keys.py +6 -6
- chia/_tests/core/cmds/test_wallet.py +3 -3
- chia/_tests/core/consensus/test_block_creation.py +3 -5
- chia/_tests/core/custom_types/test_coin.py +1 -3
- chia/_tests/core/custom_types/test_spend_bundle.py +3 -4
- chia/_tests/core/daemon/test_daemon.py +58 -58
- chia/_tests/core/daemon/test_keychain_proxy.py +2 -1
- chia/_tests/core/data_layer/conftest.py +4 -3
- chia/_tests/core/data_layer/test_data_cli.py +1 -2
- chia/_tests/core/data_layer/test_data_layer.py +5 -5
- chia/_tests/core/data_layer/test_data_layer_util.py +8 -9
- chia/_tests/core/data_layer/test_data_rpc.py +75 -93
- chia/_tests/core/data_layer/test_data_store.py +38 -37
- chia/_tests/core/data_layer/test_data_store_schema.py +11 -11
- chia/_tests/core/data_layer/util.py +11 -10
- chia/_tests/core/farmer/test_farmer_api.py +6 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +5 -10
- chia/_tests/core/full_node/ram_db.py +2 -2
- chia/_tests/core/full_node/stores/test_block_store.py +113 -11
- chia/_tests/core/full_node/stores/test_coin_store.py +37 -28
- chia/_tests/core/full_node/stores/test_full_node_store.py +34 -30
- chia/_tests/core/full_node/stores/test_hint_store.py +3 -4
- chia/_tests/core/full_node/test_address_manager.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +1 -1
- chia/_tests/core/full_node/test_conditions.py +10 -12
- chia/_tests/core/full_node/test_full_node.py +2077 -1822
- chia/_tests/core/full_node/test_generator_tools.py +4 -4
- chia/_tests/core/full_node/test_hint_management.py +2 -2
- chia/_tests/core/full_node/test_performance.py +2 -5
- chia/_tests/core/full_node/test_subscriptions.py +4 -4
- chia/_tests/core/full_node/test_tx_processing_queue.py +5 -4
- chia/_tests/core/make_block_generator.py +5 -7
- chia/_tests/core/mempool/test_mempool.py +205 -208
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +5 -5
- chia/_tests/core/mempool/test_mempool_item_queries.py +2 -4
- chia/_tests/core/mempool/test_mempool_manager.py +109 -80
- chia/_tests/core/mempool/test_mempool_performance.py +3 -4
- chia/_tests/core/mempool/test_singleton_fast_forward.py +12 -12
- chia/_tests/core/server/flood.py +6 -4
- chia/_tests/core/server/serve.py +10 -7
- chia/_tests/core/server/test_api_protocol.py +21 -0
- chia/_tests/core/server/test_capabilities.py +3 -5
- chia/_tests/core/server/test_dos.py +15 -16
- chia/_tests/core/server/test_loop.py +14 -10
- chia/_tests/core/server/test_node_discovery.py +1 -2
- chia/_tests/core/server/test_rate_limits.py +156 -44
- chia/_tests/core/server/test_server.py +8 -7
- chia/_tests/core/services/test_services.py +59 -37
- chia/_tests/core/ssl/test_ssl.py +5 -3
- chia/_tests/core/test_cost_calculation.py +5 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_db_conversion.py +5 -4
- chia/_tests/core/test_db_validation.py +6 -5
- chia/_tests/core/test_farmer_harvester_rpc.py +8 -7
- chia/_tests/core/test_filter.py +3 -5
- chia/_tests/core/test_full_node_rpc.py +64 -90
- chia/_tests/core/test_merkle_set.py +10 -10
- chia/_tests/core/test_program.py +2 -4
- chia/_tests/core/test_rpc_util.py +1 -2
- chia/_tests/core/test_seeder.py +124 -12
- chia/_tests/core/util/test_block_cache.py +5 -5
- chia/_tests/core/util/test_cached_bls.py +3 -3
- chia/_tests/core/util/test_config.py +13 -13
- chia/_tests/core/util/test_files.py +2 -2
- chia/_tests/core/util/test_jsonify.py +9 -9
- chia/_tests/core/util/test_keychain.py +13 -5
- chia/_tests/core/util/test_keyring_wrapper.py +6 -5
- chia/_tests/core/util/test_log_exceptions.py +3 -3
- chia/_tests/core/util/test_streamable.py +38 -38
- chia/_tests/db/test_db_wrapper.py +13 -12
- chia/_tests/environments/common.py +2 -2
- chia/_tests/environments/full_node.py +2 -2
- chia/_tests/environments/wallet.py +109 -48
- chia/_tests/farmer_harvester/test_farmer.py +35 -35
- chia/_tests/farmer_harvester/test_farmer_harvester.py +17 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +73 -46
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +8 -8
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +47 -47
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +6 -7
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +11 -11
- chia/_tests/generator/test_compression.py +13 -30
- chia/_tests/generator/test_generator_types.py +3 -3
- chia/_tests/generator/test_rom.py +7 -9
- chia/_tests/plot_sync/test_delta.py +2 -3
- chia/_tests/plot_sync/test_plot_sync.py +25 -24
- chia/_tests/plot_sync/test_receiver.py +9 -9
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +27 -26
- chia/_tests/plot_sync/util.py +2 -1
- chia/_tests/plotting/test_plot_manager.py +54 -11
- chia/_tests/plotting/util.py +2 -3
- chia/_tests/pools/test_pool_cli_parsing.py +128 -0
- chia/_tests/pools/test_pool_cmdline.py +993 -15
- chia/_tests/pools/test_pool_config.py +3 -5
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +10 -11
- chia/_tests/pools/test_pool_rpc.py +203 -90
- chia/_tests/pools/test_pool_wallet.py +12 -8
- chia/_tests/pools/test_wallet_pool_store.py +3 -3
- chia/_tests/process_junit.py +16 -17
- chia/_tests/rpc/test_rpc_client.py +59 -2
- chia/_tests/rpc/test_rpc_server.py +183 -0
- chia/_tests/simulation/test_simulation.py +5 -5
- chia/_tests/simulation/test_simulator.py +8 -10
- chia/_tests/simulation/test_start_simulator.py +5 -4
- chia/_tests/timelord/test_new_peak.py +19 -19
- chia/_tests/tools/test_run_block.py +1 -2
- chia/_tests/tools/test_virtual_project.py +591 -0
- chia/_tests/util/benchmark_cost.py +9 -9
- chia/_tests/util/benchmarks.py +1 -2
- chia/_tests/util/blockchain.py +12 -11
- chia/_tests/util/blockchain_mock.py +15 -15
- chia/_tests/util/build_network_protocol_files.py +12 -12
- chia/_tests/util/db_connection.py +3 -2
- chia/_tests/util/full_sync.py +14 -6
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/generator_tools_testing.py +5 -7
- chia/_tests/util/get_name_puzzle_conditions.py +52 -0
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +59 -106
- chia/_tests/util/network_protocol_data.py +7 -9
- chia/_tests/util/protocol_messages_json.py +112 -111
- chia/_tests/util/rpc.py +3 -0
- chia/_tests/util/run_block.py +16 -16
- chia/_tests/util/setup_nodes.py +25 -23
- chia/{clvm → _tests/util}/spend_sim.py +59 -55
- chia/_tests/util/split_managers.py +12 -9
- chia/_tests/util/temp_file.py +1 -1
- chia/_tests/util/test_action_scope.py +2 -1
- chia/_tests/util/test_async_pool.py +8 -8
- chia/_tests/util/test_build_job_matrix.py +2 -3
- chia/_tests/util/test_condition_tools.py +4 -6
- chia/_tests/util/test_config.py +5 -5
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +19 -11
- chia/_tests/util/test_limited_semaphore.py +4 -3
- chia/_tests/util/test_logging_filter.py +2 -3
- chia/_tests/util/test_misc.py +29 -28
- chia/_tests/util/test_network.py +32 -31
- chia/_tests/util/test_network_protocol_files.py +2 -3
- chia/_tests/util/test_network_protocol_json.py +1 -0
- chia/_tests/util/test_network_protocol_test.py +18 -19
- chia/_tests/util/test_paginator.py +3 -4
- chia/_tests/util/test_pprint.py +1 -1
- chia/_tests/util/test_priority_mutex.py +18 -17
- chia/_tests/util/test_recursive_replace.py +2 -2
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/test_timing.py +1 -1
- chia/_tests/util/test_trusted_peer.py +2 -2
- chia/_tests/util/time_out_assert.py +43 -6
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +117 -29
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +15 -15
- chia/_tests/wallet/cat_wallet/test_trades.py +50 -28
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -5
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +6 -6
- chia/_tests/wallet/clawback/test_clawback_metadata.py +1 -2
- chia/_tests/wallet/conftest.py +135 -74
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +25 -17
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +75 -75
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +10 -12
- chia/_tests/wallet/db_wallet/test_dl_offers.py +6 -6
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +18 -18
- chia/_tests/wallet/did_wallet/test_did.py +1277 -474
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +12 -11
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +115 -105
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +6 -7
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +16 -16
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +3 -3
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +38 -12
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +1 -1
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +31 -33
- chia/_tests/wallet/rpc/test_wallet_rpc.py +218 -171
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +36 -37
- chia/_tests/wallet/sync/test_wallet_sync.py +241 -78
- chia/_tests/wallet/test_address_type.py +20 -20
- chia/_tests/wallet/test_clvm_streamable.py +5 -5
- chia/_tests/wallet/test_coin_management.py +354 -0
- chia/_tests/wallet/test_coin_selection.py +34 -35
- chia/_tests/wallet/test_conditions.py +28 -16
- chia/_tests/wallet/test_debug_spend_bundle.py +156 -14
- chia/_tests/wallet/test_new_wallet_protocol.py +29 -31
- chia/_tests/wallet/test_nft_store.py +1 -2
- chia/_tests/wallet/test_notifications.py +2 -2
- chia/_tests/wallet/test_offer_parsing_performance.py +1 -1
- chia/_tests/wallet/test_puzzle_store.py +2 -3
- chia/_tests/wallet/test_sign_coin_spends.py +3 -3
- chia/_tests/wallet/test_signer_protocol.py +33 -34
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +29 -29
- chia/_tests/wallet/test_taproot.py +1 -1
- chia/_tests/wallet/test_transaction_store.py +23 -19
- chia/_tests/wallet/test_util.py +36 -32
- chia/_tests/wallet/test_wallet.py +37 -37
- chia/_tests/wallet/test_wallet_action_scope.py +8 -8
- chia/_tests/wallet/test_wallet_blockchain.py +4 -6
- chia/_tests/wallet/test_wallet_coin_store.py +34 -34
- chia/_tests/wallet/test_wallet_node.py +69 -72
- chia/_tests/wallet/test_wallet_retry.py +3 -3
- chia/_tests/wallet/test_wallet_state_manager.py +12 -5
- chia/_tests/wallet/test_wallet_trade_store.py +2 -2
- chia/_tests/wallet/test_wallet_utils.py +5 -4
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -3
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +18 -18
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +69 -40
- chia/_tests/wallet/wallet_block_tools.py +27 -27
- chia/_tests/weight_proof/test_weight_proof.py +30 -30
- chia/apis.py +19 -0
- chia/cmds/beta.py +8 -7
- chia/cmds/beta_funcs.py +15 -11
- chia/cmds/check_wallet_db.py +29 -27
- chia/cmds/chia.py +17 -9
- chia/cmds/cmd_classes.py +87 -79
- chia/cmds/cmd_helpers.py +242 -0
- chia/cmds/cmds_util.py +56 -66
- chia/cmds/coin_funcs.py +168 -153
- chia/cmds/coins.py +156 -194
- chia/cmds/configure.py +4 -3
- chia/cmds/dao.py +89 -33
- chia/cmds/dao_funcs.py +55 -33
- chia/cmds/data.py +7 -6
- chia/cmds/data_funcs.py +26 -21
- chia/cmds/db.py +4 -3
- chia/cmds/db_backup_func.py +2 -2
- chia/cmds/db_upgrade_func.py +3 -3
- chia/cmds/db_validate_func.py +2 -2
- chia/cmds/dev.py +2 -0
- chia/cmds/farm.py +18 -5
- chia/cmds/farm_funcs.py +17 -24
- chia/cmds/gh.py +275 -0
- chia/cmds/init.py +4 -11
- chia/cmds/init_funcs.py +9 -9
- chia/cmds/installers.py +5 -3
- chia/cmds/keys.py +56 -39
- chia/cmds/keys_funcs.py +30 -31
- chia/cmds/netspace.py +6 -3
- chia/cmds/netspace_funcs.py +3 -2
- chia/cmds/param_types.py +16 -6
- chia/cmds/passphrase.py +8 -7
- chia/cmds/passphrase_funcs.py +7 -61
- chia/cmds/peer.py +2 -1
- chia/cmds/peer_funcs.py +5 -5
- chia/cmds/plotnft.py +207 -153
- chia/cmds/plotnft_funcs.py +205 -174
- chia/cmds/plots.py +14 -6
- chia/cmds/plotters.py +2 -1
- chia/cmds/rpc.py +48 -28
- chia/cmds/show.py +2 -1
- chia/cmds/show_funcs.py +7 -6
- chia/cmds/signer.py +50 -58
- chia/cmds/sim.py +22 -14
- chia/cmds/sim_funcs.py +11 -11
- chia/cmds/start.py +3 -3
- chia/cmds/start_funcs.py +9 -12
- chia/cmds/stop.py +4 -3
- chia/cmds/units.py +1 -3
- chia/cmds/wallet.py +252 -96
- chia/cmds/wallet_funcs.py +217 -143
- chia/consensus/block_body_validation.py +133 -86
- chia/consensus/block_creation.py +42 -21
- chia/consensus/block_header_validation.py +32 -37
- chia/consensus/block_record.py +1 -2
- chia/consensus/blockchain.py +167 -180
- chia/consensus/blockchain_interface.py +10 -10
- chia/consensus/constants.py +2 -2
- chia/consensus/default_constants.py +3 -4
- chia/consensus/difficulty_adjustment.py +5 -5
- chia/consensus/find_fork_point.py +5 -5
- chia/consensus/full_block_to_block_record.py +4 -4
- chia/consensus/get_block_challenge.py +2 -2
- chia/consensus/get_block_generator.py +4 -3
- chia/consensus/multiprocess_validation.py +207 -304
- chia/consensus/vdf_info_computation.py +3 -3
- chia/daemon/client.py +46 -27
- chia/daemon/keychain_proxy.py +10 -9
- chia/daemon/keychain_server.py +18 -18
- chia/daemon/server.py +103 -113
- chia/daemon/windows_signal.py +2 -2
- chia/data_layer/data_layer.py +64 -76
- chia/data_layer/data_layer_api.py +8 -0
- chia/data_layer/data_layer_errors.py +3 -3
- chia/data_layer/data_layer_server.py +2 -2
- chia/data_layer/data_layer_util.py +71 -71
- chia/data_layer/data_layer_wallet.py +63 -67
- chia/data_layer/data_store.py +72 -72
- chia/data_layer/dl_wallet_store.py +10 -10
- chia/data_layer/download_data.py +5 -5
- chia/data_layer/s3_plugin_service.py +9 -9
- chia/data_layer/util/benchmark.py +0 -1
- chia/data_layer/util/plugin.py +2 -3
- chia/farmer/farmer.py +46 -43
- chia/farmer/farmer_api.py +27 -21
- chia/full_node/block_height_map.py +6 -6
- chia/full_node/block_store.py +41 -35
- chia/full_node/coin_store.py +42 -41
- chia/full_node/fee_estimate.py +2 -2
- chia/full_node/fee_estimation.py +1 -2
- chia/full_node/fee_history.py +5 -6
- chia/full_node/fee_tracker.py +24 -24
- chia/full_node/full_node.py +574 -300
- chia/full_node/full_node_api.py +181 -130
- chia/full_node/full_node_store.py +43 -43
- chia/full_node/hint_management.py +4 -4
- chia/full_node/hint_store.py +9 -10
- chia/full_node/mempool.py +25 -19
- chia/full_node/mempool_check_conditions.py +11 -42
- chia/full_node/mempool_manager.py +48 -53
- chia/full_node/pending_tx_cache.py +9 -9
- chia/full_node/subscriptions.py +23 -24
- chia/full_node/sync_store.py +8 -7
- chia/full_node/tx_processing_queue.py +3 -3
- chia/full_node/util/__init__.py +0 -0
- chia/full_node/weight_proof.py +79 -78
- chia/harvester/harvester.py +9 -8
- chia/harvester/harvester_api.py +19 -13
- chia/introducer/introducer.py +7 -5
- chia/introducer/introducer_api.py +9 -3
- chia/legacy/keyring.py +6 -5
- chia/plot_sync/delta.py +8 -8
- chia/plot_sync/receiver.py +12 -11
- chia/plot_sync/sender.py +15 -12
- chia/plotters/bladebit.py +12 -12
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +8 -8
- chia/plotters/plotters.py +6 -6
- chia/plotters/plotters_util.py +6 -4
- chia/plotting/cache.py +8 -7
- chia/plotting/check_plots.py +8 -8
- chia/plotting/create_plots.py +6 -6
- chia/plotting/manager.py +22 -22
- chia/plotting/util.py +31 -19
- chia/pools/pool_config.py +7 -7
- chia/pools/pool_puzzles.py +16 -16
- chia/pools/pool_wallet.py +64 -57
- chia/pools/pool_wallet_info.py +3 -3
- chia/protocols/full_node_protocol.py +3 -3
- chia/protocols/harvester_protocol.py +12 -12
- chia/protocols/introducer_protocol.py +1 -2
- chia/protocols/protocol_message_types.py +4 -4
- chia/protocols/protocol_state_machine.py +2 -2
- chia/protocols/protocol_timing.py +1 -0
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +2 -2
- chia/protocols/wallet_protocol.py +33 -33
- chia/rpc/crawler_rpc_api.py +12 -7
- chia/rpc/data_layer_rpc_api.py +49 -44
- chia/rpc/data_layer_rpc_client.py +41 -41
- chia/rpc/data_layer_rpc_util.py +7 -11
- chia/rpc/farmer_rpc_api.py +32 -27
- chia/rpc/farmer_rpc_client.py +14 -14
- chia/rpc/full_node_rpc_api.py +53 -48
- chia/rpc/full_node_rpc_client.py +30 -30
- chia/rpc/harvester_rpc_api.py +16 -11
- chia/rpc/harvester_rpc_client.py +6 -6
- chia/rpc/rpc_client.py +34 -14
- chia/rpc/rpc_server.py +117 -43
- chia/rpc/timelord_rpc_api.py +9 -4
- chia/rpc/util.py +11 -211
- chia/rpc/wallet_request_types.py +276 -60
- chia/rpc/wallet_rpc_api.py +563 -399
- chia/rpc/wallet_rpc_client.py +220 -250
- chia/seeder/crawl_store.py +6 -8
- chia/seeder/crawler.py +23 -36
- chia/seeder/crawler_api.py +28 -22
- chia/seeder/dns_server.py +99 -50
- chia/seeder/start_crawler.py +13 -9
- chia/server/address_manager.py +19 -19
- chia/server/address_manager_store.py +17 -17
- chia/server/api_protocol.py +106 -1
- chia/server/capabilities.py +3 -3
- chia/server/chia_policy.py +17 -16
- chia/server/introducer_peers.py +3 -3
- chia/server/node_discovery.py +34 -38
- chia/server/rate_limit_numbers.py +26 -16
- chia/server/rate_limits.py +67 -27
- chia/server/server.py +52 -31
- chia/server/signal_handlers.py +6 -3
- chia/server/ssl_context.py +5 -5
- chia/server/start_data_layer.py +37 -23
- chia/server/start_farmer.py +28 -16
- chia/server/start_full_node.py +29 -23
- chia/server/start_harvester.py +28 -15
- chia/server/start_introducer.py +27 -15
- chia/server/start_service.py +17 -29
- chia/server/start_timelord.py +25 -18
- chia/server/start_wallet.py +22 -18
- chia/server/upnp.py +4 -3
- chia/server/ws_connection.py +68 -54
- chia/simulator/add_blocks_in_batches.py +54 -0
- chia/simulator/block_tools.py +65 -64
- chia/simulator/full_node_simulator.py +66 -74
- chia/simulator/setup_services.py +10 -9
- chia/simulator/simulator_full_node_rpc_api.py +12 -14
- chia/simulator/simulator_full_node_rpc_client.py +3 -5
- chia/simulator/simulator_test_tools.py +8 -7
- chia/simulator/socket.py +1 -4
- chia/simulator/ssl_certs.py +5 -5
- chia/simulator/ssl_certs_1.py +2 -4
- chia/simulator/ssl_certs_10.py +2 -4
- chia/simulator/ssl_certs_2.py +2 -4
- chia/simulator/ssl_certs_3.py +2 -4
- chia/simulator/ssl_certs_4.py +2 -4
- chia/simulator/ssl_certs_5.py +2 -4
- chia/simulator/ssl_certs_6.py +2 -4
- chia/simulator/ssl_certs_7.py +2 -4
- chia/simulator/ssl_certs_8.py +2 -4
- chia/simulator/ssl_certs_9.py +2 -4
- chia/simulator/start_simulator.py +14 -6
- chia/simulator/wallet_tools.py +21 -20
- chia/ssl/create_ssl.py +11 -11
- chia/timelord/iters_from_block.py +2 -2
- chia/timelord/timelord.py +57 -33
- chia/timelord/timelord_api.py +12 -6
- chia/timelord/timelord_launcher.py +10 -8
- chia/timelord/timelord_state.py +5 -5
- chia/types/block_protocol.py +2 -2
- chia/types/blockchain_format/coin.py +3 -3
- chia/types/blockchain_format/program.py +17 -18
- chia/types/blockchain_format/tree_hash.py +9 -9
- chia/types/coin_spend.py +8 -8
- chia/types/condition_with_args.py +1 -2
- chia/types/eligible_coin_spends.py +16 -15
- chia/types/generator_types.py +1 -2
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +7 -7
- chia/types/mempool_submission_status.py +2 -2
- chia/types/peer_info.py +1 -1
- chia/types/spend_bundle.py +1 -2
- chia/types/transaction_queue_entry.py +2 -2
- chia/types/unfinished_header_block.py +2 -2
- chia/types/validation_state.py +14 -0
- chia/types/weight_proof.py +5 -6
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +6 -4
- chia/util/augmented_chain.py +13 -9
- chia/util/batches.py +5 -2
- chia/util/bech32m.py +14 -11
- chia/util/beta_metrics.py +5 -4
- chia/util/block_cache.py +5 -5
- chia/util/byte_types.py +2 -0
- chia/util/check_fork_next_block.py +3 -2
- chia/util/chia_logging.py +41 -21
- chia/util/collection.py +3 -3
- chia/util/condition_tools.py +18 -18
- chia/util/config.py +26 -25
- chia/util/cpu.py +2 -0
- chia/util/db_synchronous.py +2 -0
- chia/util/db_version.py +2 -0
- chia/util/db_wrapper.py +13 -10
- chia/util/default_root.py +17 -0
- chia/util/dump_keyring.py +6 -6
- chia/util/errors.py +5 -3
- chia/util/file_keyring.py +22 -33
- chia/util/files.py +2 -0
- chia/util/full_block_utils.py +31 -7
- chia/util/generator_tools.py +18 -8
- chia/util/hash.py +3 -1
- chia/util/initial-config.yaml +19 -0
- chia/util/inline_executor.py +2 -0
- chia/util/ip_address.py +39 -0
- chia/util/json_util.py +0 -4
- chia/util/keychain.py +27 -24
- chia/util/keyring_wrapper.py +65 -4
- chia/util/limited_semaphore.py +3 -1
- chia/util/lock.py +4 -2
- chia/util/log_exceptions.py +5 -2
- chia/util/logging.py +3 -1
- chia/util/lru_cache.py +2 -0
- chia/util/math.py +4 -4
- chia/util/network.py +15 -73
- chia/util/paginator.py +3 -1
- chia/util/path.py +2 -0
- chia/util/permissions.py +3 -2
- chia/util/prev_transaction_block.py +1 -3
- chia/util/priority_mutex.py +6 -3
- chia/util/profiler.py +7 -4
- chia/util/recursive_replace.py +2 -0
- chia/util/safe_cancel_task.py +2 -0
- chia/util/service_groups.py +2 -2
- chia/util/setproctitle.py +2 -0
- chia/util/significant_bits.py +2 -0
- chia/util/ssl_check.py +11 -11
- chia/util/streamable.py +44 -56
- chia/util/task_referencer.py +59 -0
- chia/util/task_timing.py +22 -18
- chia/util/timing.py +4 -1
- chia/util/vdf_prover.py +2 -3
- chia/util/virtual_project_analysis.py +540 -0
- chia/util/ws_message.py +6 -6
- chia/wallet/cat_wallet/cat_info.py +3 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -3
- chia/wallet/cat_wallet/cat_utils.py +5 -4
- chia/wallet/cat_wallet/cat_wallet.py +56 -70
- chia/wallet/cat_wallet/dao_cat_info.py +3 -3
- chia/wallet/cat_wallet/dao_cat_wallet.py +18 -18
- chia/wallet/cat_wallet/lineage_store.py +2 -2
- chia/wallet/coin_selection.py +15 -15
- chia/wallet/conditions.py +257 -71
- chia/wallet/dao_wallet/dao_info.py +4 -4
- chia/wallet/dao_wallet/dao_utils.py +43 -42
- chia/wallet/dao_wallet/dao_wallet.py +66 -68
- chia/wallet/db_wallet/db_wallet_puzzles.py +12 -8
- chia/wallet/derive_keys.py +11 -11
- chia/wallet/did_wallet/did_info.py +3 -3
- chia/wallet/did_wallet/did_wallet.py +56 -47
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -6
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/nft_info.py +4 -4
- chia/wallet/nft_wallet/nft_puzzles.py +16 -16
- chia/wallet/nft_wallet/nft_wallet.py +90 -89
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/transfer_program_puzzle.py +2 -2
- chia/wallet/nft_wallet/uncurry_nft.py +2 -2
- chia/wallet/notification_manager.py +5 -5
- chia/wallet/notification_store.py +6 -6
- chia/wallet/outer_puzzles.py +2 -2
- chia/wallet/payment.py +4 -5
- chia/wallet/puzzle_drivers.py +4 -4
- chia/wallet/puzzles/clawback/drivers.py +5 -5
- chia/wallet/puzzles/clawback/puzzle_decorator.py +7 -7
- chia/wallet/puzzles/load_clvm.py +2 -3
- chia/wallet/puzzles/p2_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_puzzle.py +2 -3
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -4
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +1 -2
- chia/wallet/puzzles/p2_puzzle_hash.py +1 -2
- chia/wallet/puzzles/puzzle_utils.py +7 -7
- chia/wallet/puzzles/singleton_top_layer.py +6 -5
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +6 -5
- chia/wallet/puzzles/tails.py +34 -30
- chia/wallet/signer_protocol.py +7 -8
- chia/wallet/singleton.py +4 -4
- chia/wallet/trade_manager.py +155 -141
- chia/wallet/trade_record.py +5 -5
- chia/wallet/trading/offer.py +100 -101
- chia/wallet/trading/trade_store.py +14 -14
- chia/wallet/transaction_record.py +31 -16
- chia/wallet/util/address_type.py +4 -4
- chia/wallet/util/blind_signer_tl.py +8 -12
- chia/wallet/util/clvm_streamable.py +15 -15
- chia/wallet/util/compute_hints.py +5 -5
- chia/wallet/util/compute_memos.py +4 -6
- chia/wallet/util/curry_and_treehash.py +3 -2
- chia/wallet/util/debug_spend_bundle.py +6 -8
- chia/wallet/util/merkle_tree.py +10 -10
- chia/wallet/util/merkle_utils.py +10 -10
- chia/wallet/util/new_peak_queue.py +3 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/{util → wallet/util}/pprint.py +2 -3
- chia/wallet/util/puzzle_compression.py +3 -4
- chia/wallet/util/puzzle_decorator.py +10 -10
- chia/wallet/util/query_filter.py +9 -10
- chia/wallet/util/tx_config.py +12 -12
- chia/wallet/util/wallet_sync_utils.py +24 -21
- chia/wallet/util/wallet_types.py +9 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +28 -27
- chia/wallet/vc_wallet/cr_cat_wallet.py +42 -40
- chia/wallet/vc_wallet/cr_outer_puzzle.py +4 -4
- chia/wallet/vc_wallet/vc_drivers.py +16 -16
- chia/wallet/vc_wallet/vc_store.py +9 -9
- chia/wallet/vc_wallet/vc_wallet.py +35 -35
- chia/wallet/wallet.py +54 -54
- chia/wallet/wallet_action_scope.py +14 -13
- chia/wallet/wallet_blockchain.py +10 -10
- chia/wallet/wallet_coin_record.py +2 -2
- chia/wallet/wallet_coin_store.py +10 -10
- chia/wallet/wallet_info.py +1 -2
- chia/wallet/wallet_interested_store.py +5 -5
- chia/wallet/wallet_nft_store.py +6 -6
- chia/wallet/wallet_node.py +72 -76
- chia/wallet/wallet_node_api.py +33 -27
- chia/wallet/wallet_pool_store.py +1 -2
- chia/wallet/wallet_protocol.py +15 -15
- chia/wallet/wallet_puzzle_store.py +35 -4
- chia/wallet/wallet_retry_store.py +2 -2
- chia/wallet/wallet_singleton_store.py +10 -9
- chia/wallet/wallet_spend_bundle.py +4 -20
- chia/wallet/wallet_state_manager.py +223 -224
- chia/wallet/wallet_transaction_store.py +44 -18
- chia/wallet/wallet_user_store.py +2 -2
- chia/wallet/wallet_weight_proof_handler.py +2 -2
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/LICENSE +1 -1
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/METADATA +67 -72
- chia_blockchain-2.5.1rc2.dist-info/RECORD +1042 -0
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/WHEEL +1 -1
- mozilla-ca/cacert.pem +32 -87
- chia/_tests/cmds/wallet/test_coins.py +0 -195
- chia/consensus/block_root_validation.py +0 -46
- chia/util/api_decorators.py +0 -89
- chia_blockchain-2.5.0rc2.dist-info/RECORD +0 -1028
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/entry_points.txt +0 -0
chia/server/node_discovery.py
CHANGED
|
@@ -9,7 +9,7 @@ from logging import Logger
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from random import Random
|
|
11
11
|
from secrets import randbits
|
|
12
|
-
from typing import Any,
|
|
12
|
+
from typing import Any, Optional
|
|
13
13
|
|
|
14
14
|
import dns.asyncresolver
|
|
15
15
|
|
|
@@ -24,7 +24,10 @@ from chia.server.ws_connection import WSChiaConnection
|
|
|
24
24
|
from chia.types.peer_info import PeerInfo, TimestampedPeerInfo, UnresolvedPeerInfo
|
|
25
25
|
from chia.util.hash import std_hash
|
|
26
26
|
from chia.util.ints import uint16, uint64
|
|
27
|
-
from chia.util.
|
|
27
|
+
from chia.util.ip_address import IPAddress
|
|
28
|
+
from chia.util.network import resolve
|
|
29
|
+
from chia.util.safe_cancel_task import cancel_task_safe
|
|
30
|
+
from chia.util.task_referencer import create_referenced_task
|
|
28
31
|
|
|
29
32
|
MAX_PEERS_RECEIVED_PER_REQUEST = 1000
|
|
30
33
|
MAX_TOTAL_PEERS_RECEIVED = 3000
|
|
@@ -46,8 +49,8 @@ class FullNodeDiscovery:
|
|
|
46
49
|
server: ChiaServer,
|
|
47
50
|
target_outbound_count: int,
|
|
48
51
|
peers_file_path: Path,
|
|
49
|
-
introducer_info: Optional[
|
|
50
|
-
dns_servers:
|
|
52
|
+
introducer_info: Optional[dict[str, Any]],
|
|
53
|
+
dns_servers: list[str],
|
|
51
54
|
peer_connect_interval: int,
|
|
52
55
|
selected_network: str,
|
|
53
56
|
default_port: Optional[int],
|
|
@@ -68,10 +71,10 @@ class FullNodeDiscovery:
|
|
|
68
71
|
self.enable_private_networks = False
|
|
69
72
|
self.peer_connect_interval = peer_connect_interval
|
|
70
73
|
self.log = log
|
|
71
|
-
self.relay_queue: Optional[asyncio.Queue[
|
|
74
|
+
self.relay_queue: Optional[asyncio.Queue[tuple[TimestampedPeerInfo, int]]] = None
|
|
72
75
|
self.address_manager: Optional[AddressManager] = None
|
|
73
|
-
self.connection_time_pretest:
|
|
74
|
-
self.received_count_from_peers:
|
|
76
|
+
self.connection_time_pretest: dict[str, Any] = {}
|
|
77
|
+
self.received_count_from_peers: dict[str, Any] = {}
|
|
75
78
|
self.lock = asyncio.Lock()
|
|
76
79
|
self.connect_peers_task: Optional[asyncio.Task[None]] = None
|
|
77
80
|
self.serialize_task: Optional[asyncio.Task[None]] = None
|
|
@@ -82,8 +85,8 @@ class FullNodeDiscovery:
|
|
|
82
85
|
except Exception:
|
|
83
86
|
self.resolver = None
|
|
84
87
|
self.log.exception("Error initializing asyncresolver")
|
|
85
|
-
self.pending_outbound_connections:
|
|
86
|
-
self.pending_tasks:
|
|
88
|
+
self.pending_outbound_connections: set[str] = set()
|
|
89
|
+
self.pending_tasks: set[asyncio.Task[None]] = set()
|
|
87
90
|
self.default_port: Optional[int] = default_port
|
|
88
91
|
if default_port is None and selected_network in NETWORK_ID_DEFAULT_PORTS:
|
|
89
92
|
self.default_port = NETWORK_ID_DEFAULT_PORTS[selected_network]
|
|
@@ -96,27 +99,20 @@ class FullNodeDiscovery:
|
|
|
96
99
|
|
|
97
100
|
async def start_tasks(self) -> None:
|
|
98
101
|
random = Random()
|
|
99
|
-
self.connect_peers_task =
|
|
100
|
-
self.serialize_task =
|
|
101
|
-
self.cleanup_task =
|
|
102
|
+
self.connect_peers_task = create_referenced_task(self._connect_to_peers(random))
|
|
103
|
+
self.serialize_task = create_referenced_task(self._periodically_serialize(random))
|
|
104
|
+
self.cleanup_task = create_referenced_task(self._periodically_cleanup())
|
|
102
105
|
|
|
103
106
|
async def _close_common(self) -> None:
|
|
104
107
|
self.is_closed = True
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
cancel_task_safe(self.connect_peers_task, self.log)
|
|
109
|
+
cancel_task_safe(self.serialize_task, self.log)
|
|
110
|
+
cancel_task_safe(self.cleanup_task, self.log)
|
|
108
111
|
for t in self.pending_tasks:
|
|
109
|
-
|
|
112
|
+
cancel_task_safe(t, self.log)
|
|
110
113
|
if len(self.pending_tasks) > 0:
|
|
111
114
|
await asyncio.wait(self.pending_tasks)
|
|
112
115
|
|
|
113
|
-
def cancel_task_safe(self, task: Optional[asyncio.Task[None]]) -> None:
|
|
114
|
-
if task is not None:
|
|
115
|
-
try:
|
|
116
|
-
task.cancel()
|
|
117
|
-
except Exception as e:
|
|
118
|
-
self.log.error(f"Error while canceling task.{e} {task}")
|
|
119
|
-
|
|
120
116
|
async def on_connect(self, peer: WSChiaConnection) -> None:
|
|
121
117
|
if (
|
|
122
118
|
peer.is_outbound is False
|
|
@@ -201,7 +197,7 @@ class FullNodeDiscovery:
|
|
|
201
197
|
self.log.warning("Skipping DNS query: asyncresolver not initialized.")
|
|
202
198
|
return
|
|
203
199
|
for rdtype in ["A", "AAAA"]:
|
|
204
|
-
peers:
|
|
200
|
+
peers: list[TimestampedPeerInfo] = []
|
|
205
201
|
result = await self.resolver.resolve(qname=dns_address, rdtype=rdtype, lifetime=30)
|
|
206
202
|
for ip in result:
|
|
207
203
|
peers.append(
|
|
@@ -402,7 +398,7 @@ class FullNodeDiscovery:
|
|
|
402
398
|
self.log.debug("Max concurrent outbound connections reached. waiting")
|
|
403
399
|
await asyncio.wait(self.pending_tasks, return_when=asyncio.FIRST_COMPLETED)
|
|
404
400
|
self.pending_tasks.add(
|
|
405
|
-
|
|
401
|
+
create_referenced_task(self.start_client_async(addr, disconnect_after_handshake))
|
|
406
402
|
)
|
|
407
403
|
|
|
408
404
|
await asyncio.sleep(connect_peer_interval)
|
|
@@ -448,7 +444,7 @@ class FullNodeDiscovery:
|
|
|
448
444
|
return port in NETWORK_ID_DEFAULT_PORTS.values() and port != self.default_port
|
|
449
445
|
|
|
450
446
|
async def _add_peers_common(
|
|
451
|
-
self, peer_list:
|
|
447
|
+
self, peer_list: list[TimestampedPeerInfo], peer_src: Optional[PeerInfo], is_full_node: bool
|
|
452
448
|
) -> None:
|
|
453
449
|
# Check if we got the peers from a full node or from the introducer.
|
|
454
450
|
peers_adjusted_timestamp = []
|
|
@@ -503,8 +499,8 @@ class FullNodePeers(FullNodeDiscovery):
|
|
|
503
499
|
server: ChiaServer,
|
|
504
500
|
target_outbound_count: int,
|
|
505
501
|
peers_file_path: Path,
|
|
506
|
-
introducer_info:
|
|
507
|
-
dns_servers:
|
|
502
|
+
introducer_info: dict[str, Any],
|
|
503
|
+
dns_servers: list[str],
|
|
508
504
|
peer_connect_interval: int,
|
|
509
505
|
selected_network: str,
|
|
510
506
|
default_port: Optional[int],
|
|
@@ -522,19 +518,19 @@ class FullNodePeers(FullNodeDiscovery):
|
|
|
522
518
|
log,
|
|
523
519
|
)
|
|
524
520
|
self.relay_queue = asyncio.Queue()
|
|
525
|
-
self.neighbour_known_peers:
|
|
521
|
+
self.neighbour_known_peers: dict[PeerInfo, set[str]] = {}
|
|
526
522
|
self.key = randbits(256)
|
|
527
523
|
|
|
528
524
|
async def start(self) -> None:
|
|
529
525
|
await self.initialize_address_manager()
|
|
530
|
-
self.self_advertise_task =
|
|
531
|
-
self.address_relay_task =
|
|
526
|
+
self.self_advertise_task = create_referenced_task(self._periodically_self_advertise_and_clean_data())
|
|
527
|
+
self.address_relay_task = create_referenced_task(self._address_relay())
|
|
532
528
|
await self.start_tasks()
|
|
533
529
|
|
|
534
530
|
async def close(self) -> None:
|
|
535
531
|
await self._close_common()
|
|
536
|
-
|
|
537
|
-
|
|
532
|
+
cancel_task_safe(self.self_advertise_task, self.log)
|
|
533
|
+
cancel_task_safe(self.address_relay_task, self.log)
|
|
538
534
|
|
|
539
535
|
async def _periodically_self_advertise_and_clean_data(self) -> None:
|
|
540
536
|
while not self.is_closed:
|
|
@@ -571,7 +567,7 @@ class FullNodePeers(FullNodeDiscovery):
|
|
|
571
567
|
self.log.error(f"Exception in self advertise: {e}")
|
|
572
568
|
self.log.error(f"Traceback: {traceback.format_exc()}")
|
|
573
569
|
|
|
574
|
-
async def add_peers_neighbour(self, peers:
|
|
570
|
+
async def add_peers_neighbour(self, peers: list[TimestampedPeerInfo], neighbour_info: PeerInfo) -> None:
|
|
575
571
|
async with self.lock:
|
|
576
572
|
for peer in peers:
|
|
577
573
|
if neighbour_info not in self.neighbour_known_peers:
|
|
@@ -604,7 +600,7 @@ class FullNodePeers(FullNodeDiscovery):
|
|
|
604
600
|
return None
|
|
605
601
|
|
|
606
602
|
async def add_peers(
|
|
607
|
-
self, peer_list:
|
|
603
|
+
self, peer_list: list[TimestampedPeerInfo], peer_src: Optional[PeerInfo], is_full_node: bool
|
|
608
604
|
) -> None:
|
|
609
605
|
try:
|
|
610
606
|
await self._add_peers_common(peer_list, peer_src, is_full_node)
|
|
@@ -683,8 +679,8 @@ class WalletPeers(FullNodeDiscovery):
|
|
|
683
679
|
server: ChiaServer,
|
|
684
680
|
target_outbound_count: int,
|
|
685
681
|
peers_file_path: Path,
|
|
686
|
-
introducer_info:
|
|
687
|
-
dns_servers:
|
|
682
|
+
introducer_info: dict[str, Any],
|
|
683
|
+
dns_servers: list[str],
|
|
688
684
|
peer_connect_interval: int,
|
|
689
685
|
selected_network: str,
|
|
690
686
|
default_port: Optional[int],
|
|
@@ -713,6 +709,6 @@ class WalletPeers(FullNodeDiscovery):
|
|
|
713
709
|
await self._close_common()
|
|
714
710
|
|
|
715
711
|
async def add_peers(
|
|
716
|
-
self, peer_list:
|
|
712
|
+
self, peer_list: list[TimestampedPeerInfo], peer_src: Optional[PeerInfo], is_full_node: bool
|
|
717
713
|
) -> None:
|
|
718
714
|
await self._add_peers_common(peer_list, peer_src, is_full_node)
|
|
@@ -4,14 +4,16 @@ from __future__ import annotations
|
|
|
4
4
|
import copy
|
|
5
5
|
import dataclasses
|
|
6
6
|
import functools
|
|
7
|
-
from typing import Any,
|
|
7
|
+
from typing import Any, Optional
|
|
8
8
|
|
|
9
9
|
from chia.protocols.protocol_message_types import ProtocolMessageTypes
|
|
10
10
|
from chia.protocols.shared_protocol import Capability
|
|
11
11
|
|
|
12
|
-
compose_rate_limits_cache:
|
|
12
|
+
compose_rate_limits_cache: dict[int, dict[str, Any]] = {}
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
# this class is used to configure the *rate* limit for a message type. The
|
|
16
|
+
# limits are counts and size per 60 seconds.
|
|
15
17
|
@dataclasses.dataclass(frozen=True)
|
|
16
18
|
class RLSettings:
|
|
17
19
|
frequency: int # Max request per time period (ie 1 min)
|
|
@@ -19,7 +21,15 @@ class RLSettings:
|
|
|
19
21
|
max_total_size: Optional[int] = None # Max cumulative size of all requests in that period
|
|
20
22
|
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
# this class is used to indicate that a message type is not subject to a rate
|
|
25
|
+
# limit, but just a per-message size limit. This may be appropriate for response
|
|
26
|
+
# messages that are implicitly limited by their corresponding request message
|
|
27
|
+
@dataclasses.dataclass(frozen=True)
|
|
28
|
+
class Unlimited:
|
|
29
|
+
max_size: int # Max size of each request
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_rate_limits_to_use(our_capabilities: list[Capability], peer_capabilities: list[Capability]) -> dict[str, Any]:
|
|
23
33
|
# This will use the newest possible rate limits that both peers support. At this time there are only two
|
|
24
34
|
# options, v1 and v2.
|
|
25
35
|
|
|
@@ -35,14 +45,14 @@ def get_rate_limits_to_use(our_capabilities: List[Capability], peer_capabilities
|
|
|
35
45
|
return rate_limits[1]
|
|
36
46
|
|
|
37
47
|
|
|
38
|
-
def compose_rate_limits(old_rate_limits:
|
|
48
|
+
def compose_rate_limits(old_rate_limits: dict[str, Any], new_rate_limits: dict[str, Any]) -> dict[str, Any]:
|
|
39
49
|
# Composes two rate limits dicts, so that the newer values override the older values
|
|
40
|
-
final_rate_limits:
|
|
41
|
-
categories:
|
|
42
|
-
all_new_msgs_lists:
|
|
50
|
+
final_rate_limits: dict[str, Any] = copy.deepcopy(new_rate_limits)
|
|
51
|
+
categories: list[str] = ["rate_limits_tx", "rate_limits_other"]
|
|
52
|
+
all_new_msgs_lists: list[list[ProtocolMessageTypes]] = [
|
|
43
53
|
list(new_rate_limits[category].keys()) for category in categories
|
|
44
54
|
]
|
|
45
|
-
all_new_msgs:
|
|
55
|
+
all_new_msgs: list[ProtocolMessageTypes] = functools.reduce(lambda a, b: a + b, all_new_msgs_lists)
|
|
46
56
|
for old_cat, mapping in old_rate_limits.items():
|
|
47
57
|
if old_cat in categories:
|
|
48
58
|
for old_protocol_msg, old_rate_limit_value in mapping.items():
|
|
@@ -94,11 +104,11 @@ rate_limits = {
|
|
|
94
104
|
ProtocolMessageTypes.request_proof_of_weight: RLSettings(5, 100),
|
|
95
105
|
ProtocolMessageTypes.respond_proof_of_weight: RLSettings(5, 50 * 1024 * 1024, 100 * 1024 * 1024),
|
|
96
106
|
ProtocolMessageTypes.request_block: RLSettings(200, 100),
|
|
97
|
-
ProtocolMessageTypes.reject_block:
|
|
107
|
+
ProtocolMessageTypes.reject_block: Unlimited(100),
|
|
98
108
|
ProtocolMessageTypes.request_blocks: RLSettings(500, 100),
|
|
99
|
-
ProtocolMessageTypes.respond_blocks:
|
|
100
|
-
ProtocolMessageTypes.reject_blocks:
|
|
101
|
-
ProtocolMessageTypes.respond_block:
|
|
109
|
+
ProtocolMessageTypes.respond_blocks: Unlimited(50 * 1024 * 1024),
|
|
110
|
+
ProtocolMessageTypes.reject_blocks: Unlimited(100),
|
|
111
|
+
ProtocolMessageTypes.respond_block: Unlimited(2 * 1024 * 1024),
|
|
102
112
|
ProtocolMessageTypes.new_unfinished_block: RLSettings(200, 100),
|
|
103
113
|
ProtocolMessageTypes.request_unfinished_block: RLSettings(200, 100),
|
|
104
114
|
ProtocolMessageTypes.new_unfinished_block2: RLSettings(200, 100),
|
|
@@ -144,10 +154,10 @@ rate_limits = {
|
|
|
144
154
|
ProtocolMessageTypes.plot_sync_done: RLSettings(1000, 100 * 1024 * 1024),
|
|
145
155
|
ProtocolMessageTypes.plot_sync_response: RLSettings(3000, 100 * 1024 * 1024),
|
|
146
156
|
ProtocolMessageTypes.coin_state_update: RLSettings(1000, 100 * 1024 * 1024),
|
|
147
|
-
ProtocolMessageTypes.
|
|
148
|
-
ProtocolMessageTypes.
|
|
149
|
-
ProtocolMessageTypes.
|
|
150
|
-
ProtocolMessageTypes.
|
|
157
|
+
ProtocolMessageTypes.register_for_ph_updates: RLSettings(1000, 100 * 1024 * 1024),
|
|
158
|
+
ProtocolMessageTypes.respond_to_ph_updates: RLSettings(1000, 100 * 1024 * 1024),
|
|
159
|
+
ProtocolMessageTypes.register_for_coin_updates: RLSettings(1000, 100 * 1024 * 1024),
|
|
160
|
+
ProtocolMessageTypes.respond_to_coin_updates: RLSettings(1000, 100 * 1024 * 1024),
|
|
151
161
|
ProtocolMessageTypes.request_remove_puzzle_subscriptions: RLSettings(1000, 100 * 1024 * 1024),
|
|
152
162
|
ProtocolMessageTypes.respond_remove_puzzle_subscriptions: RLSettings(1000, 100 * 1024 * 1024),
|
|
153
163
|
ProtocolMessageTypes.request_remove_coin_subscriptions: RLSettings(1000, 100 * 1024 * 1024),
|
chia/server/rate_limits.py
CHANGED
|
@@ -4,12 +4,12 @@ import dataclasses
|
|
|
4
4
|
import logging
|
|
5
5
|
import time
|
|
6
6
|
from collections import Counter
|
|
7
|
-
from typing import
|
|
7
|
+
from typing import Optional
|
|
8
8
|
|
|
9
9
|
from chia.protocols.protocol_message_types import ProtocolMessageTypes
|
|
10
10
|
from chia.protocols.shared_protocol import Capability
|
|
11
11
|
from chia.server.outbound_message import Message
|
|
12
|
-
from chia.server.rate_limit_numbers import RLSettings, get_rate_limits_to_use
|
|
12
|
+
from chia.server.rate_limit_numbers import RLSettings, Unlimited, get_rate_limits_to_use
|
|
13
13
|
|
|
14
14
|
log = logging.getLogger(__name__)
|
|
15
15
|
|
|
@@ -43,10 +43,12 @@ class RateLimiter:
|
|
|
43
43
|
self.non_tx_cumulative_size = 0
|
|
44
44
|
|
|
45
45
|
def process_msg_and_check(
|
|
46
|
-
self, message: Message, our_capabilities:
|
|
47
|
-
) ->
|
|
46
|
+
self, message: Message, our_capabilities: list[Capability], peer_capabilities: list[Capability]
|
|
47
|
+
) -> Optional[str]:
|
|
48
48
|
"""
|
|
49
|
-
Returns
|
|
49
|
+
Returns a string indicating which limit was hit if a rate limit is
|
|
50
|
+
exceeded, and the message should be blocked. Returns None if the limit was not
|
|
51
|
+
hit and the message is good to be sent or received.
|
|
50
52
|
"""
|
|
51
53
|
|
|
52
54
|
current_minute = int(time.time() // self.reset_seconds)
|
|
@@ -60,7 +62,7 @@ class RateLimiter:
|
|
|
60
62
|
message_type = ProtocolMessageTypes(message.type)
|
|
61
63
|
except Exception as e:
|
|
62
64
|
log.warning(f"Invalid message: {message.type}, {e}")
|
|
63
|
-
return
|
|
65
|
+
return None
|
|
64
66
|
|
|
65
67
|
new_message_counts: int = self.message_counts[message_type] + 1
|
|
66
68
|
new_cumulative_size: int = self.message_cumulative_sizes[message_type] + len(message.data)
|
|
@@ -77,30 +79,68 @@ class RateLimiter:
|
|
|
77
79
|
limits = rate_limits["rate_limits_tx"][message_type]
|
|
78
80
|
elif message_type in rate_limits["rate_limits_other"]:
|
|
79
81
|
limits = rate_limits["rate_limits_other"][message_type]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
if isinstance(limits, RLSettings):
|
|
83
|
+
non_tx_freq = rate_limits["non_tx_freq"]
|
|
84
|
+
non_tx_max_total_size = rate_limits["non_tx_max_total_size"]
|
|
85
|
+
new_non_tx_count = self.non_tx_message_counts + 1
|
|
86
|
+
new_non_tx_size = self.non_tx_cumulative_size + len(message.data)
|
|
87
|
+
if new_non_tx_count > non_tx_freq * proportion_of_limit:
|
|
88
|
+
return " ".join(
|
|
89
|
+
[
|
|
90
|
+
f"non-tx count: {new_non_tx_count}",
|
|
91
|
+
f"> {non_tx_freq * proportion_of_limit}",
|
|
92
|
+
f"(scale factor: {proportion_of_limit})",
|
|
93
|
+
]
|
|
94
|
+
)
|
|
95
|
+
if new_non_tx_size > non_tx_max_total_size * proportion_of_limit:
|
|
96
|
+
return " ".join(
|
|
97
|
+
[
|
|
98
|
+
f"non-tx size: {new_non_tx_size}",
|
|
99
|
+
f"> {non_tx_max_total_size * proportion_of_limit}",
|
|
100
|
+
f"(scale factor: {proportion_of_limit})",
|
|
101
|
+
]
|
|
102
|
+
)
|
|
103
|
+
else: # pragma: no cover
|
|
104
|
+
log.warning(
|
|
105
|
+
f"Message type {message_type} not found in rate limits (scale factor: {proportion_of_limit})",
|
|
106
|
+
)
|
|
90
107
|
|
|
91
|
-
if limits
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
if isinstance(limits, Unlimited):
|
|
109
|
+
# this message type is not rate limited. This is used for
|
|
110
|
+
# response messages and must be combined with banning peers
|
|
111
|
+
# sending unsolicited responses of this type
|
|
112
|
+
if len(message.data) > limits.max_size:
|
|
113
|
+
return f"message size: {len(message.data)} > {limits.max_size}"
|
|
114
|
+
ret = True
|
|
115
|
+
return None
|
|
116
|
+
elif isinstance(limits, RLSettings):
|
|
117
|
+
if limits.max_total_size is None:
|
|
118
|
+
limits = dataclasses.replace(limits, max_total_size=limits.frequency * limits.max_size)
|
|
119
|
+
assert limits.max_total_size is not None
|
|
94
120
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
121
|
+
if new_message_counts > limits.frequency * proportion_of_limit:
|
|
122
|
+
return " ".join(
|
|
123
|
+
[
|
|
124
|
+
f"message count: {new_message_counts}"
|
|
125
|
+
f"> {limits.frequency * proportion_of_limit}"
|
|
126
|
+
f"(scale factor: {proportion_of_limit})"
|
|
127
|
+
]
|
|
128
|
+
)
|
|
129
|
+
if len(message.data) > limits.max_size:
|
|
130
|
+
return f"message size: {len(message.data)} > {limits.max_size}"
|
|
131
|
+
if new_cumulative_size > limits.max_total_size * proportion_of_limit:
|
|
132
|
+
return " ".join(
|
|
133
|
+
[
|
|
134
|
+
f"cumulative size: {new_cumulative_size}",
|
|
135
|
+
f"> {limits.max_total_size * proportion_of_limit}",
|
|
136
|
+
f"(scale factor: {proportion_of_limit})",
|
|
137
|
+
]
|
|
138
|
+
)
|
|
101
139
|
|
|
102
|
-
|
|
103
|
-
|
|
140
|
+
ret = True
|
|
141
|
+
return None
|
|
142
|
+
else: # pragma: no cover
|
|
143
|
+
return f"Internal Error, unknown rate limit for message: {message_type}, limit: {limits}"
|
|
104
144
|
finally:
|
|
105
145
|
if self.incoming or ret:
|
|
106
146
|
# now that we determined that it's OK to send the message, commit the
|
chia/server/server.py
CHANGED
|
@@ -5,10 +5,11 @@ import logging
|
|
|
5
5
|
import ssl
|
|
6
6
|
import time
|
|
7
7
|
import traceback
|
|
8
|
+
from collections.abc import Awaitable
|
|
8
9
|
from dataclasses import dataclass, field
|
|
9
10
|
from ipaddress import IPv4Network, IPv6Network, ip_network
|
|
10
11
|
from pathlib import Path
|
|
11
|
-
from typing import Any,
|
|
12
|
+
from typing import Any, Callable, Optional, Union, cast
|
|
12
13
|
|
|
13
14
|
from aiohttp import (
|
|
14
15
|
ClientResponseError,
|
|
@@ -39,6 +40,7 @@ from chia.util.ints import uint16
|
|
|
39
40
|
from chia.util.network import WebServer, is_in_network, is_localhost, is_trusted_peer
|
|
40
41
|
from chia.util.ssl_check import verify_ssl_certs_and_keys
|
|
41
42
|
from chia.util.streamable import Streamable
|
|
43
|
+
from chia.util.task_referencer import create_referenced_task
|
|
42
44
|
|
|
43
45
|
max_message_size = 50 * 1024 * 1024 # 50MB
|
|
44
46
|
|
|
@@ -116,7 +118,7 @@ def calculate_node_id(cert_path: Path) -> bytes32:
|
|
|
116
118
|
class ChiaServer:
|
|
117
119
|
_port: Optional[int]
|
|
118
120
|
_local_type: NodeType
|
|
119
|
-
_local_capabilities_for_handshake:
|
|
121
|
+
_local_capabilities_for_handshake: list[tuple[uint16, str]]
|
|
120
122
|
_ping_interval: int
|
|
121
123
|
_network_id: str
|
|
122
124
|
_inbound_rate_limit_percent: int
|
|
@@ -124,13 +126,14 @@ class ChiaServer:
|
|
|
124
126
|
api: ApiProtocol
|
|
125
127
|
node: Any
|
|
126
128
|
root_path: Path
|
|
127
|
-
config:
|
|
129
|
+
config: dict[str, Any]
|
|
128
130
|
log: logging.Logger
|
|
129
131
|
ssl_context: ssl.SSLContext
|
|
130
132
|
ssl_client_context: ssl.SSLContext
|
|
131
133
|
node_id: bytes32
|
|
132
|
-
exempt_peer_networks:
|
|
133
|
-
|
|
134
|
+
exempt_peer_networks: list[Union[IPv4Network, IPv6Network]]
|
|
135
|
+
class_for_type: dict[NodeType, type[ApiProtocol]]
|
|
136
|
+
all_connections: dict[bytes32, WSChiaConnection] = field(default_factory=dict)
|
|
134
137
|
on_connect: Optional[ConnectionCallback] = None
|
|
135
138
|
shut_down_event: asyncio.Event = field(default_factory=asyncio.Event)
|
|
136
139
|
introducer_peers: Optional[IntroducerPeers] = None
|
|
@@ -138,7 +141,7 @@ class ChiaServer:
|
|
|
138
141
|
webserver: Optional[WebServer] = None
|
|
139
142
|
connection_close_task: Optional[asyncio.Task[None]] = None
|
|
140
143
|
received_message_callback: Optional[ConnectionCallback] = None
|
|
141
|
-
banned_peers:
|
|
144
|
+
banned_peers: dict[str, float] = field(default_factory=dict)
|
|
142
145
|
invalid_protocol_ban_seconds = INVALID_PROTOCOL_BAN_SECONDS
|
|
143
146
|
|
|
144
147
|
@classmethod
|
|
@@ -152,11 +155,12 @@ class ChiaServer:
|
|
|
152
155
|
network_id: str,
|
|
153
156
|
inbound_rate_limit_percent: int,
|
|
154
157
|
outbound_rate_limit_percent: int,
|
|
155
|
-
capabilities:
|
|
158
|
+
capabilities: list[tuple[uint16, str]],
|
|
156
159
|
root_path: Path,
|
|
157
|
-
config:
|
|
158
|
-
private_ca_crt_key:
|
|
159
|
-
chia_ca_crt_key:
|
|
160
|
+
config: dict[str, Any],
|
|
161
|
+
private_ca_crt_key: tuple[Path, Path],
|
|
162
|
+
chia_ca_crt_key: tuple[Path, Path],
|
|
163
|
+
class_for_type: dict[NodeType, type[ApiProtocol]],
|
|
160
164
|
name: str = __name__,
|
|
161
165
|
) -> ChiaServer:
|
|
162
166
|
log = logging.getLogger(name)
|
|
@@ -232,6 +236,7 @@ class ChiaServer:
|
|
|
232
236
|
node_id=calculate_node_id(node_id_cert_path),
|
|
233
237
|
exempt_peer_networks=[ip_network(net, strict=False) for net in config.get("exempt_peer_networks", [])],
|
|
234
238
|
introducer_peers=IntroducerPeers() if local_type is NodeType.INTRODUCER else None,
|
|
239
|
+
class_for_type=class_for_type,
|
|
235
240
|
)
|
|
236
241
|
|
|
237
242
|
def set_received_message_callback(self, callback: ConnectionCallback) -> None:
|
|
@@ -245,12 +250,12 @@ class ChiaServer:
|
|
|
245
250
|
is_crawler = getattr(self.node, "crawl", None)
|
|
246
251
|
while True:
|
|
247
252
|
await asyncio.sleep(600 if is_crawler is None else 2)
|
|
248
|
-
to_remove:
|
|
253
|
+
to_remove: list[WSChiaConnection] = []
|
|
249
254
|
for connection in self.all_connections.values():
|
|
250
255
|
if connection.closed:
|
|
251
256
|
to_remove.append(connection)
|
|
252
257
|
elif (
|
|
253
|
-
self._local_type
|
|
258
|
+
self._local_type in {NodeType.FULL_NODE, NodeType.WALLET}
|
|
254
259
|
) and connection.connection_type == NodeType.FULL_NODE:
|
|
255
260
|
if is_crawler is not None:
|
|
256
261
|
if time.time() - connection.creation_time > 5:
|
|
@@ -281,7 +286,7 @@ class ChiaServer:
|
|
|
281
286
|
if self.webserver is not None:
|
|
282
287
|
raise RuntimeError("ChiaServer already started")
|
|
283
288
|
if self.gc_task is None:
|
|
284
|
-
self.gc_task =
|
|
289
|
+
self.gc_task = create_referenced_task(self.garbage_collect_connections_task())
|
|
285
290
|
|
|
286
291
|
if self._port is not None:
|
|
287
292
|
self.on_connect = on_connect
|
|
@@ -332,6 +337,7 @@ class ChiaServer:
|
|
|
332
337
|
inbound_rate_limit_percent=self._inbound_rate_limit_percent,
|
|
333
338
|
outbound_rate_limit_percent=self._outbound_rate_limit_percent,
|
|
334
339
|
local_capabilities_for_handshake=self._local_capabilities_for_handshake,
|
|
340
|
+
class_for_type=self.class_for_type,
|
|
335
341
|
)
|
|
336
342
|
await connection.perform_handshake(self._network_id, self.get_port(), self._local_type)
|
|
337
343
|
assert connection.connection_type is not None, "handshake failed to set connection type, still None"
|
|
@@ -482,6 +488,7 @@ class ChiaServer:
|
|
|
482
488
|
inbound_rate_limit_percent=self._inbound_rate_limit_percent,
|
|
483
489
|
outbound_rate_limit_percent=self._outbound_rate_limit_percent,
|
|
484
490
|
local_capabilities_for_handshake=self._local_capabilities_for_handshake,
|
|
491
|
+
class_for_type=self.class_for_type,
|
|
485
492
|
session=session,
|
|
486
493
|
)
|
|
487
494
|
await connection.perform_handshake(self._network_id, server_port, self._local_type)
|
|
@@ -492,29 +499,42 @@ class ChiaServer:
|
|
|
492
499
|
connection_type_str = ""
|
|
493
500
|
if connection.connection_type is not None:
|
|
494
501
|
connection_type_str = connection.connection_type.name.lower()
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
502
|
+
if not is_feeler:
|
|
503
|
+
self.log.info(f"Connected with {connection_type_str} {target_node}")
|
|
504
|
+
else:
|
|
505
|
+
self.log.debug(f"Successful feeler connection with {connection_type_str} {target_node}")
|
|
506
|
+
create_referenced_task(connection.close(), known_unreferenced=True)
|
|
498
507
|
return True
|
|
499
508
|
except client_exceptions.ClientConnectorError as e:
|
|
500
|
-
|
|
509
|
+
if is_feeler:
|
|
510
|
+
self.log.debug(f"Feeler connection error. {e}")
|
|
511
|
+
else:
|
|
512
|
+
self.log.info(f"{e}")
|
|
501
513
|
except ProtocolError as e:
|
|
502
514
|
if connection is not None:
|
|
503
515
|
await connection.close(self.invalid_protocol_ban_seconds, WSCloseCode.PROTOCOL_ERROR, e.code)
|
|
504
516
|
if e.code == Err.INVALID_HANDSHAKE:
|
|
505
|
-
self.log.warning(
|
|
517
|
+
self.log.warning(
|
|
518
|
+
f"Invalid handshake with peer {target_node}{' during feeler connection' if is_feeler else ''}"
|
|
519
|
+
f". Maybe the peer is running old software."
|
|
520
|
+
)
|
|
506
521
|
elif e.code == Err.INCOMPATIBLE_NETWORK_ID:
|
|
507
|
-
self.log.warning(
|
|
522
|
+
self.log.warning(
|
|
523
|
+
f"Incompatible network ID{' during feeler connection' if is_feeler else ''}"
|
|
524
|
+
f". Maybe the peer is on another network"
|
|
525
|
+
)
|
|
508
526
|
elif e.code == Err.SELF_CONNECTION:
|
|
509
527
|
pass
|
|
510
528
|
else:
|
|
511
529
|
error_stack = traceback.format_exc()
|
|
512
|
-
self.log.error(
|
|
530
|
+
self.log.error(
|
|
531
|
+
f"{'Feeler connection ' if is_feeler else ''}Exception {e}, exception Stack: {error_stack}"
|
|
532
|
+
)
|
|
513
533
|
except Exception as e:
|
|
514
534
|
if connection is not None:
|
|
515
535
|
await connection.close(self.invalid_protocol_ban_seconds, WSCloseCode.PROTOCOL_ERROR, Err.UNKNOWN)
|
|
516
536
|
error_stack = traceback.format_exc()
|
|
517
|
-
self.log.error(f"Exception {e}, exception Stack: {error_stack}")
|
|
537
|
+
self.log.error(f"{'Feeler connection ' if is_feeler else ''}Exception {e}, exception Stack: {error_stack}")
|
|
518
538
|
finally:
|
|
519
539
|
if session is not None:
|
|
520
540
|
await session.close()
|
|
@@ -535,8 +555,9 @@ class ChiaServer:
|
|
|
535
555
|
ban_until: float = time.time() + ban_time
|
|
536
556
|
self.log.warning(f"Banning {connection.peer_info.host} for {ban_time} seconds")
|
|
537
557
|
if connection.peer_info.host in self.banned_peers:
|
|
538
|
-
|
|
539
|
-
self.banned_peers[connection.peer_info.host]
|
|
558
|
+
self.banned_peers[connection.peer_info.host] = max(
|
|
559
|
+
ban_until, self.banned_peers[connection.peer_info.host]
|
|
560
|
+
)
|
|
540
561
|
else:
|
|
541
562
|
self.banned_peers[connection.peer_info.host] = ban_until
|
|
542
563
|
|
|
@@ -558,7 +579,7 @@ class ChiaServer:
|
|
|
558
579
|
if on_disconnect is not None:
|
|
559
580
|
await on_disconnect(connection)
|
|
560
581
|
|
|
561
|
-
async def validate_broadcast_message_type(self, messages:
|
|
582
|
+
async def validate_broadcast_message_type(self, messages: list[Message], node_type: NodeType) -> None:
|
|
562
583
|
for message in messages:
|
|
563
584
|
if message_requires_reply(ProtocolMessageTypes(message.type)):
|
|
564
585
|
# Internal protocol logic error - we will raise, blocking messages to all peers
|
|
@@ -574,7 +595,7 @@ class ChiaServer:
|
|
|
574
595
|
|
|
575
596
|
async def send_to_all(
|
|
576
597
|
self,
|
|
577
|
-
messages:
|
|
598
|
+
messages: list[Message],
|
|
578
599
|
node_type: NodeType,
|
|
579
600
|
exclude: Optional[bytes32] = None,
|
|
580
601
|
) -> None:
|
|
@@ -586,7 +607,7 @@ class ChiaServer:
|
|
|
586
607
|
|
|
587
608
|
async def send_to_all_if(
|
|
588
609
|
self,
|
|
589
|
-
messages:
|
|
610
|
+
messages: list[Message],
|
|
590
611
|
node_type: NodeType,
|
|
591
612
|
predicate: Callable[[WSChiaConnection], bool],
|
|
592
613
|
exclude: Optional[bytes32] = None,
|
|
@@ -597,7 +618,7 @@ class ChiaServer:
|
|
|
597
618
|
for message in messages:
|
|
598
619
|
await connection.send_message(message)
|
|
599
620
|
|
|
600
|
-
async def send_to_specific(self, messages:
|
|
621
|
+
async def send_to_specific(self, messages: list[Message], node_id: bytes32) -> None:
|
|
601
622
|
if node_id in self.all_connections:
|
|
602
623
|
connection = self.all_connections[node_id]
|
|
603
624
|
for message in messages:
|
|
@@ -614,7 +635,7 @@ class ChiaServer:
|
|
|
614
635
|
|
|
615
636
|
def get_connections(
|
|
616
637
|
self, node_type: Optional[NodeType] = None, *, outbound: Optional[bool] = None
|
|
617
|
-
) ->
|
|
638
|
+
) -> list[WSChiaConnection]:
|
|
618
639
|
result = []
|
|
619
640
|
for _, connection in self.all_connections.items():
|
|
620
641
|
node_type_match = node_type is None or connection.connection_type == node_type
|
|
@@ -631,7 +652,7 @@ class ChiaServer:
|
|
|
631
652
|
self.log.error(f"Exception while closing connection {e}")
|
|
632
653
|
|
|
633
654
|
def close_all(self) -> None:
|
|
634
|
-
self.connection_close_task =
|
|
655
|
+
self.connection_close_task = create_referenced_task(self.close_all_connections())
|
|
635
656
|
if self.webserver is not None:
|
|
636
657
|
self.webserver.close()
|
|
637
658
|
|
|
@@ -707,7 +728,7 @@ class ChiaServer:
|
|
|
707
728
|
return inbound_count < cast(int, self.config.get("max_inbound_timelord", 5))
|
|
708
729
|
return True
|
|
709
730
|
|
|
710
|
-
def is_trusted_peer(self, peer: WSChiaConnection, trusted_peers:
|
|
731
|
+
def is_trusted_peer(self, peer: WSChiaConnection, trusted_peers: dict[str, Any]) -> bool:
|
|
711
732
|
return is_trusted_peer(
|
|
712
733
|
host=peer.peer_info.host,
|
|
713
734
|
node_id=peer.peer_node_id,
|
|
@@ -716,5 +737,5 @@ class ChiaServer:
|
|
|
716
737
|
testing=self.config.get("testing", False),
|
|
717
738
|
)
|
|
718
739
|
|
|
719
|
-
def set_capabilities(self, capabilities:
|
|
740
|
+
def set_capabilities(self, capabilities: list[tuple[uint16, str]]) -> None:
|
|
720
741
|
self._local_capabilities_for_handshake = capabilities
|