chia-blockchain 2.5.1rc1__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 (1042) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +195 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +145 -0
  9. chia/_tests/blockchain/test_blockchain.py +4202 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
  11. chia/_tests/blockchain/test_build_chains.py +59 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
  14. chia/_tests/build-init-files.py +92 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +72 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +149 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +55 -0
  26. chia/_tests/clvm/test_message_conditions.py +184 -0
  27. chia/_tests/clvm/test_program.py +150 -0
  28. chia/_tests/clvm/test_puzzle_compression.py +143 -0
  29. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  30. chia/_tests/clvm/test_puzzles.py +242 -0
  31. chia/_tests/clvm/test_singletons.py +540 -0
  32. chia/_tests/clvm/test_spend_sim.py +181 -0
  33. chia/_tests/cmds/__init__.py +0 -0
  34. chia/_tests/cmds/cmd_test_utils.py +469 -0
  35. chia/_tests/cmds/config.py +3 -0
  36. chia/_tests/cmds/conftest.py +23 -0
  37. chia/_tests/cmds/test_click_types.py +200 -0
  38. chia/_tests/cmds/test_cmd_framework.py +620 -0
  39. chia/_tests/cmds/test_cmds_util.py +97 -0
  40. chia/_tests/cmds/test_daemon.py +92 -0
  41. chia/_tests/cmds/test_dev_gh.py +131 -0
  42. chia/_tests/cmds/test_farm_cmd.py +66 -0
  43. chia/_tests/cmds/test_show.py +116 -0
  44. chia/_tests/cmds/test_sim.py +207 -0
  45. chia/_tests/cmds/test_timelock_args.py +75 -0
  46. chia/_tests/cmds/test_tx_config_args.py +154 -0
  47. chia/_tests/cmds/testing_classes.py +59 -0
  48. chia/_tests/cmds/wallet/__init__.py +0 -0
  49. chia/_tests/cmds/wallet/test_consts.py +47 -0
  50. chia/_tests/cmds/wallet/test_dao.py +565 -0
  51. chia/_tests/cmds/wallet/test_did.py +403 -0
  52. chia/_tests/cmds/wallet/test_nft.py +471 -0
  53. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  54. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  55. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  56. chia/_tests/cmds/wallet/test_vcs.py +400 -0
  57. chia/_tests/cmds/wallet/test_wallet.py +1125 -0
  58. chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
  59. chia/_tests/conftest.py +1419 -0
  60. chia/_tests/connection_utils.py +125 -0
  61. chia/_tests/core/__init__.py +0 -0
  62. chia/_tests/core/cmds/__init__.py +0 -0
  63. chia/_tests/core/cmds/test_beta.py +382 -0
  64. chia/_tests/core/cmds/test_keys.py +1734 -0
  65. chia/_tests/core/cmds/test_wallet.py +126 -0
  66. chia/_tests/core/config.py +3 -0
  67. chia/_tests/core/consensus/__init__.py +0 -0
  68. chia/_tests/core/consensus/test_block_creation.py +54 -0
  69. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  70. chia/_tests/core/custom_types/__init__.py +0 -0
  71. chia/_tests/core/custom_types/test_coin.py +107 -0
  72. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  73. chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
  74. chia/_tests/core/daemon/__init__.py +0 -0
  75. chia/_tests/core/daemon/config.py +4 -0
  76. chia/_tests/core/daemon/test_daemon.py +2128 -0
  77. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  78. chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
  79. chia/_tests/core/data_layer/__init__.py +0 -0
  80. chia/_tests/core/data_layer/config.py +5 -0
  81. chia/_tests/core/data_layer/conftest.py +106 -0
  82. chia/_tests/core/data_layer/test_data_cli.py +56 -0
  83. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  84. chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
  85. chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
  86. chia/_tests/core/data_layer/test_data_store.py +2424 -0
  87. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  88. chia/_tests/core/data_layer/test_plugin.py +91 -0
  89. chia/_tests/core/data_layer/util.py +233 -0
  90. chia/_tests/core/farmer/__init__.py +0 -0
  91. chia/_tests/core/farmer/config.py +3 -0
  92. chia/_tests/core/farmer/test_farmer_api.py +103 -0
  93. chia/_tests/core/full_node/__init__.py +0 -0
  94. chia/_tests/core/full_node/config.py +4 -0
  95. chia/_tests/core/full_node/dos/__init__.py +0 -0
  96. chia/_tests/core/full_node/dos/config.py +3 -0
  97. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  98. chia/_tests/core/full_node/full_sync/config.py +4 -0
  99. chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
  100. chia/_tests/core/full_node/ram_db.py +27 -0
  101. chia/_tests/core/full_node/stores/__init__.py +0 -0
  102. chia/_tests/core/full_node/stores/config.py +4 -0
  103. chia/_tests/core/full_node/stores/test_block_store.py +590 -0
  104. chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
  105. chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
  106. chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
  107. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  108. chia/_tests/core/full_node/test_address_manager.py +588 -0
  109. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  110. chia/_tests/core/full_node/test_conditions.py +556 -0
  111. chia/_tests/core/full_node/test_full_node.py +2700 -0
  112. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  113. chia/_tests/core/full_node/test_hint_management.py +104 -0
  114. chia/_tests/core/full_node/test_node_load.py +34 -0
  115. chia/_tests/core/full_node/test_performance.py +179 -0
  116. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  117. chia/_tests/core/full_node/test_transactions.py +203 -0
  118. chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
  119. chia/_tests/core/large_block.py +2388 -0
  120. chia/_tests/core/make_block_generator.py +70 -0
  121. chia/_tests/core/mempool/__init__.py +0 -0
  122. chia/_tests/core/mempool/config.py +4 -0
  123. chia/_tests/core/mempool/test_mempool.py +3255 -0
  124. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  125. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  126. chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
  127. chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
  128. chia/_tests/core/mempool/test_mempool_performance.py +64 -0
  129. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  130. chia/_tests/core/node_height.py +28 -0
  131. chia/_tests/core/server/__init__.py +0 -0
  132. chia/_tests/core/server/config.py +3 -0
  133. chia/_tests/core/server/flood.py +84 -0
  134. chia/_tests/core/server/serve.py +135 -0
  135. chia/_tests/core/server/test_api_protocol.py +21 -0
  136. chia/_tests/core/server/test_capabilities.py +66 -0
  137. chia/_tests/core/server/test_dos.py +319 -0
  138. chia/_tests/core/server/test_event_loop.py +109 -0
  139. chia/_tests/core/server/test_loop.py +294 -0
  140. chia/_tests/core/server/test_node_discovery.py +73 -0
  141. chia/_tests/core/server/test_rate_limits.py +482 -0
  142. chia/_tests/core/server/test_server.py +226 -0
  143. chia/_tests/core/server/test_upnp.py +8 -0
  144. chia/_tests/core/services/__init__.py +0 -0
  145. chia/_tests/core/services/config.py +3 -0
  146. chia/_tests/core/services/test_services.py +188 -0
  147. chia/_tests/core/ssl/__init__.py +0 -0
  148. chia/_tests/core/ssl/config.py +3 -0
  149. chia/_tests/core/ssl/test_ssl.py +202 -0
  150. chia/_tests/core/test_coins.py +33 -0
  151. chia/_tests/core/test_cost_calculation.py +313 -0
  152. chia/_tests/core/test_crawler.py +175 -0
  153. chia/_tests/core/test_crawler_rpc.py +53 -0
  154. chia/_tests/core/test_daemon_rpc.py +24 -0
  155. chia/_tests/core/test_db_conversion.py +130 -0
  156. chia/_tests/core/test_db_validation.py +162 -0
  157. chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
  158. chia/_tests/core/test_filter.py +35 -0
  159. chia/_tests/core/test_full_node_rpc.py +768 -0
  160. chia/_tests/core/test_merkle_set.py +343 -0
  161. chia/_tests/core/test_program.py +47 -0
  162. chia/_tests/core/test_rpc_util.py +86 -0
  163. chia/_tests/core/test_seeder.py +420 -0
  164. chia/_tests/core/test_setproctitle.py +13 -0
  165. chia/_tests/core/util/__init__.py +0 -0
  166. chia/_tests/core/util/config.py +4 -0
  167. chia/_tests/core/util/test_block_cache.py +44 -0
  168. chia/_tests/core/util/test_cached_bls.py +57 -0
  169. chia/_tests/core/util/test_config.py +337 -0
  170. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  171. chia/_tests/core/util/test_files.py +391 -0
  172. chia/_tests/core/util/test_jsonify.py +146 -0
  173. chia/_tests/core/util/test_keychain.py +522 -0
  174. chia/_tests/core/util/test_keyring_wrapper.py +491 -0
  175. chia/_tests/core/util/test_lockfile.py +380 -0
  176. chia/_tests/core/util/test_log_exceptions.py +187 -0
  177. chia/_tests/core/util/test_lru_cache.py +56 -0
  178. chia/_tests/core/util/test_significant_bits.py +40 -0
  179. chia/_tests/core/util/test_streamable.py +883 -0
  180. chia/_tests/db/__init__.py +0 -0
  181. chia/_tests/db/test_db_wrapper.py +566 -0
  182. chia/_tests/environments/__init__.py +0 -0
  183. chia/_tests/environments/common.py +35 -0
  184. chia/_tests/environments/full_node.py +47 -0
  185. chia/_tests/environments/wallet.py +429 -0
  186. chia/_tests/ether.py +19 -0
  187. chia/_tests/farmer_harvester/__init__.py +0 -0
  188. chia/_tests/farmer_harvester/config.py +3 -0
  189. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  190. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  191. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
  192. chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
  193. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  194. chia/_tests/fee_estimation/__init__.py +0 -0
  195. chia/_tests/fee_estimation/config.py +3 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  197. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  198. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
  199. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  200. chia/_tests/generator/__init__.py +0 -0
  201. chia/_tests/generator/puzzles/__init__.py +0 -0
  202. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  203. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  204. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  205. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  206. chia/_tests/generator/test_compression.py +201 -0
  207. chia/_tests/generator/test_generator_types.py +44 -0
  208. chia/_tests/generator/test_rom.py +180 -0
  209. chia/_tests/plot_sync/__init__.py +0 -0
  210. chia/_tests/plot_sync/config.py +3 -0
  211. chia/_tests/plot_sync/test_delta.py +101 -0
  212. chia/_tests/plot_sync/test_plot_sync.py +618 -0
  213. chia/_tests/plot_sync/test_receiver.py +451 -0
  214. chia/_tests/plot_sync/test_sender.py +116 -0
  215. chia/_tests/plot_sync/test_sync_simulated.py +451 -0
  216. chia/_tests/plot_sync/util.py +68 -0
  217. chia/_tests/plotting/__init__.py +0 -0
  218. chia/_tests/plotting/config.py +3 -0
  219. chia/_tests/plotting/test_plot_manager.py +781 -0
  220. chia/_tests/plotting/util.py +12 -0
  221. chia/_tests/pools/__init__.py +0 -0
  222. chia/_tests/pools/config.py +5 -0
  223. chia/_tests/pools/test_pool_cli_parsing.py +128 -0
  224. chia/_tests/pools/test_pool_cmdline.py +1001 -0
  225. chia/_tests/pools/test_pool_config.py +42 -0
  226. chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
  227. chia/_tests/pools/test_pool_rpc.py +1123 -0
  228. chia/_tests/pools/test_pool_wallet.py +205 -0
  229. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  230. chia/_tests/process_junit.py +348 -0
  231. chia/_tests/rpc/__init__.py +0 -0
  232. chia/_tests/rpc/test_rpc_client.py +138 -0
  233. chia/_tests/rpc/test_rpc_server.py +183 -0
  234. chia/_tests/simulation/__init__.py +0 -0
  235. chia/_tests/simulation/config.py +6 -0
  236. chia/_tests/simulation/test_simulation.py +501 -0
  237. chia/_tests/simulation/test_simulator.py +232 -0
  238. chia/_tests/simulation/test_start_simulator.py +107 -0
  239. chia/_tests/testconfig.py +13 -0
  240. chia/_tests/timelord/__init__.py +0 -0
  241. chia/_tests/timelord/config.py +3 -0
  242. chia/_tests/timelord/test_new_peak.py +437 -0
  243. chia/_tests/timelord/test_timelord.py +11 -0
  244. chia/_tests/tools/1315537.json +170 -0
  245. chia/_tests/tools/1315544.json +160 -0
  246. chia/_tests/tools/1315630.json +150 -0
  247. chia/_tests/tools/300000.json +105 -0
  248. chia/_tests/tools/442734.json +140 -0
  249. chia/_tests/tools/466212.json +130 -0
  250. chia/_tests/tools/__init__.py +0 -0
  251. chia/_tests/tools/config.py +5 -0
  252. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  253. chia/_tests/tools/test_full_sync.py +30 -0
  254. chia/_tests/tools/test_legacy_keyring.py +82 -0
  255. chia/_tests/tools/test_run_block.py +128 -0
  256. chia/_tests/tools/test_virtual_project.py +591 -0
  257. chia/_tests/util/__init__.py +0 -0
  258. chia/_tests/util/benchmark_cost.py +170 -0
  259. chia/_tests/util/benchmarks.py +153 -0
  260. chia/_tests/util/bip39_test_vectors.json +148 -0
  261. chia/_tests/util/blockchain.py +134 -0
  262. chia/_tests/util/blockchain_mock.py +132 -0
  263. chia/_tests/util/build_network_protocol_files.py +302 -0
  264. chia/_tests/util/clvm_generator.bin +0 -0
  265. chia/_tests/util/config.py +3 -0
  266. chia/_tests/util/constants.py +20 -0
  267. chia/_tests/util/db_connection.py +37 -0
  268. chia/_tests/util/full_sync.py +253 -0
  269. chia/_tests/util/gen_ssl_certs.py +114 -0
  270. chia/_tests/util/generator_tools_testing.py +45 -0
  271. chia/_tests/util/get_name_puzzle_conditions.py +52 -0
  272. chia/_tests/util/key_tool.py +36 -0
  273. chia/_tests/util/misc.py +675 -0
  274. chia/_tests/util/network_protocol_data.py +1072 -0
  275. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  276. chia/_tests/util/protocol_messages_json.py +2701 -0
  277. chia/_tests/util/rpc.py +26 -0
  278. chia/_tests/util/run_block.py +163 -0
  279. chia/_tests/util/setup_nodes.py +481 -0
  280. chia/_tests/util/spend_sim.py +492 -0
  281. chia/_tests/util/split_managers.py +102 -0
  282. chia/_tests/util/temp_file.py +14 -0
  283. chia/_tests/util/test_action_scope.py +144 -0
  284. chia/_tests/util/test_async_pool.py +366 -0
  285. chia/_tests/util/test_build_job_matrix.py +42 -0
  286. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  287. chia/_tests/util/test_chia_version.py +50 -0
  288. chia/_tests/util/test_collection.py +11 -0
  289. chia/_tests/util/test_condition_tools.py +229 -0
  290. chia/_tests/util/test_config.py +426 -0
  291. chia/_tests/util/test_dump_keyring.py +60 -0
  292. chia/_tests/util/test_errors.py +10 -0
  293. chia/_tests/util/test_full_block_utils.py +279 -0
  294. chia/_tests/util/test_installed.py +20 -0
  295. chia/_tests/util/test_limited_semaphore.py +53 -0
  296. chia/_tests/util/test_logging_filter.py +42 -0
  297. chia/_tests/util/test_misc.py +445 -0
  298. chia/_tests/util/test_network.py +73 -0
  299. chia/_tests/util/test_network_protocol_files.py +578 -0
  300. chia/_tests/util/test_network_protocol_json.py +267 -0
  301. chia/_tests/util/test_network_protocol_test.py +256 -0
  302. chia/_tests/util/test_paginator.py +71 -0
  303. chia/_tests/util/test_pprint.py +17 -0
  304. chia/_tests/util/test_priority_mutex.py +488 -0
  305. chia/_tests/util/test_recursive_replace.py +116 -0
  306. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  307. chia/_tests/util/test_service_groups.py +15 -0
  308. chia/_tests/util/test_ssl_check.py +31 -0
  309. chia/_tests/util/test_testnet_overrides.py +19 -0
  310. chia/_tests/util/test_tests_misc.py +38 -0
  311. chia/_tests/util/test_timing.py +37 -0
  312. chia/_tests/util/test_trusted_peer.py +51 -0
  313. chia/_tests/util/time_out_assert.py +191 -0
  314. chia/_tests/wallet/__init__.py +0 -0
  315. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  316. chia/_tests/wallet/cat_wallet/config.py +4 -0
  317. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  318. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  319. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
  320. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  321. chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
  322. chia/_tests/wallet/clawback/__init__.py +0 -0
  323. chia/_tests/wallet/clawback/config.py +3 -0
  324. chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
  325. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  326. chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
  327. chia/_tests/wallet/config.py +4 -0
  328. chia/_tests/wallet/conftest.py +278 -0
  329. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  330. chia/_tests/wallet/dao_wallet/config.py +3 -0
  331. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
  332. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  333. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  334. chia/_tests/wallet/db_wallet/config.py +3 -0
  335. chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
  336. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  337. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  338. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  339. chia/_tests/wallet/did_wallet/config.py +4 -0
  340. chia/_tests/wallet/did_wallet/test_did.py +2284 -0
  341. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  342. chia/_tests/wallet/nft_wallet/config.py +4 -0
  343. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
  344. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
  345. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
  346. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  347. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  348. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
  349. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  350. chia/_tests/wallet/rpc/__init__.py +0 -0
  351. chia/_tests/wallet/rpc/config.py +4 -0
  352. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
  353. chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
  354. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  355. chia/_tests/wallet/simple_sync/config.py +3 -0
  356. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
  357. chia/_tests/wallet/sync/__init__.py +0 -0
  358. chia/_tests/wallet/sync/config.py +4 -0
  359. chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
  360. chia/_tests/wallet/test_address_type.py +189 -0
  361. chia/_tests/wallet/test_bech32m.py +45 -0
  362. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  363. chia/_tests/wallet/test_coin_management.py +354 -0
  364. chia/_tests/wallet/test_coin_selection.py +588 -0
  365. chia/_tests/wallet/test_conditions.py +400 -0
  366. chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
  367. chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
  368. chia/_tests/wallet/test_nft_store.py +192 -0
  369. chia/_tests/wallet/test_notifications.py +196 -0
  370. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  371. chia/_tests/wallet/test_puzzle_store.py +132 -0
  372. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  373. chia/_tests/wallet/test_signer_protocol.py +947 -0
  374. chia/_tests/wallet/test_singleton.py +122 -0
  375. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  376. chia/_tests/wallet/test_singleton_store.py +152 -0
  377. chia/_tests/wallet/test_taproot.py +19 -0
  378. chia/_tests/wallet/test_transaction_store.py +945 -0
  379. chia/_tests/wallet/test_util.py +185 -0
  380. chia/_tests/wallet/test_wallet.py +2139 -0
  381. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  382. chia/_tests/wallet/test_wallet_blockchain.py +111 -0
  383. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  384. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  385. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  386. chia/_tests/wallet/test_wallet_node.py +780 -0
  387. chia/_tests/wallet/test_wallet_retry.py +95 -0
  388. chia/_tests/wallet/test_wallet_state_manager.py +259 -0
  389. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  390. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  391. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  392. chia/_tests/wallet/test_wallet_utils.py +156 -0
  393. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  394. chia/_tests/wallet/vc_wallet/config.py +3 -0
  395. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  396. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  397. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
  398. chia/_tests/wallet/wallet_block_tools.py +327 -0
  399. chia/_tests/weight_proof/__init__.py +0 -0
  400. chia/_tests/weight_proof/config.py +3 -0
  401. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  402. chia/apis.py +19 -0
  403. chia/clvm/__init__.py +0 -0
  404. chia/cmds/__init__.py +0 -0
  405. chia/cmds/beta.py +184 -0
  406. chia/cmds/beta_funcs.py +137 -0
  407. chia/cmds/check_wallet_db.py +420 -0
  408. chia/cmds/chia.py +151 -0
  409. chia/cmds/cmd_classes.py +323 -0
  410. chia/cmds/cmd_helpers.py +242 -0
  411. chia/cmds/cmds_util.py +488 -0
  412. chia/cmds/coin_funcs.py +275 -0
  413. chia/cmds/coins.py +182 -0
  414. chia/cmds/completion.py +49 -0
  415. chia/cmds/configure.py +332 -0
  416. chia/cmds/dao.py +1064 -0
  417. chia/cmds/dao_funcs.py +598 -0
  418. chia/cmds/data.py +708 -0
  419. chia/cmds/data_funcs.py +385 -0
  420. chia/cmds/db.py +87 -0
  421. chia/cmds/db_backup_func.py +77 -0
  422. chia/cmds/db_upgrade_func.py +452 -0
  423. chia/cmds/db_validate_func.py +184 -0
  424. chia/cmds/dev.py +18 -0
  425. chia/cmds/farm.py +100 -0
  426. chia/cmds/farm_funcs.py +200 -0
  427. chia/cmds/gh.py +275 -0
  428. chia/cmds/init.py +63 -0
  429. chia/cmds/init_funcs.py +367 -0
  430. chia/cmds/installers.py +131 -0
  431. chia/cmds/keys.py +527 -0
  432. chia/cmds/keys_funcs.py +863 -0
  433. chia/cmds/netspace.py +50 -0
  434. chia/cmds/netspace_funcs.py +54 -0
  435. chia/cmds/options.py +32 -0
  436. chia/cmds/param_types.py +238 -0
  437. chia/cmds/passphrase.py +131 -0
  438. chia/cmds/passphrase_funcs.py +292 -0
  439. chia/cmds/peer.py +51 -0
  440. chia/cmds/peer_funcs.py +129 -0
  441. chia/cmds/plotnft.py +260 -0
  442. chia/cmds/plotnft_funcs.py +405 -0
  443. chia/cmds/plots.py +230 -0
  444. chia/cmds/plotters.py +18 -0
  445. chia/cmds/rpc.py +208 -0
  446. chia/cmds/show.py +72 -0
  447. chia/cmds/show_funcs.py +215 -0
  448. chia/cmds/signer.py +296 -0
  449. chia/cmds/sim.py +225 -0
  450. chia/cmds/sim_funcs.py +509 -0
  451. chia/cmds/start.py +24 -0
  452. chia/cmds/start_funcs.py +109 -0
  453. chia/cmds/stop.py +62 -0
  454. chia/cmds/units.py +9 -0
  455. chia/cmds/wallet.py +1901 -0
  456. chia/cmds/wallet_funcs.py +1874 -0
  457. chia/consensus/__init__.py +0 -0
  458. chia/consensus/block_body_validation.py +562 -0
  459. chia/consensus/block_creation.py +546 -0
  460. chia/consensus/block_header_validation.py +1059 -0
  461. chia/consensus/block_record.py +31 -0
  462. chia/consensus/block_rewards.py +53 -0
  463. chia/consensus/blockchain.py +1087 -0
  464. chia/consensus/blockchain_interface.py +56 -0
  465. chia/consensus/coinbase.py +30 -0
  466. chia/consensus/condition_costs.py +9 -0
  467. chia/consensus/constants.py +49 -0
  468. chia/consensus/cost_calculator.py +15 -0
  469. chia/consensus/default_constants.py +89 -0
  470. chia/consensus/deficit.py +55 -0
  471. chia/consensus/difficulty_adjustment.py +412 -0
  472. chia/consensus/find_fork_point.py +111 -0
  473. chia/consensus/full_block_to_block_record.py +167 -0
  474. chia/consensus/get_block_challenge.py +106 -0
  475. chia/consensus/get_block_generator.py +27 -0
  476. chia/consensus/make_sub_epoch_summary.py +210 -0
  477. chia/consensus/multiprocess_validation.py +268 -0
  478. chia/consensus/pos_quality.py +19 -0
  479. chia/consensus/pot_iterations.py +67 -0
  480. chia/consensus/puzzles/__init__.py +0 -0
  481. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  482. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  483. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  484. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  485. chia/consensus/vdf_info_computation.py +156 -0
  486. chia/daemon/__init__.py +0 -0
  487. chia/daemon/client.py +252 -0
  488. chia/daemon/keychain_proxy.py +502 -0
  489. chia/daemon/keychain_server.py +365 -0
  490. chia/daemon/server.py +1606 -0
  491. chia/daemon/windows_signal.py +56 -0
  492. chia/data_layer/__init__.py +0 -0
  493. chia/data_layer/data_layer.py +1291 -0
  494. chia/data_layer/data_layer_api.py +33 -0
  495. chia/data_layer/data_layer_errors.py +50 -0
  496. chia/data_layer/data_layer_server.py +170 -0
  497. chia/data_layer/data_layer_util.py +985 -0
  498. chia/data_layer/data_layer_wallet.py +1311 -0
  499. chia/data_layer/data_store.py +2267 -0
  500. chia/data_layer/dl_wallet_store.py +407 -0
  501. chia/data_layer/download_data.py +389 -0
  502. chia/data_layer/puzzles/__init__.py +0 -0
  503. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  504. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  505. chia/data_layer/s3_plugin_config.yml +33 -0
  506. chia/data_layer/s3_plugin_service.py +468 -0
  507. chia/data_layer/util/__init__.py +0 -0
  508. chia/data_layer/util/benchmark.py +107 -0
  509. chia/data_layer/util/plugin.py +40 -0
  510. chia/farmer/__init__.py +0 -0
  511. chia/farmer/farmer.py +923 -0
  512. chia/farmer/farmer_api.py +820 -0
  513. chia/full_node/__init__.py +0 -0
  514. chia/full_node/bitcoin_fee_estimator.py +85 -0
  515. chia/full_node/block_height_map.py +271 -0
  516. chia/full_node/block_store.py +576 -0
  517. chia/full_node/bundle_tools.py +19 -0
  518. chia/full_node/coin_store.py +647 -0
  519. chia/full_node/fee_estimate.py +54 -0
  520. chia/full_node/fee_estimate_store.py +24 -0
  521. chia/full_node/fee_estimation.py +92 -0
  522. chia/full_node/fee_estimator.py +90 -0
  523. chia/full_node/fee_estimator_constants.py +38 -0
  524. chia/full_node/fee_estimator_interface.py +42 -0
  525. chia/full_node/fee_history.py +25 -0
  526. chia/full_node/fee_tracker.py +564 -0
  527. chia/full_node/full_node.py +3327 -0
  528. chia/full_node/full_node_api.py +2025 -0
  529. chia/full_node/full_node_store.py +1033 -0
  530. chia/full_node/hint_management.py +56 -0
  531. chia/full_node/hint_store.py +93 -0
  532. chia/full_node/mempool.py +589 -0
  533. chia/full_node/mempool_check_conditions.py +146 -0
  534. chia/full_node/mempool_manager.py +853 -0
  535. chia/full_node/pending_tx_cache.py +112 -0
  536. chia/full_node/puzzles/__init__.py +0 -0
  537. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  538. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  539. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  540. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  541. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  542. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  543. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  544. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  545. chia/full_node/signage_point.py +16 -0
  546. chia/full_node/subscriptions.py +247 -0
  547. chia/full_node/sync_store.py +146 -0
  548. chia/full_node/tx_processing_queue.py +78 -0
  549. chia/full_node/util/__init__.py +0 -0
  550. chia/full_node/weight_proof.py +1720 -0
  551. chia/harvester/__init__.py +0 -0
  552. chia/harvester/harvester.py +272 -0
  553. chia/harvester/harvester_api.py +380 -0
  554. chia/introducer/__init__.py +0 -0
  555. chia/introducer/introducer.py +122 -0
  556. chia/introducer/introducer_api.py +70 -0
  557. chia/legacy/__init__.py +0 -0
  558. chia/legacy/keyring.py +155 -0
  559. chia/plot_sync/__init__.py +0 -0
  560. chia/plot_sync/delta.py +61 -0
  561. chia/plot_sync/exceptions.py +56 -0
  562. chia/plot_sync/receiver.py +386 -0
  563. chia/plot_sync/sender.py +340 -0
  564. chia/plot_sync/util.py +43 -0
  565. chia/plotters/__init__.py +0 -0
  566. chia/plotters/bladebit.py +388 -0
  567. chia/plotters/chiapos.py +63 -0
  568. chia/plotters/madmax.py +224 -0
  569. chia/plotters/plotters.py +577 -0
  570. chia/plotters/plotters_util.py +133 -0
  571. chia/plotting/__init__.py +0 -0
  572. chia/plotting/cache.py +213 -0
  573. chia/plotting/check_plots.py +283 -0
  574. chia/plotting/create_plots.py +278 -0
  575. chia/plotting/manager.py +436 -0
  576. chia/plotting/util.py +336 -0
  577. chia/pools/__init__.py +0 -0
  578. chia/pools/pool_config.py +110 -0
  579. chia/pools/pool_puzzles.py +459 -0
  580. chia/pools/pool_wallet.py +933 -0
  581. chia/pools/pool_wallet_info.py +118 -0
  582. chia/pools/puzzles/__init__.py +0 -0
  583. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  584. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  585. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  586. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  587. chia/protocols/__init__.py +0 -0
  588. chia/protocols/farmer_protocol.py +102 -0
  589. chia/protocols/full_node_protocol.py +219 -0
  590. chia/protocols/harvester_protocol.py +216 -0
  591. chia/protocols/introducer_protocol.py +25 -0
  592. chia/protocols/pool_protocol.py +177 -0
  593. chia/protocols/protocol_message_types.py +139 -0
  594. chia/protocols/protocol_state_machine.py +87 -0
  595. chia/protocols/protocol_timing.py +8 -0
  596. chia/protocols/shared_protocol.py +86 -0
  597. chia/protocols/timelord_protocol.py +93 -0
  598. chia/protocols/wallet_protocol.py +401 -0
  599. chia/py.typed +0 -0
  600. chia/rpc/__init__.py +0 -0
  601. chia/rpc/crawler_rpc_api.py +80 -0
  602. chia/rpc/data_layer_rpc_api.py +644 -0
  603. chia/rpc/data_layer_rpc_client.py +188 -0
  604. chia/rpc/data_layer_rpc_util.py +58 -0
  605. chia/rpc/farmer_rpc_api.py +365 -0
  606. chia/rpc/farmer_rpc_client.py +86 -0
  607. chia/rpc/full_node_rpc_api.py +959 -0
  608. chia/rpc/full_node_rpc_client.py +292 -0
  609. chia/rpc/harvester_rpc_api.py +141 -0
  610. chia/rpc/harvester_rpc_client.py +54 -0
  611. chia/rpc/rpc_client.py +164 -0
  612. chia/rpc/rpc_server.py +521 -0
  613. chia/rpc/timelord_rpc_api.py +32 -0
  614. chia/rpc/util.py +93 -0
  615. chia/rpc/wallet_request_types.py +904 -0
  616. chia/rpc/wallet_rpc_api.py +4943 -0
  617. chia/rpc/wallet_rpc_client.py +1814 -0
  618. chia/seeder/__init__.py +0 -0
  619. chia/seeder/crawl_store.py +425 -0
  620. chia/seeder/crawler.py +410 -0
  621. chia/seeder/crawler_api.py +135 -0
  622. chia/seeder/dns_server.py +593 -0
  623. chia/seeder/peer_record.py +146 -0
  624. chia/seeder/start_crawler.py +92 -0
  625. chia/server/__init__.py +0 -0
  626. chia/server/address_manager.py +658 -0
  627. chia/server/address_manager_store.py +237 -0
  628. chia/server/api_protocol.py +116 -0
  629. chia/server/capabilities.py +24 -0
  630. chia/server/chia_policy.py +346 -0
  631. chia/server/introducer_peers.py +76 -0
  632. chia/server/node_discovery.py +714 -0
  633. chia/server/outbound_message.py +33 -0
  634. chia/server/rate_limit_numbers.py +214 -0
  635. chia/server/rate_limits.py +153 -0
  636. chia/server/server.py +741 -0
  637. chia/server/signal_handlers.py +120 -0
  638. chia/server/ssl_context.py +32 -0
  639. chia/server/start_data_layer.py +151 -0
  640. chia/server/start_farmer.py +98 -0
  641. chia/server/start_full_node.py +112 -0
  642. chia/server/start_harvester.py +93 -0
  643. chia/server/start_introducer.py +81 -0
  644. chia/server/start_service.py +316 -0
  645. chia/server/start_timelord.py +89 -0
  646. chia/server/start_wallet.py +113 -0
  647. chia/server/upnp.py +118 -0
  648. chia/server/ws_connection.py +766 -0
  649. chia/simulator/__init__.py +0 -0
  650. chia/simulator/add_blocks_in_batches.py +54 -0
  651. chia/simulator/block_tools.py +2054 -0
  652. chia/simulator/full_node_simulator.py +794 -0
  653. chia/simulator/keyring.py +128 -0
  654. chia/simulator/setup_services.py +506 -0
  655. chia/simulator/simulator_constants.py +13 -0
  656. chia/simulator/simulator_full_node_rpc_api.py +99 -0
  657. chia/simulator/simulator_full_node_rpc_client.py +60 -0
  658. chia/simulator/simulator_protocol.py +29 -0
  659. chia/simulator/simulator_test_tools.py +164 -0
  660. chia/simulator/socket.py +24 -0
  661. chia/simulator/ssl_certs.py +114 -0
  662. chia/simulator/ssl_certs_1.py +697 -0
  663. chia/simulator/ssl_certs_10.py +697 -0
  664. chia/simulator/ssl_certs_2.py +697 -0
  665. chia/simulator/ssl_certs_3.py +697 -0
  666. chia/simulator/ssl_certs_4.py +697 -0
  667. chia/simulator/ssl_certs_5.py +697 -0
  668. chia/simulator/ssl_certs_6.py +697 -0
  669. chia/simulator/ssl_certs_7.py +697 -0
  670. chia/simulator/ssl_certs_8.py +697 -0
  671. chia/simulator/ssl_certs_9.py +697 -0
  672. chia/simulator/start_simulator.py +143 -0
  673. chia/simulator/wallet_tools.py +246 -0
  674. chia/ssl/__init__.py +0 -0
  675. chia/ssl/chia_ca.crt +19 -0
  676. chia/ssl/chia_ca.key +28 -0
  677. chia/ssl/create_ssl.py +249 -0
  678. chia/ssl/dst_root_ca.pem +20 -0
  679. chia/timelord/__init__.py +0 -0
  680. chia/timelord/iters_from_block.py +50 -0
  681. chia/timelord/timelord.py +1226 -0
  682. chia/timelord/timelord_api.py +138 -0
  683. chia/timelord/timelord_launcher.py +190 -0
  684. chia/timelord/timelord_state.py +244 -0
  685. chia/timelord/types.py +22 -0
  686. chia/types/__init__.py +0 -0
  687. chia/types/aliases.py +35 -0
  688. chia/types/block_protocol.py +20 -0
  689. chia/types/blockchain_format/__init__.py +0 -0
  690. chia/types/blockchain_format/classgroup.py +5 -0
  691. chia/types/blockchain_format/coin.py +28 -0
  692. chia/types/blockchain_format/foliage.py +8 -0
  693. chia/types/blockchain_format/pool_target.py +5 -0
  694. chia/types/blockchain_format/program.py +269 -0
  695. chia/types/blockchain_format/proof_of_space.py +135 -0
  696. chia/types/blockchain_format/reward_chain_block.py +6 -0
  697. chia/types/blockchain_format/serialized_program.py +5 -0
  698. chia/types/blockchain_format/sized_bytes.py +11 -0
  699. chia/types/blockchain_format/slots.py +9 -0
  700. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  701. chia/types/blockchain_format/tree_hash.py +72 -0
  702. chia/types/blockchain_format/vdf.py +86 -0
  703. chia/types/clvm_cost.py +13 -0
  704. chia/types/coin_record.py +43 -0
  705. chia/types/coin_spend.py +115 -0
  706. chia/types/condition_opcodes.py +73 -0
  707. chia/types/condition_with_args.py +16 -0
  708. chia/types/eligible_coin_spends.py +365 -0
  709. chia/types/end_of_slot_bundle.py +5 -0
  710. chia/types/fee_rate.py +38 -0
  711. chia/types/full_block.py +5 -0
  712. chia/types/generator_types.py +13 -0
  713. chia/types/header_block.py +5 -0
  714. chia/types/internal_mempool_item.py +18 -0
  715. chia/types/mempool_inclusion_status.py +9 -0
  716. chia/types/mempool_item.py +85 -0
  717. chia/types/mempool_submission_status.py +30 -0
  718. chia/types/mojos.py +7 -0
  719. chia/types/peer_info.py +64 -0
  720. chia/types/signing_mode.py +29 -0
  721. chia/types/spend_bundle.py +30 -0
  722. chia/types/spend_bundle_conditions.py +7 -0
  723. chia/types/transaction_queue_entry.py +55 -0
  724. chia/types/unfinished_block.py +5 -0
  725. chia/types/unfinished_header_block.py +37 -0
  726. chia/types/validation_state.py +14 -0
  727. chia/types/weight_proof.py +49 -0
  728. chia/util/__init__.py +0 -0
  729. chia/util/action_scope.py +168 -0
  730. chia/util/async_pool.py +226 -0
  731. chia/util/augmented_chain.py +134 -0
  732. chia/util/batches.py +42 -0
  733. chia/util/bech32m.py +126 -0
  734. chia/util/beta_metrics.py +119 -0
  735. chia/util/block_cache.py +56 -0
  736. chia/util/byte_types.py +12 -0
  737. chia/util/check_fork_next_block.py +33 -0
  738. chia/util/chia_logging.py +144 -0
  739. chia/util/chia_version.py +33 -0
  740. chia/util/collection.py +17 -0
  741. chia/util/condition_tools.py +201 -0
  742. chia/util/config.py +367 -0
  743. chia/util/cpu.py +22 -0
  744. chia/util/db_synchronous.py +23 -0
  745. chia/util/db_version.py +32 -0
  746. chia/util/db_wrapper.py +430 -0
  747. chia/util/default_root.py +27 -0
  748. chia/util/dump_keyring.py +93 -0
  749. chia/util/english.txt +2048 -0
  750. chia/util/errors.py +353 -0
  751. chia/util/file_keyring.py +469 -0
  752. chia/util/files.py +97 -0
  753. chia/util/full_block_utils.py +345 -0
  754. chia/util/generator_tools.py +72 -0
  755. chia/util/hash.py +31 -0
  756. chia/util/initial-config.yaml +694 -0
  757. chia/util/inline_executor.py +26 -0
  758. chia/util/ints.py +19 -0
  759. chia/util/ip_address.py +39 -0
  760. chia/util/json_util.py +37 -0
  761. chia/util/keychain.py +676 -0
  762. chia/util/keyring_wrapper.py +327 -0
  763. chia/util/limited_semaphore.py +41 -0
  764. chia/util/lock.py +49 -0
  765. chia/util/log_exceptions.py +32 -0
  766. chia/util/logging.py +36 -0
  767. chia/util/lru_cache.py +31 -0
  768. chia/util/math.py +20 -0
  769. chia/util/network.py +182 -0
  770. chia/util/paginator.py +48 -0
  771. chia/util/path.py +31 -0
  772. chia/util/permissions.py +20 -0
  773. chia/util/prev_transaction_block.py +21 -0
  774. chia/util/priority_mutex.py +95 -0
  775. chia/util/profiler.py +197 -0
  776. chia/util/recursive_replace.py +24 -0
  777. chia/util/safe_cancel_task.py +16 -0
  778. chia/util/service_groups.py +47 -0
  779. chia/util/setproctitle.py +22 -0
  780. chia/util/significant_bits.py +32 -0
  781. chia/util/ssl_check.py +213 -0
  782. chia/util/streamable.py +642 -0
  783. chia/util/task_referencer.py +59 -0
  784. chia/util/task_timing.py +382 -0
  785. chia/util/timing.py +67 -0
  786. chia/util/vdf_prover.py +30 -0
  787. chia/util/virtual_project_analysis.py +540 -0
  788. chia/util/ws_message.py +66 -0
  789. chia/wallet/__init__.py +0 -0
  790. chia/wallet/cat_wallet/__init__.py +0 -0
  791. chia/wallet/cat_wallet/cat_constants.py +75 -0
  792. chia/wallet/cat_wallet/cat_info.py +47 -0
  793. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  794. chia/wallet/cat_wallet/cat_utils.py +164 -0
  795. chia/wallet/cat_wallet/cat_wallet.py +855 -0
  796. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  797. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  798. chia/wallet/cat_wallet/lineage_store.py +74 -0
  799. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  800. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  801. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  802. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  803. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  804. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  805. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  806. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  807. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  808. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  809. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  810. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  811. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  812. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  813. chia/wallet/coin_selection.py +188 -0
  814. chia/wallet/conditions.py +1512 -0
  815. chia/wallet/dao_wallet/__init__.py +0 -0
  816. chia/wallet/dao_wallet/dao_info.py +61 -0
  817. chia/wallet/dao_wallet/dao_utils.py +811 -0
  818. chia/wallet/dao_wallet/dao_wallet.py +2119 -0
  819. chia/wallet/db_wallet/__init__.py +0 -0
  820. chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
  821. chia/wallet/derivation_record.py +30 -0
  822. chia/wallet/derive_keys.py +146 -0
  823. chia/wallet/did_wallet/__init__.py +0 -0
  824. chia/wallet/did_wallet/did_info.py +39 -0
  825. chia/wallet/did_wallet/did_wallet.py +1494 -0
  826. chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
  827. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  828. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  829. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  830. chia/wallet/driver_protocol.py +26 -0
  831. chia/wallet/key_val_store.py +55 -0
  832. chia/wallet/lineage_proof.py +58 -0
  833. chia/wallet/nft_wallet/__init__.py +0 -0
  834. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  835. chia/wallet/nft_wallet/nft_info.py +120 -0
  836. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  837. chia/wallet/nft_wallet/nft_wallet.py +1687 -0
  838. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  839. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  840. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  841. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  842. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  843. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  844. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  845. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  846. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  847. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  848. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  849. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  850. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  851. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  852. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  853. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  854. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  855. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  856. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  857. chia/wallet/notification_manager.py +117 -0
  858. chia/wallet/notification_store.py +178 -0
  859. chia/wallet/outer_puzzles.py +84 -0
  860. chia/wallet/payment.py +33 -0
  861. chia/wallet/puzzle_drivers.py +118 -0
  862. chia/wallet/puzzles/__init__.py +0 -0
  863. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  864. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  865. chia/wallet/puzzles/clawback/__init__.py +0 -0
  866. chia/wallet/puzzles/clawback/drivers.py +188 -0
  867. chia/wallet/puzzles/clawback/metadata.py +38 -0
  868. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  869. chia/wallet/puzzles/condition_codes.clib +77 -0
  870. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  871. chia/wallet/puzzles/curry.clib +135 -0
  872. chia/wallet/puzzles/curry_by_index.clib +16 -0
  873. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  874. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  876. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  877. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  878. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  879. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  880. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  881. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  882. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  883. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  884. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  885. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  886. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  887. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  888. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  889. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  890. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  891. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  892. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  893. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  894. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  895. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  896. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  897. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  898. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  899. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  900. chia/wallet/puzzles/json.clib +25 -0
  901. chia/wallet/puzzles/load_clvm.py +161 -0
  902. chia/wallet/puzzles/merkle_utils.clib +18 -0
  903. chia/wallet/puzzles/notification.clsp +7 -0
  904. chia/wallet/puzzles/notification.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  906. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  907. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  908. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  909. chia/wallet/puzzles/p2_conditions.py +26 -0
  910. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  911. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  912. chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
  913. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  914. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  915. chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
  916. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  917. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
  919. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  920. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  921. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
  922. chia/wallet/puzzles/p2_parent.clsp +19 -0
  923. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  924. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  925. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  926. chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
  927. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  928. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  929. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  930. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  931. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  932. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  933. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  934. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  935. chia/wallet/puzzles/puzzle_utils.py +34 -0
  936. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  937. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  938. chia/wallet/puzzles/sha256tree.clib +11 -0
  939. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  940. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  941. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  942. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  943. chia/wallet/puzzles/singleton_top_layer.py +296 -0
  944. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  945. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  946. chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
  947. chia/wallet/puzzles/singleton_truths.clib +21 -0
  948. chia/wallet/puzzles/tails.py +348 -0
  949. chia/wallet/puzzles/utility_macros.clib +48 -0
  950. chia/wallet/signer_protocol.py +125 -0
  951. chia/wallet/singleton.py +106 -0
  952. chia/wallet/singleton_record.py +30 -0
  953. chia/wallet/trade_manager.py +1102 -0
  954. chia/wallet/trade_record.py +67 -0
  955. chia/wallet/trading/__init__.py +0 -0
  956. chia/wallet/trading/offer.py +702 -0
  957. chia/wallet/trading/trade_status.py +13 -0
  958. chia/wallet/trading/trade_store.py +526 -0
  959. chia/wallet/transaction_record.py +158 -0
  960. chia/wallet/transaction_sorting.py +14 -0
  961. chia/wallet/uncurried_puzzle.py +17 -0
  962. chia/wallet/util/__init__.py +0 -0
  963. chia/wallet/util/address_type.py +55 -0
  964. chia/wallet/util/blind_signer_tl.py +164 -0
  965. chia/wallet/util/clvm_streamable.py +203 -0
  966. chia/wallet/util/compute_hints.py +66 -0
  967. chia/wallet/util/compute_memos.py +43 -0
  968. chia/wallet/util/curry_and_treehash.py +91 -0
  969. chia/wallet/util/debug_spend_bundle.py +232 -0
  970. chia/wallet/util/merkle_tree.py +100 -0
  971. chia/wallet/util/merkle_utils.py +102 -0
  972. chia/wallet/util/new_peak_queue.py +82 -0
  973. chia/wallet/util/notifications.py +12 -0
  974. chia/wallet/util/peer_request_cache.py +174 -0
  975. chia/wallet/util/pprint.py +39 -0
  976. chia/wallet/util/puzzle_compression.py +95 -0
  977. chia/wallet/util/puzzle_decorator.py +100 -0
  978. chia/wallet/util/puzzle_decorator_type.py +7 -0
  979. chia/wallet/util/query_filter.py +59 -0
  980. chia/wallet/util/transaction_type.py +23 -0
  981. chia/wallet/util/tx_config.py +158 -0
  982. chia/wallet/util/wallet_sync_utils.py +351 -0
  983. chia/wallet/util/wallet_types.py +72 -0
  984. chia/wallet/vc_wallet/__init__.py +0 -0
  985. chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
  986. chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
  987. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  988. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  989. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  990. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  992. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  994. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  996. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  997. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  998. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  1002. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  1003. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  1004. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  1005. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  1006. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  1007. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  1008. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  1009. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  1010. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  1011. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  1012. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  1013. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1014. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1015. chia/wallet/vc_wallet/vc_store.py +263 -0
  1016. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1017. chia/wallet/wallet.py +698 -0
  1018. chia/wallet/wallet_action_scope.py +96 -0
  1019. chia/wallet/wallet_blockchain.py +244 -0
  1020. chia/wallet/wallet_coin_record.py +72 -0
  1021. chia/wallet/wallet_coin_store.py +351 -0
  1022. chia/wallet/wallet_info.py +35 -0
  1023. chia/wallet/wallet_interested_store.py +188 -0
  1024. chia/wallet/wallet_nft_store.py +279 -0
  1025. chia/wallet/wallet_node.py +1765 -0
  1026. chia/wallet/wallet_node_api.py +207 -0
  1027. chia/wallet/wallet_pool_store.py +119 -0
  1028. chia/wallet/wallet_protocol.py +90 -0
  1029. chia/wallet/wallet_puzzle_store.py +396 -0
  1030. chia/wallet/wallet_retry_store.py +70 -0
  1031. chia/wallet/wallet_singleton_store.py +259 -0
  1032. chia/wallet/wallet_spend_bundle.py +25 -0
  1033. chia/wallet/wallet_state_manager.py +2819 -0
  1034. chia/wallet/wallet_transaction_store.py +496 -0
  1035. chia/wallet/wallet_user_store.py +110 -0
  1036. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1037. chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
  1038. chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
  1039. chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
  1040. chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
  1041. chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
  1042. mozilla-ca/cacert.pem +3611 -0
chia/farmer/farmer.py ADDED
@@ -0,0 +1,923 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import contextlib
5
+ import json
6
+ import logging
7
+ import sys
8
+ import time
9
+ import traceback
10
+ from collections.abc import AsyncIterator
11
+ from dataclasses import dataclass
12
+ from math import floor
13
+ from pathlib import Path
14
+ from typing import TYPE_CHECKING, Any, ClassVar, Optional, Union, cast
15
+
16
+ import aiohttp
17
+ from chia_rs import AugSchemeMPL, G1Element, G2Element, PrivateKey
18
+
19
+ from chia.consensus.constants import ConsensusConstants
20
+ from chia.daemon.keychain_proxy import KeychainProxy, connect_to_keychain_and_validate, wrap_local_keychain
21
+ from chia.plot_sync.delta import Delta
22
+ from chia.plot_sync.receiver import Receiver
23
+ from chia.pools.pool_config import PoolWalletConfig, load_pool_config, update_pool_url
24
+ from chia.protocols import farmer_protocol, harvester_protocol
25
+ from chia.protocols.pool_protocol import (
26
+ AuthenticationPayload,
27
+ ErrorResponse,
28
+ GetFarmerResponse,
29
+ PoolErrorCode,
30
+ PostFarmerPayload,
31
+ PostFarmerRequest,
32
+ PutFarmerPayload,
33
+ PutFarmerRequest,
34
+ get_current_authentication_token,
35
+ )
36
+ from chia.protocols.protocol_message_types import ProtocolMessageTypes
37
+ from chia.rpc.rpc_server import StateChangedProtocol, default_get_connections
38
+ from chia.server.outbound_message import NodeType, make_msg
39
+ from chia.server.server import ChiaServer, ssl_context_for_root
40
+ from chia.server.ws_connection import WSChiaConnection
41
+ from chia.ssl.create_ssl import get_mozilla_ca_crt
42
+ from chia.types.blockchain_format.proof_of_space import ProofOfSpace
43
+ from chia.types.blockchain_format.sized_bytes import bytes32
44
+ from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash
45
+ from chia.util.byte_types import hexstr_to_bytes
46
+ from chia.util.config import config_path_for_filename, load_config, lock_and_load_config, save_config
47
+ from chia.util.errors import KeychainProxyConnectionFailure
48
+ from chia.util.hash import std_hash
49
+ from chia.util.ints import uint8, uint16, uint32, uint64
50
+ from chia.util.keychain import Keychain
51
+ from chia.util.logging import TimedDuplicateFilter
52
+ from chia.util.profiler import profile_task
53
+ from chia.util.task_referencer import create_referenced_task
54
+ from chia.wallet.derive_keys import (
55
+ find_authentication_sk,
56
+ find_owner_sk,
57
+ master_sk_to_farmer_sk,
58
+ master_sk_to_pool_sk,
59
+ match_address_to_sk,
60
+ )
61
+ from chia.wallet.puzzles.singleton_top_layer import SINGLETON_MOD
62
+
63
+ singleton_mod_hash = SINGLETON_MOD.get_tree_hash()
64
+
65
+ log = logging.getLogger(__name__)
66
+
67
+ UPDATE_POOL_INFO_INTERVAL: int = 3600
68
+ UPDATE_POOL_INFO_FAILURE_RETRY_INTERVAL: int = 120
69
+ UPDATE_POOL_FARMER_INFO_INTERVAL: int = 300
70
+
71
+
72
+ @dataclass(frozen=True)
73
+ class GetPoolInfoResult:
74
+ pool_info: dict[str, Any]
75
+ new_pool_url: Optional[str]
76
+
77
+
78
+ def strip_old_entries(pairs: list[tuple[float, Any]], before: float) -> list[tuple[float, Any]]:
79
+ for index, [timestamp, points] in enumerate(pairs):
80
+ if timestamp >= before:
81
+ if index == 0:
82
+ return pairs
83
+ if index > 0:
84
+ return pairs[index:]
85
+ return []
86
+
87
+
88
+ def increment_pool_stats(
89
+ pool_states: dict[bytes32, Any],
90
+ p2_singleton_puzzlehash: bytes32,
91
+ name: str,
92
+ current_time: float,
93
+ count: int = 1,
94
+ value: Optional[Union[int, dict[str, Any]]] = None,
95
+ ) -> None:
96
+ if p2_singleton_puzzlehash not in pool_states:
97
+ return
98
+ pool_state = pool_states[p2_singleton_puzzlehash]
99
+ if f"{name}_since_start" in pool_state:
100
+ pool_state[f"{name}_since_start"] += count
101
+ if f"{name}_24h" in pool_state:
102
+ if value is None:
103
+ pool_state[f"{name}_24h"].append((uint32(current_time), pool_state["current_difficulty"]))
104
+ else:
105
+ pool_state[f"{name}_24h"].append((uint32(current_time), value))
106
+
107
+ # Age out old 24h information for every signage point regardless
108
+ # of any failures. Note that this still lets old data remain if
109
+ # the client isn't receiving signage points.
110
+ cutoff_24h = current_time - (24 * 60 * 60)
111
+ pool_state[f"{name}_24h"] = strip_old_entries(pairs=pool_state[f"{name}_24h"], before=cutoff_24h)
112
+ return
113
+
114
+
115
+ """
116
+ HARVESTER PROTOCOL (FARMER <-> HARVESTER)
117
+ """
118
+
119
+
120
+ class Farmer:
121
+ if TYPE_CHECKING:
122
+ from chia.rpc.rpc_server import RpcServiceProtocol
123
+
124
+ _protocol_check: ClassVar[RpcServiceProtocol] = cast("Farmer", None)
125
+
126
+ def __init__(
127
+ self,
128
+ root_path: Path,
129
+ farmer_config: dict[str, Any],
130
+ pool_config: dict[str, Any],
131
+ consensus_constants: ConsensusConstants,
132
+ local_keychain: Optional[Keychain] = None,
133
+ ):
134
+ self.keychain_proxy: Optional[KeychainProxy] = None
135
+ self.local_keychain = local_keychain
136
+ self._root_path = root_path
137
+ self.config = farmer_config
138
+ self.pool_config = pool_config
139
+ # Keep track of all sps, keyed on challenge chain signage point hash
140
+ self.sps: dict[bytes32, list[farmer_protocol.NewSignagePoint]] = {}
141
+
142
+ # Keep track of harvester plot identifier (str), target sp index, and PoSpace for each challenge
143
+ self.proofs_of_space: dict[bytes32, list[tuple[str, ProofOfSpace]]] = {}
144
+
145
+ # Quality string to plot identifier and challenge_hash, for use with harvester.RequestSignatures
146
+ self.quality_str_to_identifiers: dict[bytes32, tuple[str, bytes32, bytes32, bytes32]] = {}
147
+
148
+ # number of responses to each signage point
149
+ self.number_of_responses: dict[bytes32, int] = {}
150
+
151
+ # A dictionary of keys to time added. These keys refer to keys in the above 4 dictionaries. This is used
152
+ # to periodically clear the memory
153
+ self.cache_add_time: dict[bytes32, uint64] = {}
154
+
155
+ self.plot_sync_receivers: dict[bytes32, Receiver] = {}
156
+
157
+ self.cache_clear_task: Optional[asyncio.Task[None]] = None
158
+ self.update_pool_state_task: Optional[asyncio.Task[None]] = None
159
+ self.constants = consensus_constants
160
+ self._shut_down = False
161
+ self.server: Any = None
162
+ self.state_changed_callback: Optional[StateChangedProtocol] = None
163
+ self.log = log
164
+ self.log.addFilter(TimedDuplicateFilter("No pool specific authentication_token_timeout.*", 60 * 10))
165
+ self.log.addFilter(TimedDuplicateFilter("No pool specific difficulty has been set.*", 60 * 10))
166
+
167
+ self.started = False
168
+ self.harvester_handshake_task: Optional[asyncio.Task[None]] = None
169
+
170
+ # From p2_singleton_puzzle_hash to pool state dict
171
+ self.pool_state: dict[bytes32, dict[str, Any]] = {}
172
+
173
+ # From p2_singleton to auth PrivateKey
174
+ self.authentication_keys: dict[bytes32, PrivateKey] = {}
175
+
176
+ # Last time we updated pool_state based on the config file
177
+ self.last_config_access_time: float = 0
178
+
179
+ self.all_root_sks: list[PrivateKey] = []
180
+
181
+ # Use to find missing signage points. (new_signage_point, time)
182
+ self.prev_signage_point: Optional[tuple[uint64, farmer_protocol.NewSignagePoint]] = None
183
+
184
+ @contextlib.asynccontextmanager
185
+ async def manage(self) -> AsyncIterator[None]:
186
+ async def start_task() -> None:
187
+ # `Farmer.setup_keys` returns `False` if there are no keys setup yet. In this case we just try until it
188
+ # succeeds or until we need to shut down.
189
+ while not self._shut_down:
190
+ if await self.setup_keys():
191
+ self.update_pool_state_task = create_referenced_task(self._periodically_update_pool_state_task())
192
+ self.cache_clear_task = create_referenced_task(self._periodically_clear_cache_and_refresh_task())
193
+ log.debug("start_task: initialized")
194
+ self.started = True
195
+ return
196
+ await asyncio.sleep(1)
197
+
198
+ if self.config.get("enable_profiler", False):
199
+ if sys.getprofile() is not None:
200
+ self.log.warning("not enabling profiler, getprofile() is already set")
201
+ else:
202
+ create_referenced_task(profile_task(self._root_path, "farmer", self.log), known_unreferenced=True)
203
+
204
+ create_referenced_task(start_task(), known_unreferenced=True)
205
+ try:
206
+ yield
207
+ finally:
208
+ self._shut_down = True
209
+
210
+ if self.cache_clear_task is not None:
211
+ await self.cache_clear_task
212
+ if self.update_pool_state_task is not None:
213
+ await self.update_pool_state_task
214
+ if self.keychain_proxy is not None:
215
+ proxy = self.keychain_proxy
216
+ self.keychain_proxy = None
217
+ await proxy.close()
218
+ await asyncio.sleep(0.5) # https://docs.aiohttp.org/en/stable/client_advanced.html#graceful-shutdown
219
+ self.started = False
220
+
221
+ def get_connections(self, request_node_type: Optional[NodeType]) -> list[dict[str, Any]]:
222
+ return default_get_connections(server=self.server, request_node_type=request_node_type)
223
+
224
+ async def ensure_keychain_proxy(self) -> KeychainProxy:
225
+ if self.keychain_proxy is None:
226
+ if self.local_keychain:
227
+ self.keychain_proxy = wrap_local_keychain(self.local_keychain, log=self.log)
228
+ else:
229
+ self.keychain_proxy = await connect_to_keychain_and_validate(self._root_path, self.log)
230
+ if not self.keychain_proxy:
231
+ raise KeychainProxyConnectionFailure()
232
+ return self.keychain_proxy
233
+
234
+ async def get_all_private_keys(self) -> list[tuple[PrivateKey, bytes]]:
235
+ keychain_proxy = await self.ensure_keychain_proxy()
236
+ return await keychain_proxy.get_all_private_keys()
237
+
238
+ async def setup_keys(self) -> bool:
239
+ no_keys_error_str = "No keys exist. Please run 'chia keys generate' or open the UI."
240
+ try:
241
+ self.all_root_sks = [sk for sk, _ in await self.get_all_private_keys()]
242
+ except KeychainProxyConnectionFailure:
243
+ return False
244
+
245
+ self._private_keys = [master_sk_to_farmer_sk(sk) for sk in self.all_root_sks] + [
246
+ master_sk_to_pool_sk(sk) for sk in self.all_root_sks
247
+ ]
248
+
249
+ if len(self.get_public_keys()) == 0:
250
+ log.warning(no_keys_error_str)
251
+ return False
252
+
253
+ config = load_config(self._root_path, "config.yaml")
254
+ if "xch_target_address" not in self.config:
255
+ self.config = config["farmer"]
256
+ if "xch_target_address" not in self.pool_config:
257
+ self.pool_config = config["pool"]
258
+ if "xch_target_address" not in self.config or "xch_target_address" not in self.pool_config:
259
+ log.debug("xch_target_address missing in the config")
260
+ return False
261
+
262
+ # This is the farmer configuration
263
+ self.farmer_target_encoded = self.config["xch_target_address"]
264
+ self.farmer_target = decode_puzzle_hash(self.farmer_target_encoded)
265
+
266
+ self.pool_public_keys = [G1Element.from_bytes(bytes.fromhex(pk)) for pk in self.config["pool_public_keys"]]
267
+
268
+ # This is the self pooling configuration, which is only used for original self-pooled plots
269
+ self.pool_target_encoded = self.pool_config["xch_target_address"]
270
+ self.pool_target = decode_puzzle_hash(self.pool_target_encoded)
271
+ self.pool_sks_map = {bytes(key.get_g1()): key for key in self.get_private_keys()}
272
+
273
+ assert len(self.farmer_target) == 32
274
+ assert len(self.pool_target) == 32
275
+ if len(self.pool_sks_map) == 0:
276
+ log.warning(no_keys_error_str)
277
+ return False
278
+
279
+ return True
280
+
281
+ def _set_state_changed_callback(self, callback: StateChangedProtocol) -> None:
282
+ self.state_changed_callback = callback
283
+
284
+ async def on_connect(self, peer: WSChiaConnection) -> None:
285
+ self.state_changed("add_connection", {})
286
+
287
+ async def handshake_task() -> None:
288
+ # Wait until the task in `Farmer._start` is done so that we have keys available for the handshake. Bail out
289
+ # early if we need to shut down or if the harvester is not longer connected.
290
+ # TODO: switch to event driven code
291
+ while not self.started and not self._shut_down and peer in self.server.get_connections(): # noqa: ASYNC110
292
+ await asyncio.sleep(1)
293
+
294
+ if self._shut_down:
295
+ log.debug("handshake_task: shutdown")
296
+ self.harvester_handshake_task = None
297
+ return
298
+
299
+ if peer not in self.server.get_connections():
300
+ log.debug("handshake_task: disconnected")
301
+ self.harvester_handshake_task = None
302
+ return
303
+
304
+ # Sends a handshake to the harvester
305
+ handshake = harvester_protocol.HarvesterHandshake(
306
+ self.get_public_keys(),
307
+ self.pool_public_keys,
308
+ )
309
+ msg = make_msg(ProtocolMessageTypes.harvester_handshake, handshake)
310
+ await peer.send_message(msg)
311
+ self.harvester_handshake_task = None
312
+
313
+ if peer.connection_type is NodeType.HARVESTER:
314
+ self.plot_sync_receivers[peer.peer_node_id] = Receiver(peer, self.plot_sync_callback)
315
+ self.harvester_handshake_task = create_referenced_task(handshake_task())
316
+
317
+ def set_server(self, server: ChiaServer) -> None:
318
+ self.server = server
319
+
320
+ def state_changed(self, change: str, data: dict[str, Any]) -> None:
321
+ if self.state_changed_callback is not None:
322
+ self.state_changed_callback(change, data)
323
+
324
+ def handle_failed_pool_response(self, p2_singleton_puzzle_hash: bytes32, error_message: str) -> None:
325
+ self.log.error(error_message)
326
+ increment_pool_stats(
327
+ self.pool_state,
328
+ p2_singleton_puzzle_hash,
329
+ "pool_errors",
330
+ time.time(),
331
+ value=ErrorResponse(uint16(PoolErrorCode.REQUEST_FAILED.value), error_message).to_json_dict(),
332
+ )
333
+
334
+ async def on_disconnect(self, connection: WSChiaConnection) -> None:
335
+ self.log.info(f"peer disconnected {connection.get_peer_logging()}")
336
+ self.state_changed("close_connection", {})
337
+ if connection.connection_type is NodeType.HARVESTER:
338
+ del self.plot_sync_receivers[connection.peer_node_id]
339
+ self.state_changed("harvester_removed", {"node_id": connection.peer_node_id})
340
+
341
+ async def plot_sync_callback(self, peer_id: bytes32, delta: Optional[Delta]) -> None:
342
+ log.debug(f"plot_sync_callback: peer_id {peer_id}, delta {delta}")
343
+ receiver: Receiver = self.plot_sync_receivers[peer_id]
344
+ harvester_updated: bool = delta is not None and not delta.empty()
345
+ if receiver.initial_sync() or harvester_updated:
346
+ self.state_changed("harvester_update", receiver.to_dict(True))
347
+
348
+ async def _pool_get_pool_info(self, pool_config: PoolWalletConfig) -> Optional[GetPoolInfoResult]:
349
+ try:
350
+ async with aiohttp.ClientSession(trust_env=True) as session:
351
+ url = f"{pool_config.pool_url}/pool_info"
352
+ async with session.get(url, ssl=ssl_context_for_root(get_mozilla_ca_crt(), log=self.log)) as resp:
353
+ if resp.ok:
354
+ response: dict[str, Any] = json.loads(await resp.text())
355
+ self.log.info(f"GET /pool_info response: {response}")
356
+ new_pool_url: Optional[str] = None
357
+ response_url_str = f"{resp.url}"
358
+ if (
359
+ response_url_str != url
360
+ and len(resp.history) > 0
361
+ and all(r.status in {301, 308} for r in resp.history)
362
+ ):
363
+ new_pool_url = response_url_str.replace("/pool_info", "")
364
+
365
+ return GetPoolInfoResult(pool_info=response, new_pool_url=new_pool_url)
366
+ else:
367
+ self.handle_failed_pool_response(
368
+ pool_config.p2_singleton_puzzle_hash,
369
+ f"Error in GET /pool_info {pool_config.pool_url}, {resp.status}",
370
+ )
371
+
372
+ except Exception as e:
373
+ self.handle_failed_pool_response(
374
+ pool_config.p2_singleton_puzzle_hash, f"Exception in GET /pool_info {pool_config.pool_url}, {e}"
375
+ )
376
+
377
+ return None
378
+
379
+ async def _pool_get_farmer(
380
+ self, pool_config: PoolWalletConfig, authentication_token_timeout: uint8, authentication_sk: PrivateKey
381
+ ) -> Optional[dict[str, Any]]:
382
+ authentication_token = get_current_authentication_token(authentication_token_timeout)
383
+ message: bytes32 = std_hash(
384
+ AuthenticationPayload(
385
+ "get_farmer", pool_config.launcher_id, pool_config.target_puzzle_hash, authentication_token
386
+ )
387
+ )
388
+ signature: G2Element = AugSchemeMPL.sign(authentication_sk, message)
389
+ get_farmer_params: dict[str, Union[str, int]] = {
390
+ "launcher_id": pool_config.launcher_id.hex(),
391
+ "authentication_token": authentication_token,
392
+ "signature": bytes(signature).hex(),
393
+ }
394
+ try:
395
+ async with aiohttp.ClientSession(trust_env=True) as session:
396
+ async with session.get(
397
+ f"{pool_config.pool_url}/farmer",
398
+ params=get_farmer_params,
399
+ ssl=ssl_context_for_root(get_mozilla_ca_crt(), log=self.log),
400
+ ) as resp:
401
+ if resp.ok:
402
+ response: dict[str, Any] = json.loads(await resp.text())
403
+ log_level = logging.INFO
404
+ if "error_code" in response:
405
+ log_level = logging.WARNING
406
+ increment_pool_stats(
407
+ self.pool_state,
408
+ pool_config.p2_singleton_puzzle_hash,
409
+ "pool_errors",
410
+ time.time(),
411
+ value=response,
412
+ )
413
+ self.log.log(log_level, f"GET /farmer response: {response}")
414
+ return response
415
+ else:
416
+ self.handle_failed_pool_response(
417
+ pool_config.p2_singleton_puzzle_hash,
418
+ f"Error in GET /farmer {pool_config.pool_url}, {resp.status}",
419
+ )
420
+ except Exception as e:
421
+ self.handle_failed_pool_response(
422
+ pool_config.p2_singleton_puzzle_hash, f"Exception in GET /farmer {pool_config.pool_url}, {e}"
423
+ )
424
+ return None
425
+
426
+ async def _pool_post_farmer(
427
+ self, pool_config: PoolWalletConfig, authentication_token_timeout: uint8, owner_sk: PrivateKey
428
+ ) -> Optional[dict[str, Any]]:
429
+ auth_sk: Optional[PrivateKey] = self.get_authentication_sk(pool_config)
430
+ assert auth_sk is not None
431
+ post_farmer_payload: PostFarmerPayload = PostFarmerPayload(
432
+ pool_config.launcher_id,
433
+ get_current_authentication_token(authentication_token_timeout),
434
+ auth_sk.get_g1(),
435
+ pool_config.payout_instructions,
436
+ None,
437
+ )
438
+ assert owner_sk.get_g1() == pool_config.owner_public_key
439
+ signature: G2Element = AugSchemeMPL.sign(owner_sk, post_farmer_payload.get_hash())
440
+ post_farmer_request = PostFarmerRequest(post_farmer_payload, signature)
441
+ self.log.debug(f"POST /farmer request {post_farmer_request}")
442
+ try:
443
+ async with aiohttp.ClientSession() as session:
444
+ async with session.post(
445
+ f"{pool_config.pool_url}/farmer",
446
+ json=post_farmer_request.to_json_dict(),
447
+ ssl=ssl_context_for_root(get_mozilla_ca_crt(), log=self.log),
448
+ ) as resp:
449
+ if resp.ok:
450
+ response: dict[str, Any] = json.loads(await resp.text())
451
+ log_level = logging.INFO
452
+ if "error_code" in response:
453
+ log_level = logging.WARNING
454
+ increment_pool_stats(
455
+ self.pool_state,
456
+ pool_config.p2_singleton_puzzle_hash,
457
+ "pool_errors",
458
+ time.time(),
459
+ value=response,
460
+ )
461
+ self.log.log(log_level, f"POST /farmer response: {response}")
462
+ return response
463
+ else:
464
+ self.handle_failed_pool_response(
465
+ pool_config.p2_singleton_puzzle_hash,
466
+ f"Error in POST /farmer {pool_config.pool_url}, {resp.status}",
467
+ )
468
+ except Exception as e:
469
+ self.handle_failed_pool_response(
470
+ pool_config.p2_singleton_puzzle_hash, f"Exception in POST /farmer {pool_config.pool_url}, {e}"
471
+ )
472
+ return None
473
+
474
+ async def _pool_put_farmer(
475
+ self, pool_config: PoolWalletConfig, authentication_token_timeout: uint8, owner_sk: PrivateKey
476
+ ) -> None:
477
+ auth_sk: Optional[PrivateKey] = self.get_authentication_sk(pool_config)
478
+ assert auth_sk is not None
479
+ put_farmer_payload: PutFarmerPayload = PutFarmerPayload(
480
+ pool_config.launcher_id,
481
+ get_current_authentication_token(authentication_token_timeout),
482
+ auth_sk.get_g1(),
483
+ pool_config.payout_instructions,
484
+ None,
485
+ )
486
+ assert owner_sk.get_g1() == pool_config.owner_public_key
487
+ signature: G2Element = AugSchemeMPL.sign(owner_sk, put_farmer_payload.get_hash())
488
+ put_farmer_request = PutFarmerRequest(put_farmer_payload, signature)
489
+ self.log.debug(f"PUT /farmer request {put_farmer_request}")
490
+ try:
491
+ async with aiohttp.ClientSession() as session:
492
+ async with session.put(
493
+ f"{pool_config.pool_url}/farmer",
494
+ json=put_farmer_request.to_json_dict(),
495
+ ssl=ssl_context_for_root(get_mozilla_ca_crt(), log=self.log),
496
+ ) as resp:
497
+ if resp.ok:
498
+ response: dict[str, Any] = json.loads(await resp.text())
499
+ log_level = logging.INFO
500
+ if "error_code" in response:
501
+ log_level = logging.WARNING
502
+ increment_pool_stats(
503
+ self.pool_state,
504
+ pool_config.p2_singleton_puzzle_hash,
505
+ "pool_errors",
506
+ time.time(),
507
+ value=response,
508
+ )
509
+ self.log.log(log_level, f"PUT /farmer response: {response}")
510
+ else:
511
+ self.handle_failed_pool_response(
512
+ pool_config.p2_singleton_puzzle_hash,
513
+ f"Error in PUT /farmer {pool_config.pool_url}, {resp.status}",
514
+ )
515
+ except Exception as e:
516
+ self.handle_failed_pool_response(
517
+ pool_config.p2_singleton_puzzle_hash, f"Exception in PUT /farmer {pool_config.pool_url}, {e}"
518
+ )
519
+
520
+ def get_authentication_sk(self, pool_config: PoolWalletConfig) -> Optional[PrivateKey]:
521
+ if pool_config.p2_singleton_puzzle_hash in self.authentication_keys:
522
+ return self.authentication_keys[pool_config.p2_singleton_puzzle_hash]
523
+ auth_sk: Optional[PrivateKey] = find_authentication_sk(self.all_root_sks, pool_config.owner_public_key)
524
+ if auth_sk is not None:
525
+ self.authentication_keys[pool_config.p2_singleton_puzzle_hash] = auth_sk
526
+ return auth_sk
527
+
528
+ async def update_pool_state(self) -> None:
529
+ config = load_config(self._root_path, "config.yaml")
530
+
531
+ pool_config_list: list[PoolWalletConfig] = load_pool_config(self._root_path)
532
+ for pool_config in pool_config_list:
533
+ p2_singleton_puzzle_hash = pool_config.p2_singleton_puzzle_hash
534
+
535
+ try:
536
+ authentication_sk: Optional[PrivateKey] = self.get_authentication_sk(pool_config)
537
+
538
+ if authentication_sk is None:
539
+ self.log.error(f"Could not find authentication sk for {p2_singleton_puzzle_hash}")
540
+ continue
541
+
542
+ if p2_singleton_puzzle_hash not in self.pool_state:
543
+ self.pool_state[p2_singleton_puzzle_hash] = {
544
+ "p2_singleton_puzzle_hash": p2_singleton_puzzle_hash.hex(),
545
+ "points_found_since_start": 0,
546
+ "points_found_24h": [],
547
+ "points_acknowledged_since_start": 0,
548
+ "points_acknowledged_24h": [],
549
+ "next_farmer_update": 0,
550
+ "next_pool_info_update": 0,
551
+ "current_points": 0,
552
+ "current_difficulty": None,
553
+ "pool_errors_24h": [],
554
+ "valid_partials_since_start": 0,
555
+ "valid_partials_24h": [],
556
+ "invalid_partials_since_start": 0,
557
+ "invalid_partials_24h": [],
558
+ "insufficient_partials_since_start": 0,
559
+ "insufficient_partials_24h": [],
560
+ "stale_partials_since_start": 0,
561
+ "stale_partials_24h": [],
562
+ "missing_partials_since_start": 0,
563
+ "missing_partials_24h": [],
564
+ "authentication_token_timeout": None,
565
+ "plot_count": 0,
566
+ "pool_config": pool_config,
567
+ }
568
+ self.log.info(f"Added pool: {pool_config}")
569
+ else:
570
+ self.pool_state[p2_singleton_puzzle_hash]["pool_config"] = pool_config
571
+
572
+ pool_state = self.pool_state[p2_singleton_puzzle_hash]
573
+
574
+ # Skip state update when self pooling
575
+ if pool_config.pool_url == "":
576
+ continue
577
+
578
+ enforce_https = config["full_node"]["selected_network"] == "mainnet"
579
+ if enforce_https and not pool_config.pool_url.startswith("https://"):
580
+ self.log.error(f"Pool URLs must be HTTPS on mainnet {pool_config.pool_url}")
581
+ continue
582
+
583
+ # TODO: Improve error handling below, inform about unexpected failures
584
+ if time.time() >= pool_state["next_pool_info_update"]:
585
+ pool_state["next_pool_info_update"] = time.time() + UPDATE_POOL_INFO_INTERVAL
586
+ # Makes a GET request to the pool to get the updated information
587
+ pool_info_result = await self._pool_get_pool_info(pool_config)
588
+ if pool_info_result is not None and "error_code" not in pool_info_result.pool_info:
589
+ pool_info = pool_info_result.pool_info
590
+ pool_state["authentication_token_timeout"] = pool_info["authentication_token_timeout"]
591
+ # Only update the first time from GET /pool_info, gets updated from GET /farmer later
592
+ if pool_state["current_difficulty"] is None:
593
+ pool_state["current_difficulty"] = pool_info["minimum_difficulty"]
594
+ else:
595
+ pool_state["next_pool_info_update"] = time.time() + UPDATE_POOL_INFO_FAILURE_RETRY_INTERVAL
596
+
597
+ if pool_info_result is not None and pool_info_result.new_pool_url is not None:
598
+ update_pool_url(self._root_path, pool_config, pool_info_result.new_pool_url)
599
+
600
+ if time.time() >= pool_state["next_farmer_update"]:
601
+ pool_state["next_farmer_update"] = time.time() + UPDATE_POOL_FARMER_INFO_INTERVAL
602
+ authentication_token_timeout = pool_state["authentication_token_timeout"]
603
+
604
+ async def update_pool_farmer_info() -> tuple[Optional[GetFarmerResponse], Optional[PoolErrorCode]]:
605
+ # Run a GET /farmer to see if the farmer is already known by the pool
606
+ response = await self._pool_get_farmer(
607
+ pool_config, authentication_token_timeout, authentication_sk
608
+ )
609
+ farmer_response: Optional[GetFarmerResponse] = None
610
+ error_code_response: Optional[PoolErrorCode] = None
611
+ if response is not None:
612
+ if "error_code" not in response:
613
+ farmer_response = GetFarmerResponse.from_json_dict(response)
614
+ if farmer_response is not None:
615
+ pool_state["current_difficulty"] = farmer_response.current_difficulty
616
+ pool_state["current_points"] = farmer_response.current_points
617
+ else:
618
+ try:
619
+ error_code_response = PoolErrorCode(response["error_code"])
620
+ except ValueError:
621
+ self.log.error(
622
+ f"Invalid error code received from the pool: {response['error_code']}"
623
+ )
624
+
625
+ return farmer_response, error_code_response
626
+
627
+ if authentication_token_timeout is not None:
628
+ farmer_info, error_code = await update_pool_farmer_info()
629
+ if error_code == PoolErrorCode.FARMER_NOT_KNOWN:
630
+ # Make the farmer known on the pool with a POST /farmer
631
+ owner_sk_and_index = find_owner_sk(self.all_root_sks, pool_config.owner_public_key)
632
+ assert owner_sk_and_index is not None
633
+ post_response = await self._pool_post_farmer(
634
+ pool_config, authentication_token_timeout, owner_sk_and_index[0]
635
+ )
636
+ if post_response is not None and "error_code" not in post_response:
637
+ self.log.info(
638
+ f"Welcome message from {pool_config.pool_url}: "
639
+ f"{post_response['welcome_message']}"
640
+ )
641
+ # Now we should be able to update the local farmer info
642
+ farmer_info, farmer_is_known = await update_pool_farmer_info()
643
+ if farmer_info is None and not farmer_is_known:
644
+ self.log.error("Failed to update farmer info after POST /farmer.")
645
+
646
+ # Update the farmer information on the pool if the payout instructions changed or if the
647
+ # signature is invalid (latter to make sure the pool has the correct authentication public key).
648
+ payout_instructions_update_required: bool = (
649
+ farmer_info is not None
650
+ and pool_config.payout_instructions.lower() != farmer_info.payout_instructions.lower()
651
+ )
652
+ if payout_instructions_update_required or error_code == PoolErrorCode.INVALID_SIGNATURE:
653
+ owner_sk_and_index = find_owner_sk(self.all_root_sks, pool_config.owner_public_key)
654
+ assert owner_sk_and_index is not None
655
+ await self._pool_put_farmer(
656
+ pool_config, authentication_token_timeout, owner_sk_and_index[0]
657
+ )
658
+ else:
659
+ self.log.warning(
660
+ f"No pool specific authentication_token_timeout has been set for {p2_singleton_puzzle_hash}"
661
+ f", check communication with the pool."
662
+ )
663
+
664
+ except Exception as e:
665
+ tb = traceback.format_exc()
666
+ self.log.error(f"Exception in update_pool_state for {pool_config.pool_url}, {e} {tb}")
667
+
668
+ def get_public_keys(self) -> list[G1Element]:
669
+ return [child_sk.get_g1() for child_sk in self._private_keys]
670
+
671
+ def get_private_keys(self) -> list[PrivateKey]:
672
+ return self._private_keys
673
+
674
+ async def get_reward_targets(self, search_for_private_key: bool, max_ph_to_search: int = 500) -> dict[str, Any]:
675
+ if search_for_private_key:
676
+ all_sks = await self.get_all_private_keys()
677
+ have_farmer_sk, have_pool_sk = False, False
678
+ search_addresses: list[bytes32] = [self.farmer_target, self.pool_target]
679
+ for sk, _ in all_sks:
680
+ found_addresses: set[bytes32] = match_address_to_sk(sk, search_addresses, max_ph_to_search)
681
+
682
+ if not have_farmer_sk and self.farmer_target in found_addresses:
683
+ search_addresses.remove(self.farmer_target)
684
+ have_farmer_sk = True
685
+
686
+ if not have_pool_sk and self.pool_target in found_addresses:
687
+ search_addresses.remove(self.pool_target)
688
+ have_pool_sk = True
689
+
690
+ if have_farmer_sk and have_pool_sk:
691
+ break
692
+
693
+ return {
694
+ "farmer_target": self.farmer_target_encoded,
695
+ "pool_target": self.pool_target_encoded,
696
+ "have_farmer_sk": have_farmer_sk,
697
+ "have_pool_sk": have_pool_sk,
698
+ }
699
+ return {
700
+ "farmer_target": self.farmer_target_encoded,
701
+ "pool_target": self.pool_target_encoded,
702
+ }
703
+
704
+ def set_reward_targets(self, farmer_target_encoded: Optional[str], pool_target_encoded: Optional[str]) -> None:
705
+ with lock_and_load_config(self._root_path, "config.yaml") as config:
706
+ if farmer_target_encoded is not None:
707
+ self.farmer_target_encoded = farmer_target_encoded
708
+ self.farmer_target = decode_puzzle_hash(farmer_target_encoded)
709
+ config["farmer"]["xch_target_address"] = farmer_target_encoded
710
+ if pool_target_encoded is not None:
711
+ self.pool_target_encoded = pool_target_encoded
712
+ self.pool_target = decode_puzzle_hash(pool_target_encoded)
713
+ config["pool"]["xch_target_address"] = pool_target_encoded
714
+ save_config(self._root_path, "config.yaml", config)
715
+
716
+ async def set_payout_instructions(self, launcher_id: bytes32, payout_instructions: str) -> None:
717
+ for p2_singleton_puzzle_hash, pool_state_dict in self.pool_state.items():
718
+ if launcher_id == pool_state_dict["pool_config"].launcher_id:
719
+ with lock_and_load_config(self._root_path, "config.yaml") as config:
720
+ new_list = []
721
+ pool_list = config["pool"].get("pool_list", [])
722
+ if pool_list is not None:
723
+ for list_element in pool_list:
724
+ if hexstr_to_bytes(list_element["launcher_id"]) == bytes(launcher_id):
725
+ list_element["payout_instructions"] = payout_instructions
726
+ new_list.append(list_element)
727
+
728
+ config["pool"]["pool_list"] = new_list
729
+ save_config(self._root_path, "config.yaml", config)
730
+ # Force a GET /farmer which triggers the PUT /farmer if it detects the changed instructions
731
+ pool_state_dict["next_farmer_update"] = 0
732
+ return
733
+
734
+ self.log.warning(f"Launcher id: {launcher_id} not found")
735
+
736
+ async def generate_login_link(self, launcher_id: bytes32) -> Optional[str]:
737
+ for pool_state in self.pool_state.values():
738
+ pool_config: PoolWalletConfig = pool_state["pool_config"]
739
+ if pool_config.launcher_id != launcher_id:
740
+ continue
741
+
742
+ authentication_sk: Optional[PrivateKey] = self.get_authentication_sk(pool_config)
743
+ if authentication_sk is None:
744
+ self.log.error(f"Could not find authentication sk for {pool_config.p2_singleton_puzzle_hash}")
745
+ continue
746
+ authentication_token_timeout = pool_state["authentication_token_timeout"]
747
+ if authentication_token_timeout is None:
748
+ self.log.error(
749
+ f"No pool specific authentication_token_timeout has been set for"
750
+ f"{pool_config.p2_singleton_puzzle_hash}, check communication with the pool."
751
+ )
752
+ return None
753
+
754
+ authentication_token = get_current_authentication_token(authentication_token_timeout)
755
+ message: bytes32 = std_hash(
756
+ AuthenticationPayload(
757
+ "get_login", pool_config.launcher_id, pool_config.target_puzzle_hash, authentication_token
758
+ )
759
+ )
760
+ signature: G2Element = AugSchemeMPL.sign(authentication_sk, message)
761
+ return (
762
+ pool_config.pool_url
763
+ + f"/login?launcher_id={launcher_id.hex()}&authentication_token={authentication_token}"
764
+ f"&signature={bytes(signature).hex()}"
765
+ )
766
+
767
+ return None
768
+
769
+ async def get_harvesters(self, counts_only: bool = False) -> dict[str, Any]:
770
+ harvesters: list[dict[str, Any]] = []
771
+ for connection in self.server.get_connections(NodeType.HARVESTER):
772
+ self.log.debug(f"get_harvesters host: {connection.peer_info.host}, node_id: {connection.peer_node_id}")
773
+ receiver = self.plot_sync_receivers.get(connection.peer_node_id)
774
+ if receiver is not None:
775
+ harvesters.append(receiver.to_dict(counts_only))
776
+ else:
777
+ self.log.debug(
778
+ f"get_harvesters invalid peer: {connection.peer_info.host}, node_id: {connection.peer_node_id}"
779
+ )
780
+
781
+ return {"harvesters": harvesters}
782
+
783
+ def get_receiver(self, node_id: bytes32) -> Receiver:
784
+ receiver: Optional[Receiver] = self.plot_sync_receivers.get(node_id)
785
+ if receiver is None:
786
+ raise KeyError(f"Receiver missing for {node_id}")
787
+ return receiver
788
+
789
+ def check_missing_signage_points(
790
+ self, timestamp: uint64, new_signage_point: farmer_protocol.NewSignagePoint
791
+ ) -> Optional[tuple[uint64, uint32]]:
792
+ if self.prev_signage_point is None:
793
+ self.prev_signage_point = (timestamp, new_signage_point)
794
+ return None
795
+
796
+ prev_time, prev_sp = self.prev_signage_point
797
+ self.prev_signage_point = (timestamp, new_signage_point)
798
+
799
+ if prev_sp.challenge_hash == new_signage_point.challenge_hash:
800
+ missing_sps = new_signage_point.signage_point_index - prev_sp.signage_point_index - 1
801
+ if missing_sps > 0:
802
+ return timestamp, uint32(missing_sps)
803
+ return None
804
+
805
+ actual_sp_interval_seconds = float(timestamp - prev_time)
806
+ if actual_sp_interval_seconds <= 0:
807
+ return None
808
+
809
+ expected_sp_interval_seconds = self.constants.SUB_SLOT_TIME_TARGET / self.constants.NUM_SPS_SUB_SLOT
810
+ allowance = 1.6 # Should be chosen from the range (1 <= allowance < 2)
811
+ if actual_sp_interval_seconds < expected_sp_interval_seconds * allowance:
812
+ return None
813
+
814
+ skipped_sps = uint32(floor(actual_sp_interval_seconds / expected_sp_interval_seconds))
815
+ return timestamp, skipped_sps
816
+
817
+ async def _periodically_update_pool_state_task(self) -> None:
818
+ time_slept = 0
819
+ config_path: Path = config_path_for_filename(self._root_path, "config.yaml")
820
+ while not self._shut_down:
821
+ # Every time the config file changes, read it to check the pool state
822
+ stat_info = config_path.stat()
823
+ if stat_info.st_mtime > self.last_config_access_time:
824
+ # If we detect the config file changed, refresh private keys first just in case
825
+ self.all_root_sks = [sk for sk, _ in await self.get_all_private_keys()]
826
+ self.last_config_access_time = stat_info.st_mtime
827
+ await self.update_pool_state()
828
+ time_slept = 0
829
+ elif time_slept > 60:
830
+ await self.update_pool_state()
831
+ time_slept = 0
832
+ time_slept += 1
833
+ await asyncio.sleep(1)
834
+
835
+ async def _periodically_clear_cache_and_refresh_task(self) -> None:
836
+ time_slept = 0
837
+ refresh_slept = 0
838
+ while not self._shut_down:
839
+ try:
840
+ if time_slept > self.constants.SUB_SLOT_TIME_TARGET:
841
+ now = time.time()
842
+ removed_keys: list[bytes32] = []
843
+ for key, add_time in self.cache_add_time.items():
844
+ if now - float(add_time) > self.constants.SUB_SLOT_TIME_TARGET * 3:
845
+ self.sps.pop(key, None)
846
+ self.proofs_of_space.pop(key, None)
847
+ self.quality_str_to_identifiers.pop(key, None)
848
+ self.number_of_responses.pop(key, None)
849
+ removed_keys.append(key)
850
+ for key in removed_keys:
851
+ self.cache_add_time.pop(key, None)
852
+ time_slept = 0
853
+ log.debug(
854
+ f"Cleared farmer cache. Num sps: {len(self.sps)} {len(self.proofs_of_space)} "
855
+ f"{len(self.quality_str_to_identifiers)} {len(self.number_of_responses)}"
856
+ )
857
+ time_slept += 1
858
+ refresh_slept += 1
859
+ # Periodically refresh GUI to show the correct download/upload rate.
860
+ if refresh_slept >= 30:
861
+ self.state_changed("add_connection", {})
862
+ refresh_slept = 0
863
+
864
+ except Exception:
865
+ log.error(f"_periodically_clear_cache_and_refresh_task failed: {traceback.format_exc()}")
866
+
867
+ await asyncio.sleep(1)
868
+
869
+ def notify_farmer_reward_taken_by_harvester_as_fee(
870
+ self, sp: farmer_protocol.NewSignagePoint, proof_of_space: harvester_protocol.NewProofOfSpace
871
+ ) -> None:
872
+ """
873
+ Apply a fee quality convention (see CHIP-22: https://github.com/Chia-Network/chips/pull/88)
874
+ given the proof and signage point. This will be tested against the fee threshold reported
875
+ by the harvester (if any), and logged.
876
+ """
877
+ assert proof_of_space.farmer_reward_address_override is not None
878
+
879
+ challenge_str = str(sp.challenge_hash)
880
+
881
+ ph_prefix = self.config["network_overrides"]["config"][self.config["selected_network"]]["address_prefix"]
882
+ farmer_reward_puzzle_hash = encode_puzzle_hash(proof_of_space.farmer_reward_address_override, ph_prefix)
883
+
884
+ self.log.info(
885
+ f"Farmer reward for challenge '{challenge_str}' "
886
+ + f"taken by harvester for reward address '{farmer_reward_puzzle_hash}'"
887
+ )
888
+
889
+ fee_quality = calculate_harvester_fee_quality(proof_of_space.proof.proof, sp.challenge_hash)
890
+ fee_quality_rate = float(fee_quality) / float(0xFFFFFFFF) * 100.0
891
+
892
+ if proof_of_space.fee_info is not None:
893
+ fee_threshold = proof_of_space.fee_info.applied_fee_threshold
894
+ fee_threshold_rate = float(fee_threshold) / float(0xFFFFFFFF) * 100.0
895
+
896
+ if fee_quality <= fee_threshold:
897
+ self.log.info(
898
+ f"Fee threshold passed for challenge '{challenge_str}': "
899
+ + f"{fee_quality_rate:.3f}%/{fee_threshold_rate:.3f}% ({fee_quality}/{fee_threshold})"
900
+ )
901
+ else:
902
+ self.log.warning(
903
+ f"Invalid fee threshold for challenge '{challenge_str}': "
904
+ + f"{fee_quality_rate:.3f}%/{fee_threshold_rate:.3f}% ({fee_quality}/{fee_threshold})"
905
+ )
906
+ self.log.warning(
907
+ "Harvester illegitimately took a fee reward that "
908
+ + "did not belong to it or it incorrectly applied the fee convention."
909
+ )
910
+ else:
911
+ self.log.warning(
912
+ "Harvester illegitimately took reward by failing to provide its fee rate "
913
+ + f"for challenge '{challenge_str}'. "
914
+ + f"Fee quality was {fee_quality_rate:.3f}% ({fee_quality} or 0x{fee_quality:08x})"
915
+ )
916
+
917
+
918
+ def calculate_harvester_fee_quality(proof: bytes, challenge: bytes32) -> uint32:
919
+ """
920
+ This calculates the 'fee quality' given a convention between farmers and third party harvesters.
921
+ See CHIP-22: https://github.com/Chia-Network/chips/pull/88
922
+ """
923
+ return uint32(int.from_bytes(std_hash(proof + challenge)[32 - 4 :], byteorder="big", signed=False))