chia-blockchain 2.5.0rc1__py3-none-any.whl → 2.5.1__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.
Files changed (637) hide show
  1. chia/_tests/README.md +1 -1
  2. chia/_tests/blockchain/blockchain_test_utils.py +24 -26
  3. chia/_tests/blockchain/test_augmented_chain.py +6 -8
  4. chia/_tests/blockchain/test_blockchain.py +409 -307
  5. chia/_tests/blockchain/test_blockchain_transactions.py +56 -75
  6. chia/_tests/blockchain/test_build_chains.py +11 -13
  7. chia/_tests/blockchain/test_get_block_generator.py +8 -8
  8. chia/_tests/blockchain/test_lookup_fork_chain.py +3 -4
  9. chia/_tests/build-init-files.py +3 -4
  10. chia/_tests/build-job-matrix.py +9 -9
  11. chia/_tests/check_sql_statements.py +2 -3
  12. chia/_tests/clvm/benchmark_costs.py +1 -1
  13. chia/_tests/clvm/coin_store.py +7 -5
  14. chia/_tests/clvm/test_chialisp_deserialization.py +8 -8
  15. chia/_tests/clvm/test_condition_codes.py +2 -2
  16. chia/_tests/clvm/test_curry_and_treehash.py +2 -4
  17. chia/_tests/clvm/test_message_conditions.py +184 -0
  18. chia/_tests/clvm/test_puzzle_compression.py +1 -2
  19. chia/_tests/clvm/test_puzzle_drivers.py +3 -3
  20. chia/_tests/clvm/test_puzzles.py +13 -18
  21. chia/_tests/clvm/test_singletons.py +17 -17
  22. chia/_tests/clvm/test_spend_sim.py +7 -7
  23. chia/_tests/cmds/cmd_test_utils.py +42 -45
  24. chia/_tests/cmds/conftest.py +2 -2
  25. chia/_tests/cmds/test_click_types.py +21 -16
  26. chia/_tests/cmds/test_cmd_framework.py +255 -35
  27. chia/_tests/cmds/test_cmds_util.py +2 -2
  28. chia/_tests/cmds/test_daemon.py +3 -3
  29. chia/_tests/cmds/test_dev_gh.py +131 -0
  30. chia/_tests/cmds/test_farm_cmd.py +1 -2
  31. chia/_tests/cmds/test_show.py +6 -6
  32. chia/_tests/cmds/test_tx_config_args.py +2 -1
  33. chia/_tests/cmds/wallet/test_dao.py +23 -23
  34. chia/_tests/cmds/wallet/test_did.py +29 -29
  35. chia/_tests/cmds/wallet/test_nft.py +24 -23
  36. chia/_tests/cmds/wallet/test_notifications.py +8 -8
  37. chia/_tests/cmds/wallet/test_tx_decorators.py +3 -3
  38. chia/_tests/cmds/wallet/test_vcs.py +97 -73
  39. chia/_tests/cmds/wallet/test_wallet.py +74 -75
  40. chia/_tests/cmds/wallet/test_wallet_check.py +5 -7
  41. chia/_tests/conftest.py +153 -38
  42. chia/_tests/connection_utils.py +7 -6
  43. chia/_tests/core/cmds/test_beta.py +3 -3
  44. chia/_tests/core/cmds/test_keys.py +6 -6
  45. chia/_tests/core/cmds/test_wallet.py +3 -3
  46. chia/_tests/core/consensus/test_block_creation.py +3 -5
  47. chia/_tests/core/custom_types/test_coin.py +1 -3
  48. chia/_tests/core/custom_types/test_spend_bundle.py +3 -4
  49. chia/_tests/core/daemon/test_daemon.py +58 -58
  50. chia/_tests/core/daemon/test_keychain_proxy.py +2 -1
  51. chia/_tests/core/data_layer/conftest.py +4 -3
  52. chia/_tests/core/data_layer/test_data_cli.py +1 -2
  53. chia/_tests/core/data_layer/test_data_layer.py +5 -5
  54. chia/_tests/core/data_layer/test_data_layer_util.py +8 -9
  55. chia/_tests/core/data_layer/test_data_rpc.py +75 -93
  56. chia/_tests/core/data_layer/test_data_store.py +38 -37
  57. chia/_tests/core/data_layer/test_data_store_schema.py +11 -11
  58. chia/_tests/core/data_layer/util.py +11 -10
  59. chia/_tests/core/farmer/test_farmer_api.py +6 -4
  60. chia/_tests/core/full_node/full_sync/test_full_sync.py +5 -10
  61. chia/_tests/core/full_node/ram_db.py +2 -2
  62. chia/_tests/core/full_node/stores/test_block_store.py +113 -11
  63. chia/_tests/core/full_node/stores/test_coin_store.py +37 -28
  64. chia/_tests/core/full_node/stores/test_full_node_store.py +34 -30
  65. chia/_tests/core/full_node/stores/test_hint_store.py +3 -4
  66. chia/_tests/core/full_node/test_address_manager.py +2 -2
  67. chia/_tests/core/full_node/test_block_height_map.py +1 -1
  68. chia/_tests/core/full_node/test_conditions.py +10 -12
  69. chia/_tests/core/full_node/test_full_node.py +2077 -1822
  70. chia/_tests/core/full_node/test_generator_tools.py +4 -4
  71. chia/_tests/core/full_node/test_hint_management.py +2 -2
  72. chia/_tests/core/full_node/test_performance.py +2 -5
  73. chia/_tests/core/full_node/test_subscriptions.py +4 -4
  74. chia/_tests/core/full_node/test_tx_processing_queue.py +5 -4
  75. chia/_tests/core/make_block_generator.py +5 -7
  76. chia/_tests/core/mempool/test_mempool.py +205 -208
  77. chia/_tests/core/mempool/test_mempool_fee_protocol.py +5 -5
  78. chia/_tests/core/mempool/test_mempool_item_queries.py +2 -4
  79. chia/_tests/core/mempool/test_mempool_manager.py +109 -80
  80. chia/_tests/core/mempool/test_mempool_performance.py +3 -4
  81. chia/_tests/core/mempool/test_singleton_fast_forward.py +12 -12
  82. chia/_tests/core/server/flood.py +6 -4
  83. chia/_tests/core/server/serve.py +10 -7
  84. chia/_tests/core/server/test_api_protocol.py +21 -0
  85. chia/_tests/core/server/test_capabilities.py +3 -5
  86. chia/_tests/core/server/test_dos.py +15 -16
  87. chia/_tests/core/server/test_loop.py +14 -10
  88. chia/_tests/core/server/test_node_discovery.py +1 -2
  89. chia/_tests/core/server/test_rate_limits.py +156 -44
  90. chia/_tests/core/server/test_server.py +8 -7
  91. chia/_tests/core/services/test_services.py +59 -37
  92. chia/_tests/core/ssl/test_ssl.py +5 -3
  93. chia/_tests/core/test_cost_calculation.py +5 -6
  94. chia/_tests/core/test_crawler.py +2 -2
  95. chia/_tests/core/test_db_conversion.py +5 -4
  96. chia/_tests/core/test_db_validation.py +6 -5
  97. chia/_tests/core/test_farmer_harvester_rpc.py +8 -7
  98. chia/_tests/core/test_filter.py +3 -5
  99. chia/_tests/core/test_full_node_rpc.py +64 -90
  100. chia/_tests/core/test_merkle_set.py +10 -10
  101. chia/_tests/core/test_program.py +2 -4
  102. chia/_tests/core/test_rpc_util.py +1 -2
  103. chia/_tests/core/test_seeder.py +124 -12
  104. chia/_tests/core/util/test_block_cache.py +5 -5
  105. chia/_tests/core/util/test_cached_bls.py +3 -3
  106. chia/_tests/core/util/test_config.py +13 -13
  107. chia/_tests/core/util/test_files.py +2 -2
  108. chia/_tests/core/util/test_jsonify.py +9 -9
  109. chia/_tests/core/util/test_keychain.py +13 -5
  110. chia/_tests/core/util/test_keyring_wrapper.py +6 -5
  111. chia/_tests/core/util/test_log_exceptions.py +3 -3
  112. chia/_tests/core/util/test_streamable.py +38 -38
  113. chia/_tests/db/test_db_wrapper.py +13 -12
  114. chia/_tests/environments/common.py +2 -2
  115. chia/_tests/environments/full_node.py +2 -2
  116. chia/_tests/environments/wallet.py +109 -48
  117. chia/_tests/farmer_harvester/test_farmer.py +35 -35
  118. chia/_tests/farmer_harvester/test_farmer_harvester.py +17 -17
  119. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
  120. chia/_tests/farmer_harvester/test_third_party_harvesters.py +73 -46
  121. chia/_tests/fee_estimation/test_fee_estimation_integration.py +8 -8
  122. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +47 -47
  123. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +6 -7
  124. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +11 -11
  125. chia/_tests/generator/test_compression.py +13 -30
  126. chia/_tests/generator/test_generator_types.py +3 -3
  127. chia/_tests/generator/test_rom.py +7 -9
  128. chia/_tests/plot_sync/test_delta.py +2 -3
  129. chia/_tests/plot_sync/test_plot_sync.py +25 -24
  130. chia/_tests/plot_sync/test_receiver.py +9 -9
  131. chia/_tests/plot_sync/test_sender.py +1 -1
  132. chia/_tests/plot_sync/test_sync_simulated.py +27 -26
  133. chia/_tests/plot_sync/util.py +2 -1
  134. chia/_tests/plotting/test_plot_manager.py +54 -11
  135. chia/_tests/plotting/util.py +2 -3
  136. chia/_tests/pools/test_pool_cli_parsing.py +128 -0
  137. chia/_tests/pools/test_pool_cmdline.py +993 -15
  138. chia/_tests/pools/test_pool_config.py +3 -5
  139. chia/_tests/pools/test_pool_puzzles_lifecycle.py +10 -11
  140. chia/_tests/pools/test_pool_rpc.py +203 -90
  141. chia/_tests/pools/test_pool_wallet.py +12 -8
  142. chia/_tests/pools/test_wallet_pool_store.py +3 -3
  143. chia/_tests/process_junit.py +16 -17
  144. chia/_tests/rpc/test_rpc_client.py +59 -2
  145. chia/_tests/rpc/test_rpc_server.py +183 -0
  146. chia/_tests/simulation/test_simulation.py +5 -5
  147. chia/_tests/simulation/test_simulator.py +8 -10
  148. chia/_tests/simulation/test_start_simulator.py +5 -4
  149. chia/_tests/timelord/test_new_peak.py +19 -19
  150. chia/_tests/tools/test_run_block.py +1 -2
  151. chia/_tests/tools/test_virtual_project.py +591 -0
  152. chia/_tests/util/benchmark_cost.py +9 -9
  153. chia/_tests/util/benchmarks.py +1 -2
  154. chia/_tests/util/blockchain.py +12 -11
  155. chia/_tests/util/blockchain_mock.py +15 -15
  156. chia/_tests/util/build_network_protocol_files.py +12 -12
  157. chia/_tests/util/db_connection.py +3 -2
  158. chia/_tests/util/full_sync.py +14 -6
  159. chia/_tests/util/gen_ssl_certs.py +4 -5
  160. chia/_tests/util/generator_tools_testing.py +5 -7
  161. chia/_tests/util/get_name_puzzle_conditions.py +52 -0
  162. chia/_tests/util/key_tool.py +2 -3
  163. chia/_tests/util/misc.py +59 -106
  164. chia/_tests/util/network_protocol_data.py +7 -9
  165. chia/_tests/util/protocol_messages_json.py +112 -111
  166. chia/_tests/util/rpc.py +3 -0
  167. chia/_tests/util/run_block.py +16 -16
  168. chia/_tests/util/setup_nodes.py +25 -23
  169. chia/{clvm → _tests/util}/spend_sim.py +59 -55
  170. chia/_tests/util/split_managers.py +12 -9
  171. chia/_tests/util/temp_file.py +1 -1
  172. chia/_tests/util/test_action_scope.py +2 -1
  173. chia/_tests/util/test_async_pool.py +8 -8
  174. chia/_tests/util/test_build_job_matrix.py +2 -3
  175. chia/_tests/util/test_condition_tools.py +4 -6
  176. chia/_tests/util/test_config.py +5 -5
  177. chia/_tests/util/test_dump_keyring.py +1 -1
  178. chia/_tests/util/test_full_block_utils.py +19 -11
  179. chia/_tests/util/test_limited_semaphore.py +4 -3
  180. chia/_tests/util/test_logging_filter.py +2 -3
  181. chia/_tests/util/test_misc.py +29 -28
  182. chia/_tests/util/test_network.py +32 -31
  183. chia/_tests/util/test_network_protocol_files.py +2 -3
  184. chia/_tests/util/test_network_protocol_json.py +1 -0
  185. chia/_tests/util/test_network_protocol_test.py +18 -19
  186. chia/_tests/util/test_paginator.py +3 -4
  187. chia/_tests/util/test_pprint.py +1 -1
  188. chia/_tests/util/test_priority_mutex.py +18 -17
  189. chia/_tests/util/test_recursive_replace.py +2 -2
  190. chia/_tests/util/test_testnet_overrides.py +3 -3
  191. chia/_tests/util/test_timing.py +1 -1
  192. chia/_tests/util/test_trusted_peer.py +2 -2
  193. chia/_tests/util/time_out_assert.py +43 -6
  194. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +13 -13
  195. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -1
  196. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +117 -29
  197. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +15 -15
  198. chia/_tests/wallet/cat_wallet/test_trades.py +50 -28
  199. chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -5
  200. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +6 -6
  201. chia/_tests/wallet/clawback/test_clawback_metadata.py +1 -2
  202. chia/_tests/wallet/conftest.py +135 -74
  203. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +25 -17
  204. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +75 -75
  205. chia/_tests/wallet/db_wallet/test_db_graftroot.py +10 -12
  206. chia/_tests/wallet/db_wallet/test_dl_offers.py +6 -6
  207. chia/_tests/wallet/db_wallet/test_dl_wallet.py +18 -18
  208. chia/_tests/wallet/did_wallet/test_did.py +1277 -474
  209. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +12 -11
  210. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +115 -105
  211. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +6 -7
  212. chia/_tests/wallet/nft_wallet/test_nft_offers.py +16 -16
  213. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +3 -3
  214. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +38 -12
  215. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +1 -1
  216. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +31 -33
  217. chia/_tests/wallet/rpc/test_wallet_rpc.py +218 -171
  218. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +36 -37
  219. chia/_tests/wallet/sync/test_wallet_sync.py +241 -78
  220. chia/_tests/wallet/test_address_type.py +20 -20
  221. chia/_tests/wallet/test_clvm_streamable.py +5 -5
  222. chia/_tests/wallet/test_coin_management.py +354 -0
  223. chia/_tests/wallet/test_coin_selection.py +34 -35
  224. chia/_tests/wallet/test_conditions.py +28 -16
  225. chia/_tests/wallet/test_debug_spend_bundle.py +156 -14
  226. chia/_tests/wallet/test_new_wallet_protocol.py +29 -31
  227. chia/_tests/wallet/test_nft_store.py +1 -2
  228. chia/_tests/wallet/test_notifications.py +2 -2
  229. chia/_tests/wallet/test_offer_parsing_performance.py +1 -1
  230. chia/_tests/wallet/test_puzzle_store.py +2 -3
  231. chia/_tests/wallet/test_sign_coin_spends.py +3 -3
  232. chia/_tests/wallet/test_signer_protocol.py +33 -34
  233. chia/_tests/wallet/test_singleton_lifecycle_fast.py +29 -29
  234. chia/_tests/wallet/test_taproot.py +1 -1
  235. chia/_tests/wallet/test_transaction_store.py +23 -19
  236. chia/_tests/wallet/test_util.py +36 -32
  237. chia/_tests/wallet/test_wallet.py +37 -37
  238. chia/_tests/wallet/test_wallet_action_scope.py +8 -8
  239. chia/_tests/wallet/test_wallet_blockchain.py +4 -6
  240. chia/_tests/wallet/test_wallet_coin_store.py +34 -34
  241. chia/_tests/wallet/test_wallet_node.py +69 -72
  242. chia/_tests/wallet/test_wallet_retry.py +3 -3
  243. chia/_tests/wallet/test_wallet_state_manager.py +12 -5
  244. chia/_tests/wallet/test_wallet_trade_store.py +2 -2
  245. chia/_tests/wallet/test_wallet_utils.py +5 -4
  246. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -3
  247. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +18 -18
  248. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +69 -40
  249. chia/_tests/wallet/wallet_block_tools.py +27 -27
  250. chia/_tests/weight_proof/test_weight_proof.py +30 -30
  251. chia/apis.py +19 -0
  252. chia/cmds/beta.py +8 -7
  253. chia/cmds/beta_funcs.py +15 -11
  254. chia/cmds/check_wallet_db.py +29 -27
  255. chia/cmds/chia.py +17 -9
  256. chia/cmds/cmd_classes.py +87 -79
  257. chia/cmds/cmd_helpers.py +242 -0
  258. chia/cmds/cmds_util.py +56 -66
  259. chia/cmds/coin_funcs.py +168 -153
  260. chia/cmds/coins.py +156 -194
  261. chia/cmds/configure.py +4 -3
  262. chia/cmds/dao.py +89 -33
  263. chia/cmds/dao_funcs.py +55 -33
  264. chia/cmds/data.py +7 -6
  265. chia/cmds/data_funcs.py +26 -21
  266. chia/cmds/db.py +4 -3
  267. chia/cmds/db_backup_func.py +2 -2
  268. chia/cmds/db_upgrade_func.py +3 -3
  269. chia/cmds/db_validate_func.py +2 -2
  270. chia/cmds/dev.py +2 -0
  271. chia/cmds/farm.py +18 -5
  272. chia/cmds/farm_funcs.py +17 -24
  273. chia/cmds/gh.py +275 -0
  274. chia/cmds/init.py +4 -11
  275. chia/cmds/init_funcs.py +9 -9
  276. chia/cmds/installers.py +5 -3
  277. chia/cmds/keys.py +56 -39
  278. chia/cmds/keys_funcs.py +30 -31
  279. chia/cmds/netspace.py +6 -3
  280. chia/cmds/netspace_funcs.py +3 -2
  281. chia/cmds/param_types.py +16 -6
  282. chia/cmds/passphrase.py +8 -7
  283. chia/cmds/passphrase_funcs.py +7 -61
  284. chia/cmds/peer.py +2 -1
  285. chia/cmds/peer_funcs.py +5 -5
  286. chia/cmds/plotnft.py +207 -153
  287. chia/cmds/plotnft_funcs.py +205 -174
  288. chia/cmds/plots.py +14 -6
  289. chia/cmds/plotters.py +2 -1
  290. chia/cmds/rpc.py +48 -28
  291. chia/cmds/show.py +2 -1
  292. chia/cmds/show_funcs.py +7 -6
  293. chia/cmds/signer.py +50 -58
  294. chia/cmds/sim.py +22 -14
  295. chia/cmds/sim_funcs.py +11 -11
  296. chia/cmds/start.py +3 -3
  297. chia/cmds/start_funcs.py +9 -12
  298. chia/cmds/stop.py +4 -3
  299. chia/cmds/units.py +1 -3
  300. chia/cmds/wallet.py +252 -96
  301. chia/cmds/wallet_funcs.py +217 -143
  302. chia/consensus/block_body_validation.py +133 -86
  303. chia/consensus/block_creation.py +42 -21
  304. chia/consensus/block_header_validation.py +32 -37
  305. chia/consensus/block_record.py +1 -2
  306. chia/consensus/blockchain.py +167 -180
  307. chia/consensus/blockchain_interface.py +10 -10
  308. chia/consensus/constants.py +2 -2
  309. chia/consensus/default_constants.py +3 -4
  310. chia/consensus/difficulty_adjustment.py +5 -5
  311. chia/consensus/find_fork_point.py +5 -5
  312. chia/consensus/full_block_to_block_record.py +4 -4
  313. chia/consensus/get_block_challenge.py +2 -2
  314. chia/consensus/get_block_generator.py +4 -3
  315. chia/consensus/multiprocess_validation.py +207 -304
  316. chia/consensus/vdf_info_computation.py +3 -3
  317. chia/daemon/client.py +46 -27
  318. chia/daemon/keychain_proxy.py +10 -9
  319. chia/daemon/keychain_server.py +18 -18
  320. chia/daemon/server.py +103 -113
  321. chia/daemon/windows_signal.py +2 -2
  322. chia/data_layer/data_layer.py +64 -76
  323. chia/data_layer/data_layer_api.py +8 -0
  324. chia/data_layer/data_layer_errors.py +3 -3
  325. chia/data_layer/data_layer_server.py +2 -2
  326. chia/data_layer/data_layer_util.py +71 -71
  327. chia/data_layer/data_layer_wallet.py +63 -67
  328. chia/data_layer/data_store.py +72 -72
  329. chia/data_layer/dl_wallet_store.py +10 -10
  330. chia/data_layer/download_data.py +5 -5
  331. chia/data_layer/s3_plugin_service.py +9 -9
  332. chia/data_layer/util/benchmark.py +0 -1
  333. chia/data_layer/util/plugin.py +2 -3
  334. chia/farmer/farmer.py +46 -43
  335. chia/farmer/farmer_api.py +27 -21
  336. chia/full_node/block_height_map.py +6 -6
  337. chia/full_node/block_store.py +41 -35
  338. chia/full_node/coin_store.py +42 -41
  339. chia/full_node/fee_estimate.py +2 -2
  340. chia/full_node/fee_estimation.py +1 -2
  341. chia/full_node/fee_history.py +5 -6
  342. chia/full_node/fee_tracker.py +24 -24
  343. chia/full_node/full_node.py +574 -300
  344. chia/full_node/full_node_api.py +181 -130
  345. chia/full_node/full_node_store.py +43 -43
  346. chia/full_node/hint_management.py +4 -4
  347. chia/full_node/hint_store.py +9 -10
  348. chia/full_node/mempool.py +25 -19
  349. chia/full_node/mempool_check_conditions.py +11 -42
  350. chia/full_node/mempool_manager.py +48 -53
  351. chia/full_node/pending_tx_cache.py +9 -9
  352. chia/full_node/subscriptions.py +23 -24
  353. chia/full_node/sync_store.py +8 -7
  354. chia/full_node/tx_processing_queue.py +3 -3
  355. chia/full_node/util/__init__.py +0 -0
  356. chia/full_node/weight_proof.py +79 -78
  357. chia/harvester/harvester.py +9 -8
  358. chia/harvester/harvester_api.py +19 -13
  359. chia/introducer/introducer.py +7 -5
  360. chia/introducer/introducer_api.py +9 -3
  361. chia/legacy/keyring.py +6 -5
  362. chia/plot_sync/delta.py +8 -8
  363. chia/plot_sync/receiver.py +12 -11
  364. chia/plot_sync/sender.py +15 -12
  365. chia/plotters/bladebit.py +12 -12
  366. chia/plotters/chiapos.py +2 -2
  367. chia/plotters/madmax.py +8 -8
  368. chia/plotters/plotters.py +6 -6
  369. chia/plotters/plotters_util.py +6 -4
  370. chia/plotting/cache.py +8 -7
  371. chia/plotting/check_plots.py +8 -8
  372. chia/plotting/create_plots.py +6 -6
  373. chia/plotting/manager.py +22 -22
  374. chia/plotting/util.py +31 -19
  375. chia/pools/pool_config.py +7 -7
  376. chia/pools/pool_puzzles.py +16 -16
  377. chia/pools/pool_wallet.py +64 -57
  378. chia/pools/pool_wallet_info.py +3 -3
  379. chia/protocols/full_node_protocol.py +3 -3
  380. chia/protocols/harvester_protocol.py +12 -12
  381. chia/protocols/introducer_protocol.py +1 -2
  382. chia/protocols/protocol_message_types.py +4 -4
  383. chia/protocols/protocol_state_machine.py +2 -2
  384. chia/protocols/protocol_timing.py +1 -0
  385. chia/protocols/shared_protocol.py +3 -3
  386. chia/protocols/timelord_protocol.py +2 -2
  387. chia/protocols/wallet_protocol.py +33 -33
  388. chia/rpc/crawler_rpc_api.py +12 -7
  389. chia/rpc/data_layer_rpc_api.py +49 -44
  390. chia/rpc/data_layer_rpc_client.py +41 -41
  391. chia/rpc/data_layer_rpc_util.py +7 -11
  392. chia/rpc/farmer_rpc_api.py +32 -27
  393. chia/rpc/farmer_rpc_client.py +14 -14
  394. chia/rpc/full_node_rpc_api.py +53 -48
  395. chia/rpc/full_node_rpc_client.py +30 -30
  396. chia/rpc/harvester_rpc_api.py +16 -11
  397. chia/rpc/harvester_rpc_client.py +6 -6
  398. chia/rpc/rpc_client.py +34 -14
  399. chia/rpc/rpc_server.py +117 -43
  400. chia/rpc/timelord_rpc_api.py +9 -4
  401. chia/rpc/util.py +11 -211
  402. chia/rpc/wallet_request_types.py +276 -60
  403. chia/rpc/wallet_rpc_api.py +563 -399
  404. chia/rpc/wallet_rpc_client.py +220 -250
  405. chia/seeder/crawl_store.py +6 -8
  406. chia/seeder/crawler.py +23 -36
  407. chia/seeder/crawler_api.py +28 -22
  408. chia/seeder/dns_server.py +99 -50
  409. chia/seeder/start_crawler.py +13 -9
  410. chia/server/address_manager.py +19 -19
  411. chia/server/address_manager_store.py +17 -17
  412. chia/server/api_protocol.py +106 -1
  413. chia/server/capabilities.py +3 -3
  414. chia/server/chia_policy.py +17 -16
  415. chia/server/introducer_peers.py +3 -3
  416. chia/server/node_discovery.py +34 -38
  417. chia/server/rate_limit_numbers.py +26 -16
  418. chia/server/rate_limits.py +67 -27
  419. chia/server/server.py +52 -31
  420. chia/server/signal_handlers.py +6 -3
  421. chia/server/ssl_context.py +5 -5
  422. chia/server/start_data_layer.py +37 -23
  423. chia/server/start_farmer.py +28 -16
  424. chia/server/start_full_node.py +29 -23
  425. chia/server/start_harvester.py +28 -15
  426. chia/server/start_introducer.py +27 -15
  427. chia/server/start_service.py +17 -29
  428. chia/server/start_timelord.py +25 -18
  429. chia/server/start_wallet.py +22 -18
  430. chia/server/upnp.py +4 -3
  431. chia/server/ws_connection.py +68 -54
  432. chia/simulator/add_blocks_in_batches.py +54 -0
  433. chia/simulator/block_tools.py +65 -64
  434. chia/simulator/full_node_simulator.py +66 -74
  435. chia/simulator/setup_services.py +10 -9
  436. chia/simulator/simulator_full_node_rpc_api.py +12 -14
  437. chia/simulator/simulator_full_node_rpc_client.py +3 -5
  438. chia/simulator/simulator_test_tools.py +8 -7
  439. chia/simulator/socket.py +1 -4
  440. chia/simulator/ssl_certs.py +5 -5
  441. chia/simulator/ssl_certs_1.py +2 -4
  442. chia/simulator/ssl_certs_10.py +2 -4
  443. chia/simulator/ssl_certs_2.py +2 -4
  444. chia/simulator/ssl_certs_3.py +2 -4
  445. chia/simulator/ssl_certs_4.py +2 -4
  446. chia/simulator/ssl_certs_5.py +2 -4
  447. chia/simulator/ssl_certs_6.py +2 -4
  448. chia/simulator/ssl_certs_7.py +2 -4
  449. chia/simulator/ssl_certs_8.py +2 -4
  450. chia/simulator/ssl_certs_9.py +2 -4
  451. chia/simulator/start_simulator.py +14 -6
  452. chia/simulator/wallet_tools.py +21 -20
  453. chia/ssl/create_ssl.py +11 -11
  454. chia/timelord/iters_from_block.py +2 -2
  455. chia/timelord/timelord.py +57 -33
  456. chia/timelord/timelord_api.py +12 -6
  457. chia/timelord/timelord_launcher.py +10 -8
  458. chia/timelord/timelord_state.py +5 -5
  459. chia/types/block_protocol.py +2 -2
  460. chia/types/blockchain_format/coin.py +3 -3
  461. chia/types/blockchain_format/program.py +17 -18
  462. chia/types/blockchain_format/tree_hash.py +9 -9
  463. chia/types/coin_spend.py +8 -8
  464. chia/types/condition_with_args.py +1 -2
  465. chia/types/eligible_coin_spends.py +16 -15
  466. chia/types/generator_types.py +1 -2
  467. chia/types/internal_mempool_item.py +1 -2
  468. chia/types/mempool_item.py +7 -7
  469. chia/types/mempool_submission_status.py +2 -2
  470. chia/types/peer_info.py +1 -1
  471. chia/types/spend_bundle.py +1 -2
  472. chia/types/transaction_queue_entry.py +2 -2
  473. chia/types/unfinished_header_block.py +2 -2
  474. chia/types/validation_state.py +14 -0
  475. chia/types/weight_proof.py +5 -6
  476. chia/util/action_scope.py +8 -8
  477. chia/util/async_pool.py +6 -4
  478. chia/util/augmented_chain.py +13 -9
  479. chia/util/batches.py +5 -2
  480. chia/util/bech32m.py +14 -11
  481. chia/util/beta_metrics.py +5 -4
  482. chia/util/block_cache.py +5 -5
  483. chia/util/byte_types.py +2 -0
  484. chia/util/check_fork_next_block.py +3 -2
  485. chia/util/chia_logging.py +41 -21
  486. chia/util/collection.py +3 -3
  487. chia/util/condition_tools.py +18 -18
  488. chia/util/config.py +26 -25
  489. chia/util/cpu.py +2 -0
  490. chia/util/db_synchronous.py +2 -0
  491. chia/util/db_version.py +2 -0
  492. chia/util/db_wrapper.py +13 -10
  493. chia/util/default_root.py +17 -0
  494. chia/util/dump_keyring.py +6 -6
  495. chia/util/errors.py +5 -3
  496. chia/util/file_keyring.py +22 -33
  497. chia/util/files.py +2 -0
  498. chia/util/full_block_utils.py +31 -7
  499. chia/util/generator_tools.py +18 -8
  500. chia/util/hash.py +3 -1
  501. chia/util/initial-config.yaml +19 -0
  502. chia/util/inline_executor.py +2 -0
  503. chia/util/ip_address.py +39 -0
  504. chia/util/json_util.py +0 -4
  505. chia/util/keychain.py +27 -24
  506. chia/util/keyring_wrapper.py +65 -4
  507. chia/util/limited_semaphore.py +3 -1
  508. chia/util/lock.py +4 -2
  509. chia/util/log_exceptions.py +5 -2
  510. chia/util/logging.py +3 -1
  511. chia/util/lru_cache.py +2 -0
  512. chia/util/math.py +4 -4
  513. chia/util/network.py +15 -73
  514. chia/util/paginator.py +3 -1
  515. chia/util/path.py +2 -0
  516. chia/util/permissions.py +3 -2
  517. chia/util/prev_transaction_block.py +1 -3
  518. chia/util/priority_mutex.py +6 -3
  519. chia/util/profiler.py +7 -4
  520. chia/util/recursive_replace.py +2 -0
  521. chia/util/safe_cancel_task.py +2 -0
  522. chia/util/service_groups.py +2 -2
  523. chia/util/setproctitle.py +2 -0
  524. chia/util/significant_bits.py +2 -0
  525. chia/util/ssl_check.py +11 -11
  526. chia/util/streamable.py +44 -56
  527. chia/util/task_referencer.py +59 -0
  528. chia/util/task_timing.py +22 -18
  529. chia/util/timing.py +4 -1
  530. chia/util/vdf_prover.py +2 -3
  531. chia/util/virtual_project_analysis.py +540 -0
  532. chia/util/ws_message.py +6 -6
  533. chia/wallet/cat_wallet/cat_info.py +3 -3
  534. chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -3
  535. chia/wallet/cat_wallet/cat_utils.py +5 -4
  536. chia/wallet/cat_wallet/cat_wallet.py +56 -70
  537. chia/wallet/cat_wallet/dao_cat_info.py +3 -3
  538. chia/wallet/cat_wallet/dao_cat_wallet.py +18 -18
  539. chia/wallet/cat_wallet/lineage_store.py +2 -2
  540. chia/wallet/coin_selection.py +15 -15
  541. chia/wallet/conditions.py +257 -71
  542. chia/wallet/dao_wallet/dao_info.py +4 -4
  543. chia/wallet/dao_wallet/dao_utils.py +43 -42
  544. chia/wallet/dao_wallet/dao_wallet.py +66 -68
  545. chia/wallet/db_wallet/db_wallet_puzzles.py +12 -8
  546. chia/wallet/derive_keys.py +11 -11
  547. chia/wallet/did_wallet/did_info.py +3 -3
  548. chia/wallet/did_wallet/did_wallet.py +56 -47
  549. chia/wallet/did_wallet/did_wallet_puzzles.py +7 -6
  550. chia/wallet/lineage_proof.py +4 -4
  551. chia/wallet/nft_wallet/metadata_outer_puzzle.py +2 -2
  552. chia/wallet/nft_wallet/nft_info.py +4 -4
  553. chia/wallet/nft_wallet/nft_puzzles.py +16 -16
  554. chia/wallet/nft_wallet/nft_wallet.py +90 -89
  555. chia/wallet/nft_wallet/ownership_outer_puzzle.py +2 -2
  556. chia/wallet/nft_wallet/singleton_outer_puzzle.py +2 -2
  557. chia/wallet/nft_wallet/transfer_program_puzzle.py +2 -2
  558. chia/wallet/nft_wallet/uncurry_nft.py +2 -2
  559. chia/wallet/notification_manager.py +5 -5
  560. chia/wallet/notification_store.py +6 -6
  561. chia/wallet/outer_puzzles.py +2 -2
  562. chia/wallet/payment.py +4 -5
  563. chia/wallet/puzzle_drivers.py +4 -4
  564. chia/wallet/puzzles/clawback/drivers.py +5 -5
  565. chia/wallet/puzzles/clawback/puzzle_decorator.py +7 -7
  566. chia/wallet/puzzles/load_clvm.py +2 -3
  567. chia/wallet/puzzles/p2_conditions.py +1 -2
  568. chia/wallet/puzzles/p2_delegated_conditions.py +1 -2
  569. chia/wallet/puzzles/p2_delegated_puzzle.py +2 -3
  570. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -4
  571. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +1 -2
  572. chia/wallet/puzzles/p2_puzzle_hash.py +1 -2
  573. chia/wallet/puzzles/puzzle_utils.py +7 -7
  574. chia/wallet/puzzles/singleton_top_layer.py +6 -5
  575. chia/wallet/puzzles/singleton_top_layer_v1_1.py +6 -5
  576. chia/wallet/puzzles/tails.py +34 -30
  577. chia/wallet/signer_protocol.py +7 -8
  578. chia/wallet/singleton.py +4 -4
  579. chia/wallet/trade_manager.py +155 -141
  580. chia/wallet/trade_record.py +5 -5
  581. chia/wallet/trading/offer.py +100 -101
  582. chia/wallet/trading/trade_store.py +14 -14
  583. chia/wallet/transaction_record.py +31 -16
  584. chia/wallet/util/address_type.py +4 -4
  585. chia/wallet/util/blind_signer_tl.py +8 -12
  586. chia/wallet/util/clvm_streamable.py +15 -15
  587. chia/wallet/util/compute_hints.py +5 -5
  588. chia/wallet/util/compute_memos.py +4 -6
  589. chia/wallet/util/curry_and_treehash.py +3 -2
  590. chia/wallet/util/debug_spend_bundle.py +6 -8
  591. chia/wallet/util/merkle_tree.py +10 -10
  592. chia/wallet/util/merkle_utils.py +10 -10
  593. chia/wallet/util/new_peak_queue.py +3 -3
  594. chia/wallet/util/peer_request_cache.py +8 -8
  595. chia/{util → wallet/util}/pprint.py +2 -3
  596. chia/wallet/util/puzzle_compression.py +3 -4
  597. chia/wallet/util/puzzle_decorator.py +10 -10
  598. chia/wallet/util/query_filter.py +9 -10
  599. chia/wallet/util/tx_config.py +12 -12
  600. chia/wallet/util/wallet_sync_utils.py +24 -21
  601. chia/wallet/util/wallet_types.py +9 -2
  602. chia/wallet/vc_wallet/cr_cat_drivers.py +28 -27
  603. chia/wallet/vc_wallet/cr_cat_wallet.py +42 -40
  604. chia/wallet/vc_wallet/cr_outer_puzzle.py +4 -4
  605. chia/wallet/vc_wallet/vc_drivers.py +16 -16
  606. chia/wallet/vc_wallet/vc_store.py +9 -9
  607. chia/wallet/vc_wallet/vc_wallet.py +35 -35
  608. chia/wallet/wallet.py +54 -54
  609. chia/wallet/wallet_action_scope.py +14 -13
  610. chia/wallet/wallet_blockchain.py +10 -10
  611. chia/wallet/wallet_coin_record.py +2 -2
  612. chia/wallet/wallet_coin_store.py +10 -10
  613. chia/wallet/wallet_info.py +1 -2
  614. chia/wallet/wallet_interested_store.py +5 -5
  615. chia/wallet/wallet_nft_store.py +6 -6
  616. chia/wallet/wallet_node.py +72 -76
  617. chia/wallet/wallet_node_api.py +33 -27
  618. chia/wallet/wallet_pool_store.py +1 -2
  619. chia/wallet/wallet_protocol.py +15 -15
  620. chia/wallet/wallet_puzzle_store.py +35 -4
  621. chia/wallet/wallet_retry_store.py +2 -2
  622. chia/wallet/wallet_singleton_store.py +10 -9
  623. chia/wallet/wallet_spend_bundle.py +4 -20
  624. chia/wallet/wallet_state_manager.py +223 -224
  625. chia/wallet/wallet_transaction_store.py +44 -18
  626. chia/wallet/wallet_user_store.py +2 -2
  627. chia/wallet/wallet_weight_proof_handler.py +2 -2
  628. {chia_blockchain-2.5.0rc1.dist-info → chia_blockchain-2.5.1.dist-info}/LICENSE +1 -1
  629. {chia_blockchain-2.5.0rc1.dist-info → chia_blockchain-2.5.1.dist-info}/METADATA +67 -72
  630. chia_blockchain-2.5.1.dist-info/RECORD +1042 -0
  631. {chia_blockchain-2.5.0rc1.dist-info → chia_blockchain-2.5.1.dist-info}/WHEEL +1 -1
  632. mozilla-ca/cacert.pem +32 -87
  633. chia/_tests/cmds/wallet/test_coins.py +0 -195
  634. chia/consensus/block_root_validation.py +0 -46
  635. chia/util/api_decorators.py +0 -89
  636. chia_blockchain-2.5.0rc1.dist-info/RECORD +0 -1028
  637. {chia_blockchain-2.5.0rc1.dist-info → chia_blockchain-2.5.1.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,6 @@ import random
6
6
  import time
7
7
  from dataclasses import dataclass, field, replace
8
8
  from datetime import datetime, timedelta
9
- from typing import Dict, List
10
9
 
11
10
  import aiosqlite
12
11
 
@@ -19,9 +18,9 @@ log = logging.getLogger(__name__)
19
18
  @dataclass
20
19
  class CrawlStore:
21
20
  crawl_db: aiosqlite.Connection
22
- host_to_records: Dict[str, PeerRecord] = field(default_factory=dict) # peer_id: PeerRecord
23
- host_to_selected_time: Dict[str, float] = field(default_factory=dict) # peer_id: timestamp (as a float)
24
- host_to_reliability: Dict[str, PeerReliability] = field(default_factory=dict) # peer_id: PeerReliability
21
+ host_to_records: dict[str, PeerRecord] = field(default_factory=dict) # peer_id: PeerRecord
22
+ host_to_selected_time: dict[str, float] = field(default_factory=dict) # peer_id: timestamp (as a float)
23
+ host_to_reliability: dict[str, PeerReliability] = field(default_factory=dict) # peer_id: PeerReliability
25
24
  banned_peers: int = 0
26
25
  ignored_peers: int = 0
27
26
  reliable_peers: int = 0
@@ -184,17 +183,16 @@ class CrawlStore:
184
183
  else:
185
184
  await self.peer_failed_to_connect(record)
186
185
 
187
- async def get_peers_to_crawl(self, min_batch_size: int, max_batch_size: int) -> List[PeerRecord]:
186
+ async def get_peers_to_crawl(self, min_batch_size: int, max_batch_size: int) -> list[PeerRecord]:
188
187
  now = int(time.time())
189
188
  records = []
190
189
  records_v6 = []
191
190
  counter = 0
192
191
  self.ignored_peers = 0
193
192
  self.banned_peers = 0
194
- for peer_id in self.host_to_reliability:
193
+ for peer_id, reliability in self.host_to_reliability.items():
195
194
  add = False
196
195
  counter += 1
197
- reliability = self.host_to_reliability[peer_id]
198
196
  if reliability.ignore_till < now and reliability.ban_till < now:
199
197
  add = True
200
198
  else:
@@ -410,7 +408,7 @@ class CrawlStore:
410
408
  await self.crawl_db.commit()
411
409
  await self.crawl_db.execute("VACUUM")
412
410
 
413
- to_delete: List[str] = []
411
+ to_delete: list[str] = []
414
412
 
415
413
  # Deletes the old records from the in memory Dicts
416
414
  for peer_id, peer_record in self.host_to_records.items():
chia/seeder/crawler.py CHANGED
@@ -7,22 +7,10 @@ import logging
7
7
  import time
8
8
  import traceback
9
9
  from collections import defaultdict
10
+ from collections.abc import AsyncIterator, Awaitable
10
11
  from dataclasses import dataclass, field
11
12
  from pathlib import Path
12
- from typing import (
13
- TYPE_CHECKING,
14
- Any,
15
- AsyncIterator,
16
- Awaitable,
17
- Callable,
18
- ClassVar,
19
- Dict,
20
- List,
21
- Optional,
22
- Set,
23
- Tuple,
24
- cast,
25
- )
13
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, cast
26
14
 
27
15
  import aiosqlite
28
16
 
@@ -41,6 +29,7 @@ from chia.util.chia_version import chia_short_version
41
29
  from chia.util.ints import uint32, uint64
42
30
  from chia.util.network import resolve
43
31
  from chia.util.path import path_from_root
32
+ from chia.util.task_referencer import create_referenced_task
44
33
 
45
34
  log = logging.getLogger(__name__)
46
35
 
@@ -52,7 +41,7 @@ class Crawler:
52
41
 
53
42
  _protocol_check: ClassVar[RpcServiceProtocol] = cast("Crawler", None)
54
43
 
55
- config: Dict[str, Any]
44
+ config: dict[str, Any]
56
45
  root_path: Path
57
46
  constants: ConsensusConstants
58
47
  print_status: bool = True
@@ -63,15 +52,15 @@ class Crawler:
63
52
  log: logging.Logger = log
64
53
  _shut_down: bool = False
65
54
  peer_count: int = 0
66
- with_peak: Set[PeerInfo] = field(default_factory=set)
67
- seen_nodes: Set[str] = field(default_factory=set)
55
+ with_peak: set[PeerInfo] = field(default_factory=set)
56
+ seen_nodes: set[str] = field(default_factory=set)
68
57
  minimum_version_count: int = 0
69
- peers_retrieved: List[RespondPeers] = field(default_factory=list)
70
- host_to_version: Dict[str, str] = field(default_factory=dict)
71
- versions: Dict[str, int] = field(default_factory=lambda: defaultdict(int))
72
- version_cache: List[Tuple[str, str]] = field(default_factory=list)
73
- handshake_time: Dict[str, uint64] = field(default_factory=dict)
74
- best_timestamp_per_peer: Dict[str, uint64] = field(default_factory=dict)
58
+ peers_retrieved: list[RespondPeers] = field(default_factory=list)
59
+ host_to_version: dict[str, str] = field(default_factory=dict)
60
+ versions: dict[str, int] = field(default_factory=lambda: defaultdict(int))
61
+ version_cache: list[tuple[str, str]] = field(default_factory=list)
62
+ handshake_time: dict[str, uint64] = field(default_factory=dict)
63
+ best_timestamp_per_peer: dict[str, uint64] = field(default_factory=dict)
75
64
  start_crawler_loop: bool = True
76
65
 
77
66
  @property
@@ -94,7 +83,7 @@ class Crawler:
94
83
  if self.start_crawler_loop:
95
84
  # Bootstrap the initial peers
96
85
  await self.load_bootstrap_peers()
97
- self.crawl_task = asyncio.create_task(self.crawl())
86
+ self.crawl_task = create_referenced_task(self.crawl())
98
87
  try:
99
88
  yield
100
89
  finally:
@@ -129,7 +118,7 @@ class Crawler:
129
118
  def _set_state_changed_callback(self, callback: StateChangedProtocol) -> None:
130
119
  self.state_changed_callback = callback
131
120
 
132
- def get_connections(self, request_node_type: Optional[NodeType]) -> List[Dict[str, Any]]:
121
+ def get_connections(self, request_node_type: Optional[NodeType]) -> list[dict[str, Any]]:
133
122
  return default_get_connections(server=self.server, request_node_type=request_node_type)
134
123
 
135
124
  async def create_client(
@@ -231,7 +220,7 @@ class Crawler:
231
220
  total_nodes += 1
232
221
  if peer.ip_address not in tried_nodes:
233
222
  tried_nodes.add(peer.ip_address)
234
- task = asyncio.create_task(self.connect_task(peer))
223
+ task = create_referenced_task(self.connect_task(peer))
235
224
  tasks.add(task)
236
225
  if len(tasks) >= 250:
237
226
  await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
@@ -300,18 +289,16 @@ class Crawler:
300
289
  self.versions[version] += 1
301
290
 
302
291
  # clear caches
303
- self.version_cache: List[Tuple[str, str]] = []
292
+ self.version_cache: list[tuple[str, str]] = []
304
293
  self.peers_retrieved = []
305
294
  self.server.banned_peers = {}
306
295
  self.with_peak = set()
307
296
 
308
- if len(peers_to_crawl) == 0:
309
- continue
310
-
311
- peer_cutoff = int(self.config.get("crawler", {}).get("prune_peer_days", 90))
312
- await self.save_to_db()
313
- await self.crawl_store.prune_old_peers(older_than_days=peer_cutoff)
314
- await self.print_summary(t_start, total_nodes, tried_nodes)
297
+ if len(peers_to_crawl) > 0:
298
+ peer_cutoff = int(self.config.get("crawler", {}).get("prune_peer_days", 90))
299
+ await self.save_to_db()
300
+ await self.crawl_store.prune_old_peers(older_than_days=peer_cutoff)
301
+ await self.print_summary(t_start, total_nodes, tried_nodes)
315
302
  await asyncio.sleep(15) # 15 seconds between db updates
316
303
  self._state_changed("crawl_batch_completed")
317
304
  except Exception as e:
@@ -335,7 +322,7 @@ class Crawler:
335
322
  def set_server(self, server: ChiaServer) -> None:
336
323
  self._server = server
337
324
 
338
- def _state_changed(self, change: str, change_data: Optional[Dict[str, Any]] = None) -> None:
325
+ def _state_changed(self, change: str, change_data: Optional[dict[str, Any]] = None) -> None:
339
326
  if self.state_changed_callback is not None:
340
327
  self.state_changed_callback(change, change_data)
341
328
 
@@ -362,7 +349,7 @@ class Crawler:
362
349
  async def on_connect(self, connection: WSChiaConnection) -> None:
363
350
  pass
364
351
 
365
- async def print_summary(self, t_start: float, total_nodes: int, tried_nodes: Set[str]) -> None:
352
+ async def print_summary(self, t_start: float, total_nodes: int, tried_nodes: set[str]) -> None:
366
353
  assert self.crawl_store is not None # this is only ever called from the crawl task
367
354
  if not self.print_status:
368
355
  return
@@ -1,19 +1,25 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from typing import Optional
4
+ from typing import TYPE_CHECKING, ClassVar, Optional, cast
5
5
 
6
6
  from chia.protocols import full_node_protocol, wallet_protocol
7
7
  from chia.seeder.crawler import Crawler
8
+ from chia.server.api_protocol import ApiMetadata
8
9
  from chia.server.outbound_message import Message
9
10
  from chia.server.server import ChiaServer
10
11
  from chia.server.ws_connection import WSChiaConnection
11
- from chia.util.api_decorators import api_request
12
12
 
13
13
 
14
14
  class CrawlerAPI:
15
+ if TYPE_CHECKING:
16
+ from chia.server.api_protocol import ApiProtocol
17
+
18
+ _protocol_check: ClassVar[ApiProtocol] = cast("CrawlerAPI", None)
19
+
15
20
  log: logging.Logger
16
21
  crawler: Crawler
22
+ metadata: ClassVar[ApiMetadata] = ApiMetadata()
17
23
 
18
24
  def __init__(self, crawler: Crawler) -> None:
19
25
  self.log = logging.getLogger(__name__)
@@ -27,80 +33,80 @@ class CrawlerAPI:
27
33
  def ready(self) -> bool:
28
34
  return True
29
35
 
30
- @api_request(peer_required=True)
36
+ @metadata.request(peer_required=True)
31
37
  async def request_peers(
32
38
  self, _request: full_node_protocol.RequestPeers, peer: WSChiaConnection
33
39
  ) -> Optional[Message]:
34
40
  pass
35
41
 
36
- @api_request(peer_required=True)
42
+ @metadata.request(peer_required=True)
37
43
  async def respond_peers(
38
44
  self, request: full_node_protocol.RespondPeers, peer: WSChiaConnection
39
45
  ) -> Optional[Message]:
40
46
  pass
41
47
 
42
- @api_request(peer_required=True)
48
+ @metadata.request(peer_required=True)
43
49
  async def new_peak(self, request: full_node_protocol.NewPeak, peer: WSChiaConnection) -> Optional[Message]:
44
50
  await self.crawler.new_peak(request, peer)
45
51
  return None
46
52
 
47
- @api_request()
53
+ @metadata.request()
48
54
  async def new_transaction(self, transaction: full_node_protocol.NewTransaction) -> Optional[Message]:
49
55
  pass
50
56
 
51
- @api_request(peer_required=True)
57
+ @metadata.request(peer_required=True)
52
58
  async def new_signage_point_or_end_of_sub_slot(
53
59
  self, new_sp: full_node_protocol.NewSignagePointOrEndOfSubSlot, peer: WSChiaConnection
54
60
  ) -> Optional[Message]:
55
61
  pass
56
62
 
57
- @api_request()
63
+ @metadata.request()
58
64
  async def new_unfinished_block(
59
65
  self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock
60
66
  ) -> Optional[Message]:
61
67
  pass
62
68
 
63
- @api_request()
69
+ @metadata.request()
64
70
  async def new_unfinished_block2(
65
71
  self, new_unfinished_block: full_node_protocol.NewUnfinishedBlock2
66
72
  ) -> Optional[Message]:
67
73
  pass
68
74
 
69
- @api_request(peer_required=True)
75
+ @metadata.request(peer_required=True)
70
76
  async def new_compact_vdf(
71
77
  self, request: full_node_protocol.NewCompactVDF, peer: WSChiaConnection
72
78
  ) -> Optional[Message]:
73
79
  pass
74
80
 
75
- @api_request()
81
+ @metadata.request()
76
82
  async def request_transaction(self, request: full_node_protocol.RequestTransaction) -> Optional[Message]:
77
83
  pass
78
84
 
79
- @api_request()
85
+ @metadata.request()
80
86
  async def request_proof_of_weight(self, request: full_node_protocol.RequestProofOfWeight) -> Optional[Message]:
81
87
  pass
82
88
 
83
- @api_request()
89
+ @metadata.request()
84
90
  async def request_block(self, request: full_node_protocol.RequestBlock) -> Optional[Message]:
85
91
  pass
86
92
 
87
- @api_request()
93
+ @metadata.request()
88
94
  async def request_blocks(self, request: full_node_protocol.RequestBlocks) -> Optional[Message]:
89
95
  pass
90
96
 
91
- @api_request()
97
+ @metadata.request()
92
98
  async def request_unfinished_block(
93
99
  self, request_unfinished_block: full_node_protocol.RequestUnfinishedBlock
94
100
  ) -> Optional[Message]:
95
101
  pass
96
102
 
97
- @api_request()
103
+ @metadata.request()
98
104
  async def request_signage_point_or_end_of_sub_slot(
99
105
  self, request: full_node_protocol.RequestSignagePointOrEndOfSubSlot
100
106
  ) -> Optional[Message]:
101
107
  pass
102
108
 
103
- @api_request(peer_required=True)
109
+ @metadata.request(peer_required=True)
104
110
  async def request_mempool_transactions(
105
111
  self,
106
112
  request: full_node_protocol.RequestMempoolTransactions,
@@ -108,22 +114,22 @@ class CrawlerAPI:
108
114
  ) -> Optional[Message]:
109
115
  pass
110
116
 
111
- @api_request()
117
+ @metadata.request()
112
118
  async def request_block_header(self, request: wallet_protocol.RequestBlockHeader) -> Optional[Message]:
113
119
  pass
114
120
 
115
- @api_request()
121
+ @metadata.request()
116
122
  async def request_additions(self, request: wallet_protocol.RequestAdditions) -> Optional[Message]:
117
123
  pass
118
124
 
119
- @api_request()
125
+ @metadata.request()
120
126
  async def request_removals(self, request: wallet_protocol.RequestRemovals) -> Optional[Message]:
121
127
  pass
122
128
 
123
- @api_request()
129
+ @metadata.request()
124
130
  async def request_puzzle_solution(self, request: wallet_protocol.RequestPuzzleSolution) -> Optional[Message]:
125
131
  pass
126
132
 
127
- @api_request()
133
+ @metadata.request()
128
134
  async def request_header_blocks(self, request: wallet_protocol.RequestHeaderBlocks) -> Optional[Message]:
129
135
  pass
chia/seeder/dns_server.py CHANGED
@@ -5,23 +5,26 @@ import logging
5
5
  import signal
6
6
  import sys
7
7
  import traceback
8
+ from collections.abc import AsyncIterator, Awaitable
8
9
  from contextlib import asynccontextmanager
9
10
  from dataclasses import dataclass, field
10
11
  from ipaddress import IPv4Address, IPv6Address, ip_address
11
12
  from multiprocessing import freeze_support
12
13
  from pathlib import Path
13
14
  from types import FrameType
14
- from typing import Any, AsyncIterator, Awaitable, Callable, Dict, List, Optional
15
+ from typing import Any, Callable, Optional
15
16
 
16
17
  import aiosqlite
18
+ import dns.asyncresolver
17
19
  from dnslib import AAAA, EDNS0, NS, QTYPE, RCODE, RD, RR, SOA, A, DNSError, DNSHeader, DNSQuestion, DNSRecord
18
20
 
19
21
  from chia.seeder.crawl_store import CrawlStore
20
22
  from chia.server.signal_handlers import SignalHandlers
21
23
  from chia.util.chia_logging import initialize_service_logging
22
24
  from chia.util.config import load_config, load_config_cli
23
- from chia.util.default_root import DEFAULT_ROOT_PATH
25
+ from chia.util.default_root import resolve_root_path
24
26
  from chia.util.path import path_from_root
27
+ from chia.util.task_referencer import create_referenced_task
25
28
 
26
29
  SERVICE_NAME = "seeder"
27
30
  log = logging.getLogger(__name__)
@@ -38,8 +41,8 @@ class DomainName(str):
38
41
 
39
42
  @dataclass(frozen=True)
40
43
  class PeerList:
41
- ipv4: List[IPv4Address]
42
- ipv6: List[IPv6Address]
44
+ ipv4: list[IPv4Address]
45
+ ipv6: list[IPv6Address]
43
46
 
44
47
  @property
45
48
  def no_peers(self) -> bool:
@@ -58,7 +61,7 @@ class UDPDNSServerProtocol(asyncio.DatagramProtocol):
58
61
  queue_task: Optional[asyncio.Task[None]] = field(init=False, default=None)
59
62
 
60
63
  def start(self) -> None:
61
- self.queue_task = asyncio.create_task(self.respond()) # This starts the dns respond loop.
64
+ self.queue_task = create_referenced_task(self.respond()) # This starts the dns respond loop.
62
65
 
63
66
  async def stop(self) -> None:
64
67
  if self.queue_task is not None:
@@ -79,11 +82,12 @@ class UDPDNSServerProtocol(asyncio.DatagramProtocol):
79
82
  dns_request: Optional[DNSRecord] = parse_dns_request(data)
80
83
  if dns_request is None: # Invalid Request, we can just drop it and move on.
81
84
  return
82
- asyncio.create_task(self.handler(dns_request, addr))
85
+ create_referenced_task(self.handler(dns_request, addr), known_unreferenced=True)
83
86
 
84
87
  async def respond(self) -> None:
85
88
  log.info("UDP DNS responder started.")
86
- while self.transport is None: # we wait for the transport to be set.
89
+ # TODO: switch to event driven code
90
+ while self.transport is None: # we wait for the transport to be set. # noqa: ASYNC110
87
91
  await asyncio.sleep(0.1)
88
92
  while not self.transport.is_closing():
89
93
  try:
@@ -121,7 +125,7 @@ class TCPDNSServerProtocol(asyncio.BufferedProtocol):
121
125
  peer_info: str = field(init=False, default="")
122
126
  expected_length: int = 0
123
127
  buffer: bytearray = field(init=False, default_factory=lambda: bytearray(2))
124
- futures: List[asyncio.Future[None]] = field(init=False, default_factory=list)
128
+ futures: list[asyncio.Future[None]] = field(init=False, default_factory=list)
125
129
 
126
130
  def connection_made(self, transport: asyncio.BaseTransport) -> None:
127
131
  """
@@ -176,7 +180,7 @@ class TCPDNSServerProtocol(asyncio.BufferedProtocol):
176
180
  if dns_request is None: # Invalid Request, so we disconnect and don't send anything back.
177
181
  self.transport.close()
178
182
  return
179
- self.futures.append(asyncio.create_task(self.handle_and_respond(dns_request)))
183
+ self.futures.append(create_referenced_task(self.handle_and_respond(dns_request)))
180
184
 
181
185
  self.buffer = bytearray(2 if self.expected_length == 0 else self.expected_length) # Reset the buffer if empty.
182
186
 
@@ -191,7 +195,7 @@ class TCPDNSServerProtocol(asyncio.BufferedProtocol):
191
195
  f"Received incomplete TCP DNS request of length {self.expected_length} from {self.peer_info}, "
192
196
  f"closing connection after dns replies are sent."
193
197
  )
194
- asyncio.create_task(self.wait_for_futures())
198
+ create_referenced_task(self.wait_for_futures(), known_unreferenced=True)
195
199
  return True # Keep connection open, until the futures are done.
196
200
  log.info(f"Received early EOF from {self.peer_info}, closing connection.")
197
201
  return False
@@ -263,7 +267,7 @@ async def get_dns_reply(callback: DnsCallback, dns_request: DNSRecord) -> DNSRec
263
267
 
264
268
  @dataclass
265
269
  class DNSServer:
266
- config: Dict[str, Any]
270
+ config: dict[str, Any]
267
271
  root_path: Path
268
272
  lock: asyncio.Lock = field(default_factory=asyncio.Lock)
269
273
  shutdown_event: asyncio.Event = field(default_factory=asyncio.Event)
@@ -282,11 +286,14 @@ class DNSServer:
282
286
  db_path: Path = field(init=False)
283
287
  domain: DomainName = field(init=False)
284
288
  ns1: DomainName = field(init=False)
285
- ns_records: List[RR] = field(init=False)
289
+ ns_records: list[RR] = field(init=False)
286
290
  ttl: int = field(init=False)
287
291
  soa_record: RR = field(init=False)
288
- reliable_peers_v4: List[IPv4Address] = field(default_factory=list)
289
- reliable_peers_v6: List[IPv6Address] = field(default_factory=list)
292
+ reliable_peers_v4: list[IPv4Address] = field(default_factory=list)
293
+ reliable_peers_v6: list[IPv6Address] = field(default_factory=list)
294
+ static_peers_v4: list[IPv4Address] = field(default_factory=list)
295
+ static_peers_v6: list[IPv6Address] = field(default_factory=list)
296
+ resolver: Optional[dns.asyncresolver.Resolver] = field(init=False)
290
297
  pointer_v4: int = 0
291
298
  pointer_v6: int = 0
292
299
 
@@ -307,7 +314,7 @@ class DNSServer:
307
314
  if not self.domain.endswith("."):
308
315
  self.domain = DomainName(self.domain + ".") # Make sure the domain ends with a period, as per RFC 1035.
309
316
  self.ns1: DomainName = DomainName(self.config["nameserver"])
310
- self.ns_records: List[NS] = [NS(self.ns1)]
317
+ self.ns_records: list[NS] = [NS(self.ns1)]
311
318
  self.ttl: int = self.config["ttl"]
312
319
  self.soa_record: SOA = SOA(
313
320
  mname=self.ns1, # primary name server
@@ -320,6 +327,11 @@ class DNSServer:
320
327
  self.config["soa"]["minimum"],
321
328
  ),
322
329
  )
330
+ try:
331
+ self.resolver: Optional[dns.asyncresolver.Resolver] = dns.asyncresolver.Resolver()
332
+ except Exception:
333
+ self.resolver = None
334
+ log.exception("Error initializing asyncresolver for dns_server")
323
335
 
324
336
  @asynccontextmanager
325
337
  async def run(self) -> AsyncIterator[None]:
@@ -329,7 +341,7 @@ class DNSServer:
329
341
 
330
342
  # Set up the crawl store and the peer update task.
331
343
  self.crawl_store = await CrawlStore.create(await aiosqlite.connect(self.db_path, timeout=120))
332
- self.reliable_task = asyncio.create_task(self.periodically_get_reliable_peers())
344
+ self.reliable_task = create_referenced_task(self.periodically_get_reliable_peers())
333
345
 
334
346
  # One protocol instance will be created for each udp transport, so that we can accept ipv4 and ipv6
335
347
  self.udp_transport_ipv6, self.udp_protocol_ipv6 = await loop.create_datagram_endpoint(
@@ -392,42 +404,78 @@ class DNSServer:
392
404
  async def periodically_get_reliable_peers(self) -> None:
393
405
  sleep_interval = 0
394
406
  while not self.shutdown_event.is_set() and self.crawl_store is not None:
407
+ await self.refresh_reliable_peers()
408
+ sleep_interval = min(15, sleep_interval + 1)
409
+ await asyncio.sleep(sleep_interval * 60)
410
+
411
+ async def refresh_reliable_peers(self) -> None:
412
+ if self.crawl_store is None:
413
+ return
414
+ new_reliable_peers: list[str] = []
415
+ while not self.shutdown_event.is_set():
395
416
  try:
396
417
  new_reliable_peers = await self.crawl_store.get_good_peers()
397
418
  except Exception as e:
398
419
  log.error(f"Error loading reliable peers from database: {e}. Traceback: {traceback.format_exc()}.")
420
+ await asyncio.sleep(2)
399
421
  continue
400
- if len(new_reliable_peers) == 0:
401
- log.warning("No reliable peers found in database, waiting for db to be populated.")
402
- await asyncio.sleep(2) # sleep for 2 seconds, because the db has not been populated yet.
403
- continue
404
- async with self.lock:
405
- self.reliable_peers_v4 = []
406
- self.reliable_peers_v6 = []
407
- self.pointer_v4 = 0
408
- self.pointer_v6 = 0
409
- for peer in new_reliable_peers:
422
+
423
+ static_peers = self.config.get("static_peers", [])
424
+ if len(static_peers) > 0:
425
+ log.warning("have static peers, resolving ip addresses")
426
+ for static_peer in static_peers:
410
427
  try:
411
- validated_peer = ip_address(peer)
412
- if validated_peer.version == 4:
413
- self.reliable_peers_v4.append(validated_peer)
414
- elif validated_peer.version == 6:
415
- self.reliable_peers_v6.append(validated_peer)
428
+ log.warning(f"Handling static peer {static_peer}")
429
+ # Attempt to parse as an IP address
430
+ # If this doesn't throw, we can just add to the list
431
+ # Otherwise, we have to resolve the hostname
432
+ ip_address(static_peer)
433
+ new_reliable_peers.append(static_peer)
416
434
  except ValueError:
417
- log.error(f"Invalid peer: {peer}")
418
- continue
419
- log.warning(
420
- f"Number of reliable peers discovered in dns server:"
421
- f" IPv4 count - {len(self.reliable_peers_v4)}"
422
- f" IPv6 count - {len(self.reliable_peers_v6)}"
423
- )
424
- sleep_interval = min(15, sleep_interval + 1)
425
- await asyncio.sleep(sleep_interval * 60)
435
+ # Wasn't an IP address, so resolve the hostname
436
+ log.warning(f"Not an IP address, trying to resolve {static_peer} to an IP address")
437
+ if self.resolver is not None:
438
+ for rdtype in ["A", "AAAA"]:
439
+ result = await self.resolver.resolve(qname=static_peer, rdtype=rdtype, lifetime=30)
440
+ for ip in result:
441
+ try:
442
+ ip_as_string = ip.to_text()
443
+ ip_address(ip_as_string)
444
+ new_reliable_peers.append(ip_as_string)
445
+ except ValueError:
446
+ pass
447
+
448
+ if len(new_reliable_peers) > 0:
449
+ break
450
+
451
+ log.warning("No reliable peers found in database, waiting for db to be populated.")
452
+ await asyncio.sleep(2) # sleep for 2 seconds, because the db has not been populated yet.
453
+
454
+ async with self.lock:
455
+ self.reliable_peers_v4 = []
456
+ self.reliable_peers_v6 = []
457
+ self.pointer_v4 = 0
458
+ self.pointer_v6 = 0
459
+ for peer in new_reliable_peers:
460
+ try:
461
+ validated_peer = ip_address(peer)
462
+ if validated_peer.version == 4:
463
+ self.reliable_peers_v4.append(validated_peer)
464
+ elif validated_peer.version == 6:
465
+ self.reliable_peers_v6.append(validated_peer)
466
+ except ValueError:
467
+ log.error(f"Invalid peer: {peer}")
468
+ continue
469
+ log.warning(
470
+ f"Number of reliable peers discovered in dns server:"
471
+ f" IPv4 count - {len(self.reliable_peers_v4)}"
472
+ f" IPv6 count - {len(self.reliable_peers_v6)}"
473
+ )
426
474
 
427
475
  async def get_peers_to_respond(self, ipv4_count: int, ipv6_count: int) -> PeerList:
428
476
  async with self.lock:
429
477
  # Append IPv4.
430
- ipv4_peers: List[IPv4Address] = []
478
+ ipv4_peers: list[IPv4Address] = []
431
479
  size = len(self.reliable_peers_v4)
432
480
  if ipv4_count > 0 and size <= ipv4_count:
433
481
  ipv4_peers = self.reliable_peers_v4
@@ -437,7 +485,7 @@ class DNSServer:
437
485
  ]
438
486
  self.pointer_v4 = (self.pointer_v4 + ipv4_count) % size # mark where we left off
439
487
  # Append IPv6.
440
- ipv6_peers: List[IPv6Address] = []
488
+ ipv6_peers: list[IPv6Address] = []
441
489
  size = len(self.reliable_peers_v6)
442
490
  if ipv6_count > 0 and size <= ipv6_count:
443
491
  ipv6_peers = self.reliable_peers_v6
@@ -473,7 +521,7 @@ class DNSServer:
473
521
 
474
522
  ttl: int = self.ttl
475
523
  # we add these to the list as it will allow us to respond to ns and soa requests
476
- ips: List[RD] = [self.soa_record] + self.ns_records
524
+ ips: list[RD] = [self.soa_record, *self.ns_records]
477
525
  ipv4_count = 0
478
526
  ipv6_count = 0
479
527
  if question_type is QTYPE.A:
@@ -493,7 +541,7 @@ class DNSServer:
493
541
  ips.extend([A(str(peer)) for peer in peers.ipv4])
494
542
  ips.extend([AAAA(str(peer)) for peer in peers.ipv6])
495
543
 
496
- records: Dict[DomainName, List[RD]] = { # this is where we can add other records we want to serve
544
+ records: dict[DomainName, list[RD]] = { # this is where we can add other records we want to serve
497
545
  self.domain: ips,
498
546
  }
499
547
 
@@ -503,7 +551,7 @@ class DNSServer:
503
551
  valid_domain = True
504
552
  for response in domain_responses:
505
553
  rqt: int = getattr(QTYPE, response.__class__.__name__)
506
- if question_type == rqt or question_type == QTYPE.ANY:
554
+ if question_type in {rqt, QTYPE.ANY}:
507
555
  reply.add_answer(RR(rname=qname, rtype=rqt, rclass=1, ttl=ttl, rdata=response))
508
556
  if not valid_domain and len(reply.rr) == 0: # if we didn't find any records to return
509
557
  reply.header.rcode = RCODE.NXDOMAIN
@@ -521,7 +569,7 @@ async def run_dns_server(dns_server: DNSServer) -> None: # pragma: no cover
521
569
  await dns_server.shutdown_event.wait() # this is released on SIGINT or SIGTERM or any unhandled exception
522
570
 
523
571
 
524
- def create_dns_server_service(config: Dict[str, Any], root_path: Path) -> DNSServer:
572
+ def create_dns_server_service(config: dict[str, Any], root_path: Path) -> DNSServer:
525
573
  service_config = config[SERVICE_NAME]
526
574
 
527
575
  return DNSServer(service_config, root_path)
@@ -529,12 +577,13 @@ def create_dns_server_service(config: Dict[str, Any], root_path: Path) -> DNSSer
529
577
 
530
578
  def main() -> None: # pragma: no cover
531
579
  freeze_support()
532
- root_path = DEFAULT_ROOT_PATH
580
+ root_path = resolve_root_path(override=None)
581
+
533
582
  # TODO: refactor to avoid the double load
534
- config = load_config(DEFAULT_ROOT_PATH, "config.yaml")
535
- service_config = load_config_cli(DEFAULT_ROOT_PATH, "config.yaml", SERVICE_NAME)
583
+ config = load_config(root_path, "config.yaml")
584
+ service_config = load_config_cli(root_path, "config.yaml", SERVICE_NAME)
536
585
  config[SERVICE_NAME] = service_config
537
- initialize_service_logging(service_name=SERVICE_NAME, config=config)
586
+ initialize_service_logging(service_name=SERVICE_NAME, config=config, root_path=root_path)
538
587
 
539
588
  dns_server = create_dns_server_service(config, root_path)
540
589
  asyncio.run(run_dns_server(dns_server))