chia-blockchain 2.5.0rc2__py3-none-any.whl → 2.5.1rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chia/_tests/README.md +1 -1
- chia/_tests/blockchain/blockchain_test_utils.py +24 -26
- chia/_tests/blockchain/test_augmented_chain.py +6 -8
- chia/_tests/blockchain/test_blockchain.py +409 -307
- chia/_tests/blockchain/test_blockchain_transactions.py +56 -75
- chia/_tests/blockchain/test_build_chains.py +11 -13
- chia/_tests/blockchain/test_get_block_generator.py +8 -8
- chia/_tests/blockchain/test_lookup_fork_chain.py +3 -4
- chia/_tests/build-init-files.py +3 -4
- chia/_tests/build-job-matrix.py +9 -9
- chia/_tests/check_sql_statements.py +2 -3
- chia/_tests/clvm/benchmark_costs.py +1 -1
- chia/_tests/clvm/coin_store.py +7 -5
- chia/_tests/clvm/test_chialisp_deserialization.py +8 -8
- chia/_tests/clvm/test_condition_codes.py +2 -2
- chia/_tests/clvm/test_curry_and_treehash.py +2 -4
- chia/_tests/clvm/test_message_conditions.py +184 -0
- chia/_tests/clvm/test_puzzle_compression.py +1 -2
- chia/_tests/clvm/test_puzzle_drivers.py +3 -3
- chia/_tests/clvm/test_puzzles.py +13 -18
- chia/_tests/clvm/test_singletons.py +17 -17
- chia/_tests/clvm/test_spend_sim.py +7 -7
- chia/_tests/cmds/cmd_test_utils.py +42 -45
- chia/_tests/cmds/conftest.py +2 -2
- chia/_tests/cmds/test_click_types.py +21 -16
- chia/_tests/cmds/test_cmd_framework.py +255 -35
- chia/_tests/cmds/test_cmds_util.py +2 -2
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_dev_gh.py +131 -0
- chia/_tests/cmds/test_farm_cmd.py +1 -2
- chia/_tests/cmds/test_show.py +6 -6
- chia/_tests/cmds/test_tx_config_args.py +2 -1
- chia/_tests/cmds/wallet/test_dao.py +23 -23
- chia/_tests/cmds/wallet/test_did.py +29 -29
- chia/_tests/cmds/wallet/test_nft.py +24 -23
- chia/_tests/cmds/wallet/test_notifications.py +8 -8
- chia/_tests/cmds/wallet/test_tx_decorators.py +3 -3
- chia/_tests/cmds/wallet/test_vcs.py +97 -73
- chia/_tests/cmds/wallet/test_wallet.py +74 -75
- chia/_tests/cmds/wallet/test_wallet_check.py +5 -7
- chia/_tests/conftest.py +153 -38
- chia/_tests/connection_utils.py +7 -6
- chia/_tests/core/cmds/test_beta.py +3 -3
- chia/_tests/core/cmds/test_keys.py +6 -6
- chia/_tests/core/cmds/test_wallet.py +3 -3
- chia/_tests/core/consensus/test_block_creation.py +3 -5
- chia/_tests/core/custom_types/test_coin.py +1 -3
- chia/_tests/core/custom_types/test_spend_bundle.py +3 -4
- chia/_tests/core/daemon/test_daemon.py +58 -58
- chia/_tests/core/daemon/test_keychain_proxy.py +2 -1
- chia/_tests/core/data_layer/conftest.py +4 -3
- chia/_tests/core/data_layer/test_data_cli.py +1 -2
- chia/_tests/core/data_layer/test_data_layer.py +5 -5
- chia/_tests/core/data_layer/test_data_layer_util.py +8 -9
- chia/_tests/core/data_layer/test_data_rpc.py +75 -93
- chia/_tests/core/data_layer/test_data_store.py +38 -37
- chia/_tests/core/data_layer/test_data_store_schema.py +11 -11
- chia/_tests/core/data_layer/util.py +11 -10
- chia/_tests/core/farmer/test_farmer_api.py +6 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +5 -10
- chia/_tests/core/full_node/ram_db.py +2 -2
- chia/_tests/core/full_node/stores/test_block_store.py +113 -11
- chia/_tests/core/full_node/stores/test_coin_store.py +37 -28
- chia/_tests/core/full_node/stores/test_full_node_store.py +34 -30
- chia/_tests/core/full_node/stores/test_hint_store.py +3 -4
- chia/_tests/core/full_node/test_address_manager.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +1 -1
- chia/_tests/core/full_node/test_conditions.py +10 -12
- chia/_tests/core/full_node/test_full_node.py +2077 -1822
- chia/_tests/core/full_node/test_generator_tools.py +4 -4
- chia/_tests/core/full_node/test_hint_management.py +2 -2
- chia/_tests/core/full_node/test_performance.py +2 -5
- chia/_tests/core/full_node/test_subscriptions.py +4 -4
- chia/_tests/core/full_node/test_tx_processing_queue.py +5 -4
- chia/_tests/core/make_block_generator.py +5 -7
- chia/_tests/core/mempool/test_mempool.py +205 -208
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +5 -5
- chia/_tests/core/mempool/test_mempool_item_queries.py +2 -4
- chia/_tests/core/mempool/test_mempool_manager.py +109 -80
- chia/_tests/core/mempool/test_mempool_performance.py +3 -4
- chia/_tests/core/mempool/test_singleton_fast_forward.py +12 -12
- chia/_tests/core/server/flood.py +6 -4
- chia/_tests/core/server/serve.py +10 -7
- chia/_tests/core/server/test_api_protocol.py +21 -0
- chia/_tests/core/server/test_capabilities.py +3 -5
- chia/_tests/core/server/test_dos.py +15 -16
- chia/_tests/core/server/test_loop.py +14 -10
- chia/_tests/core/server/test_node_discovery.py +1 -2
- chia/_tests/core/server/test_rate_limits.py +156 -44
- chia/_tests/core/server/test_server.py +8 -7
- chia/_tests/core/services/test_services.py +59 -37
- chia/_tests/core/ssl/test_ssl.py +5 -3
- chia/_tests/core/test_cost_calculation.py +5 -6
- chia/_tests/core/test_crawler.py +2 -2
- chia/_tests/core/test_db_conversion.py +5 -4
- chia/_tests/core/test_db_validation.py +6 -5
- chia/_tests/core/test_farmer_harvester_rpc.py +8 -7
- chia/_tests/core/test_filter.py +3 -5
- chia/_tests/core/test_full_node_rpc.py +64 -90
- chia/_tests/core/test_merkle_set.py +10 -10
- chia/_tests/core/test_program.py +2 -4
- chia/_tests/core/test_rpc_util.py +1 -2
- chia/_tests/core/test_seeder.py +124 -12
- chia/_tests/core/util/test_block_cache.py +5 -5
- chia/_tests/core/util/test_cached_bls.py +3 -3
- chia/_tests/core/util/test_config.py +13 -13
- chia/_tests/core/util/test_files.py +2 -2
- chia/_tests/core/util/test_jsonify.py +9 -9
- chia/_tests/core/util/test_keychain.py +13 -5
- chia/_tests/core/util/test_keyring_wrapper.py +6 -5
- chia/_tests/core/util/test_log_exceptions.py +3 -3
- chia/_tests/core/util/test_streamable.py +38 -38
- chia/_tests/db/test_db_wrapper.py +13 -12
- chia/_tests/environments/common.py +2 -2
- chia/_tests/environments/full_node.py +2 -2
- chia/_tests/environments/wallet.py +109 -48
- chia/_tests/farmer_harvester/test_farmer.py +35 -35
- chia/_tests/farmer_harvester/test_farmer_harvester.py +17 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +73 -46
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +8 -8
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +47 -47
- chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +6 -7
- chia/_tests/fee_estimation/test_mempoolitem_height_added.py +11 -11
- chia/_tests/generator/test_compression.py +13 -30
- chia/_tests/generator/test_generator_types.py +3 -3
- chia/_tests/generator/test_rom.py +7 -9
- chia/_tests/plot_sync/test_delta.py +2 -3
- chia/_tests/plot_sync/test_plot_sync.py +25 -24
- chia/_tests/plot_sync/test_receiver.py +9 -9
- chia/_tests/plot_sync/test_sender.py +1 -1
- chia/_tests/plot_sync/test_sync_simulated.py +27 -26
- chia/_tests/plot_sync/util.py +2 -1
- chia/_tests/plotting/test_plot_manager.py +54 -11
- chia/_tests/plotting/util.py +2 -3
- chia/_tests/pools/test_pool_cli_parsing.py +128 -0
- chia/_tests/pools/test_pool_cmdline.py +993 -15
- chia/_tests/pools/test_pool_config.py +3 -5
- chia/_tests/pools/test_pool_puzzles_lifecycle.py +10 -11
- chia/_tests/pools/test_pool_rpc.py +203 -90
- chia/_tests/pools/test_pool_wallet.py +12 -8
- chia/_tests/pools/test_wallet_pool_store.py +3 -3
- chia/_tests/process_junit.py +16 -17
- chia/_tests/rpc/test_rpc_client.py +59 -2
- chia/_tests/rpc/test_rpc_server.py +183 -0
- chia/_tests/simulation/test_simulation.py +5 -5
- chia/_tests/simulation/test_simulator.py +8 -10
- chia/_tests/simulation/test_start_simulator.py +5 -4
- chia/_tests/timelord/test_new_peak.py +19 -19
- chia/_tests/tools/test_run_block.py +1 -2
- chia/_tests/tools/test_virtual_project.py +591 -0
- chia/_tests/util/benchmark_cost.py +9 -9
- chia/_tests/util/benchmarks.py +1 -2
- chia/_tests/util/blockchain.py +12 -11
- chia/_tests/util/blockchain_mock.py +15 -15
- chia/_tests/util/build_network_protocol_files.py +12 -12
- chia/_tests/util/db_connection.py +3 -2
- chia/_tests/util/full_sync.py +14 -6
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/generator_tools_testing.py +5 -7
- chia/_tests/util/get_name_puzzle_conditions.py +52 -0
- chia/_tests/util/key_tool.py +2 -3
- chia/_tests/util/misc.py +59 -106
- chia/_tests/util/network_protocol_data.py +7 -9
- chia/_tests/util/protocol_messages_json.py +112 -111
- chia/_tests/util/rpc.py +3 -0
- chia/_tests/util/run_block.py +16 -16
- chia/_tests/util/setup_nodes.py +25 -23
- chia/{clvm → _tests/util}/spend_sim.py +59 -55
- chia/_tests/util/split_managers.py +12 -9
- chia/_tests/util/temp_file.py +1 -1
- chia/_tests/util/test_action_scope.py +2 -1
- chia/_tests/util/test_async_pool.py +8 -8
- chia/_tests/util/test_build_job_matrix.py +2 -3
- chia/_tests/util/test_condition_tools.py +4 -6
- chia/_tests/util/test_config.py +5 -5
- chia/_tests/util/test_dump_keyring.py +1 -1
- chia/_tests/util/test_full_block_utils.py +19 -11
- chia/_tests/util/test_limited_semaphore.py +4 -3
- chia/_tests/util/test_logging_filter.py +2 -3
- chia/_tests/util/test_misc.py +29 -28
- chia/_tests/util/test_network.py +32 -31
- chia/_tests/util/test_network_protocol_files.py +2 -3
- chia/_tests/util/test_network_protocol_json.py +1 -0
- chia/_tests/util/test_network_protocol_test.py +18 -19
- chia/_tests/util/test_paginator.py +3 -4
- chia/_tests/util/test_pprint.py +1 -1
- chia/_tests/util/test_priority_mutex.py +18 -17
- chia/_tests/util/test_recursive_replace.py +2 -2
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/test_timing.py +1 -1
- chia/_tests/util/test_trusted_peer.py +2 -2
- chia/_tests/util/time_out_assert.py +43 -6
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -1
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +117 -29
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +15 -15
- chia/_tests/wallet/cat_wallet/test_trades.py +50 -28
- chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -5
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +6 -6
- chia/_tests/wallet/clawback/test_clawback_metadata.py +1 -2
- chia/_tests/wallet/conftest.py +135 -74
- chia/_tests/wallet/dao_wallet/test_dao_clvm.py +25 -17
- chia/_tests/wallet/dao_wallet/test_dao_wallets.py +75 -75
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +10 -12
- chia/_tests/wallet/db_wallet/test_dl_offers.py +6 -6
- chia/_tests/wallet/db_wallet/test_dl_wallet.py +18 -18
- chia/_tests/wallet/did_wallet/test_did.py +1277 -474
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +12 -11
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +115 -105
- chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +6 -7
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +16 -16
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +3 -3
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +38 -12
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +1 -1
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +31 -33
- chia/_tests/wallet/rpc/test_wallet_rpc.py +218 -171
- chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +36 -37
- chia/_tests/wallet/sync/test_wallet_sync.py +241 -78
- chia/_tests/wallet/test_address_type.py +20 -20
- chia/_tests/wallet/test_clvm_streamable.py +5 -5
- chia/_tests/wallet/test_coin_management.py +354 -0
- chia/_tests/wallet/test_coin_selection.py +34 -35
- chia/_tests/wallet/test_conditions.py +28 -16
- chia/_tests/wallet/test_debug_spend_bundle.py +156 -14
- chia/_tests/wallet/test_new_wallet_protocol.py +29 -31
- chia/_tests/wallet/test_nft_store.py +1 -2
- chia/_tests/wallet/test_notifications.py +2 -2
- chia/_tests/wallet/test_offer_parsing_performance.py +1 -1
- chia/_tests/wallet/test_puzzle_store.py +2 -3
- chia/_tests/wallet/test_sign_coin_spends.py +3 -3
- chia/_tests/wallet/test_signer_protocol.py +33 -34
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +29 -29
- chia/_tests/wallet/test_taproot.py +1 -1
- chia/_tests/wallet/test_transaction_store.py +23 -19
- chia/_tests/wallet/test_util.py +36 -32
- chia/_tests/wallet/test_wallet.py +37 -37
- chia/_tests/wallet/test_wallet_action_scope.py +8 -8
- chia/_tests/wallet/test_wallet_blockchain.py +4 -6
- chia/_tests/wallet/test_wallet_coin_store.py +34 -34
- chia/_tests/wallet/test_wallet_node.py +69 -72
- chia/_tests/wallet/test_wallet_retry.py +3 -3
- chia/_tests/wallet/test_wallet_state_manager.py +12 -5
- chia/_tests/wallet/test_wallet_trade_store.py +2 -2
- chia/_tests/wallet/test_wallet_utils.py +5 -4
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -3
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +18 -18
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +69 -40
- chia/_tests/wallet/wallet_block_tools.py +27 -27
- chia/_tests/weight_proof/test_weight_proof.py +30 -30
- chia/apis.py +19 -0
- chia/cmds/beta.py +8 -7
- chia/cmds/beta_funcs.py +15 -11
- chia/cmds/check_wallet_db.py +29 -27
- chia/cmds/chia.py +17 -9
- chia/cmds/cmd_classes.py +87 -79
- chia/cmds/cmd_helpers.py +242 -0
- chia/cmds/cmds_util.py +56 -66
- chia/cmds/coin_funcs.py +168 -153
- chia/cmds/coins.py +156 -194
- chia/cmds/configure.py +4 -3
- chia/cmds/dao.py +89 -33
- chia/cmds/dao_funcs.py +55 -33
- chia/cmds/data.py +7 -6
- chia/cmds/data_funcs.py +26 -21
- chia/cmds/db.py +4 -3
- chia/cmds/db_backup_func.py +2 -2
- chia/cmds/db_upgrade_func.py +3 -3
- chia/cmds/db_validate_func.py +2 -2
- chia/cmds/dev.py +2 -0
- chia/cmds/farm.py +18 -5
- chia/cmds/farm_funcs.py +17 -24
- chia/cmds/gh.py +275 -0
- chia/cmds/init.py +4 -11
- chia/cmds/init_funcs.py +9 -9
- chia/cmds/installers.py +5 -3
- chia/cmds/keys.py +56 -39
- chia/cmds/keys_funcs.py +30 -31
- chia/cmds/netspace.py +6 -3
- chia/cmds/netspace_funcs.py +3 -2
- chia/cmds/param_types.py +16 -6
- chia/cmds/passphrase.py +8 -7
- chia/cmds/passphrase_funcs.py +7 -61
- chia/cmds/peer.py +2 -1
- chia/cmds/peer_funcs.py +5 -5
- chia/cmds/plotnft.py +207 -153
- chia/cmds/plotnft_funcs.py +205 -174
- chia/cmds/plots.py +14 -6
- chia/cmds/plotters.py +2 -1
- chia/cmds/rpc.py +48 -28
- chia/cmds/show.py +2 -1
- chia/cmds/show_funcs.py +7 -6
- chia/cmds/signer.py +50 -58
- chia/cmds/sim.py +22 -14
- chia/cmds/sim_funcs.py +11 -11
- chia/cmds/start.py +3 -3
- chia/cmds/start_funcs.py +9 -12
- chia/cmds/stop.py +4 -3
- chia/cmds/units.py +1 -3
- chia/cmds/wallet.py +252 -96
- chia/cmds/wallet_funcs.py +217 -143
- chia/consensus/block_body_validation.py +133 -86
- chia/consensus/block_creation.py +42 -21
- chia/consensus/block_header_validation.py +32 -37
- chia/consensus/block_record.py +1 -2
- chia/consensus/blockchain.py +167 -180
- chia/consensus/blockchain_interface.py +10 -10
- chia/consensus/constants.py +2 -2
- chia/consensus/default_constants.py +3 -4
- chia/consensus/difficulty_adjustment.py +5 -5
- chia/consensus/find_fork_point.py +5 -5
- chia/consensus/full_block_to_block_record.py +4 -4
- chia/consensus/get_block_challenge.py +2 -2
- chia/consensus/get_block_generator.py +4 -3
- chia/consensus/multiprocess_validation.py +207 -304
- chia/consensus/vdf_info_computation.py +3 -3
- chia/daemon/client.py +46 -27
- chia/daemon/keychain_proxy.py +10 -9
- chia/daemon/keychain_server.py +18 -18
- chia/daemon/server.py +103 -113
- chia/daemon/windows_signal.py +2 -2
- chia/data_layer/data_layer.py +64 -76
- chia/data_layer/data_layer_api.py +8 -0
- chia/data_layer/data_layer_errors.py +3 -3
- chia/data_layer/data_layer_server.py +2 -2
- chia/data_layer/data_layer_util.py +71 -71
- chia/data_layer/data_layer_wallet.py +63 -67
- chia/data_layer/data_store.py +72 -72
- chia/data_layer/dl_wallet_store.py +10 -10
- chia/data_layer/download_data.py +5 -5
- chia/data_layer/s3_plugin_service.py +9 -9
- chia/data_layer/util/benchmark.py +0 -1
- chia/data_layer/util/plugin.py +2 -3
- chia/farmer/farmer.py +46 -43
- chia/farmer/farmer_api.py +27 -21
- chia/full_node/block_height_map.py +6 -6
- chia/full_node/block_store.py +41 -35
- chia/full_node/coin_store.py +42 -41
- chia/full_node/fee_estimate.py +2 -2
- chia/full_node/fee_estimation.py +1 -2
- chia/full_node/fee_history.py +5 -6
- chia/full_node/fee_tracker.py +24 -24
- chia/full_node/full_node.py +574 -300
- chia/full_node/full_node_api.py +181 -130
- chia/full_node/full_node_store.py +43 -43
- chia/full_node/hint_management.py +4 -4
- chia/full_node/hint_store.py +9 -10
- chia/full_node/mempool.py +25 -19
- chia/full_node/mempool_check_conditions.py +11 -42
- chia/full_node/mempool_manager.py +48 -53
- chia/full_node/pending_tx_cache.py +9 -9
- chia/full_node/subscriptions.py +23 -24
- chia/full_node/sync_store.py +8 -7
- chia/full_node/tx_processing_queue.py +3 -3
- chia/full_node/util/__init__.py +0 -0
- chia/full_node/weight_proof.py +79 -78
- chia/harvester/harvester.py +9 -8
- chia/harvester/harvester_api.py +19 -13
- chia/introducer/introducer.py +7 -5
- chia/introducer/introducer_api.py +9 -3
- chia/legacy/keyring.py +6 -5
- chia/plot_sync/delta.py +8 -8
- chia/plot_sync/receiver.py +12 -11
- chia/plot_sync/sender.py +15 -12
- chia/plotters/bladebit.py +12 -12
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +8 -8
- chia/plotters/plotters.py +6 -6
- chia/plotters/plotters_util.py +6 -4
- chia/plotting/cache.py +8 -7
- chia/plotting/check_plots.py +8 -8
- chia/plotting/create_plots.py +6 -6
- chia/plotting/manager.py +22 -22
- chia/plotting/util.py +31 -19
- chia/pools/pool_config.py +7 -7
- chia/pools/pool_puzzles.py +16 -16
- chia/pools/pool_wallet.py +64 -57
- chia/pools/pool_wallet_info.py +3 -3
- chia/protocols/full_node_protocol.py +3 -3
- chia/protocols/harvester_protocol.py +12 -12
- chia/protocols/introducer_protocol.py +1 -2
- chia/protocols/protocol_message_types.py +4 -4
- chia/protocols/protocol_state_machine.py +2 -2
- chia/protocols/protocol_timing.py +1 -0
- chia/protocols/shared_protocol.py +3 -3
- chia/protocols/timelord_protocol.py +2 -2
- chia/protocols/wallet_protocol.py +33 -33
- chia/rpc/crawler_rpc_api.py +12 -7
- chia/rpc/data_layer_rpc_api.py +49 -44
- chia/rpc/data_layer_rpc_client.py +41 -41
- chia/rpc/data_layer_rpc_util.py +7 -11
- chia/rpc/farmer_rpc_api.py +32 -27
- chia/rpc/farmer_rpc_client.py +14 -14
- chia/rpc/full_node_rpc_api.py +53 -48
- chia/rpc/full_node_rpc_client.py +30 -30
- chia/rpc/harvester_rpc_api.py +16 -11
- chia/rpc/harvester_rpc_client.py +6 -6
- chia/rpc/rpc_client.py +34 -14
- chia/rpc/rpc_server.py +117 -43
- chia/rpc/timelord_rpc_api.py +9 -4
- chia/rpc/util.py +11 -211
- chia/rpc/wallet_request_types.py +276 -60
- chia/rpc/wallet_rpc_api.py +563 -399
- chia/rpc/wallet_rpc_client.py +220 -250
- chia/seeder/crawl_store.py +6 -8
- chia/seeder/crawler.py +23 -36
- chia/seeder/crawler_api.py +28 -22
- chia/seeder/dns_server.py +99 -50
- chia/seeder/start_crawler.py +13 -9
- chia/server/address_manager.py +19 -19
- chia/server/address_manager_store.py +17 -17
- chia/server/api_protocol.py +106 -1
- chia/server/capabilities.py +3 -3
- chia/server/chia_policy.py +17 -16
- chia/server/introducer_peers.py +3 -3
- chia/server/node_discovery.py +34 -38
- chia/server/rate_limit_numbers.py +26 -16
- chia/server/rate_limits.py +67 -27
- chia/server/server.py +52 -31
- chia/server/signal_handlers.py +6 -3
- chia/server/ssl_context.py +5 -5
- chia/server/start_data_layer.py +37 -23
- chia/server/start_farmer.py +28 -16
- chia/server/start_full_node.py +29 -23
- chia/server/start_harvester.py +28 -15
- chia/server/start_introducer.py +27 -15
- chia/server/start_service.py +17 -29
- chia/server/start_timelord.py +25 -18
- chia/server/start_wallet.py +22 -18
- chia/server/upnp.py +4 -3
- chia/server/ws_connection.py +68 -54
- chia/simulator/add_blocks_in_batches.py +54 -0
- chia/simulator/block_tools.py +65 -64
- chia/simulator/full_node_simulator.py +66 -74
- chia/simulator/setup_services.py +10 -9
- chia/simulator/simulator_full_node_rpc_api.py +12 -14
- chia/simulator/simulator_full_node_rpc_client.py +3 -5
- chia/simulator/simulator_test_tools.py +8 -7
- chia/simulator/socket.py +1 -4
- chia/simulator/ssl_certs.py +5 -5
- chia/simulator/ssl_certs_1.py +2 -4
- chia/simulator/ssl_certs_10.py +2 -4
- chia/simulator/ssl_certs_2.py +2 -4
- chia/simulator/ssl_certs_3.py +2 -4
- chia/simulator/ssl_certs_4.py +2 -4
- chia/simulator/ssl_certs_5.py +2 -4
- chia/simulator/ssl_certs_6.py +2 -4
- chia/simulator/ssl_certs_7.py +2 -4
- chia/simulator/ssl_certs_8.py +2 -4
- chia/simulator/ssl_certs_9.py +2 -4
- chia/simulator/start_simulator.py +14 -6
- chia/simulator/wallet_tools.py +21 -20
- chia/ssl/create_ssl.py +11 -11
- chia/timelord/iters_from_block.py +2 -2
- chia/timelord/timelord.py +57 -33
- chia/timelord/timelord_api.py +12 -6
- chia/timelord/timelord_launcher.py +10 -8
- chia/timelord/timelord_state.py +5 -5
- chia/types/block_protocol.py +2 -2
- chia/types/blockchain_format/coin.py +3 -3
- chia/types/blockchain_format/program.py +17 -18
- chia/types/blockchain_format/tree_hash.py +9 -9
- chia/types/coin_spend.py +8 -8
- chia/types/condition_with_args.py +1 -2
- chia/types/eligible_coin_spends.py +16 -15
- chia/types/generator_types.py +1 -2
- chia/types/internal_mempool_item.py +1 -2
- chia/types/mempool_item.py +7 -7
- chia/types/mempool_submission_status.py +2 -2
- chia/types/peer_info.py +1 -1
- chia/types/spend_bundle.py +1 -2
- chia/types/transaction_queue_entry.py +2 -2
- chia/types/unfinished_header_block.py +2 -2
- chia/types/validation_state.py +14 -0
- chia/types/weight_proof.py +5 -6
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +6 -4
- chia/util/augmented_chain.py +13 -9
- chia/util/batches.py +5 -2
- chia/util/bech32m.py +14 -11
- chia/util/beta_metrics.py +5 -4
- chia/util/block_cache.py +5 -5
- chia/util/byte_types.py +2 -0
- chia/util/check_fork_next_block.py +3 -2
- chia/util/chia_logging.py +41 -21
- chia/util/collection.py +3 -3
- chia/util/condition_tools.py +18 -18
- chia/util/config.py +26 -25
- chia/util/cpu.py +2 -0
- chia/util/db_synchronous.py +2 -0
- chia/util/db_version.py +2 -0
- chia/util/db_wrapper.py +13 -10
- chia/util/default_root.py +17 -0
- chia/util/dump_keyring.py +6 -6
- chia/util/errors.py +5 -3
- chia/util/file_keyring.py +22 -33
- chia/util/files.py +2 -0
- chia/util/full_block_utils.py +31 -7
- chia/util/generator_tools.py +18 -8
- chia/util/hash.py +3 -1
- chia/util/initial-config.yaml +19 -0
- chia/util/inline_executor.py +2 -0
- chia/util/ip_address.py +39 -0
- chia/util/json_util.py +0 -4
- chia/util/keychain.py +27 -24
- chia/util/keyring_wrapper.py +65 -4
- chia/util/limited_semaphore.py +3 -1
- chia/util/lock.py +4 -2
- chia/util/log_exceptions.py +5 -2
- chia/util/logging.py +3 -1
- chia/util/lru_cache.py +2 -0
- chia/util/math.py +4 -4
- chia/util/network.py +15 -73
- chia/util/paginator.py +3 -1
- chia/util/path.py +2 -0
- chia/util/permissions.py +3 -2
- chia/util/prev_transaction_block.py +1 -3
- chia/util/priority_mutex.py +6 -3
- chia/util/profiler.py +7 -4
- chia/util/recursive_replace.py +2 -0
- chia/util/safe_cancel_task.py +2 -0
- chia/util/service_groups.py +2 -2
- chia/util/setproctitle.py +2 -0
- chia/util/significant_bits.py +2 -0
- chia/util/ssl_check.py +11 -11
- chia/util/streamable.py +44 -56
- chia/util/task_referencer.py +59 -0
- chia/util/task_timing.py +22 -18
- chia/util/timing.py +4 -1
- chia/util/vdf_prover.py +2 -3
- chia/util/virtual_project_analysis.py +540 -0
- chia/util/ws_message.py +6 -6
- chia/wallet/cat_wallet/cat_info.py +3 -3
- chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -3
- chia/wallet/cat_wallet/cat_utils.py +5 -4
- chia/wallet/cat_wallet/cat_wallet.py +56 -70
- chia/wallet/cat_wallet/dao_cat_info.py +3 -3
- chia/wallet/cat_wallet/dao_cat_wallet.py +18 -18
- chia/wallet/cat_wallet/lineage_store.py +2 -2
- chia/wallet/coin_selection.py +15 -15
- chia/wallet/conditions.py +257 -71
- chia/wallet/dao_wallet/dao_info.py +4 -4
- chia/wallet/dao_wallet/dao_utils.py +43 -42
- chia/wallet/dao_wallet/dao_wallet.py +66 -68
- chia/wallet/db_wallet/db_wallet_puzzles.py +12 -8
- chia/wallet/derive_keys.py +11 -11
- chia/wallet/did_wallet/did_info.py +3 -3
- chia/wallet/did_wallet/did_wallet.py +56 -47
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -6
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/nft_info.py +4 -4
- chia/wallet/nft_wallet/nft_puzzles.py +16 -16
- chia/wallet/nft_wallet/nft_wallet.py +90 -89
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +2 -2
- chia/wallet/nft_wallet/transfer_program_puzzle.py +2 -2
- chia/wallet/nft_wallet/uncurry_nft.py +2 -2
- chia/wallet/notification_manager.py +5 -5
- chia/wallet/notification_store.py +6 -6
- chia/wallet/outer_puzzles.py +2 -2
- chia/wallet/payment.py +4 -5
- chia/wallet/puzzle_drivers.py +4 -4
- chia/wallet/puzzles/clawback/drivers.py +5 -5
- chia/wallet/puzzles/clawback/puzzle_decorator.py +7 -7
- chia/wallet/puzzles/load_clvm.py +2 -3
- chia/wallet/puzzles/p2_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_conditions.py +1 -2
- chia/wallet/puzzles/p2_delegated_puzzle.py +2 -3
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -4
- chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +1 -2
- chia/wallet/puzzles/p2_puzzle_hash.py +1 -2
- chia/wallet/puzzles/puzzle_utils.py +7 -7
- chia/wallet/puzzles/singleton_top_layer.py +6 -5
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +6 -5
- chia/wallet/puzzles/tails.py +34 -30
- chia/wallet/signer_protocol.py +7 -8
- chia/wallet/singleton.py +4 -4
- chia/wallet/trade_manager.py +155 -141
- chia/wallet/trade_record.py +5 -5
- chia/wallet/trading/offer.py +100 -101
- chia/wallet/trading/trade_store.py +14 -14
- chia/wallet/transaction_record.py +31 -16
- chia/wallet/util/address_type.py +4 -4
- chia/wallet/util/blind_signer_tl.py +8 -12
- chia/wallet/util/clvm_streamable.py +15 -15
- chia/wallet/util/compute_hints.py +5 -5
- chia/wallet/util/compute_memos.py +4 -6
- chia/wallet/util/curry_and_treehash.py +3 -2
- chia/wallet/util/debug_spend_bundle.py +6 -8
- chia/wallet/util/merkle_tree.py +10 -10
- chia/wallet/util/merkle_utils.py +10 -10
- chia/wallet/util/new_peak_queue.py +3 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/{util → wallet/util}/pprint.py +2 -3
- chia/wallet/util/puzzle_compression.py +3 -4
- chia/wallet/util/puzzle_decorator.py +10 -10
- chia/wallet/util/query_filter.py +9 -10
- chia/wallet/util/tx_config.py +12 -12
- chia/wallet/util/wallet_sync_utils.py +24 -21
- chia/wallet/util/wallet_types.py +9 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +28 -27
- chia/wallet/vc_wallet/cr_cat_wallet.py +42 -40
- chia/wallet/vc_wallet/cr_outer_puzzle.py +4 -4
- chia/wallet/vc_wallet/vc_drivers.py +16 -16
- chia/wallet/vc_wallet/vc_store.py +9 -9
- chia/wallet/vc_wallet/vc_wallet.py +35 -35
- chia/wallet/wallet.py +54 -54
- chia/wallet/wallet_action_scope.py +14 -13
- chia/wallet/wallet_blockchain.py +10 -10
- chia/wallet/wallet_coin_record.py +2 -2
- chia/wallet/wallet_coin_store.py +10 -10
- chia/wallet/wallet_info.py +1 -2
- chia/wallet/wallet_interested_store.py +5 -5
- chia/wallet/wallet_nft_store.py +6 -6
- chia/wallet/wallet_node.py +72 -76
- chia/wallet/wallet_node_api.py +33 -27
- chia/wallet/wallet_pool_store.py +1 -2
- chia/wallet/wallet_protocol.py +15 -15
- chia/wallet/wallet_puzzle_store.py +35 -4
- chia/wallet/wallet_retry_store.py +2 -2
- chia/wallet/wallet_singleton_store.py +10 -9
- chia/wallet/wallet_spend_bundle.py +4 -20
- chia/wallet/wallet_state_manager.py +223 -224
- chia/wallet/wallet_transaction_store.py +44 -18
- chia/wallet/wallet_user_store.py +2 -2
- chia/wallet/wallet_weight_proof_handler.py +2 -2
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/LICENSE +1 -1
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/METADATA +67 -72
- chia_blockchain-2.5.1rc2.dist-info/RECORD +1042 -0
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/WHEEL +1 -1
- mozilla-ca/cacert.pem +32 -87
- chia/_tests/cmds/wallet/test_coins.py +0 -195
- chia/consensus/block_root_validation.py +0 -46
- chia/util/api_decorators.py +0 -89
- chia_blockchain-2.5.0rc2.dist-info/RECORD +0 -1028
- {chia_blockchain-2.5.0rc2.dist-info → chia_blockchain-2.5.1rc2.dist-info}/entry_points.txt +0 -0
chia/full_node/full_node_api.py
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
-
import functools
|
|
5
4
|
import logging
|
|
6
5
|
import time
|
|
7
6
|
import traceback
|
|
7
|
+
from collections.abc import Collection
|
|
8
8
|
from concurrent.futures import ThreadPoolExecutor
|
|
9
9
|
from datetime import datetime, timezone
|
|
10
|
-
from typing import TYPE_CHECKING,
|
|
10
|
+
from typing import TYPE_CHECKING, ClassVar, Optional, cast
|
|
11
11
|
|
|
12
12
|
import anyio
|
|
13
|
-
from chia_rs import
|
|
13
|
+
from chia_rs import (
|
|
14
|
+
AugSchemeMPL,
|
|
15
|
+
G1Element,
|
|
16
|
+
G2Element,
|
|
17
|
+
MerkleSet,
|
|
18
|
+
additions_and_removals,
|
|
19
|
+
get_flags_for_height_and_constants,
|
|
20
|
+
)
|
|
14
21
|
from chiabip158 import PyBIP158
|
|
15
22
|
|
|
16
23
|
from chia.consensus.block_creation import create_unfinished_block
|
|
@@ -22,12 +29,13 @@ from chia.full_node.bundle_tools import simple_solution_generator, simple_soluti
|
|
|
22
29
|
from chia.full_node.coin_store import CoinStore
|
|
23
30
|
from chia.full_node.fee_estimate import FeeEstimate, FeeEstimateGroup, fee_rate_v2_to_v1
|
|
24
31
|
from chia.full_node.fee_estimator_interface import FeeEstimatorInterface
|
|
25
|
-
from chia.full_node.mempool_check_conditions import
|
|
32
|
+
from chia.full_node.mempool_check_conditions import get_puzzle_and_solution_for_coin
|
|
26
33
|
from chia.full_node.signage_point import SignagePoint
|
|
27
34
|
from chia.full_node.tx_processing_queue import TransactionQueueFull
|
|
28
35
|
from chia.protocols import farmer_protocol, full_node_protocol, introducer_protocol, timelord_protocol, wallet_protocol
|
|
29
36
|
from chia.protocols.full_node_protocol import RejectBlock, RejectBlocks
|
|
30
37
|
from chia.protocols.protocol_message_types import ProtocolMessageTypes
|
|
38
|
+
from chia.protocols.protocol_timing import RATE_LIMITER_BAN_SECONDS
|
|
31
39
|
from chia.protocols.shared_protocol import Capability
|
|
32
40
|
from chia.protocols.wallet_protocol import (
|
|
33
41
|
CoinState,
|
|
@@ -38,6 +46,7 @@ from chia.protocols.wallet_protocol import (
|
|
|
38
46
|
RespondFeeEstimates,
|
|
39
47
|
RespondSESInfo,
|
|
40
48
|
)
|
|
49
|
+
from chia.server.api_protocol import ApiMetadata
|
|
41
50
|
from chia.server.outbound_message import Message, make_msg
|
|
42
51
|
from chia.server.server import ChiaServer
|
|
43
52
|
from chia.server.ws_connection import WSChiaConnection
|
|
@@ -58,14 +67,14 @@ from chia.types.peer_info import PeerInfo
|
|
|
58
67
|
from chia.types.spend_bundle import SpendBundle
|
|
59
68
|
from chia.types.transaction_queue_entry import TransactionQueueEntry
|
|
60
69
|
from chia.types.unfinished_block import UnfinishedBlock
|
|
61
|
-
from chia.util.api_decorators import api_request
|
|
62
70
|
from chia.util.batches import to_batches
|
|
63
71
|
from chia.util.db_wrapper import SQLITE_MAX_VARIABLE_NUMBER
|
|
64
|
-
from chia.util.full_block_utils import header_block_from_block
|
|
65
|
-
from chia.util.generator_tools import get_block_header
|
|
72
|
+
from chia.util.full_block_utils import get_height_and_tx_status_from_block, header_block_from_block
|
|
73
|
+
from chia.util.generator_tools import get_block_header
|
|
66
74
|
from chia.util.hash import std_hash
|
|
67
75
|
from chia.util.ints import uint8, uint32, uint64, uint128
|
|
68
76
|
from chia.util.limited_semaphore import LimitedSemaphoreFullError
|
|
77
|
+
from chia.util.task_referencer import create_referenced_task
|
|
69
78
|
|
|
70
79
|
if TYPE_CHECKING:
|
|
71
80
|
from chia.full_node.full_node import FullNode
|
|
@@ -74,9 +83,15 @@ else:
|
|
|
74
83
|
|
|
75
84
|
|
|
76
85
|
class FullNodeAPI:
|
|
86
|
+
if TYPE_CHECKING:
|
|
87
|
+
from chia.server.api_protocol import ApiProtocol
|
|
88
|
+
|
|
89
|
+
_protocol_check: ClassVar[ApiProtocol] = cast("FullNodeAPI", None)
|
|
90
|
+
|
|
77
91
|
log: logging.Logger
|
|
78
92
|
full_node: FullNode
|
|
79
93
|
executor: ThreadPoolExecutor
|
|
94
|
+
metadata: ClassVar[ApiMetadata] = ApiMetadata()
|
|
80
95
|
|
|
81
96
|
def __init__(self, full_node: FullNode) -> None:
|
|
82
97
|
self.log = logging.getLogger(__name__)
|
|
@@ -91,7 +106,7 @@ class FullNodeAPI:
|
|
|
91
106
|
def ready(self) -> bool:
|
|
92
107
|
return self.full_node.initialized
|
|
93
108
|
|
|
94
|
-
@
|
|
109
|
+
@metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_peers])
|
|
95
110
|
async def request_peers(
|
|
96
111
|
self, _request: full_node_protocol.RequestPeers, peer: WSChiaConnection
|
|
97
112
|
) -> Optional[Message]:
|
|
@@ -103,7 +118,7 @@ class FullNodeAPI:
|
|
|
103
118
|
return msg
|
|
104
119
|
return None
|
|
105
120
|
|
|
106
|
-
@
|
|
121
|
+
@metadata.request(peer_required=True)
|
|
107
122
|
async def respond_peers(
|
|
108
123
|
self, request: full_node_protocol.RespondPeers, peer: WSChiaConnection
|
|
109
124
|
) -> Optional[Message]:
|
|
@@ -112,7 +127,7 @@ class FullNodeAPI:
|
|
|
112
127
|
await self.full_node.full_node_peers.add_peers(request.peer_list, peer.get_peer_info(), True)
|
|
113
128
|
return None
|
|
114
129
|
|
|
115
|
-
@
|
|
130
|
+
@metadata.request(peer_required=True)
|
|
116
131
|
async def respond_peers_introducer(
|
|
117
132
|
self, request: introducer_protocol.RespondPeersIntroducer, peer: WSChiaConnection
|
|
118
133
|
) -> Optional[Message]:
|
|
@@ -123,7 +138,7 @@ class FullNodeAPI:
|
|
|
123
138
|
await peer.close()
|
|
124
139
|
return None
|
|
125
140
|
|
|
126
|
-
@
|
|
141
|
+
@metadata.request(peer_required=True, execute_task=True)
|
|
127
142
|
async def new_peak(self, request: full_node_protocol.NewPeak, peer: WSChiaConnection) -> None:
|
|
128
143
|
"""
|
|
129
144
|
A peer notifies us that they have added a new peak to their blockchain. If we don't have it,
|
|
@@ -140,7 +155,7 @@ class FullNodeAPI:
|
|
|
140
155
|
|
|
141
156
|
return None
|
|
142
157
|
|
|
143
|
-
@
|
|
158
|
+
@metadata.request(peer_required=True)
|
|
144
159
|
async def new_transaction(
|
|
145
160
|
self, transaction: full_node_protocol.NewTransaction, peer: WSChiaConnection
|
|
146
161
|
) -> Optional[Message]:
|
|
@@ -189,7 +204,7 @@ class FullNodeAPI:
|
|
|
189
204
|
break
|
|
190
205
|
if transaction_id not in full_node.full_node_store.peers_with_tx:
|
|
191
206
|
break
|
|
192
|
-
peers_with_tx:
|
|
207
|
+
peers_with_tx: set[bytes32] = full_node.full_node_store.peers_with_tx[transaction_id]
|
|
193
208
|
if len(peers_with_tx) == 0:
|
|
194
209
|
break
|
|
195
210
|
peer_id = peers_with_tx.pop()
|
|
@@ -216,14 +231,14 @@ class FullNodeAPI:
|
|
|
216
231
|
full_node.full_node_store.tx_fetch_tasks.pop(task_id)
|
|
217
232
|
|
|
218
233
|
task_id: bytes32 = bytes32.secret()
|
|
219
|
-
fetch_task =
|
|
234
|
+
fetch_task = create_referenced_task(
|
|
220
235
|
tx_request_and_timeout(self.full_node, transaction.transaction_id, task_id)
|
|
221
236
|
)
|
|
222
237
|
self.full_node.full_node_store.tx_fetch_tasks[task_id] = fetch_task
|
|
223
238
|
return None
|
|
224
239
|
return None
|
|
225
240
|
|
|
226
|
-
@
|
|
241
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_transaction])
|
|
227
242
|
async def request_transaction(self, request: full_node_protocol.RequestTransaction) -> Optional[Message]:
|
|
228
243
|
"""Peer has requested a full transaction from us."""
|
|
229
244
|
# Ignore if syncing
|
|
@@ -238,7 +253,7 @@ class FullNodeAPI:
|
|
|
238
253
|
msg = make_msg(ProtocolMessageTypes.respond_transaction, transaction)
|
|
239
254
|
return msg
|
|
240
255
|
|
|
241
|
-
@
|
|
256
|
+
@metadata.request(peer_required=True, bytes_required=True)
|
|
242
257
|
async def respond_transaction(
|
|
243
258
|
self,
|
|
244
259
|
tx: full_node_protocol.RespondTransaction,
|
|
@@ -266,7 +281,7 @@ class FullNodeAPI:
|
|
|
266
281
|
pass # we can't do anything here, the tx will be dropped. We might do something in the future.
|
|
267
282
|
return None
|
|
268
283
|
|
|
269
|
-
@
|
|
284
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_proof_of_weight])
|
|
270
285
|
async def request_proof_of_weight(self, request: full_node_protocol.RequestProofOfWeight) -> Optional[Message]:
|
|
271
286
|
if self.full_node.weight_proof_handler is None:
|
|
272
287
|
return None
|
|
@@ -306,12 +321,12 @@ class FullNodeAPI:
|
|
|
306
321
|
self.full_node.full_node_store.serialized_wp_message = message
|
|
307
322
|
return message
|
|
308
323
|
|
|
309
|
-
@
|
|
324
|
+
@metadata.request()
|
|
310
325
|
async def respond_proof_of_weight(self, request: full_node_protocol.RespondProofOfWeight) -> Optional[Message]:
|
|
311
326
|
self.log.warning("Received proof of weight too late.")
|
|
312
327
|
return None
|
|
313
328
|
|
|
314
|
-
@
|
|
329
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_block, ProtocolMessageTypes.reject_block])
|
|
315
330
|
async def request_block(self, request: full_node_protocol.RequestBlock) -> Optional[Message]:
|
|
316
331
|
if not self.full_node.blockchain.contains_height(request.height):
|
|
317
332
|
reject = RejectBlock(request.height)
|
|
@@ -328,7 +343,7 @@ class FullNodeAPI:
|
|
|
328
343
|
return make_msg(ProtocolMessageTypes.respond_block, full_node_protocol.RespondBlock(block))
|
|
329
344
|
return make_msg(ProtocolMessageTypes.reject_block, RejectBlock(request.height))
|
|
330
345
|
|
|
331
|
-
@
|
|
346
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_blocks, ProtocolMessageTypes.reject_blocks])
|
|
332
347
|
async def request_blocks(self, request: full_node_protocol.RequestBlocks) -> Optional[Message]:
|
|
333
348
|
# note that we treat the request range as *inclusive*, but we check the
|
|
334
349
|
# size before we bump end_height. So MAX_BLOCK_COUNT_PER_REQUESTS is off
|
|
@@ -347,7 +362,7 @@ class FullNodeAPI:
|
|
|
347
362
|
return msg
|
|
348
363
|
|
|
349
364
|
if not request.include_transaction_block:
|
|
350
|
-
blocks:
|
|
365
|
+
blocks: list[FullBlock] = []
|
|
351
366
|
for i in range(request.start_height, request.end_height + 1):
|
|
352
367
|
header_hash_i: Optional[bytes32] = self.full_node.blockchain.height_to_hash(uint32(i))
|
|
353
368
|
if header_hash_i is None:
|
|
@@ -365,7 +380,7 @@ class FullNodeAPI:
|
|
|
365
380
|
full_node_protocol.RespondBlocks(request.start_height, request.end_height, blocks),
|
|
366
381
|
)
|
|
367
382
|
else:
|
|
368
|
-
blocks_bytes:
|
|
383
|
+
blocks_bytes: list[bytes] = []
|
|
369
384
|
for i in range(request.start_height, request.end_height + 1):
|
|
370
385
|
header_hash_i = self.full_node.blockchain.height_to_hash(uint32(i))
|
|
371
386
|
if header_hash_i is None:
|
|
@@ -390,33 +405,44 @@ class FullNodeAPI:
|
|
|
390
405
|
|
|
391
406
|
return msg
|
|
392
407
|
|
|
393
|
-
@
|
|
394
|
-
async def reject_block(
|
|
395
|
-
self
|
|
408
|
+
@metadata.request(peer_required=True)
|
|
409
|
+
async def reject_block(
|
|
410
|
+
self,
|
|
411
|
+
request: full_node_protocol.RejectBlock,
|
|
412
|
+
peer: WSChiaConnection,
|
|
413
|
+
) -> None:
|
|
414
|
+
self.log.warning(f"unsolicited reject_block {request.height}")
|
|
415
|
+
await peer.close(RATE_LIMITER_BAN_SECONDS)
|
|
396
416
|
|
|
397
|
-
@
|
|
398
|
-
async def reject_blocks(
|
|
399
|
-
self
|
|
417
|
+
@metadata.request(peer_required=True)
|
|
418
|
+
async def reject_blocks(
|
|
419
|
+
self,
|
|
420
|
+
request: full_node_protocol.RejectBlocks,
|
|
421
|
+
peer: WSChiaConnection,
|
|
422
|
+
) -> None:
|
|
423
|
+
self.log.warning(f"reject_blocks {request.start_height} {request.end_height}")
|
|
424
|
+
await peer.close(RATE_LIMITER_BAN_SECONDS)
|
|
400
425
|
|
|
401
|
-
@
|
|
402
|
-
async def respond_blocks(
|
|
426
|
+
@metadata.request(peer_required=True)
|
|
427
|
+
async def respond_blocks(
|
|
428
|
+
self,
|
|
429
|
+
request: full_node_protocol.RespondBlocks,
|
|
430
|
+
peer: WSChiaConnection,
|
|
431
|
+
) -> None:
|
|
403
432
|
self.log.warning("Received unsolicited/late blocks")
|
|
404
|
-
|
|
433
|
+
await peer.close(RATE_LIMITER_BAN_SECONDS)
|
|
405
434
|
|
|
406
|
-
@
|
|
435
|
+
@metadata.request(peer_required=True)
|
|
407
436
|
async def respond_block(
|
|
408
437
|
self,
|
|
409
438
|
respond_block: full_node_protocol.RespondBlock,
|
|
410
439
|
peer: WSChiaConnection,
|
|
411
440
|
) -> Optional[Message]:
|
|
412
|
-
"""
|
|
413
|
-
Receive a full block from a peer full node (or ourselves).
|
|
414
|
-
"""
|
|
415
|
-
|
|
416
441
|
self.log.warning(f"Received unsolicited/late block from peer {peer.get_peer_logging()}")
|
|
442
|
+
await peer.close(RATE_LIMITER_BAN_SECONDS)
|
|
417
443
|
return None
|
|
418
444
|
|
|
419
|
-
@
|
|
445
|
+
@metadata.request()
|
|
420
446
|
async def new_unfinished_block(
|
|
421
447
|
self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock
|
|
422
448
|
) -> Optional[Message]:
|
|
@@ -448,11 +474,11 @@ class FullNodeAPI:
|
|
|
448
474
|
await asyncio.sleep(5)
|
|
449
475
|
self.full_node.full_node_store.remove_requesting_unfinished_block(block_hash, None)
|
|
450
476
|
|
|
451
|
-
|
|
477
|
+
create_referenced_task(eventually_clear(), known_unreferenced=True)
|
|
452
478
|
|
|
453
479
|
return msg
|
|
454
480
|
|
|
455
|
-
@
|
|
481
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
|
|
456
482
|
async def request_unfinished_block(
|
|
457
483
|
self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock
|
|
458
484
|
) -> Optional[Message]:
|
|
@@ -467,7 +493,7 @@ class FullNodeAPI:
|
|
|
467
493
|
return msg
|
|
468
494
|
return None
|
|
469
495
|
|
|
470
|
-
@
|
|
496
|
+
@metadata.request()
|
|
471
497
|
async def new_unfinished_block2(
|
|
472
498
|
self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock2
|
|
473
499
|
) -> Optional[Message]:
|
|
@@ -516,11 +542,11 @@ class FullNodeAPI:
|
|
|
516
542
|
await asyncio.sleep(5)
|
|
517
543
|
self.full_node.full_node_store.remove_requesting_unfinished_block(block_hash, foliage_hash)
|
|
518
544
|
|
|
519
|
-
|
|
545
|
+
create_referenced_task(eventually_clear(), known_unreferenced=True)
|
|
520
546
|
|
|
521
547
|
return msg
|
|
522
548
|
|
|
523
|
-
@
|
|
549
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
|
|
524
550
|
async def request_unfinished_block2(
|
|
525
551
|
self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock2
|
|
526
552
|
) -> Optional[Message]:
|
|
@@ -537,21 +563,18 @@ class FullNodeAPI:
|
|
|
537
563
|
return msg
|
|
538
564
|
return None
|
|
539
565
|
|
|
540
|
-
@
|
|
566
|
+
@metadata.request(peer_required=True)
|
|
541
567
|
async def respond_unfinished_block(
|
|
542
568
|
self,
|
|
543
569
|
respond_unfinished_block: full_node_protocol.RespondUnfinishedBlock,
|
|
544
570
|
peer: WSChiaConnection,
|
|
545
|
-
respond_unfinished_block_bytes: bytes = b"",
|
|
546
571
|
) -> Optional[Message]:
|
|
547
572
|
if self.full_node.sync_store.get_sync_mode():
|
|
548
573
|
return None
|
|
549
|
-
await self.full_node.add_unfinished_block(
|
|
550
|
-
respond_unfinished_block.unfinished_block, peer, block_bytes=respond_unfinished_block_bytes
|
|
551
|
-
)
|
|
574
|
+
await self.full_node.add_unfinished_block(respond_unfinished_block.unfinished_block, peer)
|
|
552
575
|
return None
|
|
553
576
|
|
|
554
|
-
@
|
|
577
|
+
@metadata.request(peer_required=True)
|
|
555
578
|
async def new_signage_point_or_end_of_sub_slot(
|
|
556
579
|
self, new_sp: full_node_protocol.NewSignagePointOrEndOfSubSlot, peer: WSChiaConnection
|
|
557
580
|
) -> Optional[Message]:
|
|
@@ -635,12 +658,14 @@ class FullNodeAPI:
|
|
|
635
658
|
|
|
636
659
|
return make_msg(ProtocolMessageTypes.request_signage_point_or_end_of_sub_slot, full_node_request)
|
|
637
660
|
|
|
638
|
-
@
|
|
661
|
+
@metadata.request(
|
|
662
|
+
reply_types=[ProtocolMessageTypes.respond_signage_point, ProtocolMessageTypes.respond_end_of_sub_slot]
|
|
663
|
+
)
|
|
639
664
|
async def request_signage_point_or_end_of_sub_slot(
|
|
640
665
|
self, request: full_node_protocol.RequestSignagePointOrEndOfSubSlot
|
|
641
666
|
) -> Optional[Message]:
|
|
642
667
|
if request.index_from_challenge == 0:
|
|
643
|
-
sub_slot: Optional[
|
|
668
|
+
sub_slot: Optional[tuple[EndOfSubSlotBundle, int, uint128]] = self.full_node.full_node_store.get_sub_slot(
|
|
644
669
|
request.challenge_hash
|
|
645
670
|
)
|
|
646
671
|
if sub_slot is not None:
|
|
@@ -677,7 +702,7 @@ class FullNodeAPI:
|
|
|
677
702
|
self.log.info(f"Don't have signage point {request}")
|
|
678
703
|
return None
|
|
679
704
|
|
|
680
|
-
@
|
|
705
|
+
@metadata.request(peer_required=True)
|
|
681
706
|
async def respond_signage_point(
|
|
682
707
|
self, request: full_node_protocol.RespondSignagePoint, peer: WSChiaConnection
|
|
683
708
|
) -> Optional[Message]:
|
|
@@ -732,7 +757,7 @@ class FullNodeAPI:
|
|
|
732
757
|
|
|
733
758
|
return None
|
|
734
759
|
|
|
735
|
-
@
|
|
760
|
+
@metadata.request(peer_required=True)
|
|
736
761
|
async def respond_end_of_sub_slot(
|
|
737
762
|
self, request: full_node_protocol.RespondEndOfSubSlot, peer: WSChiaConnection
|
|
738
763
|
) -> Optional[Message]:
|
|
@@ -741,7 +766,7 @@ class FullNodeAPI:
|
|
|
741
766
|
msg, _ = await self.full_node.add_end_of_sub_slot(request.end_of_slot_bundle, peer)
|
|
742
767
|
return msg
|
|
743
768
|
|
|
744
|
-
@
|
|
769
|
+
@metadata.request(peer_required=True)
|
|
745
770
|
async def request_mempool_transactions(
|
|
746
771
|
self,
|
|
747
772
|
request: full_node_protocol.RequestMempoolTransactions,
|
|
@@ -749,7 +774,7 @@ class FullNodeAPI:
|
|
|
749
774
|
) -> Optional[Message]:
|
|
750
775
|
received_filter = PyBIP158(bytearray(request.filter))
|
|
751
776
|
|
|
752
|
-
items:
|
|
777
|
+
items: list[SpendBundle] = self.full_node.mempool_manager.get_items_not_in_filter(received_filter)
|
|
753
778
|
|
|
754
779
|
for item in items:
|
|
755
780
|
transaction = full_node_protocol.RespondTransaction(item)
|
|
@@ -758,7 +783,7 @@ class FullNodeAPI:
|
|
|
758
783
|
return None
|
|
759
784
|
|
|
760
785
|
# FARMER PROTOCOL
|
|
761
|
-
@
|
|
786
|
+
@metadata.request(peer_required=True)
|
|
762
787
|
async def declare_proof_of_space(
|
|
763
788
|
self, request: farmer_protocol.DeclareProofOfSpace, peer: WSChiaConnection
|
|
764
789
|
) -> Optional[Message]:
|
|
@@ -792,7 +817,7 @@ class FullNodeAPI:
|
|
|
792
817
|
assert sp_vdfs.cc_vdf is not None
|
|
793
818
|
cc_challenge_hash = sp_vdfs.cc_vdf.challenge
|
|
794
819
|
|
|
795
|
-
pos_sub_slot: Optional[
|
|
820
|
+
pos_sub_slot: Optional[tuple[EndOfSubSlotBundle, int, uint128]] = None
|
|
796
821
|
if request.challenge_hash != self.full_node.constants.GENESIS_CHALLENGE:
|
|
797
822
|
# Checks that the proof of space is a response to a recent challenge and valid SP
|
|
798
823
|
pos_sub_slot = self.full_node.full_node_store.get_sub_slot(cc_challenge_hash)
|
|
@@ -812,8 +837,8 @@ class FullNodeAPI:
|
|
|
812
837
|
# Grab best transactions from Mempool for given tip target
|
|
813
838
|
aggregate_signature: G2Element = G2Element()
|
|
814
839
|
block_generator: Optional[BlockGenerator] = None
|
|
815
|
-
additions: Optional[
|
|
816
|
-
removals: Optional[
|
|
840
|
+
additions: Optional[list[Coin]] = []
|
|
841
|
+
removals: Optional[list[Coin]] = []
|
|
817
842
|
async with self.full_node.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
818
843
|
peak: Optional[BlockRecord] = self.full_node.blockchain.get_peak()
|
|
819
844
|
|
|
@@ -853,10 +878,17 @@ class FullNodeAPI:
|
|
|
853
878
|
# when the hard fork activates, block generators are
|
|
854
879
|
# allowed to be serialized with the improved CLVM
|
|
855
880
|
# serialization format, supporting back-references
|
|
881
|
+
start_time = time.monotonic()
|
|
856
882
|
if peak.height >= self.full_node.constants.HARD_FORK_HEIGHT:
|
|
857
883
|
block_generator = simple_solution_generator_backrefs(spend_bundle)
|
|
858
884
|
else:
|
|
859
885
|
block_generator = simple_solution_generator(spend_bundle)
|
|
886
|
+
end_time = time.monotonic()
|
|
887
|
+
duration = end_time - start_time
|
|
888
|
+
self.log.log(
|
|
889
|
+
logging.INFO if duration < 1 else logging.WARNING,
|
|
890
|
+
f"serializing block generator took {duration:0.2f} seconds",
|
|
891
|
+
)
|
|
860
892
|
|
|
861
893
|
def get_plot_sig(to_sign: bytes32, _extra: G1Element) -> G2Element:
|
|
862
894
|
if to_sign == request.challenge_chain_sp:
|
|
@@ -906,7 +938,7 @@ class FullNodeAPI:
|
|
|
906
938
|
return None
|
|
907
939
|
|
|
908
940
|
try:
|
|
909
|
-
finished_sub_slots: Optional[
|
|
941
|
+
finished_sub_slots: Optional[list[EndOfSubSlotBundle]] = (
|
|
910
942
|
self.full_node.full_node_store.get_finished_sub_slots(
|
|
911
943
|
self.full_node.blockchain, prev_b, cc_challenge_hash
|
|
912
944
|
)
|
|
@@ -1011,7 +1043,7 @@ class FullNodeAPI:
|
|
|
1011
1043
|
if unfinished_block.is_transaction_block():
|
|
1012
1044
|
foliage_transaction_block_hash = unfinished_block.foliage.foliage_transaction_block_hash
|
|
1013
1045
|
else:
|
|
1014
|
-
foliage_transaction_block_hash = bytes32
|
|
1046
|
+
foliage_transaction_block_hash = bytes32.zeros
|
|
1015
1047
|
assert foliage_transaction_block_hash is not None
|
|
1016
1048
|
|
|
1017
1049
|
foliage_block_data: Optional[FoliageBlockData] = None
|
|
@@ -1065,7 +1097,7 @@ class FullNodeAPI:
|
|
|
1065
1097
|
)
|
|
1066
1098
|
return None
|
|
1067
1099
|
|
|
1068
|
-
@
|
|
1100
|
+
@metadata.request(peer_required=True)
|
|
1069
1101
|
async def signed_values(
|
|
1070
1102
|
self, farmer_request: farmer_protocol.SignedValues, peer: WSChiaConnection
|
|
1071
1103
|
) -> Optional[Message]:
|
|
@@ -1074,7 +1106,7 @@ class FullNodeAPI:
|
|
|
1074
1106
|
block, which only needs a Proof of Time to be finished. If the signature is valid,
|
|
1075
1107
|
we call the unfinished_block routine.
|
|
1076
1108
|
"""
|
|
1077
|
-
candidate_tuple: Optional[
|
|
1109
|
+
candidate_tuple: Optional[tuple[uint32, UnfinishedBlock]] = self.full_node.full_node_store.get_candidate_block(
|
|
1078
1110
|
farmer_request.quality_string
|
|
1079
1111
|
)
|
|
1080
1112
|
|
|
@@ -1125,7 +1157,7 @@ class FullNodeAPI:
|
|
|
1125
1157
|
return None
|
|
1126
1158
|
|
|
1127
1159
|
# TIMELORD PROTOCOL
|
|
1128
|
-
@
|
|
1160
|
+
@metadata.request(peer_required=True)
|
|
1129
1161
|
async def new_infusion_point_vdf(
|
|
1130
1162
|
self, request: timelord_protocol.NewInfusionPointVDF, peer: WSChiaConnection
|
|
1131
1163
|
) -> Optional[Message]:
|
|
@@ -1135,7 +1167,7 @@ class FullNodeAPI:
|
|
|
1135
1167
|
async with self.full_node.timelord_lock:
|
|
1136
1168
|
return await self.full_node.new_infusion_point_vdf(request, peer)
|
|
1137
1169
|
|
|
1138
|
-
@
|
|
1170
|
+
@metadata.request(peer_required=True)
|
|
1139
1171
|
async def new_signage_point_vdf(
|
|
1140
1172
|
self, request: timelord_protocol.NewSignagePointVDF, peer: WSChiaConnection
|
|
1141
1173
|
) -> None:
|
|
@@ -1151,7 +1183,7 @@ class FullNodeAPI:
|
|
|
1151
1183
|
)
|
|
1152
1184
|
await self.respond_signage_point(full_node_message, peer)
|
|
1153
1185
|
|
|
1154
|
-
@
|
|
1186
|
+
@metadata.request(peer_required=True)
|
|
1155
1187
|
async def new_end_of_sub_slot_vdf(
|
|
1156
1188
|
self, request: timelord_protocol.NewEndOfSubSlotVDF, peer: WSChiaConnection
|
|
1157
1189
|
) -> Optional[Message]:
|
|
@@ -1175,7 +1207,7 @@ class FullNodeAPI:
|
|
|
1175
1207
|
else:
|
|
1176
1208
|
return msg
|
|
1177
1209
|
|
|
1178
|
-
@
|
|
1210
|
+
@metadata.request()
|
|
1179
1211
|
async def request_block_header(self, request: wallet_protocol.RequestBlockHeader) -> Optional[Message]:
|
|
1180
1212
|
header_hash = self.full_node.blockchain.height_to_hash(request.height)
|
|
1181
1213
|
if header_hash is None:
|
|
@@ -1185,8 +1217,7 @@ class FullNodeAPI:
|
|
|
1185
1217
|
if block is None:
|
|
1186
1218
|
return None
|
|
1187
1219
|
|
|
1188
|
-
|
|
1189
|
-
tx_additions: List[Coin] = []
|
|
1220
|
+
removals_and_additions: Optional[tuple[Collection[bytes32], Collection[Coin]]] = None
|
|
1190
1221
|
|
|
1191
1222
|
if block.transactions_generator is not None:
|
|
1192
1223
|
block_generator: Optional[BlockGenerator] = await get_block_generator(
|
|
@@ -1198,27 +1229,30 @@ class FullNodeAPI:
|
|
|
1198
1229
|
# transactions_generator, so the block_generator should always be set
|
|
1199
1230
|
assert block_generator is not None, "failed to get block_generator for tx-block"
|
|
1200
1231
|
|
|
1201
|
-
|
|
1232
|
+
flags = get_flags_for_height_and_constants(request.height, self.full_node.constants)
|
|
1233
|
+
additions, removals = await asyncio.get_running_loop().run_in_executor(
|
|
1202
1234
|
self.executor,
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
height=request.height,
|
|
1209
|
-
constants=self.full_node.constants,
|
|
1210
|
-
),
|
|
1235
|
+
additions_and_removals,
|
|
1236
|
+
bytes(block.transactions_generator),
|
|
1237
|
+
block_generator.generator_refs,
|
|
1238
|
+
flags,
|
|
1239
|
+
self.full_node.constants,
|
|
1211
1240
|
)
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1241
|
+
# strip the hint from additions, and compute the puzzle hash for
|
|
1242
|
+
# removals
|
|
1243
|
+
removals_and_additions = ([r.name() for r in removals], [a[0] for a in additions])
|
|
1244
|
+
elif block.is_transaction_block():
|
|
1245
|
+
# This is a transaction block with just reward coins.
|
|
1246
|
+
removals_and_additions = ([], [])
|
|
1247
|
+
|
|
1248
|
+
header_block = get_block_header(block, removals_and_additions)
|
|
1215
1249
|
msg = make_msg(
|
|
1216
1250
|
ProtocolMessageTypes.respond_block_header,
|
|
1217
1251
|
wallet_protocol.RespondBlockHeader(header_block),
|
|
1218
1252
|
)
|
|
1219
1253
|
return msg
|
|
1220
1254
|
|
|
1221
|
-
@
|
|
1255
|
+
@metadata.request()
|
|
1222
1256
|
async def request_additions(self, request: wallet_protocol.RequestAdditions) -> Optional[Message]:
|
|
1223
1257
|
if request.header_hash is None:
|
|
1224
1258
|
header_hash: Optional[bytes32] = self.full_node.blockchain.height_to_hash(request.height)
|
|
@@ -1233,15 +1267,15 @@ class FullNodeAPI:
|
|
|
1233
1267
|
if self.full_node.blockchain.height_to_hash(request.height) != header_hash:
|
|
1234
1268
|
raise ValueError(f"Block {header_hash} no longer in chain, or invalid header_hash")
|
|
1235
1269
|
|
|
1236
|
-
puzzlehash_coins_map:
|
|
1270
|
+
puzzlehash_coins_map: dict[bytes32, list[Coin]] = {}
|
|
1237
1271
|
for coin_record in additions:
|
|
1238
1272
|
if coin_record.coin.puzzle_hash in puzzlehash_coins_map:
|
|
1239
1273
|
puzzlehash_coins_map[coin_record.coin.puzzle_hash].append(coin_record.coin)
|
|
1240
1274
|
else:
|
|
1241
1275
|
puzzlehash_coins_map[coin_record.coin.puzzle_hash] = [coin_record.coin]
|
|
1242
1276
|
|
|
1243
|
-
coins_map:
|
|
1244
|
-
proofs_map:
|
|
1277
|
+
coins_map: list[tuple[bytes32, list[Coin]]] = []
|
|
1278
|
+
proofs_map: list[tuple[bytes32, bytes, Optional[bytes]]] = []
|
|
1245
1279
|
|
|
1246
1280
|
if request.puzzle_hashes is None:
|
|
1247
1281
|
for puzzle_hash, coins in puzzlehash_coins_map.items():
|
|
@@ -1250,7 +1284,7 @@ class FullNodeAPI:
|
|
|
1250
1284
|
else:
|
|
1251
1285
|
# Create addition Merkle set
|
|
1252
1286
|
# Addition Merkle set contains puzzlehash and hash of all coins with that puzzlehash
|
|
1253
|
-
leafs:
|
|
1287
|
+
leafs: list[bytes32] = []
|
|
1254
1288
|
for puzzle, coins in puzzlehash_coins_map.items():
|
|
1255
1289
|
leafs.append(puzzle)
|
|
1256
1290
|
leafs.append(hash_coin_ids([c.name() for c in coins]))
|
|
@@ -1275,7 +1309,7 @@ class FullNodeAPI:
|
|
|
1275
1309
|
response = wallet_protocol.RespondAdditions(request.height, header_hash, coins_map, proofs_map)
|
|
1276
1310
|
return make_msg(ProtocolMessageTypes.respond_additions, response)
|
|
1277
1311
|
|
|
1278
|
-
@
|
|
1312
|
+
@metadata.request()
|
|
1279
1313
|
async def request_removals(self, request: wallet_protocol.RequestRemovals) -> Optional[Message]:
|
|
1280
1314
|
block: Optional[FullBlock] = await self.full_node.block_store.get_full_block(request.header_hash)
|
|
1281
1315
|
|
|
@@ -1295,21 +1329,21 @@ class FullNodeAPI:
|
|
|
1295
1329
|
assert block is not None and block.foliage_transaction_block is not None
|
|
1296
1330
|
|
|
1297
1331
|
# Note: this might return bad data if there is a reorg in this time
|
|
1298
|
-
all_removals:
|
|
1332
|
+
all_removals: list[CoinRecord] = await self.full_node.coin_store.get_coins_removed_at_height(block.height)
|
|
1299
1333
|
|
|
1300
1334
|
if self.full_node.blockchain.height_to_hash(block.height) != request.header_hash:
|
|
1301
1335
|
raise ValueError(f"Block {block.header_hash} no longer in chain")
|
|
1302
1336
|
|
|
1303
|
-
all_removals_dict:
|
|
1337
|
+
all_removals_dict: dict[bytes32, Coin] = {}
|
|
1304
1338
|
for coin_record in all_removals:
|
|
1305
1339
|
all_removals_dict[coin_record.coin.name()] = coin_record.coin
|
|
1306
1340
|
|
|
1307
|
-
coins_map:
|
|
1308
|
-
proofs_map:
|
|
1341
|
+
coins_map: list[tuple[bytes32, Optional[Coin]]] = []
|
|
1342
|
+
proofs_map: list[tuple[bytes32, bytes]] = []
|
|
1309
1343
|
|
|
1310
1344
|
# If there are no transactions, respond with empty lists
|
|
1311
1345
|
if block.transactions_generator is None:
|
|
1312
|
-
proofs: Optional[
|
|
1346
|
+
proofs: Optional[list[tuple[bytes32, bytes]]]
|
|
1313
1347
|
if request.coin_names is None:
|
|
1314
1348
|
proofs = None
|
|
1315
1349
|
else:
|
|
@@ -1321,7 +1355,7 @@ class FullNodeAPI:
|
|
|
1321
1355
|
response = wallet_protocol.RespondRemovals(block.height, block.header_hash, coins_map, None)
|
|
1322
1356
|
else:
|
|
1323
1357
|
assert block.transactions_generator
|
|
1324
|
-
leafs:
|
|
1358
|
+
leafs: list[bytes32] = []
|
|
1325
1359
|
for removed_name, removed_coin in all_removals_dict.items():
|
|
1326
1360
|
leafs.append(removed_name)
|
|
1327
1361
|
removal_merkle_set = MerkleSet(leafs)
|
|
@@ -1341,7 +1375,7 @@ class FullNodeAPI:
|
|
|
1341
1375
|
msg = make_msg(ProtocolMessageTypes.respond_removals, response)
|
|
1342
1376
|
return msg
|
|
1343
1377
|
|
|
1344
|
-
@
|
|
1378
|
+
@metadata.request()
|
|
1345
1379
|
async def send_transaction(
|
|
1346
1380
|
self, request: wallet_protocol.SendTransaction, *, test: bool = False
|
|
1347
1381
|
) -> Optional[Message]:
|
|
@@ -1372,7 +1406,7 @@ class FullNodeAPI:
|
|
|
1372
1406
|
response = wallet_protocol.TransactionAck(spend_name, uint8(status.value), error_name)
|
|
1373
1407
|
return make_msg(ProtocolMessageTypes.transaction_ack, response)
|
|
1374
1408
|
|
|
1375
|
-
@
|
|
1409
|
+
@metadata.request()
|
|
1376
1410
|
async def request_puzzle_solution(self, request: wallet_protocol.RequestPuzzleSolution) -> Optional[Message]:
|
|
1377
1411
|
coin_name = request.coin_name
|
|
1378
1412
|
height = request.height
|
|
@@ -1411,7 +1445,7 @@ class FullNodeAPI:
|
|
|
1411
1445
|
response_msg = make_msg(ProtocolMessageTypes.respond_puzzle_solution, response)
|
|
1412
1446
|
return response_msg
|
|
1413
1447
|
|
|
1414
|
-
@
|
|
1448
|
+
@metadata.request()
|
|
1415
1449
|
async def request_block_headers(self, request: wallet_protocol.RequestBlockHeaders) -> Optional[Message]:
|
|
1416
1450
|
"""Returns header blocks by directly streaming bytes into Message
|
|
1417
1451
|
|
|
@@ -1431,7 +1465,7 @@ class FullNodeAPI:
|
|
|
1431
1465
|
|
|
1432
1466
|
else:
|
|
1433
1467
|
height_to_hash = self.full_node.blockchain.height_to_hash
|
|
1434
|
-
header_hashes:
|
|
1468
|
+
header_hashes: list[bytes32] = []
|
|
1435
1469
|
for i in range(request.start_height, request.end_height + 1):
|
|
1436
1470
|
header_hash: Optional[bytes32] = height_to_hash(uint32(i))
|
|
1437
1471
|
if header_hash is None:
|
|
@@ -1442,7 +1476,24 @@ class FullNodeAPI:
|
|
|
1442
1476
|
if len(blocks_bytes) != (request.end_height - request.start_height + 1): # +1 because interval is inclusive
|
|
1443
1477
|
return make_msg(ProtocolMessageTypes.reject_block_headers, reject)
|
|
1444
1478
|
return_filter = request.return_filter
|
|
1445
|
-
header_blocks_bytes:
|
|
1479
|
+
header_blocks_bytes: list[bytes] = []
|
|
1480
|
+
for b in blocks_bytes:
|
|
1481
|
+
b_mem_view = memoryview(b)
|
|
1482
|
+
height, is_tx_block = get_height_and_tx_status_from_block(b_mem_view)
|
|
1483
|
+
if not is_tx_block:
|
|
1484
|
+
tx_addition_coins = []
|
|
1485
|
+
removal_names = []
|
|
1486
|
+
else:
|
|
1487
|
+
added_coins_records_coroutine = self.full_node.coin_store.get_coins_added_at_height(height)
|
|
1488
|
+
removed_coins_records_coroutine = self.full_node.coin_store.get_coins_removed_at_height(height)
|
|
1489
|
+
added_coins_records, removed_coins_records = await asyncio.gather(
|
|
1490
|
+
added_coins_records_coroutine, removed_coins_records_coroutine
|
|
1491
|
+
)
|
|
1492
|
+
tx_addition_coins = [record.coin for record in added_coins_records if not record.coinbase]
|
|
1493
|
+
removal_names = [record.coin.name() for record in removed_coins_records]
|
|
1494
|
+
header_blocks_bytes.append(
|
|
1495
|
+
header_block_from_block(b_mem_view, return_filter, tx_addition_coins, removal_names)
|
|
1496
|
+
)
|
|
1446
1497
|
|
|
1447
1498
|
# we're building the RespondHeaderBlocks manually to avoid cost of
|
|
1448
1499
|
# dynamic serialization
|
|
@@ -1458,7 +1509,7 @@ class FullNodeAPI:
|
|
|
1458
1509
|
respond_header_blocks_manually_streamed += b"".join(header_blocks_bytes)
|
|
1459
1510
|
return make_msg(ProtocolMessageTypes.respond_block_headers, respond_header_blocks_manually_streamed)
|
|
1460
1511
|
|
|
1461
|
-
@
|
|
1512
|
+
@metadata.request()
|
|
1462
1513
|
async def request_header_blocks(self, request: wallet_protocol.RequestHeaderBlocks) -> Optional[Message]:
|
|
1463
1514
|
"""DEPRECATED: please use RequestBlockHeaders"""
|
|
1464
1515
|
if (
|
|
@@ -1467,7 +1518,7 @@ class FullNodeAPI:
|
|
|
1467
1518
|
):
|
|
1468
1519
|
return None
|
|
1469
1520
|
height_to_hash = self.full_node.blockchain.height_to_hash
|
|
1470
|
-
header_hashes:
|
|
1521
|
+
header_hashes: list[bytes32] = []
|
|
1471
1522
|
for i in range(request.start_height, request.end_height + 1):
|
|
1472
1523
|
header_hash: Optional[bytes32] = height_to_hash(uint32(i))
|
|
1473
1524
|
if header_hash is None:
|
|
@@ -1476,7 +1527,7 @@ class FullNodeAPI:
|
|
|
1476
1527
|
return msg
|
|
1477
1528
|
header_hashes.append(header_hash)
|
|
1478
1529
|
|
|
1479
|
-
blocks:
|
|
1530
|
+
blocks: list[FullBlock] = await self.full_node.block_store.get_blocks_by_hash(header_hashes)
|
|
1480
1531
|
header_blocks = []
|
|
1481
1532
|
for block in blocks:
|
|
1482
1533
|
added_coins_records_coroutine = self.full_node.coin_store.get_coins_added_at_height(block.height)
|
|
@@ -1486,7 +1537,7 @@ class FullNodeAPI:
|
|
|
1486
1537
|
)
|
|
1487
1538
|
added_coins = [record.coin for record in added_coins_records if not record.coinbase]
|
|
1488
1539
|
removal_names = [record.coin.name() for record in removed_coins_records]
|
|
1489
|
-
header_block = get_block_header(block,
|
|
1540
|
+
header_block = get_block_header(block, (removal_names, added_coins))
|
|
1490
1541
|
header_blocks.append(header_block)
|
|
1491
1542
|
|
|
1492
1543
|
msg = make_msg(
|
|
@@ -1495,7 +1546,7 @@ class FullNodeAPI:
|
|
|
1495
1546
|
)
|
|
1496
1547
|
return msg
|
|
1497
1548
|
|
|
1498
|
-
@
|
|
1549
|
+
@metadata.request(bytes_required=True, execute_task=True)
|
|
1499
1550
|
async def respond_compact_proof_of_time(
|
|
1500
1551
|
self, request: timelord_protocol.RespondCompactProofOfTime, request_bytes: bytes = b""
|
|
1501
1552
|
) -> None:
|
|
@@ -1521,7 +1572,7 @@ class FullNodeAPI:
|
|
|
1521
1572
|
|
|
1522
1573
|
return None
|
|
1523
1574
|
|
|
1524
|
-
@
|
|
1575
|
+
@metadata.request(peer_required=True, bytes_required=True, execute_task=True)
|
|
1525
1576
|
async def new_compact_vdf(
|
|
1526
1577
|
self, request: full_node_protocol.NewCompactVDF, peer: WSChiaConnection, request_bytes: bytes = b""
|
|
1527
1578
|
) -> None:
|
|
@@ -1548,22 +1599,22 @@ class FullNodeAPI:
|
|
|
1548
1599
|
|
|
1549
1600
|
return None
|
|
1550
1601
|
|
|
1551
|
-
@
|
|
1602
|
+
@metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_compact_vdf])
|
|
1552
1603
|
async def request_compact_vdf(self, request: full_node_protocol.RequestCompactVDF, peer: WSChiaConnection) -> None:
|
|
1553
1604
|
if self.full_node.sync_store.get_sync_mode():
|
|
1554
1605
|
return None
|
|
1555
1606
|
await self.full_node.request_compact_vdf(request, peer)
|
|
1556
1607
|
return None
|
|
1557
1608
|
|
|
1558
|
-
@
|
|
1609
|
+
@metadata.request(peer_required=True)
|
|
1559
1610
|
async def respond_compact_vdf(self, request: full_node_protocol.RespondCompactVDF, peer: WSChiaConnection) -> None:
|
|
1560
1611
|
if self.full_node.sync_store.get_sync_mode():
|
|
1561
1612
|
return None
|
|
1562
1613
|
await self.full_node.add_compact_vdf(request, peer)
|
|
1563
1614
|
return None
|
|
1564
1615
|
|
|
1565
|
-
@
|
|
1566
|
-
async def
|
|
1616
|
+
@metadata.request(peer_required=True)
|
|
1617
|
+
async def register_for_ph_updates(
|
|
1567
1618
|
self, request: wallet_protocol.RegisterForPhUpdates, peer: WSChiaConnection
|
|
1568
1619
|
) -> Message:
|
|
1569
1620
|
trusted = self.is_trusted(peer)
|
|
@@ -1585,16 +1636,16 @@ class FullNodeAPI:
|
|
|
1585
1636
|
# before we send the response
|
|
1586
1637
|
|
|
1587
1638
|
# Send all coins with requested puzzle hash that have been created after the specified height
|
|
1588
|
-
states:
|
|
1639
|
+
states: set[CoinState] = await self.full_node.coin_store.get_coin_states_by_puzzle_hashes(
|
|
1589
1640
|
include_spent_coins=True, puzzle_hashes=puzzle_hashes, min_height=request.min_height, max_items=max_items
|
|
1590
1641
|
)
|
|
1591
1642
|
max_items -= len(states)
|
|
1592
1643
|
|
|
1593
1644
|
hint_coin_ids = await self.full_node.hint_store.get_coin_ids_multi(
|
|
1594
|
-
cast(
|
|
1645
|
+
cast(set[bytes], puzzle_hashes), max_items=max_items
|
|
1595
1646
|
)
|
|
1596
1647
|
|
|
1597
|
-
hint_states:
|
|
1648
|
+
hint_states: list[CoinState] = []
|
|
1598
1649
|
if len(hint_coin_ids) > 0:
|
|
1599
1650
|
hint_states = await self.full_node.coin_store.get_coin_states_by_ids(
|
|
1600
1651
|
include_spent_coins=True,
|
|
@@ -1622,11 +1673,11 @@ class FullNodeAPI:
|
|
|
1622
1673
|
)
|
|
1623
1674
|
|
|
1624
1675
|
response = wallet_protocol.RespondToPhUpdates(request.puzzle_hashes, request.min_height, list(states))
|
|
1625
|
-
msg = make_msg(ProtocolMessageTypes.
|
|
1676
|
+
msg = make_msg(ProtocolMessageTypes.respond_to_ph_updates, response)
|
|
1626
1677
|
return msg
|
|
1627
1678
|
|
|
1628
|
-
@
|
|
1629
|
-
async def
|
|
1679
|
+
@metadata.request(peer_required=True)
|
|
1680
|
+
async def register_for_coin_updates(
|
|
1630
1681
|
self, request: wallet_protocol.RegisterForCoinUpdates, peer: WSChiaConnection
|
|
1631
1682
|
) -> Message:
|
|
1632
1683
|
max_items = self.max_subscribe_response_items(peer)
|
|
@@ -1637,17 +1688,17 @@ class FullNodeAPI:
|
|
|
1637
1688
|
# times, so we can't optimize away such DB lookups (yet)
|
|
1638
1689
|
self.full_node.subscriptions.add_coin_subscriptions(peer.peer_node_id, request.coin_ids, max_subscriptions)
|
|
1639
1690
|
|
|
1640
|
-
states:
|
|
1691
|
+
states: list[CoinState] = await self.full_node.coin_store.get_coin_states_by_ids(
|
|
1641
1692
|
include_spent_coins=True, coin_ids=set(request.coin_ids), min_height=request.min_height, max_items=max_items
|
|
1642
1693
|
)
|
|
1643
1694
|
|
|
1644
1695
|
response = wallet_protocol.RespondToCoinUpdates(request.coin_ids, request.min_height, states)
|
|
1645
|
-
msg = make_msg(ProtocolMessageTypes.
|
|
1696
|
+
msg = make_msg(ProtocolMessageTypes.respond_to_coin_updates, response)
|
|
1646
1697
|
return msg
|
|
1647
1698
|
|
|
1648
|
-
@
|
|
1699
|
+
@metadata.request()
|
|
1649
1700
|
async def request_children(self, request: wallet_protocol.RequestChildren) -> Optional[Message]:
|
|
1650
|
-
coin_records:
|
|
1701
|
+
coin_records: list[CoinRecord] = await self.full_node.coin_store.get_coin_records_by_parent_ids(
|
|
1651
1702
|
True, [request.coin_name]
|
|
1652
1703
|
)
|
|
1653
1704
|
states = [record.coin_state for record in coin_records]
|
|
@@ -1655,7 +1706,7 @@ class FullNodeAPI:
|
|
|
1655
1706
|
msg = make_msg(ProtocolMessageTypes.respond_children, response)
|
|
1656
1707
|
return msg
|
|
1657
1708
|
|
|
1658
|
-
@
|
|
1709
|
+
@metadata.request()
|
|
1659
1710
|
async def request_ses_hashes(self, request: wallet_protocol.RequestSESInfo) -> Message:
|
|
1660
1711
|
"""Returns the start and end height of a sub-epoch for the height specified in request"""
|
|
1661
1712
|
|
|
@@ -1691,9 +1742,9 @@ class FullNodeAPI:
|
|
|
1691
1742
|
msg = make_msg(ProtocolMessageTypes.respond_ses_hashes, response)
|
|
1692
1743
|
return msg
|
|
1693
1744
|
|
|
1694
|
-
@
|
|
1745
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_fee_estimates])
|
|
1695
1746
|
async def request_fee_estimates(self, request: wallet_protocol.RequestFeeEstimates) -> Message:
|
|
1696
|
-
def get_fee_estimates(est: FeeEstimatorInterface, req_times:
|
|
1747
|
+
def get_fee_estimates(est: FeeEstimatorInterface, req_times: list[uint64]) -> list[FeeEstimate]:
|
|
1697
1748
|
now = datetime.now(timezone.utc)
|
|
1698
1749
|
utc_time = now.replace(tzinfo=timezone.utc)
|
|
1699
1750
|
utc_now = int(utc_time.timestamp())
|
|
@@ -1702,14 +1753,14 @@ class FullNodeAPI:
|
|
|
1702
1753
|
v1_fee_rates = [fee_rate_v2_to_v1(est) for est in fee_rates]
|
|
1703
1754
|
return [FeeEstimate(None, req_ts, fee_rate) for req_ts, fee_rate in zip(req_times, v1_fee_rates)]
|
|
1704
1755
|
|
|
1705
|
-
fee_estimates:
|
|
1756
|
+
fee_estimates: list[FeeEstimate] = get_fee_estimates(
|
|
1706
1757
|
self.full_node.mempool_manager.mempool.fee_estimator, request.time_targets
|
|
1707
1758
|
)
|
|
1708
1759
|
response = RespondFeeEstimates(FeeEstimateGroup(error=None, estimates=fee_estimates))
|
|
1709
1760
|
msg = make_msg(ProtocolMessageTypes.respond_fee_estimates, response)
|
|
1710
1761
|
return msg
|
|
1711
1762
|
|
|
1712
|
-
@
|
|
1763
|
+
@metadata.request(
|
|
1713
1764
|
peer_required=True,
|
|
1714
1765
|
reply_types=[ProtocolMessageTypes.respond_remove_puzzle_subscriptions],
|
|
1715
1766
|
)
|
|
@@ -1729,7 +1780,7 @@ class FullNodeAPI:
|
|
|
1729
1780
|
msg = make_msg(ProtocolMessageTypes.respond_remove_puzzle_subscriptions, response)
|
|
1730
1781
|
return msg
|
|
1731
1782
|
|
|
1732
|
-
@
|
|
1783
|
+
@metadata.request(
|
|
1733
1784
|
peer_required=True,
|
|
1734
1785
|
reply_types=[ProtocolMessageTypes.respond_remove_coin_subscriptions],
|
|
1735
1786
|
)
|
|
@@ -1749,7 +1800,7 @@ class FullNodeAPI:
|
|
|
1749
1800
|
msg = make_msg(ProtocolMessageTypes.respond_remove_coin_subscriptions, response)
|
|
1750
1801
|
return msg
|
|
1751
1802
|
|
|
1752
|
-
@
|
|
1803
|
+
@metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_puzzle_state])
|
|
1753
1804
|
async def request_puzzle_state(
|
|
1754
1805
|
self, request: wallet_protocol.RequestPuzzleState, peer: WSChiaConnection
|
|
1755
1806
|
) -> Message:
|
|
@@ -1828,7 +1879,7 @@ class FullNodeAPI:
|
|
|
1828
1879
|
msg = make_msg(ProtocolMessageTypes.respond_puzzle_state, response)
|
|
1829
1880
|
return msg
|
|
1830
1881
|
|
|
1831
|
-
@
|
|
1882
|
+
@metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_coin_state])
|
|
1832
1883
|
async def request_coin_state(self, request: wallet_protocol.RequestCoinState, peer: WSChiaConnection) -> Message:
|
|
1833
1884
|
max_items = self.max_subscribe_response_items(peer)
|
|
1834
1885
|
max_subscriptions = self.max_subscriptions(peer)
|
|
@@ -1886,7 +1937,7 @@ class FullNodeAPI:
|
|
|
1886
1937
|
msg = make_msg(ProtocolMessageTypes.respond_coin_state, response)
|
|
1887
1938
|
return msg
|
|
1888
1939
|
|
|
1889
|
-
@
|
|
1940
|
+
@metadata.request(reply_types=[ProtocolMessageTypes.respond_cost_info])
|
|
1890
1941
|
async def request_cost_info(self, _request: wallet_protocol.RequestCostInfo) -> Optional[Message]:
|
|
1891
1942
|
mempool_manager = self.full_node.mempool_manager
|
|
1892
1943
|
response = wallet_protocol.RespondCostInfo(
|
|
@@ -1901,7 +1952,7 @@ class FullNodeAPI:
|
|
|
1901
1952
|
return msg
|
|
1902
1953
|
|
|
1903
1954
|
async def mempool_updates_for_puzzle_hashes(
|
|
1904
|
-
self, peer: WSChiaConnection, puzzle_hashes:
|
|
1955
|
+
self, peer: WSChiaConnection, puzzle_hashes: set[bytes32], include_hints: bool
|
|
1905
1956
|
) -> None:
|
|
1906
1957
|
if Capability.MEMPOOL_UPDATES not in peer.peer_capabilities:
|
|
1907
1958
|
return
|
|
@@ -1913,10 +1964,10 @@ class FullNodeAPI:
|
|
|
1913
1964
|
self.full_node.mempool_manager.mempool.items_with_puzzle_hashes(puzzle_hashes, include_hints)
|
|
1914
1965
|
)
|
|
1915
1966
|
|
|
1916
|
-
hinted_coin_ids:
|
|
1967
|
+
hinted_coin_ids: set[bytes32] = set()
|
|
1917
1968
|
|
|
1918
1969
|
for batch in to_batches(puzzle_hashes, SQLITE_MAX_VARIABLE_NUMBER):
|
|
1919
|
-
hints_db:
|
|
1970
|
+
hints_db: tuple[bytes, ...] = tuple(batch.entries)
|
|
1920
1971
|
cursor = await conn.execute(
|
|
1921
1972
|
f"SELECT coin_id from hints INDEXED BY hint_index "
|
|
1922
1973
|
f'WHERE hint IN ({"?," * (len(batch.entries) - 1)}?)',
|
|
@@ -1939,7 +1990,7 @@ class FullNodeAPI:
|
|
|
1939
1990
|
f"Sending initial mempool items to peer {peer.peer_node_id} took {total_time:.4f}s",
|
|
1940
1991
|
)
|
|
1941
1992
|
|
|
1942
|
-
async def mempool_updates_for_coin_ids(self, peer: WSChiaConnection, coin_ids:
|
|
1993
|
+
async def mempool_updates_for_coin_ids(self, peer: WSChiaConnection, coin_ids: set[bytes32]) -> None:
|
|
1943
1994
|
if Capability.MEMPOOL_UPDATES not in peer.peer_capabilities:
|
|
1944
1995
|
return
|
|
1945
1996
|
|