chia-blockchain 2.5.0rc1__py3-none-any.whl → 2.5.1__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.0rc1.dist-info → chia_blockchain-2.5.1.dist-info}/LICENSE +1 -1
- {chia_blockchain-2.5.0rc1.dist-info → chia_blockchain-2.5.1.dist-info}/METADATA +67 -72
- chia_blockchain-2.5.1.dist-info/RECORD +1042 -0
- {chia_blockchain-2.5.0rc1.dist-info → chia_blockchain-2.5.1.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.0rc1.dist-info/RECORD +0 -1028
- {chia_blockchain-2.5.0rc1.dist-info → chia_blockchain-2.5.1.dist-info}/entry_points.txt +0 -0
chia/seeder/crawl_store.py
CHANGED
|
@@ -6,7 +6,6 @@ import random
|
|
|
6
6
|
import time
|
|
7
7
|
from dataclasses import dataclass, field, replace
|
|
8
8
|
from datetime import datetime, timedelta
|
|
9
|
-
from typing import Dict, List
|
|
10
9
|
|
|
11
10
|
import aiosqlite
|
|
12
11
|
|
|
@@ -19,9 +18,9 @@ log = logging.getLogger(__name__)
|
|
|
19
18
|
@dataclass
|
|
20
19
|
class CrawlStore:
|
|
21
20
|
crawl_db: aiosqlite.Connection
|
|
22
|
-
host_to_records:
|
|
23
|
-
host_to_selected_time:
|
|
24
|
-
host_to_reliability:
|
|
21
|
+
host_to_records: dict[str, PeerRecord] = field(default_factory=dict) # peer_id: PeerRecord
|
|
22
|
+
host_to_selected_time: dict[str, float] = field(default_factory=dict) # peer_id: timestamp (as a float)
|
|
23
|
+
host_to_reliability: dict[str, PeerReliability] = field(default_factory=dict) # peer_id: PeerReliability
|
|
25
24
|
banned_peers: int = 0
|
|
26
25
|
ignored_peers: int = 0
|
|
27
26
|
reliable_peers: int = 0
|
|
@@ -184,17 +183,16 @@ class CrawlStore:
|
|
|
184
183
|
else:
|
|
185
184
|
await self.peer_failed_to_connect(record)
|
|
186
185
|
|
|
187
|
-
async def get_peers_to_crawl(self, min_batch_size: int, max_batch_size: int) ->
|
|
186
|
+
async def get_peers_to_crawl(self, min_batch_size: int, max_batch_size: int) -> list[PeerRecord]:
|
|
188
187
|
now = int(time.time())
|
|
189
188
|
records = []
|
|
190
189
|
records_v6 = []
|
|
191
190
|
counter = 0
|
|
192
191
|
self.ignored_peers = 0
|
|
193
192
|
self.banned_peers = 0
|
|
194
|
-
for peer_id in self.host_to_reliability:
|
|
193
|
+
for peer_id, reliability in self.host_to_reliability.items():
|
|
195
194
|
add = False
|
|
196
195
|
counter += 1
|
|
197
|
-
reliability = self.host_to_reliability[peer_id]
|
|
198
196
|
if reliability.ignore_till < now and reliability.ban_till < now:
|
|
199
197
|
add = True
|
|
200
198
|
else:
|
|
@@ -410,7 +408,7 @@ class CrawlStore:
|
|
|
410
408
|
await self.crawl_db.commit()
|
|
411
409
|
await self.crawl_db.execute("VACUUM")
|
|
412
410
|
|
|
413
|
-
to_delete:
|
|
411
|
+
to_delete: list[str] = []
|
|
414
412
|
|
|
415
413
|
# Deletes the old records from the in memory Dicts
|
|
416
414
|
for peer_id, peer_record in self.host_to_records.items():
|
chia/seeder/crawler.py
CHANGED
|
@@ -7,22 +7,10 @@ import logging
|
|
|
7
7
|
import time
|
|
8
8
|
import traceback
|
|
9
9
|
from collections import defaultdict
|
|
10
|
+
from collections.abc import AsyncIterator, Awaitable
|
|
10
11
|
from dataclasses import dataclass, field
|
|
11
12
|
from pathlib import Path
|
|
12
|
-
from typing import
|
|
13
|
-
TYPE_CHECKING,
|
|
14
|
-
Any,
|
|
15
|
-
AsyncIterator,
|
|
16
|
-
Awaitable,
|
|
17
|
-
Callable,
|
|
18
|
-
ClassVar,
|
|
19
|
-
Dict,
|
|
20
|
-
List,
|
|
21
|
-
Optional,
|
|
22
|
-
Set,
|
|
23
|
-
Tuple,
|
|
24
|
-
cast,
|
|
25
|
-
)
|
|
13
|
+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, cast
|
|
26
14
|
|
|
27
15
|
import aiosqlite
|
|
28
16
|
|
|
@@ -41,6 +29,7 @@ from chia.util.chia_version import chia_short_version
|
|
|
41
29
|
from chia.util.ints import uint32, uint64
|
|
42
30
|
from chia.util.network import resolve
|
|
43
31
|
from chia.util.path import path_from_root
|
|
32
|
+
from chia.util.task_referencer import create_referenced_task
|
|
44
33
|
|
|
45
34
|
log = logging.getLogger(__name__)
|
|
46
35
|
|
|
@@ -52,7 +41,7 @@ class Crawler:
|
|
|
52
41
|
|
|
53
42
|
_protocol_check: ClassVar[RpcServiceProtocol] = cast("Crawler", None)
|
|
54
43
|
|
|
55
|
-
config:
|
|
44
|
+
config: dict[str, Any]
|
|
56
45
|
root_path: Path
|
|
57
46
|
constants: ConsensusConstants
|
|
58
47
|
print_status: bool = True
|
|
@@ -63,15 +52,15 @@ class Crawler:
|
|
|
63
52
|
log: logging.Logger = log
|
|
64
53
|
_shut_down: bool = False
|
|
65
54
|
peer_count: int = 0
|
|
66
|
-
with_peak:
|
|
67
|
-
seen_nodes:
|
|
55
|
+
with_peak: set[PeerInfo] = field(default_factory=set)
|
|
56
|
+
seen_nodes: set[str] = field(default_factory=set)
|
|
68
57
|
minimum_version_count: int = 0
|
|
69
|
-
peers_retrieved:
|
|
70
|
-
host_to_version:
|
|
71
|
-
versions:
|
|
72
|
-
version_cache:
|
|
73
|
-
handshake_time:
|
|
74
|
-
best_timestamp_per_peer:
|
|
58
|
+
peers_retrieved: list[RespondPeers] = field(default_factory=list)
|
|
59
|
+
host_to_version: dict[str, str] = field(default_factory=dict)
|
|
60
|
+
versions: dict[str, int] = field(default_factory=lambda: defaultdict(int))
|
|
61
|
+
version_cache: list[tuple[str, str]] = field(default_factory=list)
|
|
62
|
+
handshake_time: dict[str, uint64] = field(default_factory=dict)
|
|
63
|
+
best_timestamp_per_peer: dict[str, uint64] = field(default_factory=dict)
|
|
75
64
|
start_crawler_loop: bool = True
|
|
76
65
|
|
|
77
66
|
@property
|
|
@@ -94,7 +83,7 @@ class Crawler:
|
|
|
94
83
|
if self.start_crawler_loop:
|
|
95
84
|
# Bootstrap the initial peers
|
|
96
85
|
await self.load_bootstrap_peers()
|
|
97
|
-
self.crawl_task =
|
|
86
|
+
self.crawl_task = create_referenced_task(self.crawl())
|
|
98
87
|
try:
|
|
99
88
|
yield
|
|
100
89
|
finally:
|
|
@@ -129,7 +118,7 @@ class Crawler:
|
|
|
129
118
|
def _set_state_changed_callback(self, callback: StateChangedProtocol) -> None:
|
|
130
119
|
self.state_changed_callback = callback
|
|
131
120
|
|
|
132
|
-
def get_connections(self, request_node_type: Optional[NodeType]) ->
|
|
121
|
+
def get_connections(self, request_node_type: Optional[NodeType]) -> list[dict[str, Any]]:
|
|
133
122
|
return default_get_connections(server=self.server, request_node_type=request_node_type)
|
|
134
123
|
|
|
135
124
|
async def create_client(
|
|
@@ -231,7 +220,7 @@ class Crawler:
|
|
|
231
220
|
total_nodes += 1
|
|
232
221
|
if peer.ip_address not in tried_nodes:
|
|
233
222
|
tried_nodes.add(peer.ip_address)
|
|
234
|
-
task =
|
|
223
|
+
task = create_referenced_task(self.connect_task(peer))
|
|
235
224
|
tasks.add(task)
|
|
236
225
|
if len(tasks) >= 250:
|
|
237
226
|
await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
|
|
@@ -300,18 +289,16 @@ class Crawler:
|
|
|
300
289
|
self.versions[version] += 1
|
|
301
290
|
|
|
302
291
|
# clear caches
|
|
303
|
-
self.version_cache:
|
|
292
|
+
self.version_cache: list[tuple[str, str]] = []
|
|
304
293
|
self.peers_retrieved = []
|
|
305
294
|
self.server.banned_peers = {}
|
|
306
295
|
self.with_peak = set()
|
|
307
296
|
|
|
308
|
-
if len(peers_to_crawl)
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
await self.crawl_store.prune_old_peers(older_than_days=peer_cutoff)
|
|
314
|
-
await self.print_summary(t_start, total_nodes, tried_nodes)
|
|
297
|
+
if len(peers_to_crawl) > 0:
|
|
298
|
+
peer_cutoff = int(self.config.get("crawler", {}).get("prune_peer_days", 90))
|
|
299
|
+
await self.save_to_db()
|
|
300
|
+
await self.crawl_store.prune_old_peers(older_than_days=peer_cutoff)
|
|
301
|
+
await self.print_summary(t_start, total_nodes, tried_nodes)
|
|
315
302
|
await asyncio.sleep(15) # 15 seconds between db updates
|
|
316
303
|
self._state_changed("crawl_batch_completed")
|
|
317
304
|
except Exception as e:
|
|
@@ -335,7 +322,7 @@ class Crawler:
|
|
|
335
322
|
def set_server(self, server: ChiaServer) -> None:
|
|
336
323
|
self._server = server
|
|
337
324
|
|
|
338
|
-
def _state_changed(self, change: str, change_data: Optional[
|
|
325
|
+
def _state_changed(self, change: str, change_data: Optional[dict[str, Any]] = None) -> None:
|
|
339
326
|
if self.state_changed_callback is not None:
|
|
340
327
|
self.state_changed_callback(change, change_data)
|
|
341
328
|
|
|
@@ -362,7 +349,7 @@ class Crawler:
|
|
|
362
349
|
async def on_connect(self, connection: WSChiaConnection) -> None:
|
|
363
350
|
pass
|
|
364
351
|
|
|
365
|
-
async def print_summary(self, t_start: float, total_nodes: int, tried_nodes:
|
|
352
|
+
async def print_summary(self, t_start: float, total_nodes: int, tried_nodes: set[str]) -> None:
|
|
366
353
|
assert self.crawl_store is not None # this is only ever called from the crawl task
|
|
367
354
|
if not self.print_status:
|
|
368
355
|
return
|
chia/seeder/crawler_api.py
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
-
from typing import Optional
|
|
4
|
+
from typing import TYPE_CHECKING, ClassVar, Optional, cast
|
|
5
5
|
|
|
6
6
|
from chia.protocols import full_node_protocol, wallet_protocol
|
|
7
7
|
from chia.seeder.crawler import Crawler
|
|
8
|
+
from chia.server.api_protocol import ApiMetadata
|
|
8
9
|
from chia.server.outbound_message import Message
|
|
9
10
|
from chia.server.server import ChiaServer
|
|
10
11
|
from chia.server.ws_connection import WSChiaConnection
|
|
11
|
-
from chia.util.api_decorators import api_request
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class CrawlerAPI:
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from chia.server.api_protocol import ApiProtocol
|
|
17
|
+
|
|
18
|
+
_protocol_check: ClassVar[ApiProtocol] = cast("CrawlerAPI", None)
|
|
19
|
+
|
|
15
20
|
log: logging.Logger
|
|
16
21
|
crawler: Crawler
|
|
22
|
+
metadata: ClassVar[ApiMetadata] = ApiMetadata()
|
|
17
23
|
|
|
18
24
|
def __init__(self, crawler: Crawler) -> None:
|
|
19
25
|
self.log = logging.getLogger(__name__)
|
|
@@ -27,80 +33,80 @@ class CrawlerAPI:
|
|
|
27
33
|
def ready(self) -> bool:
|
|
28
34
|
return True
|
|
29
35
|
|
|
30
|
-
@
|
|
36
|
+
@metadata.request(peer_required=True)
|
|
31
37
|
async def request_peers(
|
|
32
38
|
self, _request: full_node_protocol.RequestPeers, peer: WSChiaConnection
|
|
33
39
|
) -> Optional[Message]:
|
|
34
40
|
pass
|
|
35
41
|
|
|
36
|
-
@
|
|
42
|
+
@metadata.request(peer_required=True)
|
|
37
43
|
async def respond_peers(
|
|
38
44
|
self, request: full_node_protocol.RespondPeers, peer: WSChiaConnection
|
|
39
45
|
) -> Optional[Message]:
|
|
40
46
|
pass
|
|
41
47
|
|
|
42
|
-
@
|
|
48
|
+
@metadata.request(peer_required=True)
|
|
43
49
|
async def new_peak(self, request: full_node_protocol.NewPeak, peer: WSChiaConnection) -> Optional[Message]:
|
|
44
50
|
await self.crawler.new_peak(request, peer)
|
|
45
51
|
return None
|
|
46
52
|
|
|
47
|
-
@
|
|
53
|
+
@metadata.request()
|
|
48
54
|
async def new_transaction(self, transaction: full_node_protocol.NewTransaction) -> Optional[Message]:
|
|
49
55
|
pass
|
|
50
56
|
|
|
51
|
-
@
|
|
57
|
+
@metadata.request(peer_required=True)
|
|
52
58
|
async def new_signage_point_or_end_of_sub_slot(
|
|
53
59
|
self, new_sp: full_node_protocol.NewSignagePointOrEndOfSubSlot, peer: WSChiaConnection
|
|
54
60
|
) -> Optional[Message]:
|
|
55
61
|
pass
|
|
56
62
|
|
|
57
|
-
@
|
|
63
|
+
@metadata.request()
|
|
58
64
|
async def new_unfinished_block(
|
|
59
65
|
self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock
|
|
60
66
|
) -> Optional[Message]:
|
|
61
67
|
pass
|
|
62
68
|
|
|
63
|
-
@
|
|
69
|
+
@metadata.request()
|
|
64
70
|
async def new_unfinished_block2(
|
|
65
71
|
self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock2
|
|
66
72
|
) -> Optional[Message]:
|
|
67
73
|
pass
|
|
68
74
|
|
|
69
|
-
@
|
|
75
|
+
@metadata.request(peer_required=True)
|
|
70
76
|
async def new_compact_vdf(
|
|
71
77
|
self, request: full_node_protocol.NewCompactVDF, peer: WSChiaConnection
|
|
72
78
|
) -> Optional[Message]:
|
|
73
79
|
pass
|
|
74
80
|
|
|
75
|
-
@
|
|
81
|
+
@metadata.request()
|
|
76
82
|
async def request_transaction(self, request: full_node_protocol.RequestTransaction) -> Optional[Message]:
|
|
77
83
|
pass
|
|
78
84
|
|
|
79
|
-
@
|
|
85
|
+
@metadata.request()
|
|
80
86
|
async def request_proof_of_weight(self, request: full_node_protocol.RequestProofOfWeight) -> Optional[Message]:
|
|
81
87
|
pass
|
|
82
88
|
|
|
83
|
-
@
|
|
89
|
+
@metadata.request()
|
|
84
90
|
async def request_block(self, request: full_node_protocol.RequestBlock) -> Optional[Message]:
|
|
85
91
|
pass
|
|
86
92
|
|
|
87
|
-
@
|
|
93
|
+
@metadata.request()
|
|
88
94
|
async def request_blocks(self, request: full_node_protocol.RequestBlocks) -> Optional[Message]:
|
|
89
95
|
pass
|
|
90
96
|
|
|
91
|
-
@
|
|
97
|
+
@metadata.request()
|
|
92
98
|
async def request_unfinished_block(
|
|
93
99
|
self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock
|
|
94
100
|
) -> Optional[Message]:
|
|
95
101
|
pass
|
|
96
102
|
|
|
97
|
-
@
|
|
103
|
+
@metadata.request()
|
|
98
104
|
async def request_signage_point_or_end_of_sub_slot(
|
|
99
105
|
self, request: full_node_protocol.RequestSignagePointOrEndOfSubSlot
|
|
100
106
|
) -> Optional[Message]:
|
|
101
107
|
pass
|
|
102
108
|
|
|
103
|
-
@
|
|
109
|
+
@metadata.request(peer_required=True)
|
|
104
110
|
async def request_mempool_transactions(
|
|
105
111
|
self,
|
|
106
112
|
request: full_node_protocol.RequestMempoolTransactions,
|
|
@@ -108,22 +114,22 @@ class CrawlerAPI:
|
|
|
108
114
|
) -> Optional[Message]:
|
|
109
115
|
pass
|
|
110
116
|
|
|
111
|
-
@
|
|
117
|
+
@metadata.request()
|
|
112
118
|
async def request_block_header(self, request: wallet_protocol.RequestBlockHeader) -> Optional[Message]:
|
|
113
119
|
pass
|
|
114
120
|
|
|
115
|
-
@
|
|
121
|
+
@metadata.request()
|
|
116
122
|
async def request_additions(self, request: wallet_protocol.RequestAdditions) -> Optional[Message]:
|
|
117
123
|
pass
|
|
118
124
|
|
|
119
|
-
@
|
|
125
|
+
@metadata.request()
|
|
120
126
|
async def request_removals(self, request: wallet_protocol.RequestRemovals) -> Optional[Message]:
|
|
121
127
|
pass
|
|
122
128
|
|
|
123
|
-
@
|
|
129
|
+
@metadata.request()
|
|
124
130
|
async def request_puzzle_solution(self, request: wallet_protocol.RequestPuzzleSolution) -> Optional[Message]:
|
|
125
131
|
pass
|
|
126
132
|
|
|
127
|
-
@
|
|
133
|
+
@metadata.request()
|
|
128
134
|
async def request_header_blocks(self, request: wallet_protocol.RequestHeaderBlocks) -> Optional[Message]:
|
|
129
135
|
pass
|
chia/seeder/dns_server.py
CHANGED
|
@@ -5,23 +5,26 @@ import logging
|
|
|
5
5
|
import signal
|
|
6
6
|
import sys
|
|
7
7
|
import traceback
|
|
8
|
+
from collections.abc import AsyncIterator, Awaitable
|
|
8
9
|
from contextlib import asynccontextmanager
|
|
9
10
|
from dataclasses import dataclass, field
|
|
10
11
|
from ipaddress import IPv4Address, IPv6Address, ip_address
|
|
11
12
|
from multiprocessing import freeze_support
|
|
12
13
|
from pathlib import Path
|
|
13
14
|
from types import FrameType
|
|
14
|
-
from typing import Any,
|
|
15
|
+
from typing import Any, Callable, Optional
|
|
15
16
|
|
|
16
17
|
import aiosqlite
|
|
18
|
+
import dns.asyncresolver
|
|
17
19
|
from dnslib import AAAA, EDNS0, NS, QTYPE, RCODE, RD, RR, SOA, A, DNSError, DNSHeader, DNSQuestion, DNSRecord
|
|
18
20
|
|
|
19
21
|
from chia.seeder.crawl_store import CrawlStore
|
|
20
22
|
from chia.server.signal_handlers import SignalHandlers
|
|
21
23
|
from chia.util.chia_logging import initialize_service_logging
|
|
22
24
|
from chia.util.config import load_config, load_config_cli
|
|
23
|
-
from chia.util.default_root import
|
|
25
|
+
from chia.util.default_root import resolve_root_path
|
|
24
26
|
from chia.util.path import path_from_root
|
|
27
|
+
from chia.util.task_referencer import create_referenced_task
|
|
25
28
|
|
|
26
29
|
SERVICE_NAME = "seeder"
|
|
27
30
|
log = logging.getLogger(__name__)
|
|
@@ -38,8 +41,8 @@ class DomainName(str):
|
|
|
38
41
|
|
|
39
42
|
@dataclass(frozen=True)
|
|
40
43
|
class PeerList:
|
|
41
|
-
ipv4:
|
|
42
|
-
ipv6:
|
|
44
|
+
ipv4: list[IPv4Address]
|
|
45
|
+
ipv6: list[IPv6Address]
|
|
43
46
|
|
|
44
47
|
@property
|
|
45
48
|
def no_peers(self) -> bool:
|
|
@@ -58,7 +61,7 @@ class UDPDNSServerProtocol(asyncio.DatagramProtocol):
|
|
|
58
61
|
queue_task: Optional[asyncio.Task[None]] = field(init=False, default=None)
|
|
59
62
|
|
|
60
63
|
def start(self) -> None:
|
|
61
|
-
self.queue_task =
|
|
64
|
+
self.queue_task = create_referenced_task(self.respond()) # This starts the dns respond loop.
|
|
62
65
|
|
|
63
66
|
async def stop(self) -> None:
|
|
64
67
|
if self.queue_task is not None:
|
|
@@ -79,11 +82,12 @@ class UDPDNSServerProtocol(asyncio.DatagramProtocol):
|
|
|
79
82
|
dns_request: Optional[DNSRecord] = parse_dns_request(data)
|
|
80
83
|
if dns_request is None: # Invalid Request, we can just drop it and move on.
|
|
81
84
|
return
|
|
82
|
-
|
|
85
|
+
create_referenced_task(self.handler(dns_request, addr), known_unreferenced=True)
|
|
83
86
|
|
|
84
87
|
async def respond(self) -> None:
|
|
85
88
|
log.info("UDP DNS responder started.")
|
|
86
|
-
|
|
89
|
+
# TODO: switch to event driven code
|
|
90
|
+
while self.transport is None: # we wait for the transport to be set. # noqa: ASYNC110
|
|
87
91
|
await asyncio.sleep(0.1)
|
|
88
92
|
while not self.transport.is_closing():
|
|
89
93
|
try:
|
|
@@ -121,7 +125,7 @@ class TCPDNSServerProtocol(asyncio.BufferedProtocol):
|
|
|
121
125
|
peer_info: str = field(init=False, default="")
|
|
122
126
|
expected_length: int = 0
|
|
123
127
|
buffer: bytearray = field(init=False, default_factory=lambda: bytearray(2))
|
|
124
|
-
futures:
|
|
128
|
+
futures: list[asyncio.Future[None]] = field(init=False, default_factory=list)
|
|
125
129
|
|
|
126
130
|
def connection_made(self, transport: asyncio.BaseTransport) -> None:
|
|
127
131
|
"""
|
|
@@ -176,7 +180,7 @@ class TCPDNSServerProtocol(asyncio.BufferedProtocol):
|
|
|
176
180
|
if dns_request is None: # Invalid Request, so we disconnect and don't send anything back.
|
|
177
181
|
self.transport.close()
|
|
178
182
|
return
|
|
179
|
-
self.futures.append(
|
|
183
|
+
self.futures.append(create_referenced_task(self.handle_and_respond(dns_request)))
|
|
180
184
|
|
|
181
185
|
self.buffer = bytearray(2 if self.expected_length == 0 else self.expected_length) # Reset the buffer if empty.
|
|
182
186
|
|
|
@@ -191,7 +195,7 @@ class TCPDNSServerProtocol(asyncio.BufferedProtocol):
|
|
|
191
195
|
f"Received incomplete TCP DNS request of length {self.expected_length} from {self.peer_info}, "
|
|
192
196
|
f"closing connection after dns replies are sent."
|
|
193
197
|
)
|
|
194
|
-
|
|
198
|
+
create_referenced_task(self.wait_for_futures(), known_unreferenced=True)
|
|
195
199
|
return True # Keep connection open, until the futures are done.
|
|
196
200
|
log.info(f"Received early EOF from {self.peer_info}, closing connection.")
|
|
197
201
|
return False
|
|
@@ -263,7 +267,7 @@ async def get_dns_reply(callback: DnsCallback, dns_request: DNSRecord) -> DNSRec
|
|
|
263
267
|
|
|
264
268
|
@dataclass
|
|
265
269
|
class DNSServer:
|
|
266
|
-
config:
|
|
270
|
+
config: dict[str, Any]
|
|
267
271
|
root_path: Path
|
|
268
272
|
lock: asyncio.Lock = field(default_factory=asyncio.Lock)
|
|
269
273
|
shutdown_event: asyncio.Event = field(default_factory=asyncio.Event)
|
|
@@ -282,11 +286,14 @@ class DNSServer:
|
|
|
282
286
|
db_path: Path = field(init=False)
|
|
283
287
|
domain: DomainName = field(init=False)
|
|
284
288
|
ns1: DomainName = field(init=False)
|
|
285
|
-
ns_records:
|
|
289
|
+
ns_records: list[RR] = field(init=False)
|
|
286
290
|
ttl: int = field(init=False)
|
|
287
291
|
soa_record: RR = field(init=False)
|
|
288
|
-
reliable_peers_v4:
|
|
289
|
-
reliable_peers_v6:
|
|
292
|
+
reliable_peers_v4: list[IPv4Address] = field(default_factory=list)
|
|
293
|
+
reliable_peers_v6: list[IPv6Address] = field(default_factory=list)
|
|
294
|
+
static_peers_v4: list[IPv4Address] = field(default_factory=list)
|
|
295
|
+
static_peers_v6: list[IPv6Address] = field(default_factory=list)
|
|
296
|
+
resolver: Optional[dns.asyncresolver.Resolver] = field(init=False)
|
|
290
297
|
pointer_v4: int = 0
|
|
291
298
|
pointer_v6: int = 0
|
|
292
299
|
|
|
@@ -307,7 +314,7 @@ class DNSServer:
|
|
|
307
314
|
if not self.domain.endswith("."):
|
|
308
315
|
self.domain = DomainName(self.domain + ".") # Make sure the domain ends with a period, as per RFC 1035.
|
|
309
316
|
self.ns1: DomainName = DomainName(self.config["nameserver"])
|
|
310
|
-
self.ns_records:
|
|
317
|
+
self.ns_records: list[NS] = [NS(self.ns1)]
|
|
311
318
|
self.ttl: int = self.config["ttl"]
|
|
312
319
|
self.soa_record: SOA = SOA(
|
|
313
320
|
mname=self.ns1, # primary name server
|
|
@@ -320,6 +327,11 @@ class DNSServer:
|
|
|
320
327
|
self.config["soa"]["minimum"],
|
|
321
328
|
),
|
|
322
329
|
)
|
|
330
|
+
try:
|
|
331
|
+
self.resolver: Optional[dns.asyncresolver.Resolver] = dns.asyncresolver.Resolver()
|
|
332
|
+
except Exception:
|
|
333
|
+
self.resolver = None
|
|
334
|
+
log.exception("Error initializing asyncresolver for dns_server")
|
|
323
335
|
|
|
324
336
|
@asynccontextmanager
|
|
325
337
|
async def run(self) -> AsyncIterator[None]:
|
|
@@ -329,7 +341,7 @@ class DNSServer:
|
|
|
329
341
|
|
|
330
342
|
# Set up the crawl store and the peer update task.
|
|
331
343
|
self.crawl_store = await CrawlStore.create(await aiosqlite.connect(self.db_path, timeout=120))
|
|
332
|
-
self.reliable_task =
|
|
344
|
+
self.reliable_task = create_referenced_task(self.periodically_get_reliable_peers())
|
|
333
345
|
|
|
334
346
|
# One protocol instance will be created for each udp transport, so that we can accept ipv4 and ipv6
|
|
335
347
|
self.udp_transport_ipv6, self.udp_protocol_ipv6 = await loop.create_datagram_endpoint(
|
|
@@ -392,42 +404,78 @@ class DNSServer:
|
|
|
392
404
|
async def periodically_get_reliable_peers(self) -> None:
|
|
393
405
|
sleep_interval = 0
|
|
394
406
|
while not self.shutdown_event.is_set() and self.crawl_store is not None:
|
|
407
|
+
await self.refresh_reliable_peers()
|
|
408
|
+
sleep_interval = min(15, sleep_interval + 1)
|
|
409
|
+
await asyncio.sleep(sleep_interval * 60)
|
|
410
|
+
|
|
411
|
+
async def refresh_reliable_peers(self) -> None:
|
|
412
|
+
if self.crawl_store is None:
|
|
413
|
+
return
|
|
414
|
+
new_reliable_peers: list[str] = []
|
|
415
|
+
while not self.shutdown_event.is_set():
|
|
395
416
|
try:
|
|
396
417
|
new_reliable_peers = await self.crawl_store.get_good_peers()
|
|
397
418
|
except Exception as e:
|
|
398
419
|
log.error(f"Error loading reliable peers from database: {e}. Traceback: {traceback.format_exc()}.")
|
|
420
|
+
await asyncio.sleep(2)
|
|
399
421
|
continue
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
self.reliable_peers_v4 = []
|
|
406
|
-
self.reliable_peers_v6 = []
|
|
407
|
-
self.pointer_v4 = 0
|
|
408
|
-
self.pointer_v6 = 0
|
|
409
|
-
for peer in new_reliable_peers:
|
|
422
|
+
|
|
423
|
+
static_peers = self.config.get("static_peers", [])
|
|
424
|
+
if len(static_peers) > 0:
|
|
425
|
+
log.warning("have static peers, resolving ip addresses")
|
|
426
|
+
for static_peer in static_peers:
|
|
410
427
|
try:
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
428
|
+
log.warning(f"Handling static peer {static_peer}")
|
|
429
|
+
# Attempt to parse as an IP address
|
|
430
|
+
# If this doesn't throw, we can just add to the list
|
|
431
|
+
# Otherwise, we have to resolve the hostname
|
|
432
|
+
ip_address(static_peer)
|
|
433
|
+
new_reliable_peers.append(static_peer)
|
|
416
434
|
except ValueError:
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
435
|
+
# Wasn't an IP address, so resolve the hostname
|
|
436
|
+
log.warning(f"Not an IP address, trying to resolve {static_peer} to an IP address")
|
|
437
|
+
if self.resolver is not None:
|
|
438
|
+
for rdtype in ["A", "AAAA"]:
|
|
439
|
+
result = await self.resolver.resolve(qname=static_peer, rdtype=rdtype, lifetime=30)
|
|
440
|
+
for ip in result:
|
|
441
|
+
try:
|
|
442
|
+
ip_as_string = ip.to_text()
|
|
443
|
+
ip_address(ip_as_string)
|
|
444
|
+
new_reliable_peers.append(ip_as_string)
|
|
445
|
+
except ValueError:
|
|
446
|
+
pass
|
|
447
|
+
|
|
448
|
+
if len(new_reliable_peers) > 0:
|
|
449
|
+
break
|
|
450
|
+
|
|
451
|
+
log.warning("No reliable peers found in database, waiting for db to be populated.")
|
|
452
|
+
await asyncio.sleep(2) # sleep for 2 seconds, because the db has not been populated yet.
|
|
453
|
+
|
|
454
|
+
async with self.lock:
|
|
455
|
+
self.reliable_peers_v4 = []
|
|
456
|
+
self.reliable_peers_v6 = []
|
|
457
|
+
self.pointer_v4 = 0
|
|
458
|
+
self.pointer_v6 = 0
|
|
459
|
+
for peer in new_reliable_peers:
|
|
460
|
+
try:
|
|
461
|
+
validated_peer = ip_address(peer)
|
|
462
|
+
if validated_peer.version == 4:
|
|
463
|
+
self.reliable_peers_v4.append(validated_peer)
|
|
464
|
+
elif validated_peer.version == 6:
|
|
465
|
+
self.reliable_peers_v6.append(validated_peer)
|
|
466
|
+
except ValueError:
|
|
467
|
+
log.error(f"Invalid peer: {peer}")
|
|
468
|
+
continue
|
|
469
|
+
log.warning(
|
|
470
|
+
f"Number of reliable peers discovered in dns server:"
|
|
471
|
+
f" IPv4 count - {len(self.reliable_peers_v4)}"
|
|
472
|
+
f" IPv6 count - {len(self.reliable_peers_v6)}"
|
|
473
|
+
)
|
|
426
474
|
|
|
427
475
|
async def get_peers_to_respond(self, ipv4_count: int, ipv6_count: int) -> PeerList:
|
|
428
476
|
async with self.lock:
|
|
429
477
|
# Append IPv4.
|
|
430
|
-
ipv4_peers:
|
|
478
|
+
ipv4_peers: list[IPv4Address] = []
|
|
431
479
|
size = len(self.reliable_peers_v4)
|
|
432
480
|
if ipv4_count > 0 and size <= ipv4_count:
|
|
433
481
|
ipv4_peers = self.reliable_peers_v4
|
|
@@ -437,7 +485,7 @@ class DNSServer:
|
|
|
437
485
|
]
|
|
438
486
|
self.pointer_v4 = (self.pointer_v4 + ipv4_count) % size # mark where we left off
|
|
439
487
|
# Append IPv6.
|
|
440
|
-
ipv6_peers:
|
|
488
|
+
ipv6_peers: list[IPv6Address] = []
|
|
441
489
|
size = len(self.reliable_peers_v6)
|
|
442
490
|
if ipv6_count > 0 and size <= ipv6_count:
|
|
443
491
|
ipv6_peers = self.reliable_peers_v6
|
|
@@ -473,7 +521,7 @@ class DNSServer:
|
|
|
473
521
|
|
|
474
522
|
ttl: int = self.ttl
|
|
475
523
|
# we add these to the list as it will allow us to respond to ns and soa requests
|
|
476
|
-
ips:
|
|
524
|
+
ips: list[RD] = [self.soa_record, *self.ns_records]
|
|
477
525
|
ipv4_count = 0
|
|
478
526
|
ipv6_count = 0
|
|
479
527
|
if question_type is QTYPE.A:
|
|
@@ -493,7 +541,7 @@ class DNSServer:
|
|
|
493
541
|
ips.extend([A(str(peer)) for peer in peers.ipv4])
|
|
494
542
|
ips.extend([AAAA(str(peer)) for peer in peers.ipv6])
|
|
495
543
|
|
|
496
|
-
records:
|
|
544
|
+
records: dict[DomainName, list[RD]] = { # this is where we can add other records we want to serve
|
|
497
545
|
self.domain: ips,
|
|
498
546
|
}
|
|
499
547
|
|
|
@@ -503,7 +551,7 @@ class DNSServer:
|
|
|
503
551
|
valid_domain = True
|
|
504
552
|
for response in domain_responses:
|
|
505
553
|
rqt: int = getattr(QTYPE, response.__class__.__name__)
|
|
506
|
-
if question_type
|
|
554
|
+
if question_type in {rqt, QTYPE.ANY}:
|
|
507
555
|
reply.add_answer(RR(rname=qname, rtype=rqt, rclass=1, ttl=ttl, rdata=response))
|
|
508
556
|
if not valid_domain and len(reply.rr) == 0: # if we didn't find any records to return
|
|
509
557
|
reply.header.rcode = RCODE.NXDOMAIN
|
|
@@ -521,7 +569,7 @@ async def run_dns_server(dns_server: DNSServer) -> None: # pragma: no cover
|
|
|
521
569
|
await dns_server.shutdown_event.wait() # this is released on SIGINT or SIGTERM or any unhandled exception
|
|
522
570
|
|
|
523
571
|
|
|
524
|
-
def create_dns_server_service(config:
|
|
572
|
+
def create_dns_server_service(config: dict[str, Any], root_path: Path) -> DNSServer:
|
|
525
573
|
service_config = config[SERVICE_NAME]
|
|
526
574
|
|
|
527
575
|
return DNSServer(service_config, root_path)
|
|
@@ -529,12 +577,13 @@ def create_dns_server_service(config: Dict[str, Any], root_path: Path) -> DNSSer
|
|
|
529
577
|
|
|
530
578
|
def main() -> None: # pragma: no cover
|
|
531
579
|
freeze_support()
|
|
532
|
-
root_path =
|
|
580
|
+
root_path = resolve_root_path(override=None)
|
|
581
|
+
|
|
533
582
|
# TODO: refactor to avoid the double load
|
|
534
|
-
config = load_config(
|
|
535
|
-
service_config = load_config_cli(
|
|
583
|
+
config = load_config(root_path, "config.yaml")
|
|
584
|
+
service_config = load_config_cli(root_path, "config.yaml", SERVICE_NAME)
|
|
536
585
|
config[SERVICE_NAME] = service_config
|
|
537
|
-
initialize_service_logging(service_name=SERVICE_NAME, config=config)
|
|
586
|
+
initialize_service_logging(service_name=SERVICE_NAME, config=config, root_path=root_path)
|
|
538
587
|
|
|
539
588
|
dns_server = create_dns_server_service(config, root_path)
|
|
540
589
|
asyncio.run(run_dns_server(dns_server))
|