chia-blockchain 2.5.7rc4__py3-none-any.whl → 2.6.0rc2__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/__init__.py +8 -4
- chia/_tests/blockchain/blockchain_test_utils.py +6 -8
- chia/_tests/blockchain/test_augmented_chain.py +4 -4
- chia/_tests/blockchain/test_blockchain.py +165 -190
- chia/_tests/blockchain/test_blockchain_transactions.py +5 -2
- chia/_tests/blockchain/test_build_chains.py +2 -4
- chia/_tests/blockchain/test_get_block_generator.py +2 -3
- chia/_tests/clvm/coin_store.py +4 -7
- chia/_tests/clvm/test_clvm_step.py +4 -4
- chia/_tests/clvm/test_puzzle_compression.py +2 -1
- chia/_tests/clvm/test_puzzle_drivers.py +2 -2
- chia/_tests/clvm/test_singletons.py +2 -4
- chia/_tests/clvm/test_spend_sim.py +2 -2
- chia/_tests/cmds/cmd_test_utils.py +27 -45
- chia/_tests/cmds/test_cmd_framework.py +6 -6
- chia/_tests/cmds/test_daemon.py +3 -3
- chia/_tests/cmds/test_show.py +4 -4
- chia/_tests/cmds/test_tx_config_args.py +1 -2
- chia/_tests/cmds/testing_classes.py +4 -5
- chia/_tests/cmds/wallet/test_did.py +24 -27
- chia/_tests/cmds/wallet/test_nft.py +12 -10
- chia/_tests/cmds/wallet/test_vcs.py +11 -12
- chia/_tests/cmds/wallet/test_wallet.py +134 -89
- chia/_tests/conftest.py +66 -31
- chia/_tests/connection_utils.py +2 -2
- chia/_tests/core/cmds/test_beta.py +4 -4
- chia/_tests/core/cmds/test_keys.py +2 -3
- chia/_tests/core/cmds/test_wallet.py +15 -15
- chia/_tests/core/consensus/test_pot_iterations.py +19 -73
- chia/_tests/core/custom_types/test_proof_of_space.py +124 -98
- chia/_tests/core/daemon/test_daemon.py +11 -11
- chia/_tests/core/data_layer/conftest.py +2 -2
- chia/_tests/core/data_layer/test_data_rpc.py +28 -14
- chia/_tests/core/data_layer/test_data_store.py +10 -10
- chia/_tests/core/data_layer/util.py +11 -11
- chia/_tests/core/farmer/test_farmer_api.py +2 -4
- chia/_tests/core/full_node/full_sync/test_full_sync.py +8 -7
- chia/_tests/core/full_node/stores/test_block_store.py +5 -4
- chia/_tests/core/full_node/stores/test_coin_store.py +5 -11
- chia/_tests/core/full_node/stores/test_full_node_store.py +8 -8
- chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
- chia/_tests/core/full_node/test_block_height_map.py +3 -4
- chia/_tests/core/full_node/test_conditions.py +21 -23
- chia/_tests/core/full_node/test_full_node.py +273 -70
- chia/_tests/core/full_node/test_hard_fork_utils.py +92 -0
- chia/_tests/core/full_node/test_hint_management.py +2 -4
- chia/_tests/core/full_node/test_performance.py +0 -1
- chia/_tests/core/full_node/test_prev_tx_block.py +88 -11
- chia/_tests/core/full_node/test_transactions.py +1 -2
- chia/_tests/core/full_node/test_tx_processing_queue.py +198 -30
- chia/_tests/core/mempool/test_mempool.py +54 -50
- chia/_tests/core/mempool/test_mempool_fee_estimator.py +39 -39
- chia/_tests/core/mempool/test_mempool_fee_protocol.py +2 -6
- chia/_tests/core/mempool/test_mempool_manager.py +988 -854
- chia/_tests/core/mempool/test_singleton_fast_forward.py +6 -6
- chia/_tests/core/server/serve.py +7 -7
- chia/_tests/core/server/test_dos.py +1 -2
- chia/_tests/core/server/test_event_loop.py +12 -4
- chia/_tests/core/server/test_loop.py +7 -8
- chia/_tests/core/server/test_rate_limits.py +9 -8
- chia/_tests/core/server/test_server.py +61 -1
- chia/_tests/core/services/test_services.py +2 -2
- chia/_tests/core/ssl/test_ssl.py +2 -2
- chia/_tests/core/test_cost_calculation.py +2 -6
- chia/_tests/core/test_farmer_harvester_rpc.py +3 -5
- chia/_tests/core/test_filter.py +0 -1
- chia/_tests/core/test_full_node_rpc.py +2 -2
- chia/_tests/core/test_merkle_set.py +1 -2
- chia/_tests/core/test_seeder.py +4 -4
- chia/_tests/core/util/test_config.py +4 -4
- chia/_tests/core/util/test_jsonify.py +2 -2
- chia/_tests/core/util/test_keychain.py +3 -3
- chia/_tests/core/util/test_lockfile.py +2 -1
- chia/_tests/core/util/test_log_exceptions.py +1 -2
- chia/_tests/core/util/test_streamable.py +17 -17
- chia/_tests/db/test_db_wrapper.py +3 -2
- chia/_tests/environments/wallet.py +14 -14
- chia/_tests/ether.py +4 -3
- chia/_tests/farmer_harvester/test_farmer.py +41 -24
- chia/_tests/farmer_harvester/test_farmer_harvester.py +50 -17
- chia/_tests/farmer_harvester/test_filter_prefix_bits.py +27 -27
- chia/_tests/farmer_harvester/test_third_party_harvesters.py +21 -22
- chia/_tests/fee_estimation/test_fee_estimation_integration.py +18 -18
- chia/_tests/fee_estimation/test_fee_estimation_rpc.py +11 -9
- chia/_tests/harvester/test_harvester_api.py +11 -4
- chia/_tests/plot_sync/test_plot_sync.py +13 -11
- chia/_tests/plot_sync/test_receiver.py +11 -10
- chia/_tests/plot_sync/test_sync_simulated.py +2 -2
- chia/_tests/plot_sync/util.py +1 -2
- chia/_tests/plotting/test_plot_manager.py +7 -6
- chia/_tests/plotting/test_prover.py +30 -38
- chia/_tests/pools/test_pool_cmdline.py +4 -6
- chia/_tests/pools/test_pool_rpc.py +203 -61
- chia/_tests/pools/test_pool_wallet.py +3 -3
- chia/_tests/pools/test_wallet_pool_store.py +1 -4
- chia/_tests/process_junit.py +2 -2
- chia/_tests/rpc/test_rpc_client.py +4 -4
- chia/_tests/rpc/test_rpc_server.py +3 -3
- chia/_tests/simulation/test_simulation.py +12 -25
- chia/_tests/solver/test_solver_service.py +13 -4
- chia/_tests/testconfig.py +2 -2
- chia/_tests/timelord/test_new_peak.py +22 -11
- chia/_tests/tools/test_run_block.py +0 -2
- chia/_tests/tools/test_virtual_project.py +2 -1
- chia/_tests/util/benchmarks.py +1 -0
- chia/_tests/util/blockchain.py +38 -36
- chia/_tests/util/blockchain_mock.py +11 -11
- chia/_tests/util/build_network_protocol_files.py +2 -1
- chia/_tests/util/coin_store.py +2 -1
- chia/_tests/util/config.py +1 -1
- chia/_tests/util/db_connection.py +2 -3
- chia/_tests/util/full_sync.py +9 -11
- chia/_tests/util/gen_ssl_certs.py +4 -5
- chia/_tests/util/get_name_puzzle_conditions.py +2 -0
- chia/_tests/util/misc.py +24 -24
- chia/_tests/util/network_protocol_data.py +20 -3
- chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
- chia/_tests/util/protocol_messages_json.py +292 -3
- chia/_tests/util/setup_nodes.py +62 -47
- chia/_tests/util/spend_sim.py +57 -57
- chia/_tests/util/test_async_pool.py +2 -3
- chia/_tests/util/test_chia_version.py +1 -3
- chia/_tests/util/test_config.py +3 -3
- chia/_tests/util/test_full_block_utils.py +6 -3
- chia/_tests/util/test_limited_semaphore.py +1 -2
- chia/_tests/util/test_misc.py +2 -2
- chia/_tests/util/test_network.py +1 -2
- chia/_tests/util/test_priority_mutex.py +3 -3
- chia/_tests/util/test_recursive_replace.py +5 -6
- chia/_tests/util/test_replace_str_to_bytes.py +9 -10
- chia/_tests/util/test_testnet_overrides.py +3 -3
- chia/_tests/util/time_out_assert.py +2 -2
- chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +4 -6
- chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -4
- chia/_tests/wallet/cat_wallet/test_cat_wallet.py +19 -13
- chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +13 -13
- chia/_tests/wallet/cat_wallet/test_trades.py +40 -38
- chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -4
- chia/_tests/wallet/conftest.py +6 -6
- chia/_tests/wallet/db_wallet/test_db_graftroot.py +1 -1
- chia/_tests/wallet/db_wallet/test_dl_offers.py +34 -34
- chia/_tests/wallet/did_wallet/test_did.py +16 -6
- chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +21 -21
- chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +20 -6
- chia/_tests/wallet/nft_wallet/test_nft_offers.py +19 -21
- chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +1 -2
- chia/_tests/wallet/nft_wallet/test_nft_wallet.py +121 -2
- chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +6 -9
- chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +44 -1
- chia/_tests/wallet/rpc/test_wallet_rpc.py +1672 -896
- chia/_tests/wallet/sync/test_wallet_sync.py +63 -60
- chia/_tests/wallet/test_clvm_streamable.py +2 -3
- chia/_tests/wallet/test_coin_management.py +2 -2
- chia/_tests/wallet/test_conditions.py +45 -51
- chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
- chia/_tests/wallet/test_new_wallet_protocol.py +17 -17
- chia/_tests/wallet/test_notifications.py +14 -14
- chia/_tests/wallet/test_signer_protocol.py +5 -5
- chia/_tests/wallet/test_singleton_lifecycle_fast.py +4 -3
- chia/_tests/wallet/test_transaction_store.py +20 -20
- chia/_tests/wallet/test_util.py +2 -2
- chia/_tests/wallet/test_wallet.py +380 -228
- chia/_tests/wallet/test_wallet_action_scope.py +4 -4
- chia/_tests/wallet/test_wallet_blockchain.py +12 -12
- chia/_tests/wallet/test_wallet_coin_store.py +3 -4
- chia/_tests/wallet/test_wallet_node.py +16 -15
- chia/_tests/wallet/test_wallet_test_framework.py +2 -1
- chia/_tests/wallet/test_wallet_utils.py +2 -3
- chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -5
- chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +14 -15
- chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -24
- chia/_tests/wallet/wallet_block_tools.py +12 -11
- chia/_tests/weight_proof/config.py +1 -0
- chia/_tests/weight_proof/test_weight_proof.py +5 -4
- chia/apis/__init__.py +21 -0
- chia/apis/farmer_stub.py +102 -0
- chia/apis/full_node_stub.py +374 -0
- chia/apis/harvester_stub.py +57 -0
- chia/apis/introducer_stub.py +35 -0
- chia/apis/solver_stub.py +30 -0
- chia/apis/stub_protocol_registry.py +21 -0
- chia/apis/timelord_stub.py +39 -0
- chia/apis/wallet_stub.py +161 -0
- chia/cmds/beta.py +3 -4
- chia/cmds/beta_funcs.py +4 -3
- chia/cmds/check_wallet_db.py +4 -4
- chia/cmds/chia.py +1 -2
- chia/cmds/cmd_classes.py +11 -13
- chia/cmds/cmd_helpers.py +11 -11
- chia/cmds/cmds_util.py +15 -15
- chia/cmds/coin_funcs.py +6 -7
- chia/cmds/coins.py +2 -3
- chia/cmds/configure.py +1 -2
- chia/cmds/data.py +42 -42
- chia/cmds/data_funcs.py +81 -81
- chia/cmds/db.py +4 -5
- 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/data.py +4 -4
- chia/cmds/dev/gh.py +5 -5
- chia/cmds/dev/installers.py +2 -3
- chia/cmds/dev/mempool.py +3 -4
- chia/cmds/dev/mempool_funcs.py +4 -4
- chia/cmds/dev/sim.py +8 -8
- chia/cmds/dump_keyring.py +3 -3
- chia/cmds/farm.py +6 -8
- chia/cmds/farm_funcs.py +25 -24
- chia/cmds/init_funcs.py +4 -4
- chia/cmds/keys.py +16 -18
- chia/cmds/keys_funcs.py +36 -36
- chia/cmds/netspace.py +1 -3
- chia/cmds/netspace_funcs.py +1 -2
- chia/cmds/options.py +3 -2
- chia/cmds/param_types.py +17 -16
- chia/cmds/passphrase.py +6 -7
- chia/cmds/passphrase_funcs.py +11 -13
- chia/cmds/peer.py +1 -3
- chia/cmds/peer_funcs.py +3 -3
- chia/cmds/plotnft.py +6 -7
- chia/cmds/plotnft_funcs.py +37 -26
- chia/cmds/rpc.py +3 -3
- chia/cmds/show.py +3 -5
- chia/cmds/show_funcs.py +9 -9
- chia/cmds/sim_funcs.py +25 -26
- chia/cmds/solver.py +1 -3
- chia/cmds/solver_funcs.py +1 -2
- chia/cmds/start_funcs.py +2 -2
- chia/cmds/wallet.py +76 -81
- chia/cmds/wallet_funcs.py +206 -177
- chia/consensus/augmented_chain.py +6 -6
- chia/consensus/block_body_validation.py +19 -15
- chia/consensus/block_creation.py +25 -21
- chia/consensus/block_header_validation.py +27 -13
- chia/consensus/block_height_map.py +3 -6
- chia/consensus/block_height_map_protocol.py +2 -2
- chia/consensus/block_record.py +2 -4
- chia/consensus/blockchain.py +58 -40
- chia/consensus/blockchain_interface.py +7 -7
- chia/consensus/coin_store_protocol.py +5 -6
- chia/consensus/condition_tools.py +4 -4
- chia/consensus/cost_calculator.py +2 -3
- chia/consensus/default_constants.py +19 -13
- chia/consensus/deficit.py +1 -3
- chia/consensus/difficulty_adjustment.py +3 -5
- chia/consensus/find_fork_point.py +2 -4
- chia/consensus/full_block_to_block_record.py +11 -13
- chia/consensus/generator_tools.py +2 -3
- chia/consensus/get_block_challenge.py +50 -26
- chia/consensus/get_block_generator.py +2 -3
- chia/consensus/make_sub_epoch_summary.py +8 -7
- chia/consensus/multiprocess_validation.py +31 -20
- chia/consensus/pos_quality.py +6 -23
- chia/consensus/pot_iterations.py +17 -44
- chia/consensus/signage_point.py +4 -5
- chia/consensus/vdf_info_computation.py +2 -4
- chia/daemon/client.py +8 -8
- chia/daemon/keychain_proxy.py +31 -37
- chia/daemon/server.py +32 -33
- chia/daemon/windows_signal.py +4 -3
- chia/data_layer/data_layer.py +86 -77
- chia/data_layer/data_layer_rpc_api.py +9 -9
- chia/data_layer/data_layer_rpc_client.py +13 -15
- chia/data_layer/data_layer_server.py +3 -3
- chia/data_layer/data_layer_util.py +14 -14
- chia/data_layer/data_layer_wallet.py +94 -101
- chia/data_layer/data_store.py +50 -50
- chia/data_layer/dl_wallet_store.py +9 -12
- chia/data_layer/download_data.py +8 -9
- chia/data_layer/s3_plugin_service.py +5 -9
- chia/data_layer/start_data_layer.py +5 -5
- chia/farmer/farmer.py +31 -31
- chia/farmer/farmer_api.py +45 -33
- chia/farmer/farmer_rpc_api.py +5 -4
- chia/farmer/farmer_rpc_client.py +6 -6
- chia/farmer/start_farmer.py +6 -6
- chia/full_node/block_store.py +13 -16
- chia/full_node/check_fork_next_block.py +1 -2
- chia/full_node/coin_store.py +15 -16
- chia/full_node/eligible_coin_spends.py +3 -3
- chia/full_node/fee_estimate_store.py +2 -3
- chia/full_node/fee_tracker.py +1 -2
- chia/full_node/full_block_utils.py +4 -4
- chia/full_node/full_node.py +239 -223
- chia/full_node/full_node_api.py +197 -152
- chia/full_node/full_node_rpc_api.py +34 -32
- chia/full_node/full_node_rpc_client.py +18 -19
- chia/full_node/full_node_store.py +45 -43
- chia/full_node/hard_fork_utils.py +44 -0
- chia/full_node/hint_management.py +2 -2
- chia/full_node/mempool.py +17 -19
- chia/full_node/mempool_manager.py +89 -42
- chia/full_node/pending_tx_cache.py +2 -3
- chia/full_node/start_full_node.py +5 -5
- chia/full_node/sync_store.py +3 -4
- chia/full_node/tx_processing_queue.py +120 -36
- chia/full_node/weight_proof.py +61 -48
- chia/harvester/harvester.py +25 -24
- chia/harvester/harvester_api.py +61 -38
- chia/harvester/harvester_rpc_api.py +10 -10
- chia/harvester/start_harvester.py +4 -4
- chia/introducer/introducer.py +3 -3
- chia/introducer/introducer_api.py +6 -4
- chia/introducer/start_introducer.py +4 -4
- chia/legacy/keyring.py +3 -3
- chia/plot_sync/delta.py +1 -2
- chia/plot_sync/receiver.py +20 -17
- chia/plot_sync/sender.py +15 -10
- chia/plotters/bladebit.py +7 -7
- chia/plotters/chiapos.py +2 -2
- chia/plotters/madmax.py +4 -4
- chia/plotters/plotters.py +4 -4
- chia/plotters/plotters_util.py +3 -3
- chia/plotting/cache.py +20 -14
- chia/plotting/check_plots.py +26 -35
- chia/plotting/create_plots.py +22 -23
- chia/plotting/manager.py +21 -14
- chia/plotting/prover.py +59 -42
- chia/plotting/util.py +16 -16
- chia/pools/pool_config.py +2 -1
- chia/pools/pool_puzzles.py +11 -12
- chia/pools/pool_wallet.py +34 -57
- chia/pools/pool_wallet_info.py +39 -10
- chia/protocols/farmer_protocol.py +8 -9
- chia/protocols/fee_estimate.py +3 -4
- chia/protocols/full_node_protocol.py +3 -4
- chia/protocols/harvester_protocol.py +27 -15
- chia/protocols/outbound_message.py +3 -3
- chia/protocols/pool_protocol.py +8 -9
- chia/protocols/shared_protocol.py +1 -2
- chia/protocols/solver_protocol.py +9 -2
- chia/protocols/timelord_protocol.py +4 -7
- chia/protocols/wallet_protocol.py +11 -12
- chia/rpc/rpc_client.py +9 -9
- chia/rpc/rpc_server.py +17 -17
- chia/rpc/util.py +2 -2
- chia/seeder/crawler.py +8 -8
- chia/seeder/crawler_api.py +21 -27
- chia/seeder/crawler_rpc_api.py +2 -2
- chia/seeder/dns_server.py +21 -21
- chia/seeder/start_crawler.py +4 -4
- chia/server/address_manager.py +15 -16
- chia/server/api_protocol.py +11 -11
- chia/server/chia_policy.py +46 -26
- chia/server/introducer_peers.py +2 -3
- chia/server/node_discovery.py +19 -19
- chia/server/rate_limit_numbers.py +4 -5
- chia/server/rate_limits.py +4 -4
- chia/server/resolve_peer_info.py +4 -4
- chia/server/server.py +49 -52
- chia/server/signal_handlers.py +6 -6
- chia/server/start_service.py +17 -17
- chia/server/upnp.py +4 -6
- chia/server/ws_connection.py +52 -37
- chia/simulator/add_blocks_in_batches.py +1 -3
- chia/simulator/block_tools.py +312 -200
- chia/simulator/full_node_simulator.py +56 -35
- chia/simulator/keyring.py +2 -3
- chia/simulator/setup_services.py +15 -15
- chia/simulator/simulator_full_node_rpc_api.py +1 -2
- chia/simulator/simulator_full_node_rpc_client.py +1 -2
- chia/simulator/simulator_protocol.py +1 -2
- chia/simulator/simulator_test_tools.py +3 -3
- chia/simulator/start_simulator.py +7 -7
- chia/simulator/wallet_tools.py +10 -10
- chia/solver/solver.py +10 -10
- chia/solver/solver_api.py +10 -8
- chia/solver/solver_rpc_api.py +2 -2
- chia/solver/start_solver.py +4 -4
- chia/ssl/cacert.pem +148 -90
- chia/ssl/chia_ca.crt +14 -10
- chia/ssl/chia_ca_old.crt +19 -0
- chia/ssl/create_ssl.py +4 -4
- chia/ssl/renewedselfsignedca.conf +4 -0
- chia/ssl/ssl_check.py +1 -2
- chia/timelord/iters_from_block.py +1 -4
- chia/timelord/start_timelord.py +4 -4
- chia/timelord/timelord.py +44 -40
- chia/timelord/timelord_api.py +6 -4
- chia/timelord/timelord_launcher.py +2 -2
- chia/timelord/timelord_rpc_api.py +2 -2
- chia/timelord/timelord_state.py +11 -12
- chia/types/block_protocol.py +1 -3
- chia/types/blockchain_format/coin.py +1 -3
- chia/types/blockchain_format/program.py +11 -8
- chia/types/blockchain_format/proof_of_space.py +123 -76
- chia/types/blockchain_format/tree_hash.py +3 -3
- chia/types/blockchain_format/vdf.py +1 -2
- chia/types/coin_spend.py +3 -3
- chia/types/mempool_item.py +5 -5
- chia/types/mempool_submission_status.py +2 -3
- chia/types/peer_info.py +1 -2
- chia/types/unfinished_header_block.py +3 -4
- chia/types/validation_state.py +1 -2
- chia/util/action_scope.py +8 -8
- chia/util/async_pool.py +5 -5
- chia/util/bech32m.py +1 -2
- chia/util/beta_metrics.py +2 -2
- chia/util/block_cache.py +4 -4
- chia/util/chia_logging.py +2 -2
- chia/util/chia_version.py +1 -2
- chia/util/config.py +15 -16
- chia/util/db_wrapper.py +26 -27
- chia/util/default_root.py +1 -2
- chia/util/errors.py +3 -3
- chia/util/file_keyring.py +14 -14
- chia/util/files.py +2 -3
- chia/util/hash.py +4 -4
- chia/util/initial-config.yaml +4 -5
- chia/util/inline_executor.py +2 -1
- chia/util/ip_address.py +1 -2
- chia/util/keychain.py +25 -27
- chia/util/keyring_wrapper.py +18 -19
- chia/util/lock.py +3 -4
- chia/util/log_exceptions.py +1 -2
- chia/util/lru_cache.py +2 -2
- chia/util/network.py +6 -6
- chia/util/path.py +2 -3
- chia/util/priority_mutex.py +2 -2
- chia/util/profiler.py +1 -2
- chia/util/safe_cancel_task.py +1 -2
- chia/util/streamable.py +24 -10
- chia/util/task_referencer.py +1 -1
- chia/util/timing.py +3 -3
- chia/util/virtual_project_analysis.py +6 -5
- chia/util/ws_message.py +2 -2
- chia/wallet/cat_wallet/cat_info.py +3 -4
- chia/wallet/cat_wallet/cat_outer_puzzle.py +12 -11
- chia/wallet/cat_wallet/cat_utils.py +3 -4
- chia/wallet/cat_wallet/cat_wallet.py +61 -83
- chia/wallet/cat_wallet/lineage_store.py +3 -4
- chia/wallet/cat_wallet/r_cat_wallet.py +19 -22
- chia/wallet/coin_selection.py +9 -10
- chia/wallet/conditions.py +142 -106
- chia/wallet/db_wallet/db_wallet_puzzles.py +4 -5
- chia/wallet/derivation_record.py +1 -2
- chia/wallet/derive_keys.py +2 -4
- chia/wallet/did_wallet/did_info.py +10 -11
- chia/wallet/did_wallet/did_wallet.py +36 -82
- chia/wallet/did_wallet/did_wallet_puzzles.py +7 -8
- chia/wallet/driver_protocol.py +5 -7
- chia/wallet/lineage_proof.py +4 -4
- chia/wallet/nft_wallet/metadata_outer_puzzle.py +11 -11
- chia/wallet/nft_wallet/nft_info.py +8 -9
- chia/wallet/nft_wallet/nft_puzzle_utils.py +8 -8
- chia/wallet/nft_wallet/nft_wallet.py +79 -116
- chia/wallet/nft_wallet/ownership_outer_puzzle.py +14 -14
- chia/wallet/nft_wallet/singleton_outer_puzzle.py +12 -11
- chia/wallet/nft_wallet/transfer_program_puzzle.py +11 -11
- chia/wallet/nft_wallet/uncurry_nft.py +10 -11
- chia/wallet/notification_manager.py +3 -3
- chia/wallet/notification_store.py +44 -61
- chia/wallet/outer_puzzles.py +6 -7
- chia/wallet/puzzle_drivers.py +34 -6
- chia/wallet/puzzles/clawback/drivers.py +6 -6
- chia/wallet/puzzles/deployed_puzzle_hashes.json +1 -54
- chia/wallet/puzzles/load_clvm.py +1 -1
- chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -2
- chia/wallet/puzzles/singleton_top_layer.py +2 -3
- chia/wallet/puzzles/singleton_top_layer_v1_1.py +3 -4
- chia/wallet/puzzles/tails.py +3 -3
- chia/wallet/singleton.py +5 -7
- chia/wallet/singleton_record.py +3 -3
- chia/wallet/start_wallet.py +5 -5
- chia/wallet/trade_manager.py +37 -58
- chia/wallet/trade_record.py +4 -4
- chia/wallet/trading/offer.py +59 -46
- chia/wallet/trading/trade_store.py +8 -9
- chia/wallet/transaction_record.py +8 -8
- chia/wallet/uncurried_puzzle.py +1 -2
- chia/wallet/util/clvm_streamable.py +12 -12
- chia/wallet/util/compute_hints.py +4 -5
- chia/wallet/util/curry_and_treehash.py +1 -2
- chia/wallet/util/merkle_tree.py +2 -3
- chia/wallet/util/peer_request_cache.py +8 -8
- chia/wallet/util/signing.py +85 -0
- chia/wallet/util/tx_config.py +15 -6
- chia/wallet/util/wallet_sync_utils.py +14 -16
- chia/wallet/util/wallet_types.py +2 -2
- chia/wallet/vc_wallet/cr_cat_drivers.py +10 -11
- chia/wallet/vc_wallet/cr_cat_wallet.py +50 -68
- chia/wallet/vc_wallet/cr_outer_puzzle.py +14 -13
- chia/wallet/vc_wallet/vc_drivers.py +27 -27
- chia/wallet/vc_wallet/vc_store.py +5 -6
- chia/wallet/vc_wallet/vc_wallet.py +33 -61
- chia/wallet/wallet.py +50 -78
- chia/wallet/wallet_action_scope.py +11 -11
- chia/wallet/wallet_blockchain.py +12 -12
- chia/wallet/wallet_coin_record.py +12 -6
- chia/wallet/wallet_coin_store.py +24 -25
- chia/wallet/wallet_interested_store.py +3 -5
- chia/wallet/wallet_nft_store.py +10 -11
- chia/wallet/wallet_node.py +53 -61
- chia/wallet/wallet_node_api.py +5 -3
- chia/wallet/wallet_protocol.py +23 -23
- chia/wallet/wallet_puzzle_store.py +15 -18
- chia/wallet/wallet_request_types.py +778 -114
- chia/wallet/wallet_retry_store.py +1 -3
- chia/wallet/wallet_rpc_api.py +572 -909
- chia/wallet/wallet_rpc_client.py +87 -279
- chia/wallet/wallet_singleton_store.py +3 -4
- chia/wallet/wallet_state_manager.py +332 -106
- chia/wallet/wallet_transaction_store.py +11 -14
- chia/wallet/wallet_user_store.py +4 -6
- chia/wallet/wallet_weight_proof_handler.py +4 -4
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/METADATA +6 -5
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/RECORD +510 -517
- chia/apis.py +0 -21
- chia/consensus/check_time_locks.py +0 -57
- chia/data_layer/puzzles/__init__.py +0 -0
- chia/data_layer/puzzles/graftroot_dl_offers.clsp +0 -100
- chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +0 -1
- chia/types/coin_record.py +0 -44
- chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +0 -6
- chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +0 -30
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +0 -28
- chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +0 -100
- chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +0 -78
- chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +0 -1
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +0 -74
- chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +0 -1
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/entry_points.txt +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.6.0rc2.dist-info}/licenses/LICENSE +0 -0
chia/full_node/full_node_api.py
CHANGED
|
@@ -7,12 +7,13 @@ import traceback
|
|
|
7
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, ClassVar,
|
|
10
|
+
from typing import TYPE_CHECKING, ClassVar, cast
|
|
11
11
|
|
|
12
12
|
import anyio
|
|
13
13
|
from chia_rs import (
|
|
14
14
|
AugSchemeMPL,
|
|
15
15
|
BlockRecord,
|
|
16
|
+
CoinRecord,
|
|
16
17
|
CoinState,
|
|
17
18
|
EndOfSubSlotBundle,
|
|
18
19
|
FoliageBlockData,
|
|
@@ -24,7 +25,6 @@ from chia_rs import (
|
|
|
24
25
|
PoolTarget,
|
|
25
26
|
RespondToPhUpdates,
|
|
26
27
|
RewardChainBlockUnfinished,
|
|
27
|
-
SpendBundle,
|
|
28
28
|
SubEpochSummary,
|
|
29
29
|
UnfinishedBlock,
|
|
30
30
|
additions_and_removals,
|
|
@@ -44,13 +44,14 @@ from chia.consensus.signage_point import SignagePoint
|
|
|
44
44
|
from chia.full_node.coin_store import CoinStore
|
|
45
45
|
from chia.full_node.fee_estimator_interface import FeeEstimatorInterface
|
|
46
46
|
from chia.full_node.full_block_utils import get_height_and_tx_status_from_block, header_block_from_block
|
|
47
|
-
from chia.full_node.
|
|
47
|
+
from chia.full_node.hard_fork_utils import get_flags
|
|
48
|
+
from chia.full_node.tx_processing_queue import PeerWithTx, TransactionQueueEntry, TransactionQueueFull
|
|
48
49
|
from chia.protocols import farmer_protocol, full_node_protocol, introducer_protocol, timelord_protocol, wallet_protocol
|
|
49
50
|
from chia.protocols.fee_estimate import FeeEstimate, FeeEstimateGroup, fee_rate_v2_to_v1
|
|
50
51
|
from chia.protocols.full_node_protocol import RejectBlock, RejectBlocks
|
|
51
52
|
from chia.protocols.outbound_message import Message, make_msg
|
|
52
53
|
from chia.protocols.protocol_message_types import ProtocolMessageTypes
|
|
53
|
-
from chia.protocols.protocol_timing import RATE_LIMITER_BAN_SECONDS
|
|
54
|
+
from chia.protocols.protocol_timing import CONSENSUS_ERROR_BAN_SECONDS, RATE_LIMITER_BAN_SECONDS
|
|
54
55
|
from chia.protocols.shared_protocol import Capability
|
|
55
56
|
from chia.protocols.wallet_protocol import (
|
|
56
57
|
PuzzleSolutionResponse,
|
|
@@ -66,7 +67,6 @@ from chia.server.ws_connection import WSChiaConnection
|
|
|
66
67
|
from chia.types.block_protocol import BlockInfo
|
|
67
68
|
from chia.types.blockchain_format.coin import Coin, hash_coin_ids
|
|
68
69
|
from chia.types.blockchain_format.proof_of_space import verify_and_get_quality_string
|
|
69
|
-
from chia.types.coin_record import CoinRecord
|
|
70
70
|
from chia.types.generator_types import BlockGenerator, NewBlockGenerator
|
|
71
71
|
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
|
72
72
|
from chia.types.peer_info import PeerInfo
|
|
@@ -83,11 +83,54 @@ else:
|
|
|
83
83
|
FullNode = object
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
async def tx_request_and_timeout(full_node: FullNode, transaction_id: bytes32, task_id: bytes32) -> None:
|
|
87
|
+
"""
|
|
88
|
+
Request a transaction from peers that advertised it, until we either
|
|
89
|
+
receive it or timeout.
|
|
90
|
+
"""
|
|
91
|
+
tried_peers: set[bytes32] = set()
|
|
92
|
+
try:
|
|
93
|
+
# Limit to asking a few peers, it's possible that this tx got included on chain already
|
|
94
|
+
# Highly unlikely that the peers that advertised a tx don't respond to a request. Also, if we
|
|
95
|
+
# drop some transactions, we don't want to re-fetch too many times
|
|
96
|
+
for _ in range(5):
|
|
97
|
+
peers_with_tx = full_node.full_node_store.peers_with_tx.get(transaction_id)
|
|
98
|
+
if peers_with_tx is None:
|
|
99
|
+
break
|
|
100
|
+
peers_to_try = set(peers_with_tx) - tried_peers
|
|
101
|
+
if len(peers_to_try) == 0:
|
|
102
|
+
break
|
|
103
|
+
peer_id = peers_to_try.pop()
|
|
104
|
+
tried_peers.add(peer_id)
|
|
105
|
+
assert full_node.server is not None
|
|
106
|
+
if peer_id not in full_node.server.all_connections:
|
|
107
|
+
continue
|
|
108
|
+
random_peer = full_node.server.all_connections[peer_id]
|
|
109
|
+
request_tx = full_node_protocol.RequestTransaction(transaction_id)
|
|
110
|
+
msg = make_msg(ProtocolMessageTypes.request_transaction, request_tx)
|
|
111
|
+
await random_peer.send_message(msg)
|
|
112
|
+
await asyncio.sleep(5)
|
|
113
|
+
if full_node.mempool_manager.seen(transaction_id):
|
|
114
|
+
break
|
|
115
|
+
except asyncio.CancelledError:
|
|
116
|
+
pass
|
|
117
|
+
finally:
|
|
118
|
+
# Always Cleanup
|
|
119
|
+
if transaction_id in full_node.full_node_store.peers_with_tx:
|
|
120
|
+
full_node.full_node_store.peers_with_tx.pop(transaction_id)
|
|
121
|
+
if transaction_id in full_node.full_node_store.pending_tx_request:
|
|
122
|
+
full_node.full_node_store.pending_tx_request.pop(transaction_id)
|
|
123
|
+
if task_id in full_node.full_node_store.tx_fetch_tasks:
|
|
124
|
+
full_node.full_node_store.tx_fetch_tasks.pop(task_id)
|
|
125
|
+
|
|
126
|
+
|
|
86
127
|
class FullNodeAPI:
|
|
87
128
|
if TYPE_CHECKING:
|
|
88
|
-
from chia.
|
|
129
|
+
from chia.apis.full_node_stub import FullNodeApiStub
|
|
89
130
|
|
|
90
|
-
|
|
131
|
+
# Verify this class implements the FullNodeApiStub protocol
|
|
132
|
+
def _protocol_check(self: FullNodeAPI) -> FullNodeApiStub:
|
|
133
|
+
return self
|
|
91
134
|
|
|
92
135
|
log: logging.Logger
|
|
93
136
|
full_node: FullNode
|
|
@@ -108,9 +151,7 @@ class FullNodeAPI:
|
|
|
108
151
|
return self.full_node.initialized
|
|
109
152
|
|
|
110
153
|
@metadata.request(peer_required=True, reply_types=[ProtocolMessageTypes.respond_peers])
|
|
111
|
-
async def request_peers(
|
|
112
|
-
self, _request: full_node_protocol.RequestPeers, peer: WSChiaConnection
|
|
113
|
-
) -> Optional[Message]:
|
|
154
|
+
async def request_peers(self, _request: full_node_protocol.RequestPeers, peer: WSChiaConnection) -> Message | None:
|
|
114
155
|
if peer.peer_server_port is None:
|
|
115
156
|
return None
|
|
116
157
|
peer_info = PeerInfo(peer.peer_info.host, peer.peer_server_port)
|
|
@@ -120,9 +161,7 @@ class FullNodeAPI:
|
|
|
120
161
|
return None
|
|
121
162
|
|
|
122
163
|
@metadata.request(peer_required=True)
|
|
123
|
-
async def respond_peers(
|
|
124
|
-
self, request: full_node_protocol.RespondPeers, peer: WSChiaConnection
|
|
125
|
-
) -> Optional[Message]:
|
|
164
|
+
async def respond_peers(self, request: full_node_protocol.RespondPeers, peer: WSChiaConnection) -> Message | None:
|
|
126
165
|
self.log.debug(f"Received {len(request.peer_list)} peers")
|
|
127
166
|
if self.full_node.full_node_peers is not None:
|
|
128
167
|
await self.full_node.full_node_peers.add_peers(request.peer_list, peer.get_peer_info(), True)
|
|
@@ -131,7 +170,7 @@ class FullNodeAPI:
|
|
|
131
170
|
@metadata.request(peer_required=True)
|
|
132
171
|
async def respond_peers_introducer(
|
|
133
172
|
self, request: introducer_protocol.RespondPeersIntroducer, peer: WSChiaConnection
|
|
134
|
-
) ->
|
|
173
|
+
) -> Message | None:
|
|
135
174
|
self.log.debug(f"Received {len(request.peer_list)} peers from introducer")
|
|
136
175
|
if self.full_node.full_node_peers is not None:
|
|
137
176
|
await self.full_node.full_node_peers.add_peers(request.peer_list, peer.get_peer_info(), False)
|
|
@@ -159,7 +198,7 @@ class FullNodeAPI:
|
|
|
159
198
|
@metadata.request(peer_required=True)
|
|
160
199
|
async def new_transaction(
|
|
161
200
|
self, transaction: full_node_protocol.NewTransaction, peer: WSChiaConnection
|
|
162
|
-
) ->
|
|
201
|
+
) -> Message | None:
|
|
163
202
|
"""
|
|
164
203
|
A peer notifies us of a new transaction.
|
|
165
204
|
Requests a full transaction if we haven't seen it previously, and if the fees are enough.
|
|
@@ -170,66 +209,60 @@ class FullNodeAPI:
|
|
|
170
209
|
if not (await self.full_node.synced()):
|
|
171
210
|
return None
|
|
172
211
|
|
|
173
|
-
#
|
|
174
|
-
if
|
|
212
|
+
# It's not reasonable to advertise a transaction with zero cost
|
|
213
|
+
if transaction.cost == 0:
|
|
214
|
+
self.log.warning(
|
|
215
|
+
f"Banning peer {peer.peer_node_id}. Sent us a tx {transaction.transaction_id} with zero cost."
|
|
216
|
+
)
|
|
217
|
+
await peer.close(CONSENSUS_ERROR_BAN_SECONDS)
|
|
218
|
+
return None
|
|
219
|
+
|
|
220
|
+
# If already seen, the cost and fee must match, otherwise ban the peer
|
|
221
|
+
mempool_item = self.full_node.mempool_manager.get_mempool_item(transaction.transaction_id, include_pending=True)
|
|
222
|
+
if mempool_item is not None:
|
|
223
|
+
if mempool_item.cost != transaction.cost or mempool_item.fee != transaction.fees:
|
|
224
|
+
self.log.warning(
|
|
225
|
+
f"Banning peer {peer.peer_node_id}. Sent us an already seen tx {transaction.transaction_id} "
|
|
226
|
+
f"with mismatch on cost {transaction.cost} vs validation cost {mempool_item.cost} and/or "
|
|
227
|
+
f"fee {transaction.fees} vs {mempool_item.fee}."
|
|
228
|
+
)
|
|
229
|
+
await peer.close(CONSENSUS_ERROR_BAN_SECONDS)
|
|
175
230
|
return None
|
|
176
231
|
|
|
177
232
|
if self.full_node.mempool_manager.is_fee_enough(transaction.fees, transaction.cost):
|
|
178
233
|
# If there's current pending request just add this peer to the set of peers that have this tx
|
|
179
234
|
if transaction.transaction_id in self.full_node.full_node_store.pending_tx_request:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
235
|
+
current_map = self.full_node.full_node_store.peers_with_tx.get(transaction.transaction_id)
|
|
236
|
+
if current_map is None:
|
|
237
|
+
self.full_node.full_node_store.peers_with_tx[transaction.transaction_id] = {
|
|
238
|
+
peer.peer_node_id: PeerWithTx(
|
|
239
|
+
peer_host=peer.peer_info.host,
|
|
240
|
+
advertised_fee=transaction.fees,
|
|
241
|
+
advertised_cost=transaction.cost,
|
|
242
|
+
)
|
|
243
|
+
}
|
|
185
244
|
return None
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
245
|
+
prev = current_map.get(peer.peer_node_id)
|
|
246
|
+
if prev is not None:
|
|
247
|
+
if prev.advertised_fee != transaction.fees or prev.advertised_cost != transaction.cost:
|
|
248
|
+
self.log.warning(
|
|
249
|
+
f"Banning peer {peer.peer_node_id}. Sent us a new tx {transaction.transaction_id} with "
|
|
250
|
+
f"mismatch on cost {transaction.cost} vs previous advertised cost {prev.advertised_cost} "
|
|
251
|
+
f"and/or fee {transaction.fees} vs previous advertised fee {prev.advertised_fee}."
|
|
252
|
+
)
|
|
253
|
+
await peer.close(CONSENSUS_ERROR_BAN_SECONDS)
|
|
190
254
|
return None
|
|
255
|
+
current_map[peer.peer_node_id] = PeerWithTx(
|
|
256
|
+
peer_host=peer.peer_info.host, advertised_fee=transaction.fees, advertised_cost=transaction.cost
|
|
257
|
+
)
|
|
258
|
+
return None
|
|
191
259
|
|
|
192
260
|
self.full_node.full_node_store.pending_tx_request[transaction.transaction_id] = peer.peer_node_id
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
counter = 0
|
|
199
|
-
try:
|
|
200
|
-
while True:
|
|
201
|
-
# Limit to asking a few peers, it's possible that this tx got included on chain already
|
|
202
|
-
# Highly unlikely that the peers that advertised a tx don't respond to a request. Also, if we
|
|
203
|
-
# drop some transactions, we don't want to re-fetch too many times
|
|
204
|
-
if counter == 5:
|
|
205
|
-
break
|
|
206
|
-
if transaction_id not in full_node.full_node_store.peers_with_tx:
|
|
207
|
-
break
|
|
208
|
-
peers_with_tx: set[bytes32] = full_node.full_node_store.peers_with_tx[transaction_id]
|
|
209
|
-
if len(peers_with_tx) == 0:
|
|
210
|
-
break
|
|
211
|
-
peer_id = peers_with_tx.pop()
|
|
212
|
-
assert full_node.server is not None
|
|
213
|
-
if peer_id not in full_node.server.all_connections:
|
|
214
|
-
continue
|
|
215
|
-
random_peer = full_node.server.all_connections[peer_id]
|
|
216
|
-
request_tx = full_node_protocol.RequestTransaction(transaction.transaction_id)
|
|
217
|
-
msg = make_msg(ProtocolMessageTypes.request_transaction, request_tx)
|
|
218
|
-
await random_peer.send_message(msg)
|
|
219
|
-
await asyncio.sleep(5)
|
|
220
|
-
counter += 1
|
|
221
|
-
if full_node.mempool_manager.seen(transaction_id):
|
|
222
|
-
break
|
|
223
|
-
except asyncio.CancelledError:
|
|
224
|
-
pass
|
|
225
|
-
finally:
|
|
226
|
-
# Always Cleanup
|
|
227
|
-
if transaction_id in full_node.full_node_store.peers_with_tx:
|
|
228
|
-
full_node.full_node_store.peers_with_tx.pop(transaction_id)
|
|
229
|
-
if transaction_id in full_node.full_node_store.pending_tx_request:
|
|
230
|
-
full_node.full_node_store.pending_tx_request.pop(transaction_id)
|
|
231
|
-
if task_id in full_node.full_node_store.tx_fetch_tasks:
|
|
232
|
-
full_node.full_node_store.tx_fetch_tasks.pop(task_id)
|
|
261
|
+
self.full_node.full_node_store.peers_with_tx[transaction.transaction_id] = {
|
|
262
|
+
peer.peer_node_id: PeerWithTx(
|
|
263
|
+
peer_host=peer.peer_info.host, advertised_fee=transaction.fees, advertised_cost=transaction.cost
|
|
264
|
+
)
|
|
265
|
+
}
|
|
233
266
|
|
|
234
267
|
task_id: bytes32 = bytes32.secret()
|
|
235
268
|
fetch_task = create_referenced_task(
|
|
@@ -240,7 +273,7 @@ class FullNodeAPI:
|
|
|
240
273
|
return None
|
|
241
274
|
|
|
242
275
|
@metadata.request(reply_types=[ProtocolMessageTypes.respond_transaction])
|
|
243
|
-
async def request_transaction(self, request: full_node_protocol.RequestTransaction) ->
|
|
276
|
+
async def request_transaction(self, request: full_node_protocol.RequestTransaction) -> Message | None:
|
|
244
277
|
"""Peer has requested a full transaction from us."""
|
|
245
278
|
# Ignore if syncing
|
|
246
279
|
if self.full_node.sync_store.get_sync_mode():
|
|
@@ -261,7 +294,7 @@ class FullNodeAPI:
|
|
|
261
294
|
peer: WSChiaConnection,
|
|
262
295
|
tx_bytes: bytes = b"",
|
|
263
296
|
test: bool = False,
|
|
264
|
-
) ->
|
|
297
|
+
) -> Message | None:
|
|
265
298
|
"""
|
|
266
299
|
Receives a full transaction from peer.
|
|
267
300
|
If tx is added to mempool, send tx_id to others. (new_transaction)
|
|
@@ -270,20 +303,22 @@ class FullNodeAPI:
|
|
|
270
303
|
spend_name = std_hash(tx_bytes)
|
|
271
304
|
if spend_name in self.full_node.full_node_store.pending_tx_request:
|
|
272
305
|
self.full_node.full_node_store.pending_tx_request.pop(spend_name)
|
|
306
|
+
peers_with_tx = {}
|
|
273
307
|
if spend_name in self.full_node.full_node_store.peers_with_tx:
|
|
274
|
-
self.full_node.full_node_store.peers_with_tx.pop(spend_name)
|
|
308
|
+
peers_with_tx = self.full_node.full_node_store.peers_with_tx.pop(spend_name)
|
|
275
309
|
|
|
276
310
|
# TODO: Use fee in priority calculation, to prioritize high fee TXs
|
|
277
311
|
try:
|
|
278
|
-
|
|
279
|
-
TransactionQueueEntry(tx.transaction, tx_bytes, spend_name, peer, test),
|
|
312
|
+
self.full_node.transaction_queue.put(
|
|
313
|
+
TransactionQueueEntry(tx.transaction, tx_bytes, spend_name, peer, test, peers_with_tx),
|
|
314
|
+
peer.peer_node_id,
|
|
280
315
|
)
|
|
281
316
|
except TransactionQueueFull:
|
|
282
317
|
pass # we can't do anything here, the tx will be dropped. We might do something in the future.
|
|
283
318
|
return None
|
|
284
319
|
|
|
285
320
|
@metadata.request(reply_types=[ProtocolMessageTypes.respond_proof_of_weight])
|
|
286
|
-
async def request_proof_of_weight(self, request: full_node_protocol.RequestProofOfWeight) ->
|
|
321
|
+
async def request_proof_of_weight(self, request: full_node_protocol.RequestProofOfWeight) -> Message | None:
|
|
287
322
|
if self.full_node.weight_proof_handler is None:
|
|
288
323
|
return None
|
|
289
324
|
if self.full_node.blockchain.try_block_record(request.tip) is None:
|
|
@@ -323,21 +358,21 @@ class FullNodeAPI:
|
|
|
323
358
|
return message
|
|
324
359
|
|
|
325
360
|
@metadata.request()
|
|
326
|
-
async def respond_proof_of_weight(self, request: full_node_protocol.RespondProofOfWeight) ->
|
|
361
|
+
async def respond_proof_of_weight(self, request: full_node_protocol.RespondProofOfWeight) -> Message | None:
|
|
327
362
|
self.log.warning("Received proof of weight too late.")
|
|
328
363
|
return None
|
|
329
364
|
|
|
330
365
|
@metadata.request(reply_types=[ProtocolMessageTypes.respond_block, ProtocolMessageTypes.reject_block])
|
|
331
|
-
async def request_block(self, request: full_node_protocol.RequestBlock) ->
|
|
366
|
+
async def request_block(self, request: full_node_protocol.RequestBlock) -> Message | None:
|
|
332
367
|
if not self.full_node.blockchain.contains_height(request.height):
|
|
333
368
|
reject = RejectBlock(request.height)
|
|
334
369
|
msg = make_msg(ProtocolMessageTypes.reject_block, reject)
|
|
335
370
|
return msg
|
|
336
|
-
header_hash:
|
|
371
|
+
header_hash: bytes32 | None = self.full_node.blockchain.height_to_hash(request.height)
|
|
337
372
|
if header_hash is None:
|
|
338
373
|
return make_msg(ProtocolMessageTypes.reject_block, RejectBlock(request.height))
|
|
339
374
|
|
|
340
|
-
block:
|
|
375
|
+
block: FullBlock | None = await self.full_node.block_store.get_full_block(header_hash)
|
|
341
376
|
if block is not None:
|
|
342
377
|
if not request.include_transaction_block and block.transactions_generator is not None:
|
|
343
378
|
block = block.replace(transactions_generator=None)
|
|
@@ -345,7 +380,7 @@ class FullNodeAPI:
|
|
|
345
380
|
return make_msg(ProtocolMessageTypes.reject_block, RejectBlock(request.height))
|
|
346
381
|
|
|
347
382
|
@metadata.request(reply_types=[ProtocolMessageTypes.respond_blocks, ProtocolMessageTypes.reject_blocks])
|
|
348
|
-
async def request_blocks(self, request: full_node_protocol.RequestBlocks) ->
|
|
383
|
+
async def request_blocks(self, request: full_node_protocol.RequestBlocks) -> Message | None:
|
|
349
384
|
# note that we treat the request range as *inclusive*, but we check the
|
|
350
385
|
# size before we bump end_height. So MAX_BLOCK_COUNT_PER_REQUESTS is off
|
|
351
386
|
# by one
|
|
@@ -365,12 +400,12 @@ class FullNodeAPI:
|
|
|
365
400
|
if not request.include_transaction_block:
|
|
366
401
|
blocks: list[FullBlock] = []
|
|
367
402
|
for i in range(request.start_height, request.end_height + 1):
|
|
368
|
-
header_hash_i:
|
|
403
|
+
header_hash_i: bytes32 | None = self.full_node.blockchain.height_to_hash(uint32(i))
|
|
369
404
|
if header_hash_i is None:
|
|
370
405
|
reject = RejectBlocks(request.start_height, request.end_height)
|
|
371
406
|
return make_msg(ProtocolMessageTypes.reject_blocks, reject)
|
|
372
407
|
|
|
373
|
-
block:
|
|
408
|
+
block: FullBlock | None = await self.full_node.block_store.get_full_block(header_hash_i)
|
|
374
409
|
if block is None:
|
|
375
410
|
reject = RejectBlocks(request.start_height, request.end_height)
|
|
376
411
|
return make_msg(ProtocolMessageTypes.reject_blocks, reject)
|
|
@@ -387,7 +422,7 @@ class FullNodeAPI:
|
|
|
387
422
|
if header_hash_i is None:
|
|
388
423
|
reject = RejectBlocks(request.start_height, request.end_height)
|
|
389
424
|
return make_msg(ProtocolMessageTypes.reject_blocks, reject)
|
|
390
|
-
block_bytes:
|
|
425
|
+
block_bytes: bytes | None = await self.full_node.block_store.get_full_block_bytes(header_hash_i)
|
|
391
426
|
if block_bytes is None:
|
|
392
427
|
reject = RejectBlocks(request.start_height, request.end_height)
|
|
393
428
|
msg = make_msg(ProtocolMessageTypes.reject_blocks, reject)
|
|
@@ -438,15 +473,13 @@ class FullNodeAPI:
|
|
|
438
473
|
self,
|
|
439
474
|
respond_block: full_node_protocol.RespondBlock,
|
|
440
475
|
peer: WSChiaConnection,
|
|
441
|
-
) ->
|
|
476
|
+
) -> Message | None:
|
|
442
477
|
self.log.warning(f"Received unsolicited/late block from peer {peer.get_peer_logging()}")
|
|
443
478
|
await peer.close(RATE_LIMITER_BAN_SECONDS)
|
|
444
479
|
return None
|
|
445
480
|
|
|
446
481
|
@metadata.request()
|
|
447
|
-
async def new_unfinished_block(
|
|
448
|
-
self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock
|
|
449
|
-
) -> Optional[Message]:
|
|
482
|
+
async def new_unfinished_block(self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock) -> Message | None:
|
|
450
483
|
# Ignore if syncing
|
|
451
484
|
if self.full_node.sync_store.get_sync_mode():
|
|
452
485
|
return None
|
|
@@ -482,8 +515,8 @@ class FullNodeAPI:
|
|
|
482
515
|
@metadata.request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
|
|
483
516
|
async def request_unfinished_block(
|
|
484
517
|
self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock
|
|
485
|
-
) ->
|
|
486
|
-
unfinished_block:
|
|
518
|
+
) -> Message | None:
|
|
519
|
+
unfinished_block: UnfinishedBlock | None = self.full_node.full_node_store.get_unfinished_block(
|
|
487
520
|
request_unfinished_block.unfinished_reward_hash
|
|
488
521
|
)
|
|
489
522
|
if unfinished_block is not None:
|
|
@@ -497,7 +530,7 @@ class FullNodeAPI:
|
|
|
497
530
|
@metadata.request()
|
|
498
531
|
async def new_unfinished_block2(
|
|
499
532
|
self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock2
|
|
500
|
-
) ->
|
|
533
|
+
) -> Message | None:
|
|
501
534
|
# Ignore if syncing
|
|
502
535
|
if self.full_node.sync_store.get_sync_mode():
|
|
503
536
|
return None
|
|
@@ -550,8 +583,8 @@ class FullNodeAPI:
|
|
|
550
583
|
@metadata.request(reply_types=[ProtocolMessageTypes.respond_unfinished_block])
|
|
551
584
|
async def request_unfinished_block2(
|
|
552
585
|
self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock2
|
|
553
|
-
) ->
|
|
554
|
-
unfinished_block:
|
|
586
|
+
) -> Message | None:
|
|
587
|
+
unfinished_block: UnfinishedBlock | None
|
|
555
588
|
unfinished_block, _, _ = self.full_node.full_node_store.get_unfinished_block2(
|
|
556
589
|
request_unfinished_block.unfinished_reward_hash,
|
|
557
590
|
request_unfinished_block.foliage_hash,
|
|
@@ -569,7 +602,7 @@ class FullNodeAPI:
|
|
|
569
602
|
self,
|
|
570
603
|
respond_unfinished_block: full_node_protocol.RespondUnfinishedBlock,
|
|
571
604
|
peer: WSChiaConnection,
|
|
572
|
-
) ->
|
|
605
|
+
) -> Message | None:
|
|
573
606
|
if self.full_node.sync_store.get_sync_mode():
|
|
574
607
|
return None
|
|
575
608
|
await self.full_node.add_unfinished_block(respond_unfinished_block.unfinished_block, peer)
|
|
@@ -578,7 +611,7 @@ class FullNodeAPI:
|
|
|
578
611
|
@metadata.request(peer_required=True)
|
|
579
612
|
async def new_signage_point_or_end_of_sub_slot(
|
|
580
613
|
self, new_sp: full_node_protocol.NewSignagePointOrEndOfSubSlot, peer: WSChiaConnection
|
|
581
|
-
) ->
|
|
614
|
+
) -> Message | None:
|
|
582
615
|
# Ignore if syncing
|
|
583
616
|
if self.full_node.sync_store.get_sync_mode():
|
|
584
617
|
return None
|
|
@@ -664,9 +697,9 @@ class FullNodeAPI:
|
|
|
664
697
|
)
|
|
665
698
|
async def request_signage_point_or_end_of_sub_slot(
|
|
666
699
|
self, request: full_node_protocol.RequestSignagePointOrEndOfSubSlot
|
|
667
|
-
) ->
|
|
700
|
+
) -> Message | None:
|
|
668
701
|
if request.index_from_challenge == 0:
|
|
669
|
-
sub_slot:
|
|
702
|
+
sub_slot: tuple[EndOfSubSlotBundle, int, uint128] | None = self.full_node.full_node_store.get_sub_slot(
|
|
670
703
|
request.challenge_hash
|
|
671
704
|
)
|
|
672
705
|
if sub_slot is not None:
|
|
@@ -679,7 +712,7 @@ class FullNodeAPI:
|
|
|
679
712
|
if request.challenge_hash != self.full_node.constants.GENESIS_CHALLENGE:
|
|
680
713
|
self.log.info(f"Don't have challenge hash {request.challenge_hash.hex()}")
|
|
681
714
|
|
|
682
|
-
sp:
|
|
715
|
+
sp: SignagePoint | None = self.full_node.full_node_store.get_signage_point_by_index(
|
|
683
716
|
request.challenge_hash,
|
|
684
717
|
request.index_from_challenge,
|
|
685
718
|
request.last_rc_infusion,
|
|
@@ -706,7 +739,7 @@ class FullNodeAPI:
|
|
|
706
739
|
@metadata.request(peer_required=True)
|
|
707
740
|
async def respond_signage_point(
|
|
708
741
|
self, request: full_node_protocol.RespondSignagePoint, peer: WSChiaConnection
|
|
709
|
-
) ->
|
|
742
|
+
) -> Message | None:
|
|
710
743
|
if self.full_node.sync_store.get_sync_mode():
|
|
711
744
|
return None
|
|
712
745
|
async with self.full_node.timelord_lock:
|
|
@@ -732,7 +765,7 @@ class FullNodeAPI:
|
|
|
732
765
|
)[0]
|
|
733
766
|
sub_slots_for_peak = await self.full_node.blockchain.get_sp_and_ip_sub_slots(peak.header_hash)
|
|
734
767
|
assert sub_slots_for_peak is not None
|
|
735
|
-
ip_sub_slot:
|
|
768
|
+
ip_sub_slot: EndOfSubSlotBundle | None = sub_slots_for_peak[1]
|
|
736
769
|
else:
|
|
737
770
|
sub_slot_iters = self.full_node.constants.SUB_SLOT_ITERS_STARTING
|
|
738
771
|
next_sub_slot_iters = sub_slot_iters
|
|
@@ -765,7 +798,7 @@ class FullNodeAPI:
|
|
|
765
798
|
@metadata.request(peer_required=True)
|
|
766
799
|
async def respond_end_of_sub_slot(
|
|
767
800
|
self, request: full_node_protocol.RespondEndOfSubSlot, peer: WSChiaConnection
|
|
768
|
-
) ->
|
|
801
|
+
) -> Message | None:
|
|
769
802
|
if self.full_node.sync_store.get_sync_mode():
|
|
770
803
|
return None
|
|
771
804
|
msg, _ = await self.full_node.add_end_of_sub_slot(request.end_of_slot_bundle, peer)
|
|
@@ -776,14 +809,14 @@ class FullNodeAPI:
|
|
|
776
809
|
self,
|
|
777
810
|
request: full_node_protocol.RequestMempoolTransactions,
|
|
778
811
|
peer: WSChiaConnection,
|
|
779
|
-
) ->
|
|
812
|
+
) -> Message | None:
|
|
780
813
|
received_filter = PyBIP158(bytearray(request.filter))
|
|
781
814
|
|
|
782
|
-
items
|
|
815
|
+
items = self.full_node.mempool_manager.get_items_not_in_filter(received_filter, limit=100)
|
|
783
816
|
|
|
784
817
|
for item in items:
|
|
785
|
-
transaction = full_node_protocol.
|
|
786
|
-
msg = make_msg(ProtocolMessageTypes.
|
|
818
|
+
transaction = full_node_protocol.NewTransaction(item.name, item.cost, item.fee)
|
|
819
|
+
msg = make_msg(ProtocolMessageTypes.new_transaction, transaction)
|
|
787
820
|
await peer.send_message(msg)
|
|
788
821
|
return None
|
|
789
822
|
|
|
@@ -791,7 +824,7 @@ class FullNodeAPI:
|
|
|
791
824
|
@metadata.request(peer_required=True)
|
|
792
825
|
async def declare_proof_of_space(
|
|
793
826
|
self, request: farmer_protocol.DeclareProofOfSpace, peer: WSChiaConnection
|
|
794
|
-
) ->
|
|
827
|
+
) -> Message | None:
|
|
795
828
|
"""
|
|
796
829
|
Creates a block body and header, with the proof of space, coinbase, and fee targets provided
|
|
797
830
|
by the farmer, and sends the hash of the header data back to the farmer.
|
|
@@ -800,7 +833,7 @@ class FullNodeAPI:
|
|
|
800
833
|
return None
|
|
801
834
|
|
|
802
835
|
async with self.full_node.timelord_lock:
|
|
803
|
-
sp_vdfs:
|
|
836
|
+
sp_vdfs: SignagePoint | None = self.full_node.full_node_store.get_signage_point_by_index_and_cc_output(
|
|
804
837
|
request.challenge_chain_sp, request.challenge_hash, request.signage_point_index
|
|
805
838
|
)
|
|
806
839
|
|
|
@@ -822,7 +855,7 @@ class FullNodeAPI:
|
|
|
822
855
|
assert sp_vdfs.cc_vdf is not None
|
|
823
856
|
cc_challenge_hash = sp_vdfs.cc_vdf.challenge
|
|
824
857
|
|
|
825
|
-
pos_sub_slot:
|
|
858
|
+
pos_sub_slot: tuple[EndOfSubSlotBundle, int, uint128] | None = None
|
|
826
859
|
if request.challenge_hash != self.full_node.constants.GENESIS_CHALLENGE:
|
|
827
860
|
# Checks that the proof of space is a response to a recent challenge and valid SP
|
|
828
861
|
pos_sub_slot = self.full_node.full_node_store.get_sub_slot(cc_challenge_hash)
|
|
@@ -840,24 +873,31 @@ class FullNodeAPI:
|
|
|
840
873
|
# 3. In a future sub-slot that we already know of
|
|
841
874
|
|
|
842
875
|
# Grab best transactions from Mempool for given tip target
|
|
843
|
-
new_block_gen:
|
|
876
|
+
new_block_gen: NewBlockGenerator | None
|
|
844
877
|
async with self.full_node.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
845
|
-
peak:
|
|
878
|
+
peak: BlockRecord | None = self.full_node.blockchain.get_peak()
|
|
879
|
+
tx_peak: BlockRecord | None = self.full_node.blockchain.get_tx_peak()
|
|
846
880
|
|
|
847
881
|
# Checks that the proof of space is valid
|
|
848
882
|
height: uint32
|
|
849
|
-
|
|
883
|
+
tx_height: uint32
|
|
884
|
+
if peak is None or tx_peak is None:
|
|
850
885
|
height = uint32(0)
|
|
886
|
+
tx_height = uint32(0)
|
|
851
887
|
else:
|
|
852
888
|
height = peak.height
|
|
853
|
-
|
|
889
|
+
tx_height = tx_peak.height
|
|
890
|
+
quality_string: bytes32 | None = verify_and_get_quality_string(
|
|
854
891
|
request.proof_of_space,
|
|
855
892
|
self.full_node.constants,
|
|
856
893
|
cc_challenge_hash,
|
|
857
894
|
request.challenge_chain_sp,
|
|
858
895
|
height=height,
|
|
896
|
+
prev_transaction_block_height=tx_height,
|
|
859
897
|
)
|
|
860
|
-
|
|
898
|
+
if quality_string is None:
|
|
899
|
+
self.log.warning("Received invalid proof of space in DeclareProofOfSpace from farmer")
|
|
900
|
+
return None
|
|
861
901
|
|
|
862
902
|
if peak is not None:
|
|
863
903
|
# Finds the last transaction block before this one
|
|
@@ -898,10 +938,10 @@ class FullNodeAPI:
|
|
|
898
938
|
return request.reward_chain_sp_signature
|
|
899
939
|
return G2Element()
|
|
900
940
|
|
|
901
|
-
def get_pool_sig(_1: PoolTarget, _2:
|
|
941
|
+
def get_pool_sig(_1: PoolTarget, _2: G1Element | None) -> G2Element | None:
|
|
902
942
|
return request.pool_signature
|
|
903
943
|
|
|
904
|
-
prev_b:
|
|
944
|
+
prev_b: BlockRecord | None = peak
|
|
905
945
|
|
|
906
946
|
# Finds the previous block from the signage point, ensuring that the reward chain VDF is correct
|
|
907
947
|
if prev_b is not None:
|
|
@@ -939,7 +979,7 @@ class FullNodeAPI:
|
|
|
939
979
|
return None
|
|
940
980
|
|
|
941
981
|
try:
|
|
942
|
-
finished_sub_slots:
|
|
982
|
+
finished_sub_slots: list[EndOfSubSlotBundle] | None = (
|
|
943
983
|
self.full_node.full_node_store.get_finished_sub_slots(
|
|
944
984
|
self.full_node.blockchain, prev_b, cc_challenge_hash
|
|
945
985
|
)
|
|
@@ -987,11 +1027,9 @@ class FullNodeAPI:
|
|
|
987
1027
|
required_iters: uint64 = calculate_iterations_quality(
|
|
988
1028
|
self.full_node.constants,
|
|
989
1029
|
quality_string,
|
|
990
|
-
request.proof_of_space.
|
|
1030
|
+
request.proof_of_space.param(),
|
|
991
1031
|
difficulty,
|
|
992
1032
|
request.challenge_chain_sp,
|
|
993
|
-
sub_slot_iters,
|
|
994
|
-
tx_peak.height if tx_peak is not None else uint32(0),
|
|
995
1033
|
)
|
|
996
1034
|
sp_iters: uint64 = calculate_sp_iters(self.full_node.constants, sub_slot_iters, request.signage_point_index)
|
|
997
1035
|
ip_iters: uint64 = calculate_ip_iters(
|
|
@@ -1003,7 +1041,7 @@ class FullNodeAPI:
|
|
|
1003
1041
|
|
|
1004
1042
|
# The block's timestamp must be greater than the previous transaction block's timestamp
|
|
1005
1043
|
timestamp = uint64(time.time())
|
|
1006
|
-
curr:
|
|
1044
|
+
curr: BlockRecord | None = prev_b
|
|
1007
1045
|
while curr is not None and not curr.is_transaction_block and curr.height != 0:
|
|
1008
1046
|
curr = self.full_node.blockchain.try_block_record(curr.prev_hash)
|
|
1009
1047
|
if curr is not None:
|
|
@@ -1047,9 +1085,9 @@ class FullNodeAPI:
|
|
|
1047
1085
|
foliage_transaction_block_hash = bytes32.zeros
|
|
1048
1086
|
assert foliage_transaction_block_hash is not None
|
|
1049
1087
|
|
|
1050
|
-
foliage_block_data:
|
|
1051
|
-
foliage_transaction_block_data:
|
|
1052
|
-
rc_block_unfinished:
|
|
1088
|
+
foliage_block_data: FoliageBlockData | None = None
|
|
1089
|
+
foliage_transaction_block_data: FoliageTransactionBlock | None = None
|
|
1090
|
+
rc_block_unfinished: RewardChainBlockUnfinished | None = None
|
|
1053
1091
|
if request.include_signature_source_data:
|
|
1054
1092
|
foliage_block_data = unfinished_block.foliage.foliage_block_data
|
|
1055
1093
|
rc_block_unfinished = unfinished_block.reward_chain_block
|
|
@@ -1098,13 +1136,13 @@ class FullNodeAPI:
|
|
|
1098
1136
|
@metadata.request(peer_required=True)
|
|
1099
1137
|
async def signed_values(
|
|
1100
1138
|
self, farmer_request: farmer_protocol.SignedValues, peer: WSChiaConnection
|
|
1101
|
-
) ->
|
|
1139
|
+
) -> Message | None:
|
|
1102
1140
|
"""
|
|
1103
1141
|
Signature of header hash, by the harvester. This is enough to create an unfinished
|
|
1104
1142
|
block, which only needs a Proof of Time to be finished. If the signature is valid,
|
|
1105
1143
|
we call the unfinished_block routine.
|
|
1106
1144
|
"""
|
|
1107
|
-
candidate_tuple:
|
|
1145
|
+
candidate_tuple: tuple[uint32, UnfinishedBlock] | None = self.full_node.full_node_store.get_candidate_block(
|
|
1108
1146
|
farmer_request.quality_string
|
|
1109
1147
|
)
|
|
1110
1148
|
|
|
@@ -1164,7 +1202,7 @@ class FullNodeAPI:
|
|
|
1164
1202
|
@metadata.request(peer_required=True)
|
|
1165
1203
|
async def new_infusion_point_vdf(
|
|
1166
1204
|
self, request: timelord_protocol.NewInfusionPointVDF, peer: WSChiaConnection
|
|
1167
|
-
) ->
|
|
1205
|
+
) -> Message | None:
|
|
1168
1206
|
if self.full_node.sync_store.get_sync_mode():
|
|
1169
1207
|
return None
|
|
1170
1208
|
# Lookup unfinished blocks
|
|
@@ -1190,7 +1228,7 @@ class FullNodeAPI:
|
|
|
1190
1228
|
@metadata.request(peer_required=True)
|
|
1191
1229
|
async def new_end_of_sub_slot_vdf(
|
|
1192
1230
|
self, request: timelord_protocol.NewEndOfSubSlotVDF, peer: WSChiaConnection
|
|
1193
|
-
) ->
|
|
1231
|
+
) -> Message | None:
|
|
1194
1232
|
if self.full_node.sync_store.get_sync_mode():
|
|
1195
1233
|
return None
|
|
1196
1234
|
if (
|
|
@@ -1212,19 +1250,19 @@ class FullNodeAPI:
|
|
|
1212
1250
|
return msg
|
|
1213
1251
|
|
|
1214
1252
|
@metadata.request()
|
|
1215
|
-
async def request_block_header(self, request: wallet_protocol.RequestBlockHeader) ->
|
|
1253
|
+
async def request_block_header(self, request: wallet_protocol.RequestBlockHeader) -> Message | None:
|
|
1216
1254
|
header_hash = self.full_node.blockchain.height_to_hash(request.height)
|
|
1217
1255
|
if header_hash is None:
|
|
1218
1256
|
msg = make_msg(ProtocolMessageTypes.reject_header_request, RejectHeaderRequest(request.height))
|
|
1219
1257
|
return msg
|
|
1220
|
-
block:
|
|
1258
|
+
block: FullBlock | None = await self.full_node.block_store.get_full_block(header_hash)
|
|
1221
1259
|
if block is None:
|
|
1222
1260
|
return None
|
|
1223
1261
|
|
|
1224
|
-
removals_and_additions:
|
|
1262
|
+
removals_and_additions: tuple[Collection[bytes32], Collection[Coin]] | None = None
|
|
1225
1263
|
|
|
1226
1264
|
if block.transactions_generator is not None:
|
|
1227
|
-
block_generator:
|
|
1265
|
+
block_generator: BlockGenerator | None = await get_block_generator(
|
|
1228
1266
|
self.full_node.blockchain.lookup_block_generators, block
|
|
1229
1267
|
)
|
|
1230
1268
|
# get_block_generator() returns None in case the block we specify
|
|
@@ -1232,8 +1270,7 @@ class FullNodeAPI:
|
|
|
1232
1270
|
# in this case we've already made sure `block` does have a
|
|
1233
1271
|
# transactions_generator, so the block_generator should always be set
|
|
1234
1272
|
assert block_generator is not None, "failed to get block_generator for tx-block"
|
|
1235
|
-
|
|
1236
|
-
flags = get_flags_for_height_and_constants(request.height, self.full_node.constants)
|
|
1273
|
+
flags = await get_flags(constants=self.full_node.constants, blocks=self.full_node.blockchain, block=block)
|
|
1237
1274
|
additions, removals = await asyncio.get_running_loop().run_in_executor(
|
|
1238
1275
|
self.executor,
|
|
1239
1276
|
additions_and_removals,
|
|
@@ -1257,9 +1294,9 @@ class FullNodeAPI:
|
|
|
1257
1294
|
return msg
|
|
1258
1295
|
|
|
1259
1296
|
@metadata.request()
|
|
1260
|
-
async def request_additions(self, request: wallet_protocol.RequestAdditions) ->
|
|
1297
|
+
async def request_additions(self, request: wallet_protocol.RequestAdditions) -> Message | None:
|
|
1261
1298
|
if request.header_hash is None:
|
|
1262
|
-
header_hash:
|
|
1299
|
+
header_hash: bytes32 | None = self.full_node.blockchain.height_to_hash(request.height)
|
|
1263
1300
|
else:
|
|
1264
1301
|
header_hash = request.header_hash
|
|
1265
1302
|
if header_hash is None:
|
|
@@ -1279,7 +1316,7 @@ class FullNodeAPI:
|
|
|
1279
1316
|
puzzlehash_coins_map[coin_record.coin.puzzle_hash] = [coin_record.coin]
|
|
1280
1317
|
|
|
1281
1318
|
coins_map: list[tuple[bytes32, list[Coin]]] = []
|
|
1282
|
-
proofs_map: list[tuple[bytes32, bytes,
|
|
1319
|
+
proofs_map: list[tuple[bytes32, bytes, bytes | None]] = []
|
|
1283
1320
|
|
|
1284
1321
|
if request.puzzle_hashes is None:
|
|
1285
1322
|
for puzzle_hash, coins in puzzlehash_coins_map.items():
|
|
@@ -1314,8 +1351,8 @@ class FullNodeAPI:
|
|
|
1314
1351
|
return make_msg(ProtocolMessageTypes.respond_additions, response)
|
|
1315
1352
|
|
|
1316
1353
|
@metadata.request()
|
|
1317
|
-
async def request_removals(self, request: wallet_protocol.RequestRemovals) ->
|
|
1318
|
-
block:
|
|
1354
|
+
async def request_removals(self, request: wallet_protocol.RequestRemovals) -> Message | None:
|
|
1355
|
+
block: FullBlock | None = await self.full_node.block_store.get_full_block(request.header_hash)
|
|
1319
1356
|
|
|
1320
1357
|
# We lock so that the coin store does not get modified
|
|
1321
1358
|
peak_height = self.full_node.blockchain.get_peak_height()
|
|
@@ -1342,12 +1379,12 @@ class FullNodeAPI:
|
|
|
1342
1379
|
for coin_record in all_removals:
|
|
1343
1380
|
all_removals_dict[coin_record.coin.name()] = coin_record.coin
|
|
1344
1381
|
|
|
1345
|
-
coins_map: list[tuple[bytes32,
|
|
1382
|
+
coins_map: list[tuple[bytes32, Coin | None]] = []
|
|
1346
1383
|
proofs_map: list[tuple[bytes32, bytes]] = []
|
|
1347
1384
|
|
|
1348
1385
|
# If there are no transactions, respond with empty lists
|
|
1349
1386
|
if block.transactions_generator is None:
|
|
1350
|
-
proofs:
|
|
1387
|
+
proofs: list[tuple[bytes32, bytes]] | None
|
|
1351
1388
|
if request.coin_names is None:
|
|
1352
1389
|
proofs = None
|
|
1353
1390
|
else:
|
|
@@ -1379,18 +1416,26 @@ class FullNodeAPI:
|
|
|
1379
1416
|
msg = make_msg(ProtocolMessageTypes.respond_removals, response)
|
|
1380
1417
|
return msg
|
|
1381
1418
|
|
|
1382
|
-
@metadata.request()
|
|
1419
|
+
@metadata.request(peer_required=True)
|
|
1383
1420
|
async def send_transaction(
|
|
1384
|
-
self, request: wallet_protocol.SendTransaction, *, test: bool = False
|
|
1385
|
-
) ->
|
|
1421
|
+
self, request: wallet_protocol.SendTransaction, peer: WSChiaConnection, *, test: bool = False
|
|
1422
|
+
) -> Message | None:
|
|
1386
1423
|
spend_name = request.transaction.name()
|
|
1387
1424
|
if self.full_node.mempool_manager.get_spendbundle(spend_name) is not None:
|
|
1388
1425
|
self.full_node.mempool_manager.remove_seen(spend_name)
|
|
1389
1426
|
response = wallet_protocol.TransactionAck(spend_name, uint8(MempoolInclusionStatus.SUCCESS), None)
|
|
1390
1427
|
return make_msg(ProtocolMessageTypes.transaction_ack, response)
|
|
1391
|
-
|
|
1428
|
+
high_priority = self.is_trusted(peer)
|
|
1392
1429
|
queue_entry = TransactionQueueEntry(request.transaction, None, spend_name, None, test)
|
|
1393
|
-
|
|
1430
|
+
try:
|
|
1431
|
+
self.full_node.transaction_queue.put(queue_entry, peer_id=peer.peer_node_id, high_priority=high_priority)
|
|
1432
|
+
except TransactionQueueFull:
|
|
1433
|
+
return make_msg(
|
|
1434
|
+
ProtocolMessageTypes.transaction_ack,
|
|
1435
|
+
wallet_protocol.TransactionAck(
|
|
1436
|
+
spend_name, uint8(MempoolInclusionStatus.FAILED), "Transaction queue full"
|
|
1437
|
+
),
|
|
1438
|
+
)
|
|
1394
1439
|
try:
|
|
1395
1440
|
with anyio.fail_after(delay=45):
|
|
1396
1441
|
status, error = await queue_entry.done.wait()
|
|
@@ -1408,7 +1453,7 @@ class FullNodeAPI:
|
|
|
1408
1453
|
return make_msg(ProtocolMessageTypes.transaction_ack, response)
|
|
1409
1454
|
|
|
1410
1455
|
@metadata.request()
|
|
1411
|
-
async def request_puzzle_solution(self, request: wallet_protocol.RequestPuzzleSolution) ->
|
|
1456
|
+
async def request_puzzle_solution(self, request: wallet_protocol.RequestPuzzleSolution) -> Message | None:
|
|
1412
1457
|
coin_name = request.coin_name
|
|
1413
1458
|
height = request.height
|
|
1414
1459
|
coin_record = await self.full_node.coin_store.get_coin_record(coin_name)
|
|
@@ -1417,16 +1462,16 @@ class FullNodeAPI:
|
|
|
1417
1462
|
if coin_record is None or coin_record.spent_block_index != height:
|
|
1418
1463
|
return reject_msg
|
|
1419
1464
|
|
|
1420
|
-
header_hash:
|
|
1465
|
+
header_hash: bytes32 | None = self.full_node.blockchain.height_to_hash(height)
|
|
1421
1466
|
if header_hash is None:
|
|
1422
1467
|
return reject_msg
|
|
1423
1468
|
|
|
1424
|
-
block:
|
|
1469
|
+
block: BlockInfo | None = await self.full_node.block_store.get_block_info(header_hash)
|
|
1425
1470
|
|
|
1426
1471
|
if block is None or block.transactions_generator is None:
|
|
1427
1472
|
return reject_msg
|
|
1428
1473
|
|
|
1429
|
-
block_generator:
|
|
1474
|
+
block_generator: BlockGenerator | None = await get_block_generator(
|
|
1430
1475
|
self.full_node.blockchain.lookup_block_generators, block
|
|
1431
1476
|
)
|
|
1432
1477
|
assert block_generator is not None
|
|
@@ -1448,7 +1493,7 @@ class FullNodeAPI:
|
|
|
1448
1493
|
return response_msg
|
|
1449
1494
|
|
|
1450
1495
|
@metadata.request()
|
|
1451
|
-
async def request_block_headers(self, request: wallet_protocol.RequestBlockHeaders) ->
|
|
1496
|
+
async def request_block_headers(self, request: wallet_protocol.RequestBlockHeaders) -> Message | None:
|
|
1452
1497
|
"""Returns header blocks by directly streaming bytes into Message
|
|
1453
1498
|
|
|
1454
1499
|
This method should be used instead of RequestHeaderBlocks
|
|
@@ -1501,7 +1546,7 @@ class FullNodeAPI:
|
|
|
1501
1546
|
return make_msg(ProtocolMessageTypes.respond_block_headers, respond_header_blocks_manually_streamed)
|
|
1502
1547
|
|
|
1503
1548
|
@metadata.request()
|
|
1504
|
-
async def request_header_blocks(self, request: wallet_protocol.RequestHeaderBlocks) ->
|
|
1549
|
+
async def request_header_blocks(self, request: wallet_protocol.RequestHeaderBlocks) -> Message | None:
|
|
1505
1550
|
"""DEPRECATED: please use RequestBlockHeaders"""
|
|
1506
1551
|
if (
|
|
1507
1552
|
request.end_height < request.start_height
|
|
@@ -1511,7 +1556,7 @@ class FullNodeAPI:
|
|
|
1511
1556
|
height_to_hash = self.full_node.blockchain.height_to_hash
|
|
1512
1557
|
header_hashes: list[bytes32] = []
|
|
1513
1558
|
for i in range(request.start_height, request.end_height + 1):
|
|
1514
|
-
header_hash:
|
|
1559
|
+
header_hash: bytes32 | None = height_to_hash(uint32(i))
|
|
1515
1560
|
if header_hash is None:
|
|
1516
1561
|
reject = RejectHeaderBlocks(request.start_height, request.end_height)
|
|
1517
1562
|
msg = make_msg(ProtocolMessageTypes.reject_header_blocks, reject)
|
|
@@ -1688,7 +1733,7 @@ class FullNodeAPI:
|
|
|
1688
1733
|
return msg
|
|
1689
1734
|
|
|
1690
1735
|
@metadata.request()
|
|
1691
|
-
async def request_children(self, request: wallet_protocol.RequestChildren) ->
|
|
1736
|
+
async def request_children(self, request: wallet_protocol.RequestChildren) -> Message | None:
|
|
1692
1737
|
coin_records: list[CoinRecord] = await self.full_node.coin_store.get_coin_records_by_parent_ids(
|
|
1693
1738
|
True, [request.coin_name]
|
|
1694
1739
|
)
|
|
@@ -1820,7 +1865,7 @@ class FullNodeAPI:
|
|
|
1820
1865
|
return msg
|
|
1821
1866
|
|
|
1822
1867
|
# Check if the request would exceed the subscription limit now.
|
|
1823
|
-
def check_subscription_limit() ->
|
|
1868
|
+
def check_subscription_limit() -> Message | None:
|
|
1824
1869
|
new_subscription_count = len(puzzle_hashes) + subs.peer_subscription_count(peer.peer_node_id)
|
|
1825
1870
|
|
|
1826
1871
|
if request.subscribe_when_finished and new_subscription_count > max_subscriptions:
|
|
@@ -1892,7 +1937,7 @@ class FullNodeAPI:
|
|
|
1892
1937
|
return msg
|
|
1893
1938
|
|
|
1894
1939
|
# Check if the request would exceed the subscription limit now.
|
|
1895
|
-
def check_subscription_limit() ->
|
|
1940
|
+
def check_subscription_limit() -> Message | None:
|
|
1896
1941
|
new_subscription_count = len(coin_ids) + subs.peer_subscription_count(peer.peer_node_id)
|
|
1897
1942
|
|
|
1898
1943
|
if request.subscribe and new_subscription_count > max_subscriptions:
|
|
@@ -1929,7 +1974,7 @@ class FullNodeAPI:
|
|
|
1929
1974
|
return msg
|
|
1930
1975
|
|
|
1931
1976
|
@metadata.request(reply_types=[ProtocolMessageTypes.respond_cost_info])
|
|
1932
|
-
async def request_cost_info(self, _request: wallet_protocol.RequestCostInfo) ->
|
|
1977
|
+
async def request_cost_info(self, _request: wallet_protocol.RequestCostInfo) -> Message | None:
|
|
1933
1978
|
mempool_manager = self.full_node.mempool_manager
|
|
1934
1979
|
response = wallet_protocol.RespondCostInfo(
|
|
1935
1980
|
max_transaction_cost=mempool_manager.max_tx_clvm_cost,
|