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.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,125 @@ 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
|
-
self._transaction_queue_task: asyncio.Task[None] = create_referenced_task(self._handle_transactions())
|
|
292
|
-
|
|
293
|
-
self._init_weight_proof = create_referenced_task(self.initialize_weight_proof())
|
|
294
|
-
|
|
295
|
-
if self.config.get("enable_profiler", False):
|
|
296
|
-
create_referenced_task(profile_task(self.root_path, "node", self.log), known_unreferenced=True)
|
|
297
|
-
|
|
298
|
-
self.profile_block_validation = self.config.get("profile_block_validation", False)
|
|
299
|
-
if self.profile_block_validation: # pragma: no cover
|
|
300
|
-
# this is not covered by any unit tests as it's essentially test code
|
|
301
|
-
# itself. It's exercised manually when investigating performance issues
|
|
302
|
-
profile_dir = path_from_root(self.root_path, "block-validation-profile")
|
|
303
|
-
profile_dir.mkdir(parents=True, exist_ok=True)
|
|
304
|
-
|
|
305
|
-
if self.config.get("enable_memory_profiler", False):
|
|
306
|
-
create_referenced_task(mem_profile_task(self.root_path, "node", self.log), known_unreferenced=True)
|
|
307
|
-
|
|
308
|
-
time_taken = time.monotonic() - start_time
|
|
309
|
-
peak: Optional[BlockRecord] = self.blockchain.get_peak()
|
|
310
|
-
if peak is None:
|
|
311
|
-
self.log.info(f"Initialized with empty blockchain time taken: {int(time_taken)}s")
|
|
312
|
-
if not await self.coin_store.is_empty():
|
|
313
|
-
self.log.error(
|
|
314
|
-
"Inconsistent blockchain DB file! Could not find peak block but found some coins! "
|
|
315
|
-
"This is a fatal error. The blockchain database may be corrupt"
|
|
316
|
-
)
|
|
317
|
-
raise RuntimeError("corrupt blockchain DB")
|
|
318
|
-
else:
|
|
319
|
-
self.log.info(
|
|
320
|
-
f"Blockchain initialized to peak {peak.header_hash} height"
|
|
321
|
-
f" {peak.height}, "
|
|
322
|
-
f"time taken: {int(time_taken)}s"
|
|
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(
|
|
290
|
+
1000, self.log, max_tx_clvm_cost=uint64(self.constants.MAX_BLOCK_COST_CLVM // 2)
|
|
323
291
|
)
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
292
|
+
self._transaction_queue_task: asyncio.Task[None] = create_referenced_task(self._handle_transactions())
|
|
293
|
+
|
|
294
|
+
self._init_weight_proof = create_referenced_task(self.initialize_weight_proof())
|
|
295
|
+
|
|
296
|
+
if self.config.get("enable_profiler", False):
|
|
297
|
+
create_referenced_task(profile_task(self.root_path, "node", self.log), known_unreferenced=True)
|
|
298
|
+
|
|
299
|
+
self.profile_block_validation = self.config.get("profile_block_validation", False)
|
|
300
|
+
if self.profile_block_validation: # pragma: no cover
|
|
301
|
+
# this is not covered by any unit tests as it's essentially test code
|
|
302
|
+
# itself. It's exercised manually when investigating performance issues
|
|
303
|
+
profile_dir = path_from_root(self.root_path, "block-validation-profile")
|
|
304
|
+
profile_dir.mkdir(parents=True, exist_ok=True)
|
|
305
|
+
|
|
306
|
+
if self.config.get("enable_memory_profiler", False):
|
|
307
|
+
create_referenced_task(mem_profile_task(self.root_path, "node", self.log), known_unreferenced=True)
|
|
308
|
+
|
|
309
|
+
time_taken = time.monotonic() - start_time
|
|
310
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
311
|
+
if peak is None:
|
|
312
|
+
self.log.info(f"Initialized with empty blockchain time taken: {int(time_taken)}s")
|
|
313
|
+
if not await self.coin_store.is_empty():
|
|
314
|
+
self.log.error(
|
|
315
|
+
"Inconsistent blockchain DB file! Could not find peak block but found some coins! "
|
|
316
|
+
"This is a fatal error. The blockchain database may be corrupt"
|
|
317
|
+
)
|
|
318
|
+
raise RuntimeError("corrupt blockchain DB")
|
|
319
|
+
else:
|
|
320
|
+
self.log.info(
|
|
321
|
+
f"Blockchain initialized to peak {peak.header_hash} height"
|
|
322
|
+
f" {peak.height}, "
|
|
323
|
+
f"time taken: {int(time_taken)}s"
|
|
335
324
|
)
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
self.
|
|
346
|
-
|
|
347
|
-
|
|
325
|
+
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
326
|
+
pending_tx = await self.mempool_manager.new_peak(self.blockchain.get_tx_peak(), None)
|
|
327
|
+
# No pending transactions when starting up
|
|
328
|
+
assert len(pending_tx.spend_bundle_ids) == 0
|
|
329
|
+
|
|
330
|
+
full_peak: FullBlock | None = await self.blockchain.get_full_peak()
|
|
331
|
+
assert full_peak is not None
|
|
332
|
+
state_change_summary = StateChangeSummary(peak, uint32(max(peak.height - 1, 0)), [], [], [], [])
|
|
333
|
+
# Must be called under priority_mutex
|
|
334
|
+
ppp_result: PeakPostProcessingResult = await self.peak_post_processing(
|
|
335
|
+
full_peak, state_change_summary, None
|
|
336
|
+
)
|
|
337
|
+
# Can be called outside of priority_mutex
|
|
338
|
+
await self.peak_post_processing_2(full_peak, None, state_change_summary, ppp_result)
|
|
339
|
+
if self.config["send_uncompact_interval"] != 0:
|
|
340
|
+
sanitize_weight_proof_only = False
|
|
341
|
+
if "sanitize_weight_proof_only" in self.config:
|
|
342
|
+
sanitize_weight_proof_only = self.config["sanitize_weight_proof_only"]
|
|
343
|
+
assert self.config["target_uncompact_proofs"] != 0
|
|
344
|
+
self.uncompact_task = create_referenced_task(
|
|
345
|
+
self.broadcast_uncompact_blocks(
|
|
346
|
+
self.config["send_uncompact_interval"],
|
|
347
|
+
self.config["target_uncompact_proofs"],
|
|
348
|
+
sanitize_weight_proof_only,
|
|
349
|
+
)
|
|
348
350
|
)
|
|
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)
|
|
351
|
+
if self.wallet_sync_task is None or self.wallet_sync_task.done():
|
|
352
|
+
self.wallet_sync_task = create_referenced_task(self._wallets_sync_task_handler())
|
|
353
|
+
|
|
354
|
+
self.initialized = True
|
|
355
|
+
|
|
356
|
+
try:
|
|
357
|
+
async with contextlib.AsyncExitStack() as aexit_stack:
|
|
358
|
+
if self.full_node_peers is not None:
|
|
359
|
+
await aexit_stack.enter_async_context(self.full_node_peers.manage())
|
|
360
|
+
yield
|
|
361
|
+
finally:
|
|
362
|
+
self._shut_down = True
|
|
363
|
+
if self._init_weight_proof is not None:
|
|
364
|
+
self._init_weight_proof.cancel()
|
|
365
|
+
|
|
366
|
+
# blockchain is created in _start and in certain cases it may not exist here during _close
|
|
367
|
+
if self._blockchain is not None:
|
|
368
|
+
self.blockchain.shut_down()
|
|
369
|
+
if self.uncompact_task is not None:
|
|
370
|
+
self.uncompact_task.cancel()
|
|
371
|
+
if self._transaction_queue_task is not None:
|
|
372
|
+
self._transaction_queue_task.cancel()
|
|
373
|
+
cancel_task_safe(task=self.wallet_sync_task, log=self.log)
|
|
374
|
+
for one_tx_task in self._tx_task_list:
|
|
375
|
+
if not one_tx_task.done():
|
|
376
|
+
cancel_task_safe(task=one_tx_task, log=self.log)
|
|
377
|
+
for one_sync_task in self._sync_task_list:
|
|
378
|
+
if not one_sync_task.done():
|
|
379
|
+
cancel_task_safe(task=one_sync_task, log=self.log)
|
|
380
|
+
for segment_task in self._segment_task_list:
|
|
381
|
+
cancel_task_safe(segment_task, self.log)
|
|
382
|
+
for task_id, task in list(self.full_node_store.tx_fetch_tasks.items()):
|
|
383
|
+
cancel_task_safe(task, self.log)
|
|
384
|
+
if self._init_weight_proof is not None:
|
|
385
|
+
await asyncio.wait([self._init_weight_proof])
|
|
386
|
+
for one_tx_task in self._tx_task_list:
|
|
387
|
+
if one_tx_task.done():
|
|
388
|
+
self.log.info(f"TX task {one_tx_task.get_name()} done")
|
|
389
|
+
else:
|
|
390
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
391
|
+
self.log.info(f"Awaiting TX task {one_tx_task.get_name()}")
|
|
392
|
+
await one_tx_task
|
|
393
|
+
for one_sync_task in self._sync_task_list:
|
|
394
|
+
if one_sync_task.done():
|
|
395
|
+
self.log.info(f"Long sync task {one_sync_task.get_name()} done")
|
|
396
|
+
else:
|
|
397
|
+
with contextlib.suppress(asyncio.CancelledError):
|
|
398
|
+
self.log.info(f"Awaiting long sync task {one_sync_task.get_name()}")
|
|
399
|
+
await one_sync_task
|
|
400
|
+
await asyncio.gather(*self._segment_task_list, return_exceptions=True)
|
|
403
401
|
|
|
404
402
|
@property
|
|
405
403
|
def block_store(self) -> BlockStore:
|
|
@@ -456,7 +454,7 @@ class FullNode:
|
|
|
456
454
|
assert self._compact_vdf_sem is not None
|
|
457
455
|
return self._compact_vdf_sem
|
|
458
456
|
|
|
459
|
-
def get_connections(self, request_node_type:
|
|
457
|
+
def get_connections(self, request_node_type: NodeType | None) -> list[dict[str, Any]]:
|
|
460
458
|
connections = self.server.get_connections(request_node_type)
|
|
461
459
|
con_info: list[dict[str, Any]] = []
|
|
462
460
|
if self.sync_store is not None:
|
|
@@ -498,7 +496,9 @@ class FullNode:
|
|
|
498
496
|
async def _handle_one_transaction(self, entry: TransactionQueueEntry) -> None:
|
|
499
497
|
peer = entry.peer
|
|
500
498
|
try:
|
|
501
|
-
inc_status, err = await self.add_transaction(
|
|
499
|
+
inc_status, err = await self.add_transaction(
|
|
500
|
+
entry.transaction, entry.spend_name, peer, entry.test, entry.peers_with_tx
|
|
501
|
+
)
|
|
502
502
|
entry.done.set((inc_status, err))
|
|
503
503
|
except asyncio.CancelledError:
|
|
504
504
|
error_stack = traceback.format_exc()
|
|
@@ -572,7 +572,7 @@ class FullNode:
|
|
|
572
572
|
self.log.error(f"Exception in peer discovery: {e}")
|
|
573
573
|
self.log.error(f"Exception Stack: {error_stack}")
|
|
574
574
|
|
|
575
|
-
def _state_changed(self, change: str, change_data:
|
|
575
|
+
def _state_changed(self, change: str, change_data: dict[str, Any] | None = None) -> None:
|
|
576
576
|
if self.state_changed_callback is not None:
|
|
577
577
|
self.state_changed_callback(change, change_data)
|
|
578
578
|
|
|
@@ -639,7 +639,7 @@ class FullNode:
|
|
|
639
639
|
if not response:
|
|
640
640
|
raise ValueError(f"Error short batch syncing, invalid/no response for {height}-{end_height}")
|
|
641
641
|
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
642
|
-
state_change_summary:
|
|
642
|
+
state_change_summary: StateChangeSummary | None
|
|
643
643
|
prev_b = None
|
|
644
644
|
if response.blocks[0].height > 0:
|
|
645
645
|
prev_b = await self.blockchain.get_block_record_from_db(response.blocks[0].prev_header_hash)
|
|
@@ -656,7 +656,7 @@ class FullNode:
|
|
|
656
656
|
raise ValueError(f"Error short batch syncing, failed to validate blocks {height}-{end_height}")
|
|
657
657
|
if state_change_summary is not None:
|
|
658
658
|
try:
|
|
659
|
-
peak_fb:
|
|
659
|
+
peak_fb: FullBlock | None = await self.blockchain.get_full_peak()
|
|
660
660
|
assert peak_fb is not None
|
|
661
661
|
ppp_result: PeakPostProcessingResult = await self.peak_post_processing(
|
|
662
662
|
peak_fb,
|
|
@@ -697,7 +697,7 @@ class FullNode:
|
|
|
697
697
|
try:
|
|
698
698
|
self.sync_store.increment_backtrack_syncing(node_id=peer.peer_node_id)
|
|
699
699
|
|
|
700
|
-
unfinished_block:
|
|
700
|
+
unfinished_block: UnfinishedBlock | None = self.full_node_store.get_unfinished_block(target_unf_hash)
|
|
701
701
|
curr_height: int = target_height
|
|
702
702
|
found_fork_point = False
|
|
703
703
|
blocks = []
|
|
@@ -773,7 +773,7 @@ class FullNode:
|
|
|
773
773
|
return None
|
|
774
774
|
|
|
775
775
|
# Not interested in less heavy peaks
|
|
776
|
-
peak:
|
|
776
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
777
777
|
curr_peak_height = uint32(0) if peak is None else peak.height
|
|
778
778
|
if peak is not None and peak.weight > request.weight:
|
|
779
779
|
return None
|
|
@@ -785,7 +785,7 @@ class FullNode:
|
|
|
785
785
|
peak_peers: set[bytes32] = self.sync_store.get_peers_that_have_peak([target_peak.header_hash])
|
|
786
786
|
# Don't ask if we already know this peer has the peak
|
|
787
787
|
if peer.peer_node_id not in peak_peers:
|
|
788
|
-
target_peak_response:
|
|
788
|
+
target_peak_response: RespondBlock | None = await peer.call_api(
|
|
789
789
|
FullNodeAPI.request_block,
|
|
790
790
|
full_node_protocol.RequestBlock(target_peak.height, False),
|
|
791
791
|
timeout=10,
|
|
@@ -839,7 +839,7 @@ class FullNode:
|
|
|
839
839
|
self._sync_task_list.append(create_referenced_task(self._sync()))
|
|
840
840
|
|
|
841
841
|
async def send_peak_to_timelords(
|
|
842
|
-
self, peak_block:
|
|
842
|
+
self, peak_block: FullBlock | None = None, peer: WSChiaConnection | None = None
|
|
843
843
|
) -> None:
|
|
844
844
|
"""
|
|
845
845
|
Sends current peak to timelords
|
|
@@ -849,7 +849,7 @@ class FullNode:
|
|
|
849
849
|
if peak_block is not None:
|
|
850
850
|
peak = self.blockchain.block_record(peak_block.header_hash)
|
|
851
851
|
difficulty = self.blockchain.get_next_sub_slot_iters_and_difficulty(peak.header_hash, False)[1]
|
|
852
|
-
ses:
|
|
852
|
+
ses: SubEpochSummary | None = next_sub_epoch_summary(
|
|
853
853
|
self.constants,
|
|
854
854
|
self.blockchain,
|
|
855
855
|
peak.required_iters,
|
|
@@ -893,12 +893,12 @@ class FullNode:
|
|
|
893
893
|
else:
|
|
894
894
|
await self.server.send_to_specific([msg], peer.peer_node_id)
|
|
895
895
|
|
|
896
|
-
async def synced(self, block_is_current_at:
|
|
896
|
+
async def synced(self, block_is_current_at: uint64 | None = None) -> bool:
|
|
897
897
|
if block_is_current_at is None:
|
|
898
898
|
block_is_current_at = uint64(time.time() - 60 * 7)
|
|
899
899
|
if "simulator" in str(self.config.get("selected_network")):
|
|
900
900
|
return True # sim is always synced because it has no peers
|
|
901
|
-
curr:
|
|
901
|
+
curr: BlockRecord | None = self.blockchain.get_peak()
|
|
902
902
|
if curr is None:
|
|
903
903
|
return False
|
|
904
904
|
|
|
@@ -941,7 +941,7 @@ class FullNode:
|
|
|
941
941
|
msg = make_msg(ProtocolMessageTypes.request_mempool_transactions, mempool_request)
|
|
942
942
|
await connection.send_message(msg)
|
|
943
943
|
|
|
944
|
-
peak_full:
|
|
944
|
+
peak_full: FullBlock | None = await self.blockchain.get_full_peak()
|
|
945
945
|
|
|
946
946
|
if peak_full is not None:
|
|
947
947
|
peak: BlockRecord = self.blockchain.block_record(peak_full.header_hash)
|
|
@@ -987,7 +987,7 @@ class FullNode:
|
|
|
987
987
|
- Disconnect peers that provide invalid blocks or don't have the blocks
|
|
988
988
|
"""
|
|
989
989
|
# Ensure we are only syncing once and not double calling this method
|
|
990
|
-
fork_point:
|
|
990
|
+
fork_point: uint32 | None = None
|
|
991
991
|
if self.sync_store.get_sync_mode():
|
|
992
992
|
return None
|
|
993
993
|
|
|
@@ -1087,7 +1087,7 @@ class FullNode:
|
|
|
1087
1087
|
self.log.info(
|
|
1088
1088
|
f"Requesting weight proof from peer {weight_proof_peer.peer_info.host} up to height {peak_height}"
|
|
1089
1089
|
)
|
|
1090
|
-
cur_peak:
|
|
1090
|
+
cur_peak: BlockRecord | None = self.blockchain.get_peak()
|
|
1091
1091
|
if cur_peak is not None and peak_weight <= cur_peak.weight:
|
|
1092
1092
|
raise ValueError("Not performing sync, already caught up.")
|
|
1093
1093
|
wp_timeout = 360
|
|
@@ -1187,7 +1187,7 @@ class FullNode:
|
|
|
1187
1187
|
blockchain = AugmentedBlockchain(self.blockchain)
|
|
1188
1188
|
peers_with_peak: list[WSChiaConnection] = self.get_peers_with_peak(peak_hash)
|
|
1189
1189
|
|
|
1190
|
-
async def fetch_blocks(output_queue: asyncio.Queue[
|
|
1190
|
+
async def fetch_blocks(output_queue: asyncio.Queue[tuple[WSChiaConnection, list[FullBlock]] | None]) -> None:
|
|
1191
1191
|
# the rate limit for respond_blocks is 100 messages / 60 seconds.
|
|
1192
1192
|
# But the limit is scaled to 30% for outbound messages, so that's 30
|
|
1193
1193
|
# messages per 60 seconds.
|
|
@@ -1294,11 +1294,9 @@ class FullNode:
|
|
|
1294
1294
|
await output_queue.put(None)
|
|
1295
1295
|
|
|
1296
1296
|
async def validate_blocks(
|
|
1297
|
-
input_queue: asyncio.Queue[
|
|
1297
|
+
input_queue: asyncio.Queue[tuple[WSChiaConnection, list[FullBlock]] | None],
|
|
1298
1298
|
output_queue: asyncio.Queue[
|
|
1299
|
-
|
|
1300
|
-
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]]
|
|
1301
|
-
]
|
|
1299
|
+
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]] | None
|
|
1302
1300
|
],
|
|
1303
1301
|
) -> None:
|
|
1304
1302
|
nonlocal blockchain
|
|
@@ -1309,7 +1307,7 @@ class FullNode:
|
|
|
1309
1307
|
|
|
1310
1308
|
try:
|
|
1311
1309
|
while True:
|
|
1312
|
-
res:
|
|
1310
|
+
res: tuple[WSChiaConnection, list[FullBlock]] | None = await input_queue.get()
|
|
1313
1311
|
if res is None:
|
|
1314
1312
|
self.log.debug("done fetching blocks")
|
|
1315
1313
|
return None
|
|
@@ -1351,9 +1349,7 @@ class FullNode:
|
|
|
1351
1349
|
|
|
1352
1350
|
async def ingest_blocks(
|
|
1353
1351
|
input_queue: asyncio.Queue[
|
|
1354
|
-
|
|
1355
|
-
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]]
|
|
1356
|
-
]
|
|
1352
|
+
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]] | None
|
|
1357
1353
|
],
|
|
1358
1354
|
) -> None:
|
|
1359
1355
|
nonlocal fork_info
|
|
@@ -1396,7 +1392,7 @@ class FullNode:
|
|
|
1396
1392
|
f"Added blocks {start_height} to {end_height} "
|
|
1397
1393
|
f"({block_rate:.3g} blocks/s) (from: {peer.peer_info.ip})"
|
|
1398
1394
|
)
|
|
1399
|
-
peak:
|
|
1395
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
1400
1396
|
if state_change_summary is not None:
|
|
1401
1397
|
assert peak is not None
|
|
1402
1398
|
# Hints must be added to the DB. The other post-processing tasks are not required when syncing
|
|
@@ -1413,9 +1409,9 @@ class FullNode:
|
|
|
1413
1409
|
# height, in that case.
|
|
1414
1410
|
self.blockchain.clean_block_record(end_height - self.constants.BLOCKS_CACHE_SIZE)
|
|
1415
1411
|
|
|
1416
|
-
block_queue: asyncio.Queue[
|
|
1412
|
+
block_queue: asyncio.Queue[tuple[WSChiaConnection, list[FullBlock]] | None] = asyncio.Queue(maxsize=10)
|
|
1417
1413
|
validation_queue: asyncio.Queue[
|
|
1418
|
-
|
|
1414
|
+
tuple[WSChiaConnection, ValidationState, list[Awaitable[PreValidationResult]], list[FullBlock]] | None
|
|
1419
1415
|
] = asyncio.Queue(maxsize=10)
|
|
1420
1416
|
|
|
1421
1417
|
fetch_task = create_referenced_task(fetch_blocks(block_queue))
|
|
@@ -1501,8 +1497,8 @@ class FullNode:
|
|
|
1501
1497
|
fork_info: ForkInfo,
|
|
1502
1498
|
vs: ValidationState, # in-out parameter
|
|
1503
1499
|
blockchain: AugmentedBlockchain,
|
|
1504
|
-
wp_summaries:
|
|
1505
|
-
) -> tuple[bool,
|
|
1500
|
+
wp_summaries: list[SubEpochSummary] | None = None,
|
|
1501
|
+
) -> tuple[bool, StateChangeSummary | None]:
|
|
1506
1502
|
# Precondition: All blocks must be contiguous blocks, index i+1 must be the parent of index i
|
|
1507
1503
|
# Returns a bool for success, as well as a StateChangeSummary if the peak was advanced
|
|
1508
1504
|
|
|
@@ -1584,7 +1580,7 @@ class FullNode:
|
|
|
1584
1580
|
blockchain: AugmentedBlockchain,
|
|
1585
1581
|
blocks_to_validate: list[FullBlock],
|
|
1586
1582
|
vs: ValidationState,
|
|
1587
|
-
wp_summaries:
|
|
1583
|
+
wp_summaries: list[SubEpochSummary] | None = None,
|
|
1588
1584
|
) -> Sequence[Awaitable[PreValidationResult]]:
|
|
1589
1585
|
"""
|
|
1590
1586
|
This is a thin wrapper over pre_validate_block().
|
|
@@ -1625,15 +1621,15 @@ class FullNode:
|
|
|
1625
1621
|
fork_info: ForkInfo,
|
|
1626
1622
|
peer_info: PeerInfo,
|
|
1627
1623
|
vs: ValidationState, # in-out parameter
|
|
1628
|
-
) -> tuple[
|
|
1629
|
-
agg_state_change_summary:
|
|
1624
|
+
) -> tuple[StateChangeSummary | None, Err | None]:
|
|
1625
|
+
agg_state_change_summary: StateChangeSummary | None = None
|
|
1630
1626
|
block_record = await self.blockchain.get_block_record_from_db(blocks_to_validate[0].prev_header_hash)
|
|
1631
1627
|
for i, block in enumerate(blocks_to_validate):
|
|
1632
1628
|
header_hash = block.header_hash
|
|
1633
1629
|
assert vs.prev_ses_block is None or vs.prev_ses_block.height < block.height
|
|
1634
1630
|
assert pre_validation_results[i].error is None
|
|
1635
1631
|
assert pre_validation_results[i].required_iters is not None
|
|
1636
|
-
state_change_summary:
|
|
1632
|
+
state_change_summary: StateChangeSummary | None
|
|
1637
1633
|
# when adding blocks in batches, we won't have any overlapping
|
|
1638
1634
|
# signatures with the mempool. There won't be any cache hits, so
|
|
1639
1635
|
# there's no need to pass the BLS cache in
|
|
@@ -1696,8 +1692,8 @@ class FullNode:
|
|
|
1696
1692
|
return agg_state_change_summary, None
|
|
1697
1693
|
|
|
1698
1694
|
async def get_sub_slot_iters_difficulty_ses_block(
|
|
1699
|
-
self, block: FullBlock, ssi:
|
|
1700
|
-
) -> tuple[uint64, uint64,
|
|
1695
|
+
self, block: FullBlock, ssi: uint64 | None, diff: uint64 | None
|
|
1696
|
+
) -> tuple[uint64, uint64, BlockRecord | None]:
|
|
1701
1697
|
prev_ses_block = None
|
|
1702
1698
|
if ssi is None or diff is None:
|
|
1703
1699
|
if block.height == 0:
|
|
@@ -1734,7 +1730,7 @@ class FullNode:
|
|
|
1734
1730
|
assert diff is not None
|
|
1735
1731
|
return ssi, diff, prev_ses_block
|
|
1736
1732
|
|
|
1737
|
-
async def _finish_sync(self, fork_point:
|
|
1733
|
+
async def _finish_sync(self, fork_point: uint32 | None) -> None:
|
|
1738
1734
|
"""
|
|
1739
1735
|
Finalize sync by setting sync mode to False, clearing all sync information, and adding any final
|
|
1740
1736
|
blocks that we have finalized recently.
|
|
@@ -1747,8 +1743,8 @@ class FullNode:
|
|
|
1747
1743
|
return None
|
|
1748
1744
|
|
|
1749
1745
|
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
1750
|
-
peak:
|
|
1751
|
-
peak_fb:
|
|
1746
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
1747
|
+
peak_fb: FullBlock | None = await self.blockchain.get_full_peak()
|
|
1752
1748
|
if peak_fb is not None:
|
|
1753
1749
|
if fork_point is None:
|
|
1754
1750
|
fork_point = uint32(max(peak_fb.height - 1, 0))
|
|
@@ -1766,7 +1762,7 @@ class FullNode:
|
|
|
1766
1762
|
await self.weight_proof_handler.get_proof_of_weight(peak.header_hash)
|
|
1767
1763
|
self._state_changed("block")
|
|
1768
1764
|
|
|
1769
|
-
def has_valid_pool_sig(self, block:
|
|
1765
|
+
def has_valid_pool_sig(self, block: UnfinishedBlock | FullBlock) -> bool:
|
|
1770
1766
|
if (
|
|
1771
1767
|
block.foliage.foliage_block_data.pool_target
|
|
1772
1768
|
== PoolTarget(self.constants.GENESIS_PRE_FARM_POOL_PUZZLE_HASH, uint32(0))
|
|
@@ -1786,7 +1782,7 @@ class FullNode:
|
|
|
1786
1782
|
self,
|
|
1787
1783
|
request: full_node_protocol.RespondSignagePoint,
|
|
1788
1784
|
peer: WSChiaConnection,
|
|
1789
|
-
ip_sub_slot:
|
|
1785
|
+
ip_sub_slot: EndOfSubSlotBundle | None,
|
|
1790
1786
|
) -> None:
|
|
1791
1787
|
self.log.info(
|
|
1792
1788
|
f"⏲️ Finished signage point {request.index_from_challenge}/"
|
|
@@ -1796,7 +1792,7 @@ class FullNode:
|
|
|
1796
1792
|
)
|
|
1797
1793
|
self.signage_point_times[request.index_from_challenge] = time.time()
|
|
1798
1794
|
sub_slot_tuple = self.full_node_store.get_sub_slot(request.challenge_chain_vdf.challenge)
|
|
1799
|
-
prev_challenge:
|
|
1795
|
+
prev_challenge: bytes32 | None
|
|
1800
1796
|
if sub_slot_tuple is not None:
|
|
1801
1797
|
prev_challenge = sub_slot_tuple[0].challenge_chain.challenge_chain_end_of_slot_vdf.challenge
|
|
1802
1798
|
else:
|
|
@@ -1850,7 +1846,7 @@ class FullNode:
|
|
|
1850
1846
|
self,
|
|
1851
1847
|
block: FullBlock,
|
|
1852
1848
|
state_change_summary: StateChangeSummary,
|
|
1853
|
-
peer:
|
|
1849
|
+
peer: WSChiaConnection | None,
|
|
1854
1850
|
) -> PeakPostProcessingResult:
|
|
1855
1851
|
"""
|
|
1856
1852
|
Must be called under self.blockchain.priority_mutex. This updates the internal state of the full node with the
|
|
@@ -1889,10 +1885,10 @@ class FullNode:
|
|
|
1889
1885
|
if not self.sync_store.get_sync_mode():
|
|
1890
1886
|
self.blockchain.clean_block_records()
|
|
1891
1887
|
|
|
1892
|
-
fork_block:
|
|
1888
|
+
fork_block: BlockRecord | None = None
|
|
1893
1889
|
if state_change_summary.fork_height != block.height - 1 and block.height != 0:
|
|
1894
1890
|
# This is a reorg
|
|
1895
|
-
fork_hash:
|
|
1891
|
+
fork_hash: bytes32 | None = self.blockchain.height_to_hash(state_change_summary.fork_height)
|
|
1896
1892
|
assert fork_hash is not None
|
|
1897
1893
|
fork_block = await self.blockchain.get_block_record_from_db(fork_hash)
|
|
1898
1894
|
|
|
@@ -1907,7 +1903,7 @@ class FullNode:
|
|
|
1907
1903
|
difficulty,
|
|
1908
1904
|
)
|
|
1909
1905
|
|
|
1910
|
-
signage_points: list[tuple[RespondSignagePoint, WSChiaConnection,
|
|
1906
|
+
signage_points: list[tuple[RespondSignagePoint, WSChiaConnection, EndOfSubSlotBundle | None]] = []
|
|
1911
1907
|
if fns_peak_result.new_signage_points is not None and peer is not None:
|
|
1912
1908
|
for index, sp in fns_peak_result.new_signage_points:
|
|
1913
1909
|
assert (
|
|
@@ -1958,7 +1954,7 @@ class FullNode:
|
|
|
1958
1954
|
async def peak_post_processing_2(
|
|
1959
1955
|
self,
|
|
1960
1956
|
block: FullBlock,
|
|
1961
|
-
peer:
|
|
1957
|
+
peer: WSChiaConnection | None,
|
|
1962
1958
|
state_change_summary: StateChangeSummary,
|
|
1963
1959
|
ppp_result: PeakPostProcessingResult,
|
|
1964
1960
|
) -> None:
|
|
@@ -2037,11 +2033,11 @@ class FullNode:
|
|
|
2037
2033
|
async def add_block(
|
|
2038
2034
|
self,
|
|
2039
2035
|
block: FullBlock,
|
|
2040
|
-
peer:
|
|
2041
|
-
bls_cache:
|
|
2036
|
+
peer: WSChiaConnection | None = None,
|
|
2037
|
+
bls_cache: BLSCache | None = None,
|
|
2042
2038
|
raise_on_disconnected: bool = False,
|
|
2043
|
-
fork_info:
|
|
2044
|
-
) ->
|
|
2039
|
+
fork_info: ForkInfo | None = None,
|
|
2040
|
+
) -> Message | None:
|
|
2045
2041
|
"""
|
|
2046
2042
|
Add a full block from a peer full node (or ourselves).
|
|
2047
2043
|
"""
|
|
@@ -2055,7 +2051,7 @@ class FullNode:
|
|
|
2055
2051
|
await self.blockchain.run_single_block(block, fork_info)
|
|
2056
2052
|
return None
|
|
2057
2053
|
|
|
2058
|
-
pre_validation_result:
|
|
2054
|
+
pre_validation_result: PreValidationResult | None = None
|
|
2059
2055
|
if (
|
|
2060
2056
|
block.is_transaction_block()
|
|
2061
2057
|
and block.transactions_info is not None
|
|
@@ -2065,9 +2061,9 @@ class FullNode:
|
|
|
2065
2061
|
# This is the case where we already had the unfinished block, and asked for this block without
|
|
2066
2062
|
# the transactions (since we already had them). Therefore, here we add the transactions.
|
|
2067
2063
|
unfinished_rh: bytes32 = block.reward_chain_block.get_unfinished().get_hash()
|
|
2068
|
-
foliage_hash:
|
|
2064
|
+
foliage_hash: bytes32 | None = block.foliage.foliage_transaction_block_hash
|
|
2069
2065
|
assert foliage_hash is not None
|
|
2070
|
-
unf_entry:
|
|
2066
|
+
unf_entry: UnfinishedBlockEntry | None = self.full_node_store.get_unfinished_block_result(
|
|
2071
2067
|
unfinished_rh, foliage_hash
|
|
2072
2068
|
)
|
|
2073
2069
|
assert unf_entry is None or unf_entry.result is None or unf_entry.result.validated_signature is True
|
|
@@ -2094,7 +2090,7 @@ class FullNode:
|
|
|
2094
2090
|
if peer is None:
|
|
2095
2091
|
return None
|
|
2096
2092
|
|
|
2097
|
-
block_response:
|
|
2093
|
+
block_response: Any | None = await peer.call_api(
|
|
2098
2094
|
FullNodeAPI.request_block, full_node_protocol.RequestBlock(block.height, True)
|
|
2099
2095
|
)
|
|
2100
2096
|
if block_response is None or not isinstance(block_response, full_node_protocol.RespondBlock):
|
|
@@ -2117,8 +2113,8 @@ class FullNode:
|
|
|
2117
2113
|
)
|
|
2118
2114
|
# This recursion ends here, we cannot recurse again because transactions_generator is not None
|
|
2119
2115
|
return await self.add_block(new_block, peer, bls_cache)
|
|
2120
|
-
state_change_summary:
|
|
2121
|
-
ppp_result:
|
|
2116
|
+
state_change_summary: StateChangeSummary | None = None
|
|
2117
|
+
ppp_result: PeakPostProcessingResult | None = None
|
|
2122
2118
|
async with (
|
|
2123
2119
|
self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high),
|
|
2124
2120
|
enable_profiler(self.profile_block_validation) as pr,
|
|
@@ -2156,14 +2152,14 @@ class FullNode:
|
|
|
2156
2152
|
ValidationState(ssi, diff, prev_ses_block),
|
|
2157
2153
|
)
|
|
2158
2154
|
pre_validation_result = await future
|
|
2159
|
-
added:
|
|
2155
|
+
added: AddBlockResult | None = None
|
|
2160
2156
|
add_block_start = time.monotonic()
|
|
2161
2157
|
pre_validation_time = add_block_start - validation_start
|
|
2162
2158
|
try:
|
|
2163
2159
|
if pre_validation_result.error is not None:
|
|
2164
2160
|
if Err(pre_validation_result.error) == Err.INVALID_PREV_BLOCK_HASH:
|
|
2165
2161
|
added = AddBlockResult.DISCONNECTED_BLOCK
|
|
2166
|
-
error_code:
|
|
2162
|
+
error_code: Err | None = Err.INVALID_PREV_BLOCK_HASH
|
|
2167
2163
|
elif Err(pre_validation_result.error) == Err.TIMESTAMP_TOO_FAR_IN_FUTURE:
|
|
2168
2164
|
raise TimestampError
|
|
2169
2165
|
else:
|
|
@@ -2267,8 +2263,8 @@ class FullNode:
|
|
|
2267
2263
|
|
|
2268
2264
|
state_changed_data: dict[str, Any] = {
|
|
2269
2265
|
"transaction_block": False,
|
|
2270
|
-
"k_size": block.reward_chain_block.proof_of_space.
|
|
2271
|
-
"
|
|
2266
|
+
"k_size": block.reward_chain_block.proof_of_space.param().size_v1,
|
|
2267
|
+
"strength": block.reward_chain_block.proof_of_space.param().strength_v2,
|
|
2272
2268
|
"header_hash": block.header_hash,
|
|
2273
2269
|
"fork_height": None,
|
|
2274
2270
|
"rolled_back_records": None,
|
|
@@ -2311,7 +2307,7 @@ class FullNode:
|
|
|
2311
2307
|
async def add_unfinished_block(
|
|
2312
2308
|
self,
|
|
2313
2309
|
block: UnfinishedBlock,
|
|
2314
|
-
peer:
|
|
2310
|
+
peer: WSChiaConnection | None,
|
|
2315
2311
|
farmed_block: bool = False,
|
|
2316
2312
|
) -> None:
|
|
2317
2313
|
"""
|
|
@@ -2344,7 +2340,7 @@ class FullNode:
|
|
|
2344
2340
|
if self.full_node_store.get_unfinished_block2(block_hash, foliage_tx_hash)[0] is not None:
|
|
2345
2341
|
return None
|
|
2346
2342
|
|
|
2347
|
-
peak:
|
|
2343
|
+
peak: BlockRecord | None = self.blockchain.get_peak()
|
|
2348
2344
|
if peak is not None:
|
|
2349
2345
|
if block.total_iters < peak.sp_total_iters(self.constants):
|
|
2350
2346
|
# This means this unfinished block is pretty far behind, it will not add weight to our chain
|
|
@@ -2372,7 +2368,7 @@ class FullNode:
|
|
|
2372
2368
|
|
|
2373
2369
|
# The clvm generator and aggregate signature are validated outside of the lock, to allow other blocks and
|
|
2374
2370
|
# transactions to get validated
|
|
2375
|
-
npc_result:
|
|
2371
|
+
npc_result: NPCResult | None = None
|
|
2376
2372
|
pre_validation_time = None
|
|
2377
2373
|
|
|
2378
2374
|
async with self.blockchain.priority_mutex.acquire(priority=BlockchainMutexPriority.high):
|
|
@@ -2450,7 +2446,7 @@ class FullNode:
|
|
|
2450
2446
|
else:
|
|
2451
2447
|
height = uint32(self.blockchain.block_record(block.prev_header_hash).height + 1)
|
|
2452
2448
|
|
|
2453
|
-
ses:
|
|
2449
|
+
ses: SubEpochSummary | None = next_sub_epoch_summary(
|
|
2454
2450
|
self.constants,
|
|
2455
2451
|
self.blockchain,
|
|
2456
2452
|
validate_result.required_iters,
|
|
@@ -2542,7 +2538,7 @@ class FullNode:
|
|
|
2542
2538
|
# don't send this to peers with old clients
|
|
2543
2539
|
return conn.protocol_version > Version("0.0.35")
|
|
2544
2540
|
|
|
2545
|
-
peer_id:
|
|
2541
|
+
peer_id: bytes32 | None = None if peer is None else peer.peer_node_id
|
|
2546
2542
|
await self.server.send_to_all_if([msg], NodeType.FULL_NODE, old_clients, peer_id)
|
|
2547
2543
|
await self.server.send_to_all_if([msg2], NodeType.FULL_NODE, new_clients, peer_id)
|
|
2548
2544
|
|
|
@@ -2557,10 +2553,10 @@ class FullNode:
|
|
|
2557
2553
|
)
|
|
2558
2554
|
|
|
2559
2555
|
async def new_infusion_point_vdf(
|
|
2560
|
-
self, request: timelord_protocol.NewInfusionPointVDF, timelord_peer:
|
|
2561
|
-
) ->
|
|
2556
|
+
self, request: timelord_protocol.NewInfusionPointVDF, timelord_peer: WSChiaConnection | None = None
|
|
2557
|
+
) -> Message | None:
|
|
2562
2558
|
# Lookup unfinished blocks
|
|
2563
|
-
unfinished_block:
|
|
2559
|
+
unfinished_block: UnfinishedBlock | None = self.full_node_store.get_unfinished_block(
|
|
2564
2560
|
request.unfinished_reward_hash
|
|
2565
2561
|
)
|
|
2566
2562
|
|
|
@@ -2570,7 +2566,7 @@ class FullNode:
|
|
|
2570
2566
|
)
|
|
2571
2567
|
return None
|
|
2572
2568
|
|
|
2573
|
-
prev_b:
|
|
2569
|
+
prev_b: BlockRecord | None = None
|
|
2574
2570
|
|
|
2575
2571
|
target_rc_hash = request.reward_chain_ip_vdf.challenge
|
|
2576
2572
|
last_slot_cc_hash = request.challenge_chain_ip_vdf.challenge
|
|
@@ -2584,7 +2580,7 @@ class FullNode:
|
|
|
2584
2580
|
else:
|
|
2585
2581
|
# Find the prev block, starts looking backwards from the peak. target_rc_hash must be the hash of a block
|
|
2586
2582
|
# and not an end of slot (since we just looked through the slots and backtracked)
|
|
2587
|
-
curr:
|
|
2583
|
+
curr: BlockRecord | None = self.blockchain.get_peak()
|
|
2588
2584
|
|
|
2589
2585
|
for _ in range(10):
|
|
2590
2586
|
if curr is None:
|
|
@@ -2603,7 +2599,7 @@ class FullNode:
|
|
|
2603
2599
|
)
|
|
2604
2600
|
return None
|
|
2605
2601
|
|
|
2606
|
-
finished_sub_slots:
|
|
2602
|
+
finished_sub_slots: list[EndOfSubSlotBundle] | None = self.full_node_store.get_finished_sub_slots(
|
|
2607
2603
|
self.blockchain,
|
|
2608
2604
|
prev_b,
|
|
2609
2605
|
last_slot_cc_hash,
|
|
@@ -2663,7 +2659,7 @@ class FullNode:
|
|
|
2663
2659
|
|
|
2664
2660
|
async def add_end_of_sub_slot(
|
|
2665
2661
|
self, end_of_slot_bundle: EndOfSubSlotBundle, peer: WSChiaConnection
|
|
2666
|
-
) -> tuple[
|
|
2662
|
+
) -> tuple[Message | None, bool]:
|
|
2667
2663
|
fetched_ss = self.full_node_store.get_sub_slot(end_of_slot_bundle.challenge_chain.get_hash())
|
|
2668
2664
|
|
|
2669
2665
|
# We are not interested in sub-slots which have the same challenge chain but different reward chain. If there
|
|
@@ -2761,8 +2757,15 @@ class FullNode:
|
|
|
2761
2757
|
return None, False
|
|
2762
2758
|
|
|
2763
2759
|
async def add_transaction(
|
|
2764
|
-
self,
|
|
2765
|
-
|
|
2760
|
+
self,
|
|
2761
|
+
transaction: SpendBundle,
|
|
2762
|
+
spend_name: bytes32,
|
|
2763
|
+
peer: WSChiaConnection | None = None,
|
|
2764
|
+
test: bool = False,
|
|
2765
|
+
# Map of peer ID to its hostname, the fee and the cost it advertised
|
|
2766
|
+
# for this transaction.
|
|
2767
|
+
peers_with_tx: dict[bytes32, PeerWithTx] = {},
|
|
2768
|
+
) -> tuple[MempoolInclusionStatus, Err | None]:
|
|
2766
2769
|
if self.sync_store.get_sync_mode():
|
|
2767
2770
|
return MempoolInclusionStatus.FAILED, Err.NO_TRANSACTIONS_WHILE_SYNCING
|
|
2768
2771
|
if not test and not (await self.synced()):
|
|
@@ -2810,10 +2813,25 @@ class FullNode:
|
|
|
2810
2813
|
f"{self.mempool_manager.mempool.total_mempool_cost() / 5000000}"
|
|
2811
2814
|
)
|
|
2812
2815
|
|
|
2813
|
-
# Only broadcast successful transactions, not pending ones. Otherwise it's a DOS
|
|
2814
|
-
# vector.
|
|
2815
2816
|
mempool_item = self.mempool_manager.get_mempool_item(spend_name)
|
|
2816
2817
|
assert mempool_item is not None
|
|
2818
|
+
# Now that we validated this transaction, check what fees and
|
|
2819
|
+
# costs the peers have advertised for it.
|
|
2820
|
+
for peer_id, entry in peers_with_tx.items():
|
|
2821
|
+
if entry.advertised_fee == mempool_item.fee and entry.advertised_cost == mempool_item.cost:
|
|
2822
|
+
continue
|
|
2823
|
+
self.log.warning(
|
|
2824
|
+
f"Banning peer {peer_id}. Sent us a new tx {spend_name} with mismatch "
|
|
2825
|
+
f"on cost {entry.advertised_cost} vs validation cost {mempool_item.cost} and/or "
|
|
2826
|
+
f"fee {entry.advertised_fee} vs {mempool_item.fee}."
|
|
2827
|
+
)
|
|
2828
|
+
peer = self.server.all_connections.get(peer_id)
|
|
2829
|
+
if peer is None:
|
|
2830
|
+
self.server.ban_peer(entry.peer_host, CONSENSUS_ERROR_BAN_SECONDS)
|
|
2831
|
+
else:
|
|
2832
|
+
await peer.close(CONSENSUS_ERROR_BAN_SECONDS)
|
|
2833
|
+
# Only broadcast successful transactions, not pending ones. Otherwise it's a DOS
|
|
2834
|
+
# vector.
|
|
2817
2835
|
await self.broadcast_removed_tx(info.removals)
|
|
2818
2836
|
await self.broadcast_added_tx(mempool_item, current_peer=peer)
|
|
2819
2837
|
|
|
@@ -2825,9 +2843,7 @@ class FullNode:
|
|
|
2825
2843
|
self.log.debug(f"Wasn't able to add transaction with id {spend_name}, status {status} error: {error}")
|
|
2826
2844
|
return status, error
|
|
2827
2845
|
|
|
2828
|
-
async def broadcast_added_tx(
|
|
2829
|
-
self, mempool_item: MempoolItem, current_peer: Optional[WSChiaConnection] = None
|
|
2830
|
-
) -> None:
|
|
2846
|
+
async def broadcast_added_tx(self, mempool_item: MempoolItem, current_peer: WSChiaConnection | None = None) -> None:
|
|
2831
2847
|
assert mempool_item.fee >= 0
|
|
2832
2848
|
assert mempool_item.cost is not None
|
|
2833
2849
|
|
|
@@ -3136,7 +3152,7 @@ class FullNode:
|
|
|
3136
3152
|
)
|
|
3137
3153
|
if header_block is None:
|
|
3138
3154
|
return None
|
|
3139
|
-
vdf_proof:
|
|
3155
|
+
vdf_proof: VDFProof | None = None
|
|
3140
3156
|
field_vdf = CompressibleVDFField(int(request.field_vdf))
|
|
3141
3157
|
if field_vdf == CompressibleVDFField.CC_EOS_VDF:
|
|
3142
3158
|
for sub_slot in header_block.finished_sub_slots:
|
|
@@ -3356,7 +3372,7 @@ class FullNode:
|
|
|
3356
3372
|
async def node_next_block_check(
|
|
3357
3373
|
peer: WSChiaConnection, potential_peek: uint32, blockchain: BlockchainInterface
|
|
3358
3374
|
) -> bool:
|
|
3359
|
-
block_response:
|
|
3375
|
+
block_response: Any | None = await peer.call_api(
|
|
3360
3376
|
FullNodeAPI.request_block, full_node_protocol.RequestBlock(potential_peek, True)
|
|
3361
3377
|
)
|
|
3362
3378
|
if block_response is not None and isinstance(block_response, full_node_protocol.RespondBlock):
|