chia-blockchain 2.5.4rc1__py3-none-any.whl → 2.5.5__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/blockchain/blockchain_test_utils.py +2 -3
- chia/_tests/blockchain/test_augmented_chain.py +2 -3
- chia/_tests/blockchain/test_blockchain.py +261 -44
- chia/_tests/blockchain/test_blockchain_transactions.py +4 -3
- chia/_tests/blockchain/test_build_chains.py +197 -1
- chia/_tests/blockchain/test_get_block_generator.py +1 -1
- chia/_tests/blockchain/test_lookup_fork_chain.py +1 -1
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +3 -4
- chia/_tests/clvm/test_message_conditions.py +2 -2
- chia/_tests/clvm/test_puzzle_compression.py +2 -3
- chia/_tests/clvm/test_puzzles.py +1 -2
- chia/_tests/clvm/test_singletons.py +2 -3
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +30 -25
- chia/_tests/cmds/test_dev_gh.py +1 -1
- chia/_tests/cmds/test_farm_cmd.py +1 -1
- chia/_tests/cmds/test_show.py +1 -2
- chia/_tests/cmds/wallet/test_did.py +101 -56
- chia/_tests/cmds/wallet/test_nft.py +109 -84
- chia/_tests/cmds/wallet/test_notifications.py +1 -1
- chia/_tests/cmds/wallet/test_offer.toffer +1 -1
- chia/_tests/cmds/wallet/test_vcs.py +8 -8
- chia/_tests/cmds/wallet/test_wallet.py +100 -46
- chia/_tests/conftest.py +31 -20
- chia/_tests/connection_utils.py +1 -1
- chia/_tests/core/consensus/stores/__init__.py +0 -0
- chia/_tests/core/consensus/stores/test_coin_store_protocol.py +40 -0
- chia/_tests/core/consensus/test_block_creation.py +2 -31
- chia/_tests/core/consensus/test_pot_iterations.py +38 -3
- chia/_tests/core/custom_types/test_proof_of_space.py +154 -26
- chia/_tests/core/custom_types/test_spend_bundle.py +2 -3
- chia/_tests/core/daemon/test_daemon.py +80 -0
- chia/_tests/core/data_layer/test_data_layer.py +1 -1
- chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
- chia/_tests/core/data_layer/test_data_rpc.py +14 -10
- chia/_tests/core/data_layer/test_data_store.py +5 -5
- chia/_tests/core/farmer/test_farmer_api.py +2 -2
- chia/_tests/core/full_node/full_sync/test_full_sync.py +446 -406
- chia/_tests/core/full_node/ram_db.py +3 -1
- chia/_tests/core/full_node/stores/test_block_store.py +28 -16
- chia/_tests/core/full_node/stores/test_coin_store.py +277 -185
- chia/_tests/core/full_node/stores/test_full_node_store.py +11 -4
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_address_manager.py +200 -27
- chia/_tests/core/full_node/test_block_height_map.py +2 -2
- chia/_tests/core/full_node/test_conditions.py +7 -6
- chia/_tests/core/full_node/test_full_node.py +456 -40
- chia/_tests/core/full_node/test_generator_tools.py +32 -2
- chia/_tests/core/full_node/test_hint_management.py +1 -1
- chia/_tests/core/full_node/test_node_load.py +20 -21
- chia/_tests/core/full_node/test_performance.py +3 -4
- chia/_tests/core/full_node/test_prev_tx_block.py +43 -0
- chia/_tests/core/full_node/test_subscriptions.py +1 -2
- chia/_tests/core/full_node/test_transactions.py +9 -5
- chia/_tests/core/full_node/test_tx_processing_queue.py +1 -2
- chia/_tests/core/large_block.py +1 -2
- chia/_tests/core/make_block_generator.py +3 -4
- chia/_tests/core/mempool/test_mempool.py +36 -86
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
- chia/_tests/core/mempool/test_mempool_item_queries.py +1 -3
- chia/_tests/core/mempool/test_mempool_manager.py +529 -69
- chia/_tests/core/mempool/test_mempool_performance.py +3 -2
- chia/_tests/core/mempool/test_singleton_fast_forward.py +61 -132
- chia/_tests/core/server/flood.py +1 -1
- chia/_tests/core/server/test_dos.py +1 -1
- chia/_tests/core/server/test_node_discovery.py +41 -27
- chia/_tests/core/server/test_rate_limits.py +1 -1
- chia/_tests/core/server/test_server.py +1 -1
- chia/_tests/core/services/test_services.py +5 -5
- chia/_tests/core/ssl/test_ssl.py +1 -1
- chia/_tests/core/test_cost_calculation.py +6 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_crawler_rpc.py +1 -1
- chia/_tests/core/test_db_conversion.py +3 -1
- chia/_tests/core/test_db_validation.py +5 -3
- chia/_tests/core/test_farmer_harvester_rpc.py +15 -15
- chia/_tests/core/test_filter.py +4 -1
- chia/_tests/core/test_full_node_rpc.py +99 -82
- chia/_tests/core/test_program.py +2 -2
- chia/_tests/core/util/test_block_cache.py +1 -1
- chia/_tests/core/util/test_keychain.py +2 -2
- chia/_tests/core/util/test_lockfile.py +1 -1
- chia/_tests/core/util/test_log_exceptions.py +5 -5
- chia/_tests/core/util/test_streamable.py +81 -22
- chia/_tests/db/test_db_wrapper.py +1 -3
- chia/_tests/environments/wallet.py +5 -5
- chia/_tests/farmer_harvester/test_farmer.py +9 -7
- chia/_tests/farmer_harvester/test_farmer_harvester.py +11 -4
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +15 -9
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -2
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +7 -5
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
- chia/_tests/generator/test_compression.py +1 -2
- chia/_tests/generator/test_rom.py +8 -4
- chia/_tests/plot_sync/test_plot_sync.py +3 -3
- chia/_tests/plot_sync/test_receiver.py +3 -3
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +3 -3
- chia/_tests/plot_sync/util.py +2 -2
- chia/_tests/pools/test_pool_cmdline.py +48 -21
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +2 -3
- chia/_tests/pools/test_pool_rpc.py +237 -105
- chia/_tests/pools/test_pool_wallet.py +11 -2
- chia/_tests/pools/test_wallet_pool_store.py +5 -4
- chia/_tests/rpc/test_rpc_client.py +1 -1
- chia/_tests/simulation/test_simulation.py +13 -8
- chia/_tests/simulation/test_simulator.py +2 -2
- chia/_tests/timelord/test_new_peak.py +191 -47
- chia/_tests/timelord/test_timelord.py +1 -1
- chia/_tests/tools/test_full_sync.py +0 -2
- chia/_tests/tools/test_run_block.py +3 -1
- chia/_tests/util/benchmark_cost.py +3 -3
- chia/_tests/util/benchmarks.py +2 -2
- chia/_tests/util/blockchain.py +11 -5
- chia/_tests/util/blockchain_mock.py +1 -4
- chia/_tests/util/coin_store.py +29 -0
- chia/_tests/util/constants.py +2 -18
- chia/_tests/util/full_sync.py +3 -3
- chia/_tests/util/generator_tools_testing.py +2 -3
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +33 -31
- chia/_tests/util/network_protocol_data.py +19 -17
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +3 -1
- chia/_tests/util/run_block.py +2 -2
- chia/_tests/util/setup_nodes.py +7 -7
- chia/_tests/util/spend_sim.py +47 -55
- chia/_tests/util/test_condition_tools.py +5 -4
- chia/_tests/util/test_config.py +2 -2
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +12 -14
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_paginator.py +4 -4
- chia/_tests/util/test_priority_mutex.py +2 -2
- chia/_tests/util/test_replace_str_to_bytes.py +15 -5
- chia/_tests/util/test_ssl_check.py +1 -1
- chia/_tests/util/test_testnet_overrides.py +13 -3
- chia/_tests/util/time_out_assert.py +4 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -2
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +352 -432
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +3 -6
- chia/_tests/wallet/cat_wallet/test_trades.py +53 -77
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -1
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +3 -3
- chia/_tests/wallet/clawback/test_clawback_metadata.py +4 -2
- chia/_tests/wallet/conftest.py +11 -12
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +11 -4
- chia/_tests/wallet/db_wallet/test_dl_offers.py +433 -130
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +3 -3
- chia/_tests/wallet/did_wallet/test_did.py +2132 -2000
- chia/_tests/wallet/nft_wallet/config.py +1 -1
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1610 -742
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +486 -907
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +4 -4
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +517 -294
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +133 -62
- chia/_tests/wallet/rpc/test_wallet_rpc.py +495 -265
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +10 -6
- chia/_tests/wallet/sync/test_wallet_sync.py +89 -60
- chia/_tests/wallet/test_clvm_casts.py +88 -0
- chia/_tests/wallet/test_coin_management.py +1 -1
- chia/_tests/wallet/test_coin_selection.py +1 -1
- chia/_tests/wallet/test_conditions.py +1 -1
- chia/_tests/wallet/test_new_wallet_protocol.py +13 -11
- chia/_tests/wallet/test_notifications.py +5 -3
- chia/_tests/wallet/test_sign_coin_spends.py +6 -6
- chia/_tests/wallet/test_signer_protocol.py +13 -12
- chia/_tests/wallet/test_singleton.py +1 -1
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +5 -7
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +108 -29
- chia/_tests/wallet/test_wallet_action_scope.py +9 -2
- chia/_tests/wallet/test_wallet_blockchain.py +2 -3
- chia/_tests/wallet/test_wallet_key_val_store.py +1 -2
- chia/_tests/wallet/test_wallet_node.py +2 -4
- chia/_tests/wallet/test_wallet_retry.py +4 -2
- chia/_tests/wallet/test_wallet_state_manager.py +191 -5
- chia/_tests/wallet/test_wallet_test_framework.py +1 -1
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +8 -8
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -12
- chia/_tests/wallet/wallet_block_tools.py +6 -6
- chia/_tests/weight_proof/test_weight_proof.py +10 -48
- chia/apis.py +1 -1
- chia/cmds/beta.py +1 -1
- chia/cmds/chia.py +9 -9
- chia/cmds/cmd_classes.py +12 -11
- chia/cmds/cmd_helpers.py +1 -1
- chia/cmds/cmds_util.py +12 -9
- chia/cmds/coin_funcs.py +2 -2
- chia/cmds/configure.py +2 -2
- chia/cmds/data.py +0 -2
- chia/cmds/data_funcs.py +1 -1
- chia/cmds/db_validate_func.py +1 -2
- chia/cmds/dev/__init__.py +0 -0
- chia/cmds/dev/data.py +273 -0
- chia/cmds/{gh.py → dev/gh.py} +5 -5
- chia/cmds/dev/main.py +22 -0
- chia/cmds/dev/mempool.py +78 -0
- chia/cmds/dev/mempool_funcs.py +63 -0
- chia/cmds/farm_funcs.py +5 -4
- chia/cmds/init_funcs.py +11 -11
- chia/cmds/keys.py +2 -2
- chia/cmds/keys_funcs.py +4 -4
- chia/cmds/netspace_funcs.py +1 -1
- chia/cmds/peer_funcs.py +2 -2
- chia/cmds/plotnft_funcs.py +72 -26
- chia/cmds/rpc.py +1 -1
- chia/cmds/show_funcs.py +5 -5
- chia/cmds/signer.py +8 -7
- chia/cmds/sim_funcs.py +8 -9
- chia/cmds/wallet.py +2 -2
- chia/cmds/wallet_funcs.py +165 -131
- chia/{util → consensus}/augmented_chain.py +1 -2
- chia/consensus/block_body_validation.py +54 -40
- chia/consensus/block_creation.py +42 -76
- chia/consensus/block_header_validation.py +32 -26
- chia/consensus/block_record.py +0 -3
- chia/consensus/blockchain.py +23 -32
- chia/consensus/blockchain_interface.py +1 -5
- chia/consensus/check_time_locks.py +57 -0
- chia/consensus/coin_store_protocol.py +151 -0
- chia/consensus/coinbase.py +0 -6
- chia/consensus/condition_costs.py +4 -0
- chia/{util → consensus}/condition_tools.py +4 -5
- chia/consensus/cost_calculator.py +1 -1
- chia/consensus/default_constants.py +32 -9
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +1 -2
- chia/consensus/find_fork_point.py +1 -3
- chia/consensus/full_block_to_block_record.py +1 -6
- chia/{util → consensus}/generator_tools.py +1 -3
- chia/consensus/get_block_challenge.py +30 -7
- chia/consensus/make_sub_epoch_summary.py +1 -5
- chia/consensus/multiprocess_validation.py +21 -20
- chia/consensus/pot_iterations.py +74 -13
- chia/{util → consensus}/prev_transaction_block.py +1 -1
- chia/consensus/vdf_info_computation.py +1 -3
- chia/daemon/keychain_proxy.py +5 -5
- chia/daemon/server.py +22 -5
- chia/data_layer/data_layer.py +92 -51
- chia/{rpc → data_layer}/data_layer_rpc_api.py +1 -1
- chia/{rpc → data_layer}/data_layer_rpc_util.py +3 -6
- chia/data_layer/data_layer_util.py +4 -6
- chia/data_layer/data_layer_wallet.py +42 -69
- chia/data_layer/dl_wallet_store.py +12 -6
- chia/data_layer/download_data.py +3 -3
- chia/data_layer/s3_plugin_service.py +0 -1
- chia/farmer/farmer.py +3 -4
- chia/farmer/farmer_api.py +11 -7
- chia/{rpc → farmer}/farmer_rpc_client.py +1 -1
- chia/full_node/block_height_map.py +7 -6
- chia/full_node/block_store.py +5 -7
- chia/full_node/bundle_tools.py +1 -2
- chia/full_node/coin_store.py +153 -124
- chia/{types → full_node}/eligible_coin_spends.py +39 -70
- chia/full_node/fee_estimator.py +1 -1
- chia/full_node/fee_estimator_interface.py +0 -8
- chia/full_node/fee_tracker.py +25 -25
- chia/full_node/full_node.py +70 -53
- chia/full_node/full_node_api.py +57 -40
- chia/{rpc → full_node}/full_node_rpc_api.py +87 -8
- chia/{rpc → full_node}/full_node_rpc_client.py +7 -6
- chia/full_node/full_node_store.py +23 -8
- chia/full_node/mempool.py +206 -53
- chia/full_node/mempool_check_conditions.py +20 -63
- chia/full_node/mempool_manager.py +53 -47
- chia/full_node/subscriptions.py +1 -3
- chia/full_node/tx_processing_queue.py +50 -3
- chia/full_node/weight_proof.py +46 -37
- chia/harvester/harvester.py +1 -1
- chia/harvester/harvester_api.py +22 -7
- chia/introducer/introducer.py +1 -1
- chia/introducer/introducer_api.py +1 -1
- chia/plot_sync/exceptions.py +1 -1
- chia/plot_sync/receiver.py +1 -1
- chia/plot_sync/sender.py +2 -2
- chia/pools/pool_puzzles.py +13 -18
- chia/pools/pool_wallet.py +23 -46
- chia/protocols/farmer_protocol.py +11 -3
- chia/protocols/full_node_protocol.py +1 -4
- chia/protocols/harvester_protocol.py +3 -3
- chia/protocols/pool_protocol.py +1 -2
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +1 -3
- chia/protocols/wallet_protocol.py +3 -3
- chia/rpc/rpc_client.py +7 -8
- chia/rpc/rpc_server.py +3 -3
- chia/rpc/util.py +3 -1
- chia/seeder/crawler.py +1 -1
- chia/seeder/crawler_api.py +1 -1
- chia/seeder/dns_server.py +2 -0
- chia/seeder/start_crawler.py +3 -3
- chia/server/address_manager.py +286 -38
- chia/server/address_manager_store.py +0 -215
- chia/{types → server}/aliases.py +7 -7
- chia/server/api_protocol.py +1 -1
- chia/server/chia_policy.py +1 -1
- chia/server/node_discovery.py +76 -113
- chia/server/rate_limits.py +1 -1
- chia/server/resolve_peer_info.py +43 -0
- chia/server/server.py +5 -5
- chia/server/start_data_layer.py +4 -4
- chia/server/start_farmer.py +5 -4
- chia/server/start_full_node.py +5 -4
- chia/server/start_harvester.py +7 -5
- chia/server/start_introducer.py +2 -2
- chia/server/start_service.py +1 -1
- chia/server/start_timelord.py +7 -5
- chia/server/start_wallet.py +7 -5
- chia/server/ws_connection.py +1 -1
- chia/simulator/add_blocks_in_batches.py +2 -2
- chia/simulator/block_tools.py +245 -201
- chia/simulator/full_node_simulator.py +38 -10
- chia/simulator/setup_services.py +12 -12
- chia/simulator/simulator_full_node_rpc_api.py +2 -2
- chia/simulator/simulator_full_node_rpc_client.py +2 -2
- chia/simulator/simulator_test_tools.py +2 -2
- chia/simulator/start_simulator.py +1 -1
- chia/simulator/wallet_tools.py +10 -18
- chia/ssl/create_ssl.py +1 -1
- chia/timelord/iters_from_block.py +14 -14
- chia/timelord/timelord.py +15 -11
- chia/timelord/timelord_api.py +14 -2
- chia/timelord/timelord_state.py +20 -14
- chia/types/blockchain_format/program.py +53 -10
- chia/types/blockchain_format/proof_of_space.py +73 -19
- chia/types/coin_spend.py +3 -56
- chia/types/generator_types.py +28 -0
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +12 -7
- chia/types/unfinished_header_block.py +1 -2
- chia/types/validation_state.py +1 -2
- chia/types/weight_proof.py +1 -3
- chia/util/action_scope.py +3 -3
- chia/util/block_cache.py +1 -2
- chia/util/byte_types.py +1 -1
- chia/util/casts.py +21 -0
- chia/util/config.py +0 -37
- chia/util/db_wrapper.py +8 -1
- chia/util/errors.py +3 -2
- chia/util/initial-config.yaml +21 -5
- chia/util/keychain.py +6 -7
- chia/util/keyring_wrapper.py +5 -5
- chia/util/limited_semaphore.py +1 -1
- chia/util/priority_mutex.py +1 -1
- chia/util/streamable.py +63 -5
- chia/util/task_timing.py +1 -1
- chia/util/virtual_project_analysis.py +1 -1
- chia/wallet/cat_wallet/cat_info.py +7 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +9 -5
- chia/wallet/cat_wallet/cat_utils.py +1 -1
- chia/wallet/cat_wallet/cat_wallet.py +44 -36
- chia/wallet/cat_wallet/lineage_store.py +7 -0
- chia/wallet/cat_wallet/r_cat_wallet.py +274 -0
- chia/wallet/conditions.py +5 -10
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -4
- chia/wallet/derivation_record.py +33 -0
- chia/wallet/derive_keys.py +3 -3
- chia/wallet/did_wallet/did_info.py +12 -3
- chia/wallet/did_wallet/did_wallet.py +132 -101
- chia/wallet/did_wallet/did_wallet_puzzles.py +9 -9
- chia/wallet/driver_protocol.py +3 -1
- chia/{types/spend_bundle.py → wallet/estimate_fees.py} +2 -7
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/nft_puzzle_utils.py +1 -1
- chia/wallet/nft_wallet/nft_wallet.py +69 -112
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +5 -3
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +6 -4
- chia/wallet/nft_wallet/transfer_program_puzzle.py +4 -2
- chia/wallet/nft_wallet/uncurry_nft.py +4 -6
- chia/wallet/notification_manager.py +2 -3
- chia/wallet/outer_puzzles.py +7 -2
- chia/wallet/puzzle_drivers.py +1 -1
- chia/wallet/puzzles/clawback/drivers.py +5 -4
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -1
- chia/wallet/puzzles/singleton_top_layer.py +2 -1
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +2 -1
- chia/wallet/puzzles/tails.py +1 -3
- chia/wallet/signer_protocol.py +5 -6
- chia/wallet/singleton.py +5 -4
- chia/wallet/singleton_record.py +1 -1
- chia/wallet/trade_manager.py +18 -20
- chia/wallet/trade_record.py +3 -6
- chia/wallet/trading/offer.py +12 -13
- chia/wallet/uncurried_puzzle.py +2 -2
- chia/wallet/util/compute_additions.py +58 -0
- chia/wallet/util/compute_hints.py +3 -3
- chia/wallet/util/compute_memos.py +4 -4
- chia/wallet/util/curry_and_treehash.py +2 -1
- chia/wallet/util/debug_spend_bundle.py +1 -1
- chia/wallet/util/merkle_tree.py +1 -1
- chia/wallet/util/peer_request_cache.py +1 -2
- chia/wallet/util/tx_config.py +3 -8
- chia/wallet/util/wallet_sync_utils.py +10 -5
- chia/wallet/util/wallet_types.py +1 -0
- chia/wallet/vc_wallet/cr_cat_drivers.py +17 -18
- chia/wallet/vc_wallet/cr_cat_wallet.py +30 -28
- chia/wallet/vc_wallet/cr_outer_puzzle.py +5 -3
- chia/wallet/vc_wallet/vc_drivers.py +50 -8
- chia/wallet/vc_wallet/vc_store.py +3 -5
- chia/wallet/vc_wallet/vc_wallet.py +15 -22
- chia/wallet/wallet.py +36 -46
- chia/wallet/wallet_action_scope.py +73 -4
- chia/wallet/wallet_blockchain.py +1 -3
- chia/wallet/wallet_interested_store.py +1 -1
- chia/wallet/wallet_nft_store.py +3 -3
- chia/wallet/wallet_node.py +17 -16
- chia/wallet/wallet_node_api.py +4 -5
- chia/wallet/wallet_pool_store.py +1 -1
- chia/wallet/wallet_protocol.py +2 -0
- chia/wallet/wallet_puzzle_store.py +1 -1
- chia/{rpc → wallet}/wallet_request_types.py +670 -81
- chia/{rpc → wallet}/wallet_rpc_api.py +735 -766
- chia/{rpc → wallet}/wallet_rpc_client.py +268 -420
- chia/wallet/wallet_singleton_store.py +8 -7
- chia/wallet/wallet_spend_bundle.py +4 -3
- chia/wallet/wallet_state_manager.py +320 -191
- chia/wallet/wallet_weight_proof_handler.py +1 -2
- chia/wallet/wsm_apis.py +98 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/METADATA +7 -7
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/RECORD +443 -436
- mozilla-ca/cacert.pem +3 -165
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +0 -145
- chia/cmds/dev.py +0 -18
- chia/types/blockchain_format/slots.py +0 -9
- chia/types/blockchain_format/sub_epoch_summary.py +0 -5
- chia/types/end_of_slot_bundle.py +0 -5
- chia/types/full_block.py +0 -5
- chia/types/header_block.py +0 -5
- chia/types/spend_bundle_conditions.py +0 -7
- chia/types/transaction_queue_entry.py +0 -56
- chia/types/unfinished_block.py +0 -5
- /chia/cmds/{installers.py → dev/installers.py} +0 -0
- /chia/cmds/{sim.py → dev/sim.py} +0 -0
- /chia/{util → cmds}/dump_keyring.py +0 -0
- /chia/{full_node → consensus}/signage_point.py +0 -0
- /chia/{rpc → data_layer}/data_layer_rpc_client.py +0 -0
- /chia/{rpc → farmer}/farmer_rpc_api.py +0 -0
- /chia/{util → full_node}/full_block_utils.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_api.py +0 -0
- /chia/{rpc → harvester}/harvester_rpc_client.py +0 -0
- /chia/{full_node → protocols}/fee_estimate.py +0 -0
- /chia/{server → protocols}/outbound_message.py +0 -0
- /chia/{rpc → seeder}/crawler_rpc_api.py +0 -0
- /chia/{util → simulator}/vdf_prover.py +0 -0
- /chia/{util → ssl}/ssl_check.py +0 -0
- /chia/{rpc → timelord}/timelord_rpc_api.py +0 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/LICENSE +0 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/entry_points.txt +0 -0
chia/seeder/dns_server.py
CHANGED
chia/seeder/start_crawler.py
CHANGED
|
@@ -11,13 +11,13 @@ from chia_rs import ConsensusConstants
|
|
|
11
11
|
from chia.apis import ApiProtocolRegistry
|
|
12
12
|
from chia.consensus.constants import replace_str_to_bytes
|
|
13
13
|
from chia.consensus.default_constants import DEFAULT_CONSTANTS
|
|
14
|
-
from chia.
|
|
14
|
+
from chia.protocols.outbound_message import NodeType
|
|
15
15
|
from chia.seeder.crawler import Crawler
|
|
16
16
|
from chia.seeder.crawler_api import CrawlerAPI
|
|
17
|
-
from chia.
|
|
17
|
+
from chia.seeder.crawler_rpc_api import CrawlerRpcApi
|
|
18
|
+
from chia.server.aliases import CrawlerService
|
|
18
19
|
from chia.server.signal_handlers import SignalHandlers
|
|
19
20
|
from chia.server.start_service import RpcInfo, Service, async_run
|
|
20
|
-
from chia.types.aliases import CrawlerService
|
|
21
21
|
from chia.util.chia_logging import initialize_service_logging
|
|
22
22
|
from chia.util.config import load_config, load_config_cli
|
|
23
23
|
from chia.util.default_root import resolve_root_path
|
chia/server/address_manager.py
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import functools
|
|
4
|
+
import io
|
|
3
5
|
import logging
|
|
4
6
|
import math
|
|
5
7
|
import time
|
|
6
8
|
from asyncio import Lock
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from ipaddress import IPv4Address, IPv6Address, ip_address
|
|
11
|
+
from pathlib import Path
|
|
7
12
|
from random import choice, randrange
|
|
8
13
|
from secrets import randbits
|
|
14
|
+
from timeit import default_timer as timer
|
|
9
15
|
from typing import Optional
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
import aiofiles
|
|
18
|
+
from chia_rs.sized_ints import uint16, uint32, uint64
|
|
12
19
|
|
|
20
|
+
from chia.server.address_manager_store import PeerDataSerialization
|
|
13
21
|
from chia.types.peer_info import PeerInfo, TimestampedPeerInfo
|
|
14
22
|
from chia.util.hash import std_hash
|
|
23
|
+
from chia.util.ip_address import IPAddress
|
|
15
24
|
|
|
16
25
|
TRIED_BUCKETS_PER_GROUP = 8
|
|
17
26
|
NEW_BUCKETS_PER_SOURCE_GROUP = 64
|
|
@@ -43,8 +52,10 @@ class ExtendedPeerInfo:
|
|
|
43
52
|
addr.port,
|
|
44
53
|
)
|
|
45
54
|
self.timestamp: int = addr.timestamp
|
|
46
|
-
self.src:
|
|
47
|
-
if src_peer is None:
|
|
55
|
+
self.src: PeerInfo
|
|
56
|
+
if src_peer is not None:
|
|
57
|
+
self.src = src_peer
|
|
58
|
+
else:
|
|
48
59
|
self.src = self.peer_info
|
|
49
60
|
self.random_pos: Optional[int] = None
|
|
50
61
|
self.is_tried: bool = False
|
|
@@ -55,7 +66,6 @@ class ExtendedPeerInfo:
|
|
|
55
66
|
self.last_count_attempt: int = 0
|
|
56
67
|
|
|
57
68
|
def to_string(self) -> str:
|
|
58
|
-
assert self.src is not None
|
|
59
69
|
out = (
|
|
60
70
|
self.peer_info.host
|
|
61
71
|
+ " "
|
|
@@ -69,6 +79,52 @@ class ExtendedPeerInfo:
|
|
|
69
79
|
)
|
|
70
80
|
return out
|
|
71
81
|
|
|
82
|
+
@classmethod
|
|
83
|
+
def encode_ip_type(cls, ip: IPAddress) -> bytes:
|
|
84
|
+
if isinstance(ip._inner, IPv4Address):
|
|
85
|
+
return b"\x00"
|
|
86
|
+
elif isinstance(ip._inner, IPv6Address):
|
|
87
|
+
return b"\x01"
|
|
88
|
+
raise TypeError("Unsupported IPAddress type.") # pragma: no cover
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def decode_ip(cls, data: io.BytesIO) -> str:
|
|
92
|
+
ip_type = data.read(1)
|
|
93
|
+
if ip_type == b"\x00":
|
|
94
|
+
ip_len = 4
|
|
95
|
+
elif ip_type == b"\x01":
|
|
96
|
+
ip_len = 16
|
|
97
|
+
else:
|
|
98
|
+
raise TypeError("Unknown IPAddress type byte.")
|
|
99
|
+
ip_bytes = data.read(ip_len)
|
|
100
|
+
ip = str(ip_address(ip_bytes))
|
|
101
|
+
return ip
|
|
102
|
+
|
|
103
|
+
def stream(self, out: io.BytesIO) -> None:
|
|
104
|
+
out.write(self.encode_ip_type(self.peer_info._ip))
|
|
105
|
+
out.write(self.peer_info._ip._inner.packed)
|
|
106
|
+
self.peer_info.port.stream(out)
|
|
107
|
+
uint64(self.timestamp).stream(out)
|
|
108
|
+
out.write(self.encode_ip_type(self.src._ip))
|
|
109
|
+
out.write(self.src._ip._inner.packed)
|
|
110
|
+
self.src.port.stream(out)
|
|
111
|
+
|
|
112
|
+
@classmethod
|
|
113
|
+
def parse(cls, data: io.BytesIO) -> ExtendedPeerInfo:
|
|
114
|
+
# Decode peer_info
|
|
115
|
+
peer_ip = cls.decode_ip(data)
|
|
116
|
+
peer_port = uint16.parse(data)
|
|
117
|
+
timestamp = uint64.parse(data)
|
|
118
|
+
|
|
119
|
+
# Decode src
|
|
120
|
+
src_ip = cls.decode_ip(data)
|
|
121
|
+
src_port = uint16.parse(data)
|
|
122
|
+
|
|
123
|
+
peer_info = TimestampedPeerInfo(peer_ip, uint16(peer_port), uint64(timestamp))
|
|
124
|
+
src_peer = PeerInfo(src_ip, uint16(src_port))
|
|
125
|
+
|
|
126
|
+
return cls(peer_info, src_peer)
|
|
127
|
+
|
|
72
128
|
@classmethod
|
|
73
129
|
def from_string(cls, peer_str: str) -> ExtendedPeerInfo:
|
|
74
130
|
blobs = peer_str.split(" ")
|
|
@@ -159,42 +215,152 @@ class ExtendedPeerInfo:
|
|
|
159
215
|
return chance
|
|
160
216
|
|
|
161
217
|
|
|
218
|
+
def create_tried_matrix() -> list[list[int]]:
|
|
219
|
+
return [[-1 for x in range(BUCKET_SIZE)] for y in range(TRIED_BUCKET_COUNT)]
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def create_new_matrix() -> list[list[int]]:
|
|
223
|
+
return [[-1 for x in range(BUCKET_SIZE)] for y in range(NEW_BUCKET_COUNT)]
|
|
224
|
+
|
|
225
|
+
|
|
162
226
|
# This is a Python port from 'CAddrMan' class from Bitcoin core code.
|
|
227
|
+
@dataclass
|
|
163
228
|
class AddressManager:
|
|
164
|
-
id_count: int
|
|
165
|
-
key: int
|
|
166
|
-
random_pos: list[int]
|
|
167
|
-
tried_matrix: list[list[int]]
|
|
168
|
-
new_matrix: list[list[int]]
|
|
169
|
-
tried_count: int
|
|
170
|
-
new_count: int
|
|
171
|
-
map_addr: dict[str, int]
|
|
172
|
-
map_info: dict[int, ExtendedPeerInfo]
|
|
173
|
-
last_good: int
|
|
174
|
-
tried_collisions: list[int]
|
|
175
|
-
used_new_matrix_positions: set[tuple[int, int]]
|
|
176
|
-
used_tried_matrix_positions: set[tuple[int, int]]
|
|
177
|
-
allow_private_subnets: bool
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
229
|
+
id_count: int = 0
|
|
230
|
+
key: int = field(default_factory=functools.partial(randbits, 256))
|
|
231
|
+
random_pos: list[int] = field(default_factory=list)
|
|
232
|
+
tried_matrix: list[list[int]] = field(default_factory=create_tried_matrix)
|
|
233
|
+
new_matrix: list[list[int]] = field(default_factory=create_new_matrix)
|
|
234
|
+
tried_count: int = 0
|
|
235
|
+
new_count: int = 0
|
|
236
|
+
map_addr: dict[str, int] = field(default_factory=dict)
|
|
237
|
+
map_info: dict[int, ExtendedPeerInfo] = field(default_factory=dict)
|
|
238
|
+
last_good: int = 1
|
|
239
|
+
tried_collisions: list[int] = field(default_factory=list)
|
|
240
|
+
used_new_matrix_positions: set[tuple[int, int]] = field(default_factory=set)
|
|
241
|
+
used_tried_matrix_positions: set[tuple[int, int]] = field(default_factory=set)
|
|
242
|
+
allow_private_subnets: bool = False
|
|
243
|
+
lock: Lock = field(default_factory=Lock)
|
|
244
|
+
|
|
245
|
+
@classmethod
|
|
246
|
+
async def create_address_manager(cls, peers_file_path: Path) -> AddressManager:
|
|
247
|
+
"""
|
|
248
|
+
Create an address manager using data deserialized from a peers file.
|
|
249
|
+
"""
|
|
250
|
+
address_manager: Optional[AddressManager] = None
|
|
251
|
+
if peers_file_path.exists():
|
|
252
|
+
try:
|
|
253
|
+
log.info(f"Loading peers from {peers_file_path}")
|
|
254
|
+
# try using the old method
|
|
255
|
+
address_manager = await cls._deserialize(peers_file_path)
|
|
256
|
+
except Exception:
|
|
257
|
+
try:
|
|
258
|
+
# try using the new method
|
|
259
|
+
async with aiofiles.open(peers_file_path, "rb") as f:
|
|
260
|
+
address_manager = cls.deserialize_bytes(io.BytesIO(await f.read()))
|
|
261
|
+
except Exception:
|
|
262
|
+
log.exception(f"Unable to create address_manager from {peers_file_path}")
|
|
263
|
+
|
|
264
|
+
if address_manager is None:
|
|
265
|
+
log.info("Creating new address_manager")
|
|
266
|
+
address_manager = AddressManager()
|
|
267
|
+
|
|
268
|
+
return address_manager
|
|
269
|
+
|
|
270
|
+
def serialize_bytes(self) -> bytes:
|
|
271
|
+
out = io.BytesIO()
|
|
272
|
+
nodes = io.BytesIO()
|
|
273
|
+
trieds = io.BytesIO()
|
|
274
|
+
new_table = io.BytesIO()
|
|
275
|
+
unique_ids: dict[int, int] = {}
|
|
276
|
+
count_ids: int = 0
|
|
277
|
+
|
|
278
|
+
for node_id, info in self.map_info.items():
|
|
279
|
+
unique_ids[node_id] = count_ids
|
|
280
|
+
if info.ref_count > 0:
|
|
281
|
+
assert count_ids != self.new_count
|
|
282
|
+
info.stream(nodes)
|
|
283
|
+
count_ids += 1
|
|
284
|
+
if info.is_tried:
|
|
285
|
+
info.stream(nodes)
|
|
286
|
+
|
|
287
|
+
out.write(self.key.to_bytes(32, byteorder="big"))
|
|
288
|
+
uint64(count_ids).stream(out)
|
|
289
|
+
|
|
290
|
+
count = 0
|
|
291
|
+
for bucket in range(NEW_BUCKET_COUNT):
|
|
292
|
+
for i in range(BUCKET_SIZE):
|
|
293
|
+
if self.new_matrix[bucket][i] != -1:
|
|
294
|
+
count += 1
|
|
295
|
+
uint64(unique_ids[self.new_matrix[bucket][i]]).stream(new_table)
|
|
296
|
+
uint64(bucket).stream(new_table)
|
|
297
|
+
|
|
298
|
+
# give ourselves a clue how long the new_table is
|
|
299
|
+
uint32(count).stream(out)
|
|
300
|
+
out.write(new_table.getvalue())
|
|
301
|
+
|
|
302
|
+
out.write(nodes.getvalue())
|
|
303
|
+
out.write(trieds.getvalue())
|
|
304
|
+
return out.getvalue()
|
|
305
|
+
|
|
306
|
+
@classmethod
|
|
307
|
+
def deserialize_bytes(cls, data: io.BytesIO) -> AddressManager:
|
|
308
|
+
address_manager = AddressManager()
|
|
309
|
+
|
|
310
|
+
address_manager.key = int.from_bytes(data.read(32), byteorder="big")
|
|
311
|
+
|
|
312
|
+
address_manager.new_count = uint64.parse(data)
|
|
313
|
+
# deserialize new_table
|
|
314
|
+
new_table_count = uint32.parse(data)
|
|
315
|
+
new_table_nodes: list[tuple[uint64, uint64]] = []
|
|
316
|
+
for i in range(new_table_count):
|
|
317
|
+
node_id = uint64.parse(data)
|
|
318
|
+
bucket = uint64.parse(data)
|
|
319
|
+
new_table_nodes.append((node_id, bucket))
|
|
320
|
+
|
|
321
|
+
# deserialize node info
|
|
322
|
+
address_manager.id_count = 0
|
|
323
|
+
length = len(data.getvalue())
|
|
324
|
+
while data.tell() < length:
|
|
325
|
+
# breakpoint()
|
|
326
|
+
info = ExtendedPeerInfo.parse(data)
|
|
327
|
+
# check if we're a new node
|
|
328
|
+
if address_manager.id_count < address_manager.new_count:
|
|
329
|
+
address_manager.map_addr[info.peer_info.host] = address_manager.id_count
|
|
330
|
+
address_manager.map_info[address_manager.id_count] = info
|
|
331
|
+
info.random_pos = len(address_manager.random_pos)
|
|
332
|
+
address_manager.random_pos.append(address_manager.id_count)
|
|
333
|
+
address_manager.id_count += 1
|
|
334
|
+
else:
|
|
335
|
+
# we're a tried node
|
|
336
|
+
tried_bucket = info.get_tried_bucket(address_manager.key)
|
|
337
|
+
tried_bucket_pos = info.get_bucket_position(address_manager.key, False, tried_bucket)
|
|
338
|
+
if address_manager.tried_matrix[tried_bucket][tried_bucket_pos] == -1:
|
|
339
|
+
info.random_pos = len(address_manager.random_pos)
|
|
340
|
+
info.is_tried = True
|
|
341
|
+
id_count = address_manager.id_count
|
|
342
|
+
address_manager.random_pos.append(id_count)
|
|
343
|
+
address_manager.map_info[id_count] = info
|
|
344
|
+
address_manager.map_addr[info.peer_info.host] = id_count
|
|
345
|
+
address_manager.tried_matrix[tried_bucket][tried_bucket_pos] = id_count
|
|
346
|
+
address_manager.id_count += 1
|
|
347
|
+
address_manager.tried_count += 1
|
|
348
|
+
|
|
349
|
+
# process
|
|
350
|
+
for node_id, bucket in new_table_nodes:
|
|
351
|
+
if node_id >= 0 and node_id < address_manager.new_count:
|
|
352
|
+
info = address_manager.map_info[node_id]
|
|
353
|
+
bucket_pos = info.get_bucket_position(address_manager.key, True, bucket)
|
|
354
|
+
if address_manager.new_matrix[bucket][bucket_pos] == -1 and info.ref_count < NEW_BUCKETS_PER_ADDRESS:
|
|
355
|
+
info.ref_count += 1
|
|
356
|
+
address_manager.new_matrix[bucket][bucket_pos] = node_id
|
|
357
|
+
|
|
358
|
+
# remove deads
|
|
359
|
+
address_manager.prune_dead_peers()
|
|
360
|
+
|
|
361
|
+
address_manager.load_used_table_positions()
|
|
362
|
+
|
|
363
|
+
return address_manager
|
|
198
364
|
|
|
199
365
|
def make_private_subnets_valid(self) -> None:
|
|
200
366
|
self.allow_private_subnets = True
|
|
@@ -231,6 +397,11 @@ class AddressManager:
|
|
|
231
397
|
if self.tried_matrix[bucket][pos] != -1:
|
|
232
398
|
self.used_tried_matrix_positions.add((bucket, pos))
|
|
233
399
|
|
|
400
|
+
def prune_dead_peers(self) -> None:
|
|
401
|
+
for id, info in list(self.map_info.items()):
|
|
402
|
+
if not info.is_tried and info.ref_count == 0:
|
|
403
|
+
self.delete_new_entry_(id)
|
|
404
|
+
|
|
234
405
|
def create_(self, addr: TimestampedPeerInfo, addr_src: Optional[PeerInfo]) -> tuple[ExtendedPeerInfo, int]:
|
|
235
406
|
self.id_count += 1
|
|
236
407
|
node_id = self.id_count
|
|
@@ -657,3 +828,80 @@ class AddressManager:
|
|
|
657
828
|
timestamp = math.floor(time.time())
|
|
658
829
|
async with self.lock:
|
|
659
830
|
self.connect_(addr, timestamp)
|
|
831
|
+
|
|
832
|
+
# This function is deprecated in favour of deserialize_bytes()
|
|
833
|
+
# it remains here for backwards compatibility and migration
|
|
834
|
+
@classmethod
|
|
835
|
+
async def _deserialize(cls, peers_file_path: Path) -> AddressManager:
|
|
836
|
+
"""
|
|
837
|
+
Create an address manager using data deserialized from a peers file.
|
|
838
|
+
"""
|
|
839
|
+
peer_data: Optional[PeerDataSerialization] = None
|
|
840
|
+
address_manager = AddressManager()
|
|
841
|
+
start_time = timer()
|
|
842
|
+
# if this fails, we pass the exception up to the function that called us and try the other type of deserializing
|
|
843
|
+
peer_data = await cls._read_peers(peers_file_path)
|
|
844
|
+
|
|
845
|
+
if peer_data is not None:
|
|
846
|
+
metadata: dict[str, str] = {key: value for key, value in peer_data.metadata}
|
|
847
|
+
nodes: list[tuple[int, ExtendedPeerInfo]] = [
|
|
848
|
+
(node_id, ExtendedPeerInfo.from_string(info_str)) for node_id, info_str in peer_data.nodes
|
|
849
|
+
]
|
|
850
|
+
new_table_entries: list[tuple[int, int]] = [(node_id, bucket) for node_id, bucket in peer_data.new_table]
|
|
851
|
+
log.debug(f"Deserializing peer data took {timer() - start_time} seconds")
|
|
852
|
+
|
|
853
|
+
address_manager.key = int(metadata["key"])
|
|
854
|
+
address_manager.new_count = int(metadata["new_count"])
|
|
855
|
+
# address_manager.tried_count = int(metadata["tried_count"])
|
|
856
|
+
address_manager.tried_count = 0
|
|
857
|
+
new_table_nodes = [(node_id, info) for node_id, info in nodes if node_id < address_manager.new_count]
|
|
858
|
+
for n, info in new_table_nodes:
|
|
859
|
+
address_manager.map_addr[info.peer_info.host] = n
|
|
860
|
+
address_manager.map_info[n] = info
|
|
861
|
+
info.random_pos = len(address_manager.random_pos)
|
|
862
|
+
address_manager.random_pos.append(n)
|
|
863
|
+
address_manager.id_count = len(new_table_nodes)
|
|
864
|
+
tried_table_nodes = [(node_id, info) for node_id, info in nodes if node_id >= address_manager.new_count]
|
|
865
|
+
# lost_count = 0
|
|
866
|
+
for node_id, info in tried_table_nodes:
|
|
867
|
+
tried_bucket = info.get_tried_bucket(address_manager.key)
|
|
868
|
+
tried_bucket_pos = info.get_bucket_position(address_manager.key, False, tried_bucket)
|
|
869
|
+
if address_manager.tried_matrix[tried_bucket][tried_bucket_pos] == -1:
|
|
870
|
+
info.random_pos = len(address_manager.random_pos)
|
|
871
|
+
info.is_tried = True
|
|
872
|
+
id_count = address_manager.id_count
|
|
873
|
+
address_manager.random_pos.append(id_count)
|
|
874
|
+
address_manager.map_info[id_count] = info
|
|
875
|
+
address_manager.map_addr[info.peer_info.host] = id_count
|
|
876
|
+
address_manager.tried_matrix[tried_bucket][tried_bucket_pos] = id_count
|
|
877
|
+
address_manager.id_count += 1
|
|
878
|
+
address_manager.tried_count += 1
|
|
879
|
+
# else:
|
|
880
|
+
# lost_count += 1
|
|
881
|
+
|
|
882
|
+
# address_manager.tried_count -= lost_count
|
|
883
|
+
for node_id, bucket in new_table_entries:
|
|
884
|
+
if node_id >= 0 and node_id < address_manager.new_count:
|
|
885
|
+
info = address_manager.map_info[node_id]
|
|
886
|
+
bucket_pos = info.get_bucket_position(address_manager.key, True, bucket)
|
|
887
|
+
if (
|
|
888
|
+
address_manager.new_matrix[bucket][bucket_pos] == -1
|
|
889
|
+
and info.ref_count < NEW_BUCKETS_PER_ADDRESS
|
|
890
|
+
):
|
|
891
|
+
info.ref_count += 1
|
|
892
|
+
address_manager.new_matrix[bucket][bucket_pos] = node_id
|
|
893
|
+
|
|
894
|
+
address_manager.prune_dead_peers()
|
|
895
|
+
|
|
896
|
+
address_manager.load_used_table_positions()
|
|
897
|
+
|
|
898
|
+
return address_manager
|
|
899
|
+
|
|
900
|
+
# this is a deprecated function, only kept around for migration to the new format
|
|
901
|
+
@classmethod
|
|
902
|
+
async def _read_peers(cls, peers_file_path: Path) -> PeerDataSerialization:
|
|
903
|
+
"""
|
|
904
|
+
Read the peers file and return the data as a PeerDataSerialization object.
|
|
905
|
+
"""
|
|
906
|
+
async with aiofiles.open(peers_file_path, "rb") as f:
|
|
907
|
+
return PeerDataSerialization.from_bytes(await f.read())
|
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import asyncio
|
|
4
3
|
import logging
|
|
5
4
|
from dataclasses import dataclass
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from timeit import default_timer as timer
|
|
8
|
-
from typing import Any, Optional
|
|
9
5
|
|
|
10
|
-
import aiofiles
|
|
11
6
|
from chia_rs.sized_ints import uint64
|
|
12
7
|
|
|
13
|
-
from chia.server.address_manager import (
|
|
14
|
-
BUCKET_SIZE,
|
|
15
|
-
NEW_BUCKET_COUNT,
|
|
16
|
-
NEW_BUCKETS_PER_ADDRESS,
|
|
17
|
-
AddressManager,
|
|
18
|
-
ExtendedPeerInfo,
|
|
19
|
-
)
|
|
20
|
-
from chia.util.files import write_file_async
|
|
21
8
|
from chia.util.streamable import Streamable, streamable
|
|
22
9
|
|
|
23
10
|
log = logging.getLogger(__name__)
|
|
@@ -33,205 +20,3 @@ class PeerDataSerialization(Streamable):
|
|
|
33
20
|
metadata: list[tuple[str, str]]
|
|
34
21
|
nodes: list[tuple[uint64, str]]
|
|
35
22
|
new_table: list[tuple[uint64, uint64]]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
async def makePeerDataSerialization(
|
|
39
|
-
metadata: list[tuple[str, Any]], nodes: list[tuple[int, ExtendedPeerInfo]], new_table: list[tuple[int, int]]
|
|
40
|
-
) -> bytes:
|
|
41
|
-
"""
|
|
42
|
-
Create a PeerDataSerialization, adapting the provided collections
|
|
43
|
-
"""
|
|
44
|
-
transformed_nodes: list[tuple[uint64, str]] = []
|
|
45
|
-
transformed_new_table: list[tuple[uint64, uint64]] = []
|
|
46
|
-
|
|
47
|
-
for index, [node_id, peer_info] in enumerate(nodes):
|
|
48
|
-
transformed_nodes.append((uint64(node_id), peer_info.to_string()))
|
|
49
|
-
# Come up to breathe for a moment
|
|
50
|
-
if index % 1000 == 0:
|
|
51
|
-
await asyncio.sleep(0)
|
|
52
|
-
|
|
53
|
-
for index, [node_id, bucket_id] in enumerate(new_table):
|
|
54
|
-
transformed_new_table.append((uint64(node_id), uint64(bucket_id)))
|
|
55
|
-
# Come up to breathe for a moment
|
|
56
|
-
if index % 1000 == 0:
|
|
57
|
-
await asyncio.sleep(0)
|
|
58
|
-
|
|
59
|
-
serialized_bytes: bytes = bytes(PeerDataSerialization(metadata, transformed_nodes, transformed_new_table))
|
|
60
|
-
return serialized_bytes
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class AddressManagerStore:
|
|
64
|
-
"""
|
|
65
|
-
Metadata table:
|
|
66
|
-
- private key
|
|
67
|
-
- new table count
|
|
68
|
-
- tried table count
|
|
69
|
-
Nodes table:
|
|
70
|
-
* Maps entries from new/tried table to unique node ids.
|
|
71
|
-
- node_id
|
|
72
|
-
- IP, port, together with the IP, port of the source peer.
|
|
73
|
-
New table:
|
|
74
|
-
* Stores node_id, bucket for each occurrence in the new table of an entry.
|
|
75
|
-
* Once we know the buckets, we can also deduce the bucket positions.
|
|
76
|
-
Every other information, such as tried_matrix, map_addr, map_info, random_pos,
|
|
77
|
-
be deduced and it is not explicitly stored, instead it is recalculated.
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
@classmethod
|
|
81
|
-
async def create_address_manager(cls, peers_file_path: Path) -> AddressManager:
|
|
82
|
-
"""
|
|
83
|
-
Create an address manager using data deserialized from a peers file.
|
|
84
|
-
"""
|
|
85
|
-
address_manager: Optional[AddressManager] = None
|
|
86
|
-
if peers_file_path.exists():
|
|
87
|
-
try:
|
|
88
|
-
log.info(f"Loading peers from {peers_file_path}")
|
|
89
|
-
address_manager = await cls._deserialize(peers_file_path)
|
|
90
|
-
except Exception:
|
|
91
|
-
log.exception(f"Unable to create address_manager from {peers_file_path}")
|
|
92
|
-
|
|
93
|
-
if address_manager is None:
|
|
94
|
-
log.info("Creating new address_manager")
|
|
95
|
-
address_manager = AddressManager()
|
|
96
|
-
|
|
97
|
-
return address_manager
|
|
98
|
-
|
|
99
|
-
@classmethod
|
|
100
|
-
async def serialize(cls, address_manager: AddressManager, peers_file_path: Path) -> None:
|
|
101
|
-
"""
|
|
102
|
-
Serialize the address manager's peer data to a file.
|
|
103
|
-
"""
|
|
104
|
-
metadata: list[tuple[str, str]] = []
|
|
105
|
-
nodes: list[tuple[int, ExtendedPeerInfo]] = []
|
|
106
|
-
new_table_entries: list[tuple[int, int]] = []
|
|
107
|
-
unique_ids: dict[int, int] = {}
|
|
108
|
-
count_ids: int = 0
|
|
109
|
-
|
|
110
|
-
log.info("Serializing peer data")
|
|
111
|
-
metadata.append(("key", str(address_manager.key)))
|
|
112
|
-
|
|
113
|
-
for node_id, info in address_manager.map_info.items():
|
|
114
|
-
unique_ids[node_id] = count_ids
|
|
115
|
-
if info.ref_count > 0:
|
|
116
|
-
assert count_ids != address_manager.new_count
|
|
117
|
-
nodes.append((count_ids, info))
|
|
118
|
-
count_ids += 1
|
|
119
|
-
metadata.append(("new_count", str(count_ids)))
|
|
120
|
-
|
|
121
|
-
tried_ids = 0
|
|
122
|
-
for node_id, info in address_manager.map_info.items():
|
|
123
|
-
if info.is_tried:
|
|
124
|
-
assert info is not None
|
|
125
|
-
assert tried_ids != address_manager.tried_count
|
|
126
|
-
nodes.append((count_ids, info))
|
|
127
|
-
count_ids += 1
|
|
128
|
-
tried_ids += 1
|
|
129
|
-
metadata.append(("tried_count", str(tried_ids)))
|
|
130
|
-
|
|
131
|
-
for bucket in range(NEW_BUCKET_COUNT):
|
|
132
|
-
for i in range(BUCKET_SIZE):
|
|
133
|
-
if address_manager.new_matrix[bucket][i] != -1:
|
|
134
|
-
index = unique_ids[address_manager.new_matrix[bucket][i]]
|
|
135
|
-
new_table_entries.append((index, bucket))
|
|
136
|
-
|
|
137
|
-
try:
|
|
138
|
-
# Ensure the parent directory exists
|
|
139
|
-
peers_file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
140
|
-
start_time = timer()
|
|
141
|
-
await cls._write_peers(peers_file_path, metadata, nodes, new_table_entries)
|
|
142
|
-
log.debug(f"Serializing peer data took {timer() - start_time} seconds")
|
|
143
|
-
except Exception:
|
|
144
|
-
log.exception(f"Failed to write peer data to {peers_file_path}")
|
|
145
|
-
|
|
146
|
-
@classmethod
|
|
147
|
-
async def _deserialize(cls, peers_file_path: Path) -> AddressManager:
|
|
148
|
-
"""
|
|
149
|
-
Create an address manager using data deserialized from a peers file.
|
|
150
|
-
"""
|
|
151
|
-
peer_data: Optional[PeerDataSerialization] = None
|
|
152
|
-
address_manager = AddressManager()
|
|
153
|
-
start_time = timer()
|
|
154
|
-
try:
|
|
155
|
-
peer_data = await cls._read_peers(peers_file_path)
|
|
156
|
-
except Exception:
|
|
157
|
-
log.exception(f"Unable to deserialize peers from {peers_file_path}")
|
|
158
|
-
|
|
159
|
-
if peer_data is not None:
|
|
160
|
-
metadata: dict[str, str] = {key: value for key, value in peer_data.metadata}
|
|
161
|
-
nodes: list[tuple[int, ExtendedPeerInfo]] = [
|
|
162
|
-
(node_id, ExtendedPeerInfo.from_string(info_str)) for node_id, info_str in peer_data.nodes
|
|
163
|
-
]
|
|
164
|
-
new_table_entries: list[tuple[int, int]] = [(node_id, bucket) for node_id, bucket in peer_data.new_table]
|
|
165
|
-
log.debug(f"Deserializing peer data took {timer() - start_time} seconds")
|
|
166
|
-
|
|
167
|
-
address_manager.key = int(metadata["key"])
|
|
168
|
-
address_manager.new_count = int(metadata["new_count"])
|
|
169
|
-
# address_manager.tried_count = int(metadata["tried_count"])
|
|
170
|
-
address_manager.tried_count = 0
|
|
171
|
-
|
|
172
|
-
new_table_nodes = [(node_id, info) for node_id, info in nodes if node_id < address_manager.new_count]
|
|
173
|
-
for n, info in new_table_nodes:
|
|
174
|
-
address_manager.map_addr[info.peer_info.host] = n
|
|
175
|
-
address_manager.map_info[n] = info
|
|
176
|
-
info.random_pos = len(address_manager.random_pos)
|
|
177
|
-
address_manager.random_pos.append(n)
|
|
178
|
-
address_manager.id_count = len(new_table_nodes)
|
|
179
|
-
tried_table_nodes = [(node_id, info) for node_id, info in nodes if node_id >= address_manager.new_count]
|
|
180
|
-
# lost_count = 0
|
|
181
|
-
for node_id, info in tried_table_nodes:
|
|
182
|
-
tried_bucket = info.get_tried_bucket(address_manager.key)
|
|
183
|
-
tried_bucket_pos = info.get_bucket_position(address_manager.key, False, tried_bucket)
|
|
184
|
-
if address_manager.tried_matrix[tried_bucket][tried_bucket_pos] == -1:
|
|
185
|
-
info.random_pos = len(address_manager.random_pos)
|
|
186
|
-
info.is_tried = True
|
|
187
|
-
id_count = address_manager.id_count
|
|
188
|
-
address_manager.random_pos.append(id_count)
|
|
189
|
-
address_manager.map_info[id_count] = info
|
|
190
|
-
address_manager.map_addr[info.peer_info.host] = id_count
|
|
191
|
-
address_manager.tried_matrix[tried_bucket][tried_bucket_pos] = id_count
|
|
192
|
-
address_manager.id_count += 1
|
|
193
|
-
address_manager.tried_count += 1
|
|
194
|
-
# else:
|
|
195
|
-
# lost_count += 1
|
|
196
|
-
|
|
197
|
-
# address_manager.tried_count -= lost_count
|
|
198
|
-
for node_id, bucket in new_table_entries:
|
|
199
|
-
if node_id >= 0 and node_id < address_manager.new_count:
|
|
200
|
-
info = address_manager.map_info[node_id]
|
|
201
|
-
bucket_pos = info.get_bucket_position(address_manager.key, True, bucket)
|
|
202
|
-
if (
|
|
203
|
-
address_manager.new_matrix[bucket][bucket_pos] == -1
|
|
204
|
-
and info.ref_count < NEW_BUCKETS_PER_ADDRESS
|
|
205
|
-
):
|
|
206
|
-
info.ref_count += 1
|
|
207
|
-
address_manager.new_matrix[bucket][bucket_pos] = node_id
|
|
208
|
-
|
|
209
|
-
for node_id, info in list(address_manager.map_info.items()):
|
|
210
|
-
if not info.is_tried and info.ref_count == 0:
|
|
211
|
-
address_manager.delete_new_entry_(node_id)
|
|
212
|
-
|
|
213
|
-
address_manager.load_used_table_positions()
|
|
214
|
-
|
|
215
|
-
return address_manager
|
|
216
|
-
|
|
217
|
-
@classmethod
|
|
218
|
-
async def _read_peers(cls, peers_file_path: Path) -> PeerDataSerialization:
|
|
219
|
-
"""
|
|
220
|
-
Read the peers file and return the data as a PeerDataSerialization object.
|
|
221
|
-
"""
|
|
222
|
-
async with aiofiles.open(peers_file_path, "rb") as f:
|
|
223
|
-
return PeerDataSerialization.from_bytes(await f.read())
|
|
224
|
-
|
|
225
|
-
@classmethod
|
|
226
|
-
async def _write_peers(
|
|
227
|
-
cls,
|
|
228
|
-
peers_file_path: Path,
|
|
229
|
-
metadata: list[tuple[str, Any]],
|
|
230
|
-
nodes: list[tuple[int, ExtendedPeerInfo]],
|
|
231
|
-
new_table: list[tuple[int, int]],
|
|
232
|
-
) -> None:
|
|
233
|
-
"""
|
|
234
|
-
Serializes the given peer data and writes it to the peers file.
|
|
235
|
-
"""
|
|
236
|
-
serialized_bytes: bytes = await makePeerDataSerialization(metadata, nodes, new_table)
|
|
237
|
-
await write_file_async(peers_file_path, serialized_bytes, file_mode=0o644)
|
chia/{types → server}/aliases.py
RENAMED
|
@@ -2,28 +2,28 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from chia.data_layer.data_layer import DataLayer
|
|
4
4
|
from chia.data_layer.data_layer_api import DataLayerAPI
|
|
5
|
+
from chia.data_layer.data_layer_rpc_api import DataLayerRpcApi
|
|
5
6
|
from chia.farmer.farmer import Farmer
|
|
6
7
|
from chia.farmer.farmer_api import FarmerAPI
|
|
8
|
+
from chia.farmer.farmer_rpc_api import FarmerRpcApi
|
|
7
9
|
from chia.full_node.full_node import FullNode
|
|
8
10
|
from chia.full_node.full_node_api import FullNodeAPI
|
|
11
|
+
from chia.full_node.full_node_rpc_api import FullNodeRpcApi
|
|
9
12
|
from chia.harvester.harvester import Harvester
|
|
10
13
|
from chia.harvester.harvester_api import HarvesterAPI
|
|
14
|
+
from chia.harvester.harvester_rpc_api import HarvesterRpcApi
|
|
11
15
|
from chia.introducer.introducer import Introducer
|
|
12
16
|
from chia.introducer.introducer_api import IntroducerAPI
|
|
13
|
-
from chia.rpc.crawler_rpc_api import CrawlerRpcApi
|
|
14
|
-
from chia.rpc.data_layer_rpc_api import DataLayerRpcApi
|
|
15
|
-
from chia.rpc.farmer_rpc_api import FarmerRpcApi
|
|
16
|
-
from chia.rpc.full_node_rpc_api import FullNodeRpcApi
|
|
17
|
-
from chia.rpc.harvester_rpc_api import HarvesterRpcApi
|
|
18
|
-
from chia.rpc.timelord_rpc_api import TimelordRpcApi
|
|
19
|
-
from chia.rpc.wallet_rpc_api import WalletRpcApi
|
|
20
17
|
from chia.seeder.crawler import Crawler
|
|
21
18
|
from chia.seeder.crawler_api import CrawlerAPI
|
|
19
|
+
from chia.seeder.crawler_rpc_api import CrawlerRpcApi
|
|
22
20
|
from chia.server.start_service import Service
|
|
23
21
|
from chia.timelord.timelord import Timelord
|
|
24
22
|
from chia.timelord.timelord_api import TimelordAPI
|
|
23
|
+
from chia.timelord.timelord_rpc_api import TimelordRpcApi
|
|
25
24
|
from chia.wallet.wallet_node import WalletNode
|
|
26
25
|
from chia.wallet.wallet_node_api import WalletNodeAPI
|
|
26
|
+
from chia.wallet.wallet_rpc_api import WalletRpcApi
|
|
27
27
|
|
|
28
28
|
CrawlerService = Service[Crawler, CrawlerAPI, CrawlerRpcApi]
|
|
29
29
|
DataLayerService = Service[DataLayer, DataLayerAPI, DataLayerRpcApi]
|
chia/server/api_protocol.py
CHANGED
|
@@ -9,8 +9,8 @@ from typing import Callable, ClassVar, Optional, TypeVar, Union, final, get_type
|
|
|
9
9
|
|
|
10
10
|
from typing_extensions import Concatenate, ParamSpec, Protocol
|
|
11
11
|
|
|
12
|
+
from chia.protocols.outbound_message import Message
|
|
12
13
|
from chia.protocols.protocol_message_types import ProtocolMessageTypes
|
|
13
|
-
from chia.server.outbound_message import Message
|
|
14
14
|
from chia.util.streamable import Streamable
|
|
15
15
|
|
|
16
16
|
|