chia-blockchain 2.5.7rc4__py3-none-any.whl → 2.5.8rc1__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_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 +59 -30
- 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 +225 -62
- 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 +109 -25
- chia/_tests/core/mempool/test_mempool.py +29 -37
- 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 +963 -839
- 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 +8 -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 +43 -47
- 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 +4 -6
- 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 +14 -14
- 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 +372 -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 +16 -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 +42 -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 +238 -224
- chia/full_node/full_node_api.py +193 -150
- chia/full_node/full_node_rpc_api.py +53 -31
- chia/full_node/full_node_rpc_client.py +18 -19
- chia/full_node/full_node_store.py +45 -43
- 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 +34 -13
- 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 +3 -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 +22 -8
- 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 +120 -105
- 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.5.8rc1.dist-info}/METADATA +6 -5
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/RECORD +507 -516
- 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.5.8rc1.dist-info}/WHEEL +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/entry_points.txt +0 -0
- {chia_blockchain-2.5.7rc4.dist-info → chia_blockchain-2.5.8rc1.dist-info}/licenses/LICENSE +0 -0
chia/full_node/full_node.py
CHANGED
|
@@ -10,15 +10,16 @@ import random
|
|
|
10
10
|
import sqlite3
|
|
11
11
|
import time
|
|
12
12
|
import traceback
|
|
13
|
-
from collections.abc import AsyncIterator, Awaitable, Sequence
|
|
13
|
+
from collections.abc import AsyncIterator, Awaitable, Callable, Sequence
|
|
14
14
|
from multiprocessing.context import BaseContext
|
|
15
15
|
from pathlib import Path
|
|
16
|
-
from typing import TYPE_CHECKING, Any,
|
|
16
|
+
from typing import TYPE_CHECKING, Any, ClassVar, TextIO, cast, final
|
|
17
17
|
|
|
18
18
|
from chia_rs import (
|
|
19
19
|
AugSchemeMPL,
|
|
20
20
|
BlockRecord,
|
|
21
21
|
BLSCache,
|
|
22
|
+
CoinRecord,
|
|
22
23
|
CoinState,
|
|
23
24
|
ConsensusConstants,
|
|
24
25
|
EndOfSubSlotBundle,
|
|
@@ -61,7 +62,7 @@ from chia.full_node.mempool import MempoolRemoveInfo
|
|
|
61
62
|
from chia.full_node.mempool_manager import MempoolManager
|
|
62
63
|
from chia.full_node.subscriptions import PeerSubscriptions, peers_for_spend_bundle
|
|
63
64
|
from chia.full_node.sync_store import Peak, SyncStore
|
|
64
|
-
from chia.full_node.tx_processing_queue import TransactionQueue, TransactionQueueEntry
|
|
65
|
+
from chia.full_node.tx_processing_queue import PeerWithTx, TransactionQueue, TransactionQueueEntry
|
|
65
66
|
from chia.full_node.weight_proof import WeightProofHandler
|
|
66
67
|
from chia.protocols import farmer_protocol, full_node_protocol, timelord_protocol, wallet_protocol
|
|
67
68
|
from chia.protocols.farmer_protocol import SignagePointSourceData, SPSubSlotSourceData, SPVDFSourceData
|
|
@@ -77,7 +78,6 @@ from chia.server.server import ChiaServer
|
|
|
77
78
|
from chia.server.ws_connection import WSChiaConnection
|
|
78
79
|
from chia.types.blockchain_format.classgroup import ClassgroupElement
|
|
79
80
|
from chia.types.blockchain_format.vdf import CompressibleVDFField, VDFInfo, VDFProof, validate_vdf
|
|
80
|
-
from chia.types.coin_record import CoinRecord
|
|
81
81
|
from chia.types.mempool_inclusion_status import MempoolInclusionStatus
|
|
82
82
|
from chia.types.mempool_item import MempoolItem
|
|
83
83
|
from chia.types.peer_info import PeerInfo
|
|
@@ -106,7 +106,7 @@ class PeakPostProcessingResult:
|
|
|
106
106
|
fns_peak_result: FullNodeStorePeakResult # The result of calling FullNodeStore.new_peak
|
|
107
107
|
hints: list[tuple[bytes32, bytes]] # The hints added to the DB
|
|
108
108
|
lookup_coin_ids: list[bytes32] # The coin IDs that we need to look up to notify wallets of changes
|
|
109
|
-
signage_points: list[tuple[RespondSignagePoint, WSChiaConnection,
|
|
109
|
+
signage_points: list[tuple[RespondSignagePoint, WSChiaConnection, EndOfSubSlotBundle | None]]
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
@dataclasses.dataclass(frozen=True)
|
|
@@ -135,39 +135,39 @@ class FullNode:
|
|
|
135
135
|
wallet_sync_queue: asyncio.Queue[WalletUpdate]
|
|
136
136
|
_segment_task_list: list[asyncio.Task[None]] = dataclasses.field(default_factory=list)
|
|
137
137
|
initialized: bool = False
|
|
138
|
-
_server:
|
|
138
|
+
_server: ChiaServer | None = None
|
|
139
139
|
_shut_down: bool = False
|
|
140
140
|
pow_creation: dict[bytes32, asyncio.Event] = dataclasses.field(default_factory=dict)
|
|
141
|
-
state_changed_callback:
|
|
142
|
-
full_node_peers:
|
|
141
|
+
state_changed_callback: StateChangedProtocol | None = None
|
|
142
|
+
full_node_peers: FullNodePeers | None = None
|
|
143
143
|
sync_store: SyncStore = dataclasses.field(default_factory=SyncStore)
|
|
144
|
-
uncompact_task:
|
|
144
|
+
uncompact_task: asyncio.Task[None] | None = None
|
|
145
145
|
compact_vdf_requests: set[bytes32] = dataclasses.field(default_factory=set)
|
|
146
146
|
# TODO: Logging isn't setup yet so the log entries related to parsing the
|
|
147
147
|
# config would end up on stdout if handled here.
|
|
148
|
-
multiprocessing_context:
|
|
148
|
+
multiprocessing_context: BaseContext | None = None
|
|
149
149
|
_ui_tasks: set[asyncio.Task[None]] = dataclasses.field(default_factory=set)
|
|
150
150
|
subscriptions: PeerSubscriptions = dataclasses.field(default_factory=PeerSubscriptions)
|
|
151
|
-
_transaction_queue_task:
|
|
152
|
-
simulator_transaction_callback:
|
|
151
|
+
_transaction_queue_task: asyncio.Task[None] | None = None
|
|
152
|
+
simulator_transaction_callback: Callable[[bytes32], Awaitable[None]] | None = None
|
|
153
153
|
_sync_task_list: list[asyncio.Task[None]] = dataclasses.field(default_factory=list)
|
|
154
|
-
_transaction_queue:
|
|
154
|
+
_transaction_queue: TransactionQueue | None = None
|
|
155
155
|
_tx_task_list: list[asyncio.Task[None]] = dataclasses.field(default_factory=list)
|
|
156
|
-
_compact_vdf_sem:
|
|
157
|
-
_new_peak_sem:
|
|
158
|
-
_add_transaction_semaphore:
|
|
159
|
-
_db_wrapper:
|
|
160
|
-
_hint_store:
|
|
161
|
-
_block_store:
|
|
162
|
-
_coin_store:
|
|
163
|
-
_mempool_manager:
|
|
164
|
-
_init_weight_proof:
|
|
165
|
-
_blockchain:
|
|
166
|
-
_timelord_lock:
|
|
167
|
-
weight_proof_handler:
|
|
156
|
+
_compact_vdf_sem: LimitedSemaphore | None = None
|
|
157
|
+
_new_peak_sem: LimitedSemaphore | None = None
|
|
158
|
+
_add_transaction_semaphore: asyncio.Semaphore | None = None
|
|
159
|
+
_db_wrapper: DBWrapper2 | None = None
|
|
160
|
+
_hint_store: HintStore | None = None
|
|
161
|
+
_block_store: BlockStore | None = None
|
|
162
|
+
_coin_store: CoinStoreProtocol | None = None
|
|
163
|
+
_mempool_manager: MempoolManager | None = None
|
|
164
|
+
_init_weight_proof: asyncio.Task[None] | None = None
|
|
165
|
+
_blockchain: Blockchain | None = None
|
|
166
|
+
_timelord_lock: asyncio.Lock | None = None
|
|
167
|
+
weight_proof_handler: WeightProofHandler | None = None
|
|
168
168
|
# hashes of peaks that failed long sync on chip13 Validation
|
|
169
169
|
bad_peak_cache: dict[bytes32, uint32] = dataclasses.field(default_factory=dict)
|
|
170
|
-
wallet_sync_task:
|
|
170
|
+
wallet_sync_task: asyncio.Task[None] | None = None
|
|
171
171
|
_bls_cache: BLSCache = dataclasses.field(default_factory=lambda: BLSCache(50000))
|
|
172
172
|
|
|
173
173
|
@property
|
|
@@ -215,9 +215,9 @@ class FullNode:
|
|
|
215
215
|
# These many respond_transaction tasks can be active at any point in time
|
|
216
216
|
self._add_transaction_semaphore = asyncio.Semaphore(200)
|
|
217
217
|
|
|
218
|
-
sql_log_path:
|
|
218
|
+
sql_log_path: Path | None = None
|
|
219
219
|
with contextlib.ExitStack() as exit_stack:
|
|
220
|
-
sql_log_file:
|
|
220
|
+
sql_log_file: TextIO | None = None
|
|
221
221
|
if self.config.get("log_sqlite_cmds", False):
|
|
222
222
|
sql_log_path = path_from_root(self.root_path, "log/sql.log")
|
|
223
223
|
self.log.info(f"logging SQL commands to {sql_log_path}")
|
|
@@ -279,127 +279,123 @@ class FullNode:
|
|
|
279
279
|
log_coins=log_coins,
|
|
280
280
|
)
|
|
281
281
|
|
|
282
|
-
|
|
282
|
+
async with MempoolManager.managed(
|
|
283
283
|
get_coin_records=self.coin_store.get_coin_records,
|
|
284
284
|
get_unspent_lineage_info_for_puzzle_hash=self.coin_store.get_unspent_lineage_info_for_puzzle_hash,
|
|
285
285
|
consensus_constants=self.constants,
|
|
286
286
|
single_threaded=single_threaded,
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
f"time taken: {int(time_taken)}s"
|
|
323
|
-
)
|
|
324
|
-
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
325
|
-
pending_tx = await self.mempool_manager.new_peak(self.blockchain.get_tx_peak(), None)
|
|
326
|
-
# No pending transactions when starting up
|
|
327
|
-
assert len(pending_tx.spend_bundle_ids) == 0
|
|
328
|
-
|
|
329
|
-
full_peak: Optional[FullBlock] = await self.blockchain.get_full_peak()
|
|
330
|
-
assert full_peak is not None
|
|
331
|
-
state_change_summary = StateChangeSummary(peak, uint32(max(peak.height - 1, 0)), [], [], [], [])
|
|
332
|
-
# Must be called under priority_mutex
|
|
333
|
-
ppp_result: PeakPostProcessingResult = await self.peak_post_processing(
|
|
334
|
-
full_peak, state_change_summary, None
|
|
287
|
+
) as self._mempool_manager:
|
|
288
|
+
# Transactions go into this queue from the server, and get sent to respond_transaction
|
|
289
|
+
self._transaction_queue = TransactionQueue(1000, self.log)
|
|
290
|
+
self._transaction_queue_task: asyncio.Task[None] = create_referenced_task(self._handle_transactions())
|
|
291
|
+
|
|
292
|
+
self._init_weight_proof = create_referenced_task(self.initialize_weight_proof())
|
|
293
|
+
|
|
294
|
+
if self.config.get("enable_profiler", False):
|
|
295
|
+
create_referenced_task(profile_task(self.root_path, "node", self.log), known_unreferenced=True)
|
|
296
|
+
|
|
297
|
+
self.profile_block_validation = self.config.get("profile_block_validation", False)
|
|
298
|
+
if self.profile_block_validation: # pragma: no cover
|
|
299
|
+
# this is not covered by any unit tests as it's essentially test code
|
|
300
|
+
# itself. It's exercised manually when investigating performance issues
|
|
301
|
+
profile_dir = path_from_root(self.root_path, "block-validation-profile")
|
|
302
|
+
profile_dir.mkdir(parents=True, exist_ok=True)
|
|
303
|
+
|
|
304
|
+
if self.config.get("enable_memory_profiler", False):
|
|
305
|
+
create_referenced_task(mem_profile_task(self.root_path, "node", self.log), known_unreferenced=True)
|
|
306
|
+
|
|
307
|
+
time_taken = time.monotonic() - start_time
|
|
308
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
309
|
+
if peak is None:
|
|
310
|
+
self.log.info(f"Initialized with empty blockchain time taken: {int(time_taken)}s")
|
|
311
|
+
if not await self.coin_store.is_empty():
|
|
312
|
+
self.log.error(
|
|
313
|
+
"Inconsistent blockchain DB file! Could not find peak block but found some coins! "
|
|
314
|
+
"This is a fatal error. The blockchain database may be corrupt"
|
|
315
|
+
)
|
|
316
|
+
raise RuntimeError("corrupt blockchain DB")
|
|
317
|
+
else:
|
|
318
|
+
self.log.info(
|
|
319
|
+
f"Blockchain initialized to peak {peak.header_hash} height"
|
|
320
|
+
f" {peak.height}, "
|
|
321
|
+
f"time taken: {int(time_taken)}s"
|
|
335
322
|
)
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
self.
|
|
346
|
-
|
|
347
|
-
|
|
323
|
+
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
324
|
+
pending_tx = await self.mempool_manager.new_peak(self.blockchain.get_tx_peak(), None)
|
|
325
|
+
# No pending transactions when starting up
|
|
326
|
+
assert len(pending_tx.spend_bundle_ids) == 0
|
|
327
|
+
|
|
328
|
+
full_peak: FullBlock | None = await self.blockchain.get_full_peak()
|
|
329
|
+
assert full_peak is not None
|
|
330
|
+
state_change_summary = StateChangeSummary(peak, uint32(max(peak.height - 1, 0)), [], [], [], [])
|
|
331
|
+
# Must be called under priority_mutex
|
|
332
|
+
ppp_result: PeakPostProcessingResult = await self.peak_post_processing(
|
|
333
|
+
full_peak, state_change_summary, None
|
|
334
|
+
)
|
|
335
|
+
# Can be called outside of priority_mutex
|
|
336
|
+
await self.peak_post_processing_2(full_peak, None, state_change_summary, ppp_result)
|
|
337
|
+
if self.config["send_uncompact_interval"] != 0:
|
|
338
|
+
sanitize_weight_proof_only = False
|
|
339
|
+
if "sanitize_weight_proof_only" in self.config:
|
|
340
|
+
sanitize_weight_proof_only = self.config["sanitize_weight_proof_only"]
|
|
341
|
+
assert self.config["target_uncompact_proofs"] != 0
|
|
342
|
+
self.uncompact_task = create_referenced_task(
|
|
343
|
+
self.broadcast_uncompact_blocks(
|
|
344
|
+
self.config["send_uncompact_interval"],
|
|
345
|
+
self.config["target_uncompact_proofs"],
|
|
346
|
+
sanitize_weight_proof_only,
|
|
347
|
+
)
|
|
348
348
|
)
|
|
349
|
-
)
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
self.
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
self.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
cancel_task_safe(task
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
self.log.info(f"
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
with contextlib.suppress(asyncio.CancelledError):
|
|
400
|
-
self.log.info(f"Awaiting long sync task {one_sync_task.get_name()}")
|
|
401
|
-
await one_sync_task
|
|
402
|
-
await asyncio.gather(*self._segment_task_list, return_exceptions=True)
|
|
349
|
+
if self.wallet_sync_task is None or self.wallet_sync_task.done():
|
|
350
|
+
self.wallet_sync_task = create_referenced_task(self._wallets_sync_task_handler())
|
|
351
|
+
|
|
352
|
+
self.initialized = True
|
|
353
|
+
|
|
354
|
+
try:
|
|
355
|
+
async with contextlib.AsyncExitStack() as aexit_stack:
|
|
356
|
+
if self.full_node_peers is not None:
|
|
357
|
+
await aexit_stack.enter_async_context(self.full_node_peers.manage())
|
|
358
|
+
yield
|
|
359
|
+
finally:
|
|
360
|
+
self._shut_down = True
|
|
361
|
+
if self._init_weight_proof is not None:
|
|
362
|
+
self._init_weight_proof.cancel()
|
|
363
|
+
|
|
364
|
+
# blockchain is created in _start and in certain cases it may not exist here during _close
|
|
365
|
+
if self._blockchain is not None:
|
|
366
|
+
self.blockchain.shut_down()
|
|
367
|
+
if self.uncompact_task is not None:
|
|
368
|
+
self.uncompact_task.cancel()
|
|
369
|
+
if self._transaction_queue_task is not None:
|
|
370
|
+
self._transaction_queue_task.cancel()
|
|
371
|
+
cancel_task_safe(task=self.wallet_sync_task, log=self.log)
|
|
372
|
+
for one_tx_task in self._tx_task_list:
|
|
373
|
+
if not one_tx_task.done():
|
|
374
|
+
cancel_task_safe(task=one_tx_task, log=self.log)
|
|
375
|
+
for one_sync_task in self._sync_task_list:
|
|
376
|
+
if not one_sync_task.done():
|
|
377
|
+
cancel_task_safe(task=one_sync_task, log=self.log)
|
|
378
|
+
for segment_task in self._segment_task_list:
|
|
379
|
+
cancel_task_safe(segment_task, self.log)
|
|
380
|
+
for task_id, task in list(self.full_node_store.tx_fetch_tasks.items()):
|
|
381
|
+
cancel_task_safe(task, self.log)
|
|
382
|
+
if self._init_weight_proof is not None:
|
|
383
|
+
await asyncio.wait([self._init_weight_proof])
|
|
384
|
+
for one_tx_task in self._tx_task_list:
|
|
385
|
+
if one_tx_task.done():
|
|
386
|
+
self.log.info(f"TX task {one_tx_task.get_name()} done")
|
|
387
|
+
else:
|
|
388
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
389
|
+
self.log.info(f"Awaiting TX task {one_tx_task.get_name()}")
|
|
390
|
+
await one_tx_task
|
|
391
|
+
for one_sync_task in self._sync_task_list:
|
|
392
|
+
if one_sync_task.done():
|
|
393
|
+
self.log.info(f"Long sync task {one_sync_task.get_name()} done")
|
|
394
|
+
else:
|
|
395
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
396
|
+
self.log.info(f"Awaiting long sync task {one_sync_task.get_name()}")
|
|
397
|
+
await one_sync_task
|
|
398
|
+
await asyncio.gather(*self._segment_task_list, return_exceptions=True)
|
|
403
399
|
|
|
404
400
|
@property
|
|
405
401
|
def block_store(self) -> BlockStore:
|
|
@@ -456,7 +452,7 @@ class FullNode:
|
|
|
456
452
|
assert self._compact_vdf_sem is not None
|
|
457
453
|
return self._compact_vdf_sem
|
|
458
454
|
|
|
459
|
-
def get_connections(self, request_node_type:
|
|
455
|
+
def get_connections(self, request_node_type: NodeType | None) -> list[dict[str, Any]]:
|
|
460
456
|
connections = self.server.get_connections(request_node_type)
|
|
461
457
|
con_info: list[dict[str, Any]] = []
|
|
462
458
|
if self.sync_store is not None:
|
|
@@ -498,7 +494,9 @@ class FullNode:
|
|
|
498
494
|
async def _handle_one_transaction(self, entry: TransactionQueueEntry) -> None:
|
|
499
495
|
peer = entry.peer
|
|
500
496
|
try:
|
|
501
|
-
inc_status, err = await self.add_transaction(
|
|
497
|
+
inc_status, err = await self.add_transaction(
|
|
498
|
+
entry.transaction, entry.spend_name, peer, entry.test, entry.peers_with_tx
|
|
499
|
+
)
|
|
502
500
|
entry.done.set((inc_status, err))
|
|
503
501
|
except asyncio.CancelledError:
|
|
504
502
|
error_stack = traceback.format_exc()
|
|
@@ -572,7 +570,7 @@ class FullNode:
|
|
|
572
570
|
self.log.error(f"Exception in peer discovery: {e}")
|
|
573
571
|
self.log.error(f"Exception Stack: {error_stack}")
|
|
574
572
|
|
|
575
|
-
def _state_changed(self, change: str, change_data:
|
|
573
|
+
def _state_changed(self, change: str, change_data: dict[str, Any] | None = None) -> None:
|
|
576
574
|
if self.state_changed_callback is not None:
|
|
577
575
|
self.state_changed_callback(change, change_data)
|
|
578
576
|
|
|
@@ -639,7 +637,7 @@ class FullNode:
|
|
|
639
637
|
if not response:
|
|
640
638
|
raise ValueError(f"Error short batch syncing, invalid/no response for {height}-{end_height}")
|
|
641
639
|
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
642
|
-
state_change_summary:
|
|
640
|
+
state_change_summary: StateChangeSummary | None
|
|
643
641
|
prev_b = None
|
|
644
642
|
if response.blocks[0].height > 0:
|
|
645
643
|
prev_b = await self.blockchain.get_block_record_from_db(response.blocks[0].prev_header_hash)
|
|
@@ -656,7 +654,7 @@ class FullNode:
|
|
|
656
654
|
raise ValueError(f"Error short batch syncing, failed to validate blocks {height}-{end_height}")
|
|
657
655
|
if state_change_summary is not None:
|
|
658
656
|
try:
|
|
659
|
-
peak_fb:
|
|
657
|
+
peak_fb: FullBlock | None = await self.blockchain.get_full_peak()
|
|
660
658
|
assert peak_fb is not None
|
|
661
659
|
ppp_result: PeakPostProcessingResult = await self.peak_post_processing(
|
|
662
660
|
peak_fb,
|
|
@@ -697,7 +695,7 @@ class FullNode:
|
|
|
697
695
|
try:
|
|
698
696
|
self.sync_store.increment_backtrack_syncing(node_id=peer.peer_node_id)
|
|
699
697
|
|
|
700
|
-
unfinished_block:
|
|
698
|
+
unfinished_block: UnfinishedBlock | None = self.full_node_store.get_unfinished_block(target_unf_hash)
|
|
701
699
|
curr_height: int = target_height
|
|
702
700
|
found_fork_point = False
|
|
703
701
|
blocks = []
|
|
@@ -773,7 +771,7 @@ class FullNode:
|
|
|
773
771
|
return None
|
|
774
772
|
|
|
775
773
|
# Not interested in less heavy peaks
|
|
776
|
-
peak:
|
|
774
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
777
775
|
curr_peak_height = uint32(0) if peak is None else peak.height
|
|
778
776
|
if peak is not None and peak.weight > request.weight:
|
|
779
777
|
return None
|
|
@@ -785,7 +783,7 @@ class FullNode:
|
|
|
785
783
|
peak_peers: set[bytes32] = self.sync_store.get_peers_that_have_peak([target_peak.header_hash])
|
|
786
784
|
# Don't ask if we already know this peer has the peak
|
|
787
785
|
if peer.peer_node_id not in peak_peers:
|
|
788
|
-
target_peak_response:
|
|
786
|
+
target_peak_response: RespondBlock | None = await peer.call_api(
|
|
789
787
|
FullNodeAPI.request_block,
|
|
790
788
|
full_node_protocol.RequestBlock(target_peak.height, False),
|
|
791
789
|
timeout=10,
|
|
@@ -839,7 +837,7 @@ class FullNode:
|
|
|
839
837
|
self._sync_task_list.append(create_referenced_task(self._sync()))
|
|
840
838
|
|
|
841
839
|
async def send_peak_to_timelords(
|
|
842
|
-
self, peak_block:
|
|
840
|
+
self, peak_block: FullBlock | None = None, peer: WSChiaConnection | None = None
|
|
843
841
|
) -> None:
|
|
844
842
|
"""
|
|
845
843
|
Sends current peak to timelords
|
|
@@ -849,7 +847,7 @@ class FullNode:
|
|
|
849
847
|
if peak_block is not None:
|
|
850
848
|
peak = self.blockchain.block_record(peak_block.header_hash)
|
|
851
849
|
difficulty = self.blockchain.get_next_sub_slot_iters_and_difficulty(peak.header_hash, False)[1]
|
|
852
|
-
ses:
|
|
850
|
+
ses: SubEpochSummary | None = next_sub_epoch_summary(
|
|
853
851
|
self.constants,
|
|
854
852
|
self.blockchain,
|
|
855
853
|
peak.required_iters,
|
|
@@ -893,12 +891,12 @@ class FullNode:
|
|
|
893
891
|
else:
|
|
894
892
|
await self.server.send_to_specific([msg], peer.peer_node_id)
|
|
895
893
|
|
|
896
|
-
async def synced(self, block_is_current_at:
|
|
894
|
+
async def synced(self, block_is_current_at: uint64 | None = None) -> bool:
|
|
897
895
|
if block_is_current_at is None:
|
|
898
896
|
block_is_current_at = uint64(time.time() - 60 * 7)
|
|
899
897
|
if "simulator" in str(self.config.get("selected_network")):
|
|
900
898
|
return True # sim is always synced because it has no peers
|
|
901
|
-
curr:
|
|
899
|
+
curr: BlockRecord | None = self.blockchain.get_peak()
|
|
902
900
|
if curr is None:
|
|
903
901
|
return False
|
|
904
902
|
|
|
@@ -941,7 +939,7 @@ class FullNode:
|
|
|
941
939
|
msg = make_msg(ProtocolMessageTypes.request_mempool_transactions, mempool_request)
|
|
942
940
|
await connection.send_message(msg)
|
|
943
941
|
|
|
944
|
-
peak_full:
|
|
942
|
+
peak_full: FullBlock | None = await self.blockchain.get_full_peak()
|
|
945
943
|
|
|
946
944
|
if peak_full is not None:
|
|
947
945
|
peak: BlockRecord = self.blockchain.block_record(peak_full.header_hash)
|
|
@@ -987,7 +985,7 @@ class FullNode:
|
|
|
987
985
|
- Disconnect peers that provide invalid blocks or don't have the blocks
|
|
988
986
|
"""
|
|
989
987
|
# Ensure we are only syncing once and not double calling this method
|
|
990
|
-
fork_point:
|
|
988
|
+
fork_point: uint32 | None = None
|
|
991
989
|
if self.sync_store.get_sync_mode():
|
|
992
990
|
return None
|
|
993
991
|
|
|
@@ -1087,7 +1085,7 @@ class FullNode:
|
|
|
1087
1085
|
self.log.info(
|
|
1088
1086
|
f"Requesting weight proof from peer {weight_proof_peer.peer_info.host} up to height {peak_height}"
|
|
1089
1087
|
)
|
|
1090
|
-
cur_peak:
|
|
1088
|
+
cur_peak: BlockRecord | None = self.blockchain.get_peak()
|
|
1091
1089
|
if cur_peak is not None and peak_weight <= cur_peak.weight:
|
|
1092
1090
|
raise ValueError("Not performing sync, already caught up.")
|
|
1093
1091
|
wp_timeout = 360
|
|
@@ -1187,7 +1185,7 @@ class FullNode:
|
|
|
1187
1185
|
blockchain = AugmentedBlockchain(self.blockchain)
|
|
1188
1186
|
peers_with_peak: list[WSChiaConnection] = self.get_peers_with_peak(peak_hash)
|
|
1189
1187
|
|
|
1190
|
-
async def fetch_blocks(output_queue: asyncio.Queue[
|
|
1188
|
+
async def fetch_blocks(output_queue: asyncio.Queue[tuple[WSChiaConnection, list[FullBlock]] | None]) -> None:
|
|
1191
1189
|
# the rate limit for respond_blocks is 100 messages / 60 seconds.
|
|
1192
1190
|
# But the limit is scaled to 30% for outbound messages, so that's 30
|
|
1193
1191
|
# messages per 60 seconds.
|
|
@@ -1294,11 +1292,9 @@ class FullNode:
|
|
|
1294
1292
|
await output_queue.put(None)
|
|
1295
1293
|
|
|
1296
1294
|
async def validate_blocks(
|
|
1297
|
-
input_queue: asyncio.Queue[
|
|
1295
|
+
input_queue: asyncio.Queue[tuple[WSChiaConnection, list[FullBlock]] | None],
|
|
1298
1296
|
output_queue: asyncio.Queue[
|
|
1299
|
-
|
|
1300
|
-
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]]
|
|
1301
|
-
]
|
|
1297
|
+
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]] | None
|
|
1302
1298
|
],
|
|
1303
1299
|
) -> None:
|
|
1304
1300
|
nonlocal blockchain
|
|
@@ -1309,7 +1305,7 @@ class FullNode:
|
|
|
1309
1305
|
|
|
1310
1306
|
try:
|
|
1311
1307
|
while True:
|
|
1312
|
-
res:
|
|
1308
|
+
res: tuple[WSChiaConnection, list[FullBlock]] | None = await input_queue.get()
|
|
1313
1309
|
if res is None:
|
|
1314
1310
|
self.log.debug("done fetching blocks")
|
|
1315
1311
|
return None
|
|
@@ -1351,9 +1347,7 @@ class FullNode:
|
|
|
1351
1347
|
|
|
1352
1348
|
async def ingest_blocks(
|
|
1353
1349
|
input_queue: asyncio.Queue[
|
|
1354
|
-
|
|
1355
|
-
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]]
|
|
1356
|
-
]
|
|
1350
|
+
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]] | None
|
|
1357
1351
|
],
|
|
1358
1352
|
) -> None:
|
|
1359
1353
|
nonlocal fork_info
|
|
@@ -1396,7 +1390,7 @@ class FullNode:
|
|
|
1396
1390
|
f"Added blocks {start_height} to {end_height} "
|
|
1397
1391
|
f"({block_rate:.3g} blocks/s) (from: {peer.peer_info.ip})"
|
|
1398
1392
|
)
|
|
1399
|
-
peak:
|
|
1393
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
1400
1394
|
if state_change_summary is not None:
|
|
1401
1395
|
assert peak is not None
|
|
1402
1396
|
# Hints must be added to the DB. The other post-processing tasks are not required when syncing
|
|
@@ -1413,9 +1407,9 @@ class FullNode:
|
|
|
1413
1407
|
# height, in that case.
|
|
1414
1408
|
self.blockchain.clean_block_record(end_height - self.constants.BLOCKS_CACHE_SIZE)
|
|
1415
1409
|
|
|
1416
|
-
block_queue: asyncio.Queue[
|
|
1410
|
+
block_queue: asyncio.Queue[tuple[WSChiaConnection, list[FullBlock]] | None] = asyncio.Queue(maxsize=10)
|
|
1417
1411
|
validation_queue: asyncio.Queue[
|
|
1418
|
-
|
|
1412
|
+
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]] | None
|
|
1419
1413
|
] = asyncio.Queue(maxsize=10)
|
|
1420
1414
|
|
|
1421
1415
|
fetch_task = create_referenced_task(fetch_blocks(block_queue))
|
|
@@ -1501,8 +1495,8 @@ class FullNode:
|
|
|
1501
1495
|
fork_info: ForkInfo,
|
|
1502
1496
|
vs: ValidationState, # in-out parameter
|
|
1503
1497
|
blockchain: AugmentedBlockchain,
|
|
1504
|
-
wp_summaries:
|
|
1505
|
-
) -> tuple[bool,
|
|
1498
|
+
wp_summaries: list[SubEpochSummary] | None = None,
|
|
1499
|
+
) -> tuple[bool, StateChangeSummary | None]:
|
|
1506
1500
|
# Precondition: All blocks must be contiguous blocks, index i+1 must be the parent of index i
|
|
1507
1501
|
# Returns a bool for success, as well as a StateChangeSummary if the peak was advanced
|
|
1508
1502
|
|
|
@@ -1584,7 +1578,7 @@ class FullNode:
|
|
|
1584
1578
|
blockchain: AugmentedBlockchain,
|
|
1585
1579
|
blocks_to_validate: list[FullBlock],
|
|
1586
1580
|
vs: ValidationState,
|
|
1587
|
-
wp_summaries:
|
|
1581
|
+
wp_summaries: list[SubEpochSummary] | None = None,
|
|
1588
1582
|
) -> Sequence[Awaitable[PreValidationResult]]:
|
|
1589
1583
|
"""
|
|
1590
1584
|
This is a thin wrapper over pre_validate_block().
|
|
@@ -1625,15 +1619,15 @@ class FullNode:
|
|
|
1625
1619
|
fork_info: ForkInfo,
|
|
1626
1620
|
peer_info: PeerInfo,
|
|
1627
1621
|
vs: ValidationState, # in-out parameter
|
|
1628
|
-
) -> tuple[
|
|
1629
|
-
agg_state_change_summary:
|
|
1622
|
+
) -> tuple[StateChangeSummary | None, Err | None]:
|
|
1623
|
+
agg_state_change_summary: StateChangeSummary | None = None
|
|
1630
1624
|
block_record = await self.blockchain.get_block_record_from_db(blocks_to_validate[0].prev_header_hash)
|
|
1631
1625
|
for i, block in enumerate(blocks_to_validate):
|
|
1632
1626
|
header_hash = block.header_hash
|
|
1633
1627
|
assert vs.prev_ses_block is None or vs.prev_ses_block.height < block.height
|
|
1634
1628
|
assert pre_validation_results[i].error is None
|
|
1635
1629
|
assert pre_validation_results[i].required_iters is not None
|
|
1636
|
-
state_change_summary:
|
|
1630
|
+
state_change_summary: StateChangeSummary | None
|
|
1637
1631
|
# when adding blocks in batches, we won't have any overlapping
|
|
1638
1632
|
# signatures with the mempool. There won't be any cache hits, so
|
|
1639
1633
|
# there's no need to pass the BLS cache in
|
|
@@ -1696,8 +1690,8 @@ class FullNode:
|
|
|
1696
1690
|
return agg_state_change_summary, None
|
|
1697
1691
|
|
|
1698
1692
|
async def get_sub_slot_iters_difficulty_ses_block(
|
|
1699
|
-
self, block: FullBlock, ssi:
|
|
1700
|
-
) -> tuple[uint64, uint64,
|
|
1693
|
+
self, block: FullBlock, ssi: uint64 | None, diff: uint64 | None
|
|
1694
|
+
) -> tuple[uint64, uint64, BlockRecord | None]:
|
|
1701
1695
|
prev_ses_block = None
|
|
1702
1696
|
if ssi is None or diff is None:
|
|
1703
1697
|
if block.height == 0:
|
|
@@ -1734,7 +1728,7 @@ class FullNode:
|
|
|
1734
1728
|
assert diff is not None
|
|
1735
1729
|
return ssi, diff, prev_ses_block
|
|
1736
1730
|
|
|
1737
|
-
async def _finish_sync(self, fork_point:
|
|
1731
|
+
async def _finish_sync(self, fork_point: uint32 | None) -> None:
|
|
1738
1732
|
"""
|
|
1739
1733
|
Finalize sync by setting sync mode to False, clearing all sync information, and adding any final
|
|
1740
1734
|
blocks that we have finalized recently.
|
|
@@ -1747,8 +1741,8 @@ class FullNode:
|
|
|
1747
1741
|
return None
|
|
1748
1742
|
|
|
1749
1743
|
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
1750
|
-
peak:
|
|
1751
|
-
peak_fb:
|
|
1744
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
1745
|
+
peak_fb: FullBlock | None = await self.blockchain.get_full_peak()
|
|
1752
1746
|
if peak_fb is not None:
|
|
1753
1747
|
if fork_point is None:
|
|
1754
1748
|
fork_point = uint32(max(peak_fb.height - 1, 0))
|
|
@@ -1766,7 +1760,7 @@ class FullNode:
|
|
|
1766
1760
|
await self.weight_proof_handler.get_proof_of_weight(peak.header_hash)
|
|
1767
1761
|
self._state_changed("block")
|
|
1768
1762
|
|
|
1769
|
-
def has_valid_pool_sig(self, block:
|
|
1763
|
+
def has_valid_pool_sig(self, block: UnfinishedBlock | FullBlock) -> bool:
|
|
1770
1764
|
if (
|
|
1771
1765
|
block.foliage.foliage_block_data.pool_target
|
|
1772
1766
|
== PoolTarget(self.constants.GENESIS_PRE_FARM_POOL_PUZZLE_HASH, uint32(0))
|
|
@@ -1786,7 +1780,7 @@ class FullNode:
|
|
|
1786
1780
|
self,
|
|
1787
1781
|
request: full_node_protocol.RespondSignagePoint,
|
|
1788
1782
|
peer: WSChiaConnection,
|
|
1789
|
-
ip_sub_slot:
|
|
1783
|
+
ip_sub_slot: EndOfSubSlotBundle | None,
|
|
1790
1784
|
) -> None:
|
|
1791
1785
|
self.log.info(
|
|
1792
1786
|
f"⏲️ Finished signage point {request.index_from_challenge}/"
|
|
@@ -1796,7 +1790,7 @@ class FullNode:
|
|
|
1796
1790
|
)
|
|
1797
1791
|
self.signage_point_times[request.index_from_challenge] = time.time()
|
|
1798
1792
|
sub_slot_tuple = self.full_node_store.get_sub_slot(request.challenge_chain_vdf.challenge)
|
|
1799
|
-
prev_challenge:
|
|
1793
|
+
prev_challenge: bytes32 | None
|
|
1800
1794
|
if sub_slot_tuple is not None:
|
|
1801
1795
|
prev_challenge = sub_slot_tuple[0].challenge_chain.challenge_chain_end_of_slot_vdf.challenge
|
|
1802
1796
|
else:
|
|
@@ -1850,7 +1844,7 @@ class FullNode:
|
|
|
1850
1844
|
self,
|
|
1851
1845
|
block: FullBlock,
|
|
1852
1846
|
state_change_summary: StateChangeSummary,
|
|
1853
|
-
peer:
|
|
1847
|
+
peer: WSChiaConnection | None,
|
|
1854
1848
|
) -> PeakPostProcessingResult:
|
|
1855
1849
|
"""
|
|
1856
1850
|
Must be called under self.blockchain.priority_mutex. This updates the internal state of the full node with the
|
|
@@ -1889,10 +1883,10 @@ class FullNode:
|
|
|
1889
1883
|
if not self.sync_store.get_sync_mode():
|
|
1890
1884
|
self.blockchain.clean_block_records()
|
|
1891
1885
|
|
|
1892
|
-
fork_block:
|
|
1886
|
+
fork_block: BlockRecord | None = None
|
|
1893
1887
|
if state_change_summary.fork_height != block.height - 1 and block.height != 0:
|
|
1894
1888
|
# This is a reorg
|
|
1895
|
-
fork_hash:
|
|
1889
|
+
fork_hash: bytes32 | None = self.blockchain.height_to_hash(state_change_summary.fork_height)
|
|
1896
1890
|
assert fork_hash is not None
|
|
1897
1891
|
fork_block = await self.blockchain.get_block_record_from_db(fork_hash)
|
|
1898
1892
|
|
|
@@ -1907,7 +1901,7 @@ class FullNode:
|
|
|
1907
1901
|
difficulty,
|
|
1908
1902
|
)
|
|
1909
1903
|
|
|
1910
|
-
signage_points: list[tuple[RespondSignagePoint, WSChiaConnection,
|
|
1904
|
+
signage_points: list[tuple[RespondSignagePoint, WSChiaConnection, EndOfSubSlotBundle | None]] = []
|
|
1911
1905
|
if fns_peak_result.new_signage_points is not None and peer is not None:
|
|
1912
1906
|
for index, sp in fns_peak_result.new_signage_points:
|
|
1913
1907
|
assert (
|
|
@@ -1958,7 +1952,7 @@ class FullNode:
|
|
|
1958
1952
|
async def peak_post_processing_2(
|
|
1959
1953
|
self,
|
|
1960
1954
|
block: FullBlock,
|
|
1961
|
-
peer:
|
|
1955
|
+
peer: WSChiaConnection | None,
|
|
1962
1956
|
state_change_summary: StateChangeSummary,
|
|
1963
1957
|
ppp_result: PeakPostProcessingResult,
|
|
1964
1958
|
) -> None:
|
|
@@ -2037,11 +2031,11 @@ class FullNode:
|
|
|
2037
2031
|
async def add_block(
|
|
2038
2032
|
self,
|
|
2039
2033
|
block: FullBlock,
|
|
2040
|
-
peer:
|
|
2041
|
-
bls_cache:
|
|
2034
|
+
peer: WSChiaConnection | None = None,
|
|
2035
|
+
bls_cache: BLSCache | None = None,
|
|
2042
2036
|
raise_on_disconnected: bool = False,
|
|
2043
|
-
fork_info:
|
|
2044
|
-
) ->
|
|
2037
|
+
fork_info: ForkInfo | None = None,
|
|
2038
|
+
) -> Message | None:
|
|
2045
2039
|
"""
|
|
2046
2040
|
Add a full block from a peer full node (or ourselves).
|
|
2047
2041
|
"""
|
|
@@ -2055,7 +2049,7 @@ class FullNode:
|
|
|
2055
2049
|
await self.blockchain.run_single_block(block, fork_info)
|
|
2056
2050
|
return None
|
|
2057
2051
|
|
|
2058
|
-
pre_validation_result:
|
|
2052
|
+
pre_validation_result: PreValidationResult | None = None
|
|
2059
2053
|
if (
|
|
2060
2054
|
block.is_transaction_block()
|
|
2061
2055
|
and block.transactions_info is not None
|
|
@@ -2065,9 +2059,9 @@ class FullNode:
|
|
|
2065
2059
|
# This is the case where we already had the unfinished block, and asked for this block without
|
|
2066
2060
|
# the transactions (since we already had them). Therefore, here we add the transactions.
|
|
2067
2061
|
unfinished_rh: bytes32 = block.reward_chain_block.get_unfinished().get_hash()
|
|
2068
|
-
foliage_hash:
|
|
2062
|
+
foliage_hash: bytes32 | None = block.foliage.foliage_transaction_block_hash
|
|
2069
2063
|
assert foliage_hash is not None
|
|
2070
|
-
unf_entry:
|
|
2064
|
+
unf_entry: UnfinishedBlockEntry | None = self.full_node_store.get_unfinished_block_result(
|
|
2071
2065
|
unfinished_rh, foliage_hash
|
|
2072
2066
|
)
|
|
2073
2067
|
assert unf_entry is None or unf_entry.result is None or unf_entry.result.validated_signature is True
|
|
@@ -2094,7 +2088,7 @@ class FullNode:
|
|
|
2094
2088
|
if peer is None:
|
|
2095
2089
|
return None
|
|
2096
2090
|
|
|
2097
|
-
block_response:
|
|
2091
|
+
block_response: Any | None = await peer.call_api(
|
|
2098
2092
|
FullNodeAPI.request_block, full_node_protocol.RequestBlock(block.height, True)
|
|
2099
2093
|
)
|
|
2100
2094
|
if block_response is None or not isinstance(block_response, full_node_protocol.RespondBlock):
|
|
@@ -2117,8 +2111,8 @@ class FullNode:
|
|
|
2117
2111
|
)
|
|
2118
2112
|
# This recursion ends here, we cannot recurse again because transactions_generator is not None
|
|
2119
2113
|
return await self.add_block(new_block, peer, bls_cache)
|
|
2120
|
-
state_change_summary:
|
|
2121
|
-
ppp_result:
|
|
2114
|
+
state_change_summary: StateChangeSummary | None = None
|
|
2115
|
+
ppp_result: PeakPostProcessingResult | None = None
|
|
2122
2116
|
async with (
|
|
2123
2117
|
self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high),
|
|
2124
2118
|
enable_profiler(self.profile_block_validation) as pr,
|
|
@@ -2156,14 +2150,14 @@ class FullNode:
|
|
|
2156
2150
|
ValidationState(ssi, diff, prev_ses_block),
|
|
2157
2151
|
)
|
|
2158
2152
|
pre_validation_result = await future
|
|
2159
|
-
added:
|
|
2153
|
+
added: AddBlockResult | None = None
|
|
2160
2154
|
add_block_start = time.monotonic()
|
|
2161
2155
|
pre_validation_time = add_block_start - validation_start
|
|
2162
2156
|
try:
|
|
2163
2157
|
if pre_validation_result.error is not None:
|
|
2164
2158
|
if Err(pre_validation_result.error) == Err.INVALID_PREV_BLOCK_HASH:
|
|
2165
2159
|
added = AddBlockResult.DISCONNECTED_BLOCK
|
|
2166
|
-
error_code:
|
|
2160
|
+
error_code: Err | None = Err.INVALID_PREV_BLOCK_HASH
|
|
2167
2161
|
elif Err(pre_validation_result.error) == Err.TIMESTAMP_TOO_FAR_IN_FUTURE:
|
|
2168
2162
|
raise TimestampError
|
|
2169
2163
|
else:
|
|
@@ -2267,8 +2261,8 @@ class FullNode:
|
|
|
2267
2261
|
|
|
2268
2262
|
state_changed_data: dict[str, Any] = {
|
|
2269
2263
|
"transaction_block": False,
|
|
2270
|
-
"k_size": block.reward_chain_block.proof_of_space.
|
|
2271
|
-
"
|
|
2264
|
+
"k_size": block.reward_chain_block.proof_of_space.param().size_v1,
|
|
2265
|
+
"strength": block.reward_chain_block.proof_of_space.param().strength_v2,
|
|
2272
2266
|
"header_hash": block.header_hash,
|
|
2273
2267
|
"fork_height": None,
|
|
2274
2268
|
"rolled_back_records": None,
|
|
@@ -2311,7 +2305,7 @@ class FullNode:
|
|
|
2311
2305
|
async def add_unfinished_block(
|
|
2312
2306
|
self,
|
|
2313
2307
|
block: UnfinishedBlock,
|
|
2314
|
-
peer:
|
|
2308
|
+
peer: WSChiaConnection | None,
|
|
2315
2309
|
farmed_block: bool = False,
|
|
2316
2310
|
) -> None:
|
|
2317
2311
|
"""
|
|
@@ -2344,7 +2338,7 @@ class FullNode:
|
|
|
2344
2338
|
if self.full_node_store.get_unfinished_block2(block_hash, foliage_tx_hash)[0] is not None:
|
|
2345
2339
|
return None
|
|
2346
2340
|
|
|
2347
|
-
peak:
|
|
2341
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
2348
2342
|
if peak is not None:
|
|
2349
2343
|
if block.total_iters < peak.sp_total_iters(self.constants):
|
|
2350
2344
|
# This means this unfinished block is pretty far behind, it will not add weight to our chain
|
|
@@ -2372,7 +2366,7 @@ class FullNode:
|
|
|
2372
2366
|
|
|
2373
2367
|
# The clvm generator and aggregate signature are validated outside of the lock, to allow other blocks and
|
|
2374
2368
|
# transactions to get validated
|
|
2375
|
-
npc_result:
|
|
2369
|
+
npc_result: NPCResult | None = None
|
|
2376
2370
|
pre_validation_time = None
|
|
2377
2371
|
|
|
2378
2372
|
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
@@ -2450,7 +2444,7 @@ class FullNode:
|
|
|
2450
2444
|
else:
|
|
2451
2445
|
height = uint32(self.blockchain.block_record(block.prev_header_hash).height + 1)
|
|
2452
2446
|
|
|
2453
|
-
ses:
|
|
2447
|
+
ses: SubEpochSummary | None = next_sub_epoch_summary(
|
|
2454
2448
|
self.constants,
|
|
2455
2449
|
self.blockchain,
|
|
2456
2450
|
validate_result.required_iters,
|
|
@@ -2542,7 +2536,7 @@ class FullNode:
|
|
|
2542
2536
|
# don't send this to peers with old clients
|
|
2543
2537
|
return conn.protocol_version > Version("0.0.35")
|
|
2544
2538
|
|
|
2545
|
-
peer_id:
|
|
2539
|
+
peer_id: bytes32 | None = None if peer is None else peer.peer_node_id
|
|
2546
2540
|
await self.server.send_to_all_if([msg], NodeType.FULL_NODE, old_clients, peer_id)
|
|
2547
2541
|
await self.server.send_to_all_if([msg2], NodeType.FULL_NODE, new_clients, peer_id)
|
|
2548
2542
|
|
|
@@ -2557,10 +2551,10 @@ class FullNode:
|
|
|
2557
2551
|
)
|
|
2558
2552
|
|
|
2559
2553
|
async def new_infusion_point_vdf(
|
|
2560
|
-
self, request: timelord_protocol.NewInfusionPointVDF, timelord_peer:
|
|
2561
|
-
) ->
|
|
2554
|
+
self, request: timelord_protocol.NewInfusionPointVDF, timelord_peer: WSChiaConnection | None = None
|
|
2555
|
+
) -> Message | None:
|
|
2562
2556
|
# Lookup unfinished blocks
|
|
2563
|
-
unfinished_block:
|
|
2557
|
+
unfinished_block: UnfinishedBlock | None = self.full_node_store.get_unfinished_block(
|
|
2564
2558
|
request.unfinished_reward_hash
|
|
2565
2559
|
)
|
|
2566
2560
|
|
|
@@ -2570,7 +2564,7 @@ class FullNode:
|
|
|
2570
2564
|
)
|
|
2571
2565
|
return None
|
|
2572
2566
|
|
|
2573
|
-
prev_b:
|
|
2567
|
+
prev_b: BlockRecord | None = None
|
|
2574
2568
|
|
|
2575
2569
|
target_rc_hash = request.reward_chain_ip_vdf.challenge
|
|
2576
2570
|
last_slot_cc_hash = request.challenge_chain_ip_vdf.challenge
|
|
@@ -2584,7 +2578,7 @@ class FullNode:
|
|
|
2584
2578
|
else:
|
|
2585
2579
|
# Find the prev block, starts looking backwards from the peak. target_rc_hash must be the hash of a block
|
|
2586
2580
|
# and not an end of slot (since we just looked through the slots and backtracked)
|
|
2587
|
-
curr:
|
|
2581
|
+
curr: BlockRecord | None = self.blockchain.get_peak()
|
|
2588
2582
|
|
|
2589
2583
|
for _ in range(10):
|
|
2590
2584
|
if curr is None:
|
|
@@ -2603,7 +2597,7 @@ class FullNode:
|
|
|
2603
2597
|
)
|
|
2604
2598
|
return None
|
|
2605
2599
|
|
|
2606
|
-
finished_sub_slots:
|
|
2600
|
+
finished_sub_slots: list[EndOfSubSlotBundle] | None = self.full_node_store.get_finished_sub_slots(
|
|
2607
2601
|
self.blockchain,
|
|
2608
2602
|
prev_b,
|
|
2609
2603
|
last_slot_cc_hash,
|
|
@@ -2663,7 +2657,7 @@ class FullNode:
|
|
|
2663
2657
|
|
|
2664
2658
|
async def add_end_of_sub_slot(
|
|
2665
2659
|
self, end_of_slot_bundle: EndOfSubSlotBundle, peer: WSChiaConnection
|
|
2666
|
-
) -> tuple[
|
|
2660
|
+
) -> tuple[Message | None, bool]:
|
|
2667
2661
|
fetched_ss = self.full_node_store.get_sub_slot(end_of_slot_bundle.challenge_chain.get_hash())
|
|
2668
2662
|
|
|
2669
2663
|
# We are not interested in sub-slots which have the same challenge chain but different reward chain. If there
|
|
@@ -2761,8 +2755,15 @@ class FullNode:
|
|
|
2761
2755
|
return None, False
|
|
2762
2756
|
|
|
2763
2757
|
async def add_transaction(
|
|
2764
|
-
self,
|
|
2765
|
-
|
|
2758
|
+
self,
|
|
2759
|
+
transaction: SpendBundle,
|
|
2760
|
+
spend_name: bytes32,
|
|
2761
|
+
peer: WSChiaConnection | None = None,
|
|
2762
|
+
test: bool = False,
|
|
2763
|
+
# Map of peer ID to its hostname, the fee and the cost it advertised
|
|
2764
|
+
# for this transaction.
|
|
2765
|
+
peers_with_tx: dict[bytes32, PeerWithTx] = {},
|
|
2766
|
+
) -> tuple[MempoolInclusionStatus, Err | None]:
|
|
2766
2767
|
if self.sync_store.get_sync_mode():
|
|
2767
2768
|
return MempoolInclusionStatus.FAILED, Err.NO_TRANSACTIONS_WHILE_SYNCING
|
|
2768
2769
|
if not test and not (await self.synced()):
|
|
@@ -2810,10 +2811,25 @@ class FullNode:
|
|
|
2810
2811
|
f"{self.mempool_manager.mempool.total_mempool_cost() / 5000000}"
|
|
2811
2812
|
)
|
|
2812
2813
|
|
|
2813
|
-
# Only broadcast successful transactions, not pending ones. Otherwise it's a DOS
|
|
2814
|
-
# vector.
|
|
2815
2814
|
mempool_item = self.mempool_manager.get_mempool_item(spend_name)
|
|
2816
2815
|
assert mempool_item is not None
|
|
2816
|
+
# Now that we validated this transaction, check what fees and
|
|
2817
|
+
# costs the peers have advertised for it.
|
|
2818
|
+
for peer_id, entry in peers_with_tx.items():
|
|
2819
|
+
if entry.advertised_fee == mempool_item.fee and entry.advertised_cost == mempool_item.cost:
|
|
2820
|
+
continue
|
|
2821
|
+
self.log.warning(
|
|
2822
|
+
f"Banning peer {peer_id}. Sent us a new tx {spend_name} with mismatch "
|
|
2823
|
+
f"on cost {entry.advertised_cost} vs validation cost {mempool_item.cost} and/or "
|
|
2824
|
+
f"fee {entry.advertised_fee} vs {mempool_item.fee}."
|
|
2825
|
+
)
|
|
2826
|
+
peer = self.server.all_connections.get(peer_id)
|
|
2827
|
+
if peer is None:
|
|
2828
|
+
self.server.ban_peer(entry.peer_host, CONSENSUS_ERROR_BAN_SECONDS)
|
|
2829
|
+
else:
|
|
2830
|
+
await peer.close(CONSENSUS_ERROR_BAN_SECONDS)
|
|
2831
|
+
# Only broadcast successful transactions, not pending ones. Otherwise it's a DOS
|
|
2832
|
+
# vector.
|
|
2817
2833
|
await self.broadcast_removed_tx(info.removals)
|
|
2818
2834
|
await self.broadcast_added_tx(mempool_item, current_peer=peer)
|
|
2819
2835
|
|
|
@@ -2825,9 +2841,7 @@ class FullNode:
|
|
|
2825
2841
|
self.log.debug(f"Wasn't able to add transaction with id {spend_name}, status {status} error: {error}")
|
|
2826
2842
|
return status, error
|
|
2827
2843
|
|
|
2828
|
-
async def broadcast_added_tx(
|
|
2829
|
-
self, mempool_item: MempoolItem, current_peer: Optional[WSChiaConnection] = None
|
|
2830
|
-
) -> None:
|
|
2844
|
+
async def broadcast_added_tx(self, mempool_item: MempoolItem, current_peer: WSChiaConnection | None = None) -> None:
|
|
2831
2845
|
assert mempool_item.fee >= 0
|
|
2832
2846
|
assert mempool_item.cost is not None
|
|
2833
2847
|
|
|
@@ -3136,7 +3150,7 @@ class FullNode:
|
|
|
3136
3150
|
)
|
|
3137
3151
|
if header_block is None:
|
|
3138
3152
|
return None
|
|
3139
|
-
vdf_proof:
|
|
3153
|
+
vdf_proof: VDFProof | None = None
|
|
3140
3154
|
field_vdf = CompressibleVDFField(int(request.field_vdf))
|
|
3141
3155
|
if field_vdf == CompressibleVDFField.CC_EOS_VDF:
|
|
3142
3156
|
for sub_slot in header_block.finished_sub_slots:
|
|
@@ -3356,7 +3370,7 @@ class FullNode:
|
|
|
3356
3370
|
async def node_next_block_check(
|
|
3357
3371
|
peer: WSChiaConnection, potential_peek: uint32, blockchain: BlockchainInterface
|
|
3358
3372
|
) -> bool:
|
|
3359
|
-
block_response:
|
|
3373
|
+
block_response: Any | None = await peer.call_api(
|
|
3360
3374
|
FullNodeAPI.request_block, full_node_protocol.RequestBlock(potential_peek, True)
|
|
3361
3375
|
)
|
|
3362
3376
|
if block_response is not None and isinstance(block_response, full_node_protocol.RespondBlock):
|