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
@@ -0,0 +1,1226 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import contextlib
5
+ import dataclasses
6
+ import io
7
+ import logging
8
+ import os
9
+ import random
10
+ import tempfile
11
+ import time
12
+ import traceback
13
+ from collections.abc import AsyncIterator
14
+ from concurrent.futures import ThreadPoolExecutor
15
+ from pathlib import Path
16
+ from typing import IO, TYPE_CHECKING, Any, ClassVar, Optional, cast
17
+
18
+ from chiavdf import create_discriminant, prove
19
+
20
+ from chia.consensus.constants import ConsensusConstants
21
+ from chia.consensus.pot_iterations import calculate_sp_iters, is_overflow_block
22
+ from chia.protocols import timelord_protocol
23
+ from chia.protocols.protocol_message_types import ProtocolMessageTypes
24
+ from chia.rpc.rpc_server import StateChangedProtocol, default_get_connections
25
+ from chia.server.outbound_message import NodeType, make_msg
26
+ from chia.server.server import ChiaServer
27
+ from chia.server.ws_connection import WSChiaConnection
28
+ from chia.timelord.iters_from_block import iters_from_block
29
+ from chia.timelord.timelord_state import LastState
30
+ from chia.timelord.types import Chain, IterationType, StateType
31
+ from chia.types.blockchain_format.classgroup import ClassgroupElement
32
+ from chia.types.blockchain_format.reward_chain_block import RewardChainBlock
33
+ from chia.types.blockchain_format.sized_bytes import bytes32
34
+ from chia.types.blockchain_format.slots import (
35
+ ChallengeChainSubSlot,
36
+ InfusedChallengeChainSubSlot,
37
+ RewardChainSubSlot,
38
+ SubSlotProofs,
39
+ )
40
+ from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
41
+ from chia.types.blockchain_format.vdf import VDFInfo, VDFProof, validate_vdf
42
+ from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
43
+ from chia.util.ints import uint8, uint16, uint32, uint64, uint128
44
+ from chia.util.streamable import Streamable, streamable
45
+ from chia.util.task_referencer import create_referenced_task
46
+
47
+ log = logging.getLogger(__name__)
48
+
49
+
50
+ @streamable
51
+ @dataclasses.dataclass(frozen=True)
52
+ class BlueboxProcessData(Streamable):
53
+ challenge: bytes32
54
+ size_bits: uint16
55
+ iters: uint64
56
+
57
+
58
+ def prove_bluebox_slow(payload: bytes, executor_shutdown_tempfile_name: str) -> bytes:
59
+ bluebox_process_data = BlueboxProcessData.from_bytes(payload)
60
+ initial_el = b"\x08" + (b"\x00" * 99)
61
+ return cast(
62
+ bytes,
63
+ prove(
64
+ bluebox_process_data.challenge,
65
+ initial_el,
66
+ bluebox_process_data.size_bits,
67
+ bluebox_process_data.iters,
68
+ executor_shutdown_tempfile_name,
69
+ ),
70
+ )
71
+
72
+
73
+ def _create_shutdown_file() -> IO[bytes]:
74
+ return tempfile.NamedTemporaryFile(prefix="chia_timelord_executor_shutdown_trigger")
75
+
76
+
77
+ class Timelord:
78
+ if TYPE_CHECKING:
79
+ from chia.rpc.rpc_server import RpcServiceProtocol
80
+
81
+ _protocol_check: ClassVar[RpcServiceProtocol] = cast("Timelord", None)
82
+
83
+ @property
84
+ def server(self) -> ChiaServer:
85
+ # This is a stop gap until the class usage is refactored such the values of
86
+ # integral attributes are known at creation of the instance.
87
+ if self._server is None:
88
+ raise RuntimeError("server not assigned")
89
+
90
+ return self._server
91
+
92
+ def __init__(self, root_path: Path, config: dict[str, Any], constants: ConsensusConstants) -> None:
93
+ self.config = config
94
+ self.root_path = root_path
95
+ self.constants = constants
96
+ self._shut_down = False
97
+ self.free_clients: list[tuple[str, asyncio.StreamReader, asyncio.StreamWriter]] = []
98
+ self.ip_whitelist = self.config["vdf_clients"]["ip"]
99
+ self._server: Optional[ChiaServer] = None
100
+ self.chain_type_to_stream: dict[Chain, tuple[str, asyncio.StreamReader, asyncio.StreamWriter]] = {}
101
+ self.chain_start_time: dict[Chain, float] = {}
102
+ # Chains that currently don't have a vdf_client.
103
+ self.unspawned_chains: list[Chain] = [
104
+ Chain.CHALLENGE_CHAIN,
105
+ Chain.REWARD_CHAIN,
106
+ Chain.INFUSED_CHALLENGE_CHAIN,
107
+ ]
108
+ # Chains that currently accept iterations.
109
+ self.allows_iters: list[Chain] = []
110
+ # Last peak received, None if it's already processed.
111
+ self.new_peak: Optional[timelord_protocol.NewPeakTimelord] = None
112
+ # Last state received. Can either be a new peak or a new EndOfSubslotBundle.
113
+ # Unfinished block info, iters adjusted to the last peak.
114
+ self.unfinished_blocks: list[timelord_protocol.NewUnfinishedBlockTimelord] = []
115
+ # Signage points iters, adjusted to the last peak.
116
+ self.signage_point_iters: list[tuple[uint64, uint8]] = []
117
+ # For each chain, send those info when the process spawns.
118
+ self.iters_to_submit: dict[Chain, list[uint64]] = {}
119
+ self.iters_submitted: dict[Chain, list[uint64]] = {}
120
+ self.iters_finished: set[uint64] = set()
121
+ # For each iteration submitted, know if it's a signage point, an infusion point or an end of slot.
122
+ self.iteration_to_proof_type: dict[uint64, IterationType] = {}
123
+ # List of proofs finished.
124
+ self.proofs_finished: list[tuple[Chain, VDFInfo, VDFProof, int]] = []
125
+ # Data to send at vdf_client initialization.
126
+ self.overflow_blocks: list[timelord_protocol.NewUnfinishedBlockTimelord] = []
127
+ # Incremented each time `reset_chains` has been called.
128
+ # Used to label proofs in `finished_proofs` and to only filter proofs corresponding to the most recent state.
129
+ self.num_resets: int = 0
130
+
131
+ self.process_communication_tasks: list[asyncio.Task[None]] = []
132
+ self.main_loop: Optional[asyncio.Task[None]] = None
133
+ self.vdf_server: Optional[asyncio.base_events.Server] = None
134
+ self._shut_down = False
135
+ self.vdf_failures: list[tuple[Chain, Optional[int]]] = []
136
+ self.vdf_failures_count: int = 0
137
+ self.vdf_failure_time: float = 0
138
+ self.total_unfinished: int = 0
139
+ self.total_infused: int = 0
140
+ self.state_changed_callback: Optional[StateChangedProtocol] = None
141
+ self.bluebox_mode = self.config.get("bluebox_mode", False)
142
+ # Support backwards compatibility for the old `config.yaml` that has field `sanitizer_mode`.
143
+ if not self.bluebox_mode:
144
+ self.bluebox_mode = self.config.get("sanitizer_mode", False)
145
+ self.pending_bluebox_info: list[tuple[float, timelord_protocol.RequestCompactProofOfTime]] = []
146
+ self.last_active_time = time.time()
147
+ self.max_allowed_inactivity_time = 60
148
+ self._executor_shutdown_tempfile: Optional[IO[bytes]] = None
149
+ self.bluebox_pool: Optional[ThreadPoolExecutor] = None
150
+
151
+ @contextlib.asynccontextmanager
152
+ async def manage(self) -> AsyncIterator[None]:
153
+ self.lock: asyncio.Lock = asyncio.Lock()
154
+ self.vdf_server = await asyncio.start_server(
155
+ self._handle_client,
156
+ self.config["vdf_server"]["host"],
157
+ int(self.config["vdf_server"]["port"]),
158
+ )
159
+ self.last_state: LastState = LastState(self.constants)
160
+ slow_bluebox = self.config.get("slow_bluebox", False)
161
+ if not self.bluebox_mode:
162
+ self.main_loop = create_referenced_task(self._manage_chains())
163
+ else:
164
+ if os.name == "nt" or slow_bluebox:
165
+ # `vdf_client` doesn't build on windows, use `prove()` from chiavdf.
166
+ workers = self.config.get("slow_bluebox_process_count", 1)
167
+ self._executor_shutdown_tempfile = _create_shutdown_file()
168
+ self.bluebox_pool = ThreadPoolExecutor(
169
+ max_workers=workers,
170
+ )
171
+ self.main_loop = create_referenced_task(
172
+ self._start_manage_discriminant_queue_sanitizer_slow(self.bluebox_pool, workers)
173
+ )
174
+ else:
175
+ self.main_loop = create_referenced_task(self._manage_discriminant_queue_sanitizer())
176
+ log.info(f"Started timelord, listening on port {self.get_vdf_server_port()}")
177
+ try:
178
+ yield
179
+ finally:
180
+ self._shut_down = True
181
+ if self._executor_shutdown_tempfile is not None:
182
+ self._executor_shutdown_tempfile.close()
183
+ for task in self.process_communication_tasks:
184
+ task.cancel()
185
+ if self.main_loop is not None:
186
+ self.main_loop.cancel()
187
+ if self.bluebox_pool is not None:
188
+ self.bluebox_pool.shutdown()
189
+
190
+ def get_connections(self, request_node_type: Optional[NodeType]) -> list[dict[str, Any]]:
191
+ return default_get_connections(server=self.server, request_node_type=request_node_type)
192
+
193
+ async def on_connect(self, connection: WSChiaConnection) -> None:
194
+ pass
195
+
196
+ def get_vdf_server_port(self) -> Optional[uint16]:
197
+ if self.vdf_server is not None:
198
+ return uint16(self.vdf_server.sockets[0].getsockname()[1])
199
+ return None
200
+
201
+ def _set_state_changed_callback(self, callback: StateChangedProtocol) -> None:
202
+ self.state_changed_callback = callback
203
+
204
+ def state_changed(self, change: str, change_data: Optional[dict[str, Any]] = None) -> None:
205
+ if self.state_changed_callback is not None:
206
+ self.state_changed_callback(change, change_data)
207
+
208
+ def set_server(self, server: ChiaServer) -> None:
209
+ self._server = server
210
+
211
+ async def _handle_client(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> None:
212
+ async with self.lock:
213
+ client_ip = writer.get_extra_info("peername")[0]
214
+ log.debug(f"New timelord connection from client: {client_ip}.")
215
+ if client_ip in self.ip_whitelist:
216
+ self.free_clients.append((client_ip, reader, writer))
217
+ log.debug(f"Added new VDF client {client_ip}.")
218
+
219
+ async def _stop_chain(self, chain: Chain) -> None:
220
+ try:
221
+ _, _, stop_writer = self.chain_type_to_stream.pop(chain)
222
+ if chain not in self.unspawned_chains:
223
+ self.unspawned_chains.append(chain)
224
+ if chain in self.allows_iters:
225
+ self.allows_iters.remove(chain)
226
+ stop_writer.write(b"010")
227
+ await stop_writer.drain()
228
+ else:
229
+ log.error(f"Trying to stop {chain} before its initialization.")
230
+ stop_writer.close()
231
+ await stop_writer.wait_closed()
232
+ except ConnectionResetError as e:
233
+ log.error(f"{e}")
234
+ except Exception as e:
235
+ log.error(f"Exception in stop chain: {type(e)} {e}")
236
+
237
+ def get_height(self) -> uint32:
238
+ if self.last_state.state_type == StateType.FIRST_SUB_SLOT:
239
+ return uint32(0)
240
+ else:
241
+ return uint32(self.last_state.get_height() + 1)
242
+
243
+ def _can_infuse_unfinished_block(self, block: timelord_protocol.NewUnfinishedBlockTimelord) -> Optional[uint64]:
244
+ assert self.last_state is not None
245
+ sub_slot_iters = self.last_state.get_sub_slot_iters()
246
+ difficulty = self.last_state.get_difficulty()
247
+ ip_iters = self.last_state.get_last_ip()
248
+ rc_block = block.reward_chain_block
249
+ try:
250
+ block_sp_iters, block_ip_iters = iters_from_block(
251
+ self.constants,
252
+ rc_block,
253
+ sub_slot_iters,
254
+ difficulty,
255
+ self.get_height(),
256
+ )
257
+ except Exception as e:
258
+ log.warning(f"Received invalid unfinished block: {e}.")
259
+ return None
260
+ block_sp_total_iters = self.last_state.total_iters - ip_iters + block_sp_iters
261
+ if is_overflow_block(self.constants, block.reward_chain_block.signage_point_index):
262
+ block_sp_total_iters -= self.last_state.get_sub_slot_iters()
263
+ found_index = -1
264
+ for index, (rc, total_iters) in enumerate(self.last_state.reward_challenge_cache):
265
+ if rc == block.rc_prev:
266
+ found_index = index
267
+ break
268
+ if found_index == -1:
269
+ log.warning(f"Will not infuse {block.rc_prev} because its reward chain challenge is not in the chain")
270
+ return None
271
+ if ip_iters > block_ip_iters:
272
+ log.warning("Too late to infuse block")
273
+ return None
274
+
275
+ new_block_iters = uint64(block_ip_iters - ip_iters)
276
+ if len(self.last_state.reward_challenge_cache) > found_index + 1:
277
+ if self.last_state.reward_challenge_cache[found_index + 1][1] < block_sp_total_iters:
278
+ log.warning(
279
+ f"Will not infuse unfinished block {block.rc_prev} sp total iters {block_sp_total_iters}, "
280
+ f"because there is another infusion before its SP"
281
+ )
282
+ return None
283
+ if self.last_state.reward_challenge_cache[found_index][1] > block_sp_total_iters:
284
+ if not is_overflow_block(self.constants, block.reward_chain_block.signage_point_index):
285
+ log.error(
286
+ f"Will not infuse unfinished block {block.rc_prev}, sp total iters: {block_sp_total_iters}, "
287
+ f"because its iters are too low"
288
+ )
289
+ return None
290
+
291
+ if new_block_iters > 0:
292
+ return new_block_iters
293
+ return None
294
+
295
+ async def _reset_chains(self, *, first_run: bool = False, only_eos: bool = False) -> None:
296
+ # First, stop all chains.
297
+ self.last_active_time = time.time()
298
+ log.debug("Resetting chains")
299
+ ip_iters = self.last_state.get_last_ip()
300
+ sub_slot_iters = self.last_state.get_sub_slot_iters()
301
+
302
+ if not first_run:
303
+ for chain in list(self.chain_type_to_stream.keys()):
304
+ await self._stop_chain(chain)
305
+
306
+ # Adjust all signage points iterations to the peak.
307
+ iters_per_signage = uint64(sub_slot_iters // self.constants.NUM_SPS_SUB_SLOT)
308
+ self.signage_point_iters = [
309
+ (uint64(k * iters_per_signage - ip_iters), uint8(k))
310
+ for k in range(1, self.constants.NUM_SPS_SUB_SLOT)
311
+ if k * iters_per_signage - ip_iters > 0
312
+ ]
313
+ for sp, k in self.signage_point_iters:
314
+ assert k * iters_per_signage > 0
315
+ assert k * iters_per_signage < sub_slot_iters
316
+ # Adjust all unfinished blocks iterations to the peak.
317
+ new_unfinished_blocks = []
318
+ self.iters_finished = set()
319
+ self.proofs_finished = []
320
+ self.num_resets += 1
321
+ for chain in [Chain.CHALLENGE_CHAIN, Chain.REWARD_CHAIN, Chain.INFUSED_CHALLENGE_CHAIN]:
322
+ self.iters_to_submit[chain] = []
323
+ self.iters_submitted[chain] = []
324
+ self.iteration_to_proof_type = {}
325
+ if not only_eos:
326
+ for block in self.unfinished_blocks + self.overflow_blocks:
327
+ new_block_iters: Optional[uint64] = self._can_infuse_unfinished_block(block)
328
+ # Does not add duplicates, or blocks that we cannot infuse
329
+ if new_block_iters and new_block_iters not in self.iters_to_submit[Chain.CHALLENGE_CHAIN]:
330
+ if block not in self.unfinished_blocks:
331
+ self.total_unfinished += 1
332
+ new_unfinished_blocks.append(block)
333
+ for chain in [Chain.REWARD_CHAIN, Chain.CHALLENGE_CHAIN]:
334
+ self.iters_to_submit[chain].append(new_block_iters)
335
+ if self.last_state.get_deficit() < self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
336
+ self.iters_to_submit[Chain.INFUSED_CHALLENGE_CHAIN].append(new_block_iters)
337
+ self.iteration_to_proof_type[new_block_iters] = IterationType.INFUSION_POINT
338
+ # Remove all unfinished blocks that have already passed.
339
+ self.unfinished_blocks = new_unfinished_blocks
340
+
341
+ # remove overflow blocks that were moved to unfinished cache
342
+ for block in new_unfinished_blocks:
343
+ if block in self.overflow_blocks:
344
+ self.overflow_blocks.remove(block)
345
+ # Signage points.
346
+ if not only_eos and len(self.signage_point_iters) > 0:
347
+ count_signage = 0
348
+ for signage, k in self.signage_point_iters:
349
+ for chain in [Chain.CHALLENGE_CHAIN, Chain.REWARD_CHAIN]:
350
+ self.iters_to_submit[chain].append(signage)
351
+ self.iteration_to_proof_type[signage] = IterationType.SIGNAGE_POINT
352
+ count_signage += 1
353
+ if count_signage == 3:
354
+ break
355
+ left_subslot_iters = uint64(sub_slot_iters - ip_iters)
356
+ assert left_subslot_iters > 0
357
+
358
+ if self.last_state.get_deficit() < self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
359
+ self.iters_to_submit[Chain.INFUSED_CHALLENGE_CHAIN].append(left_subslot_iters)
360
+ self.iters_to_submit[Chain.CHALLENGE_CHAIN].append(left_subslot_iters)
361
+ self.iters_to_submit[Chain.REWARD_CHAIN].append(left_subslot_iters)
362
+ self.iteration_to_proof_type[left_subslot_iters] = IterationType.END_OF_SUBSLOT
363
+
364
+ for chain, iters in self.iters_to_submit.items():
365
+ for iteration in iters:
366
+ assert iteration > 0
367
+
368
+ async def _handle_new_peak(self) -> None:
369
+ assert self.new_peak is not None
370
+ self.last_state.set_state(self.new_peak)
371
+
372
+ if self.total_unfinished > 0:
373
+ remove_unfinished = []
374
+ for unf_block_timelord in self.unfinished_blocks + self.overflow_blocks:
375
+ if (
376
+ unf_block_timelord.reward_chain_block.get_hash()
377
+ == self.new_peak.reward_chain_block.get_unfinished().get_hash()
378
+ ):
379
+ if unf_block_timelord not in self.unfinished_blocks:
380
+ # We never got the EOS for this, but we have the block in overflow list
381
+ self.total_unfinished += 1
382
+
383
+ remove_unfinished.append(unf_block_timelord)
384
+ if len(remove_unfinished) > 0:
385
+ self.total_infused += 1
386
+ for block in remove_unfinished:
387
+ if block in self.unfinished_blocks:
388
+ self.unfinished_blocks.remove(block)
389
+ if block in self.overflow_blocks:
390
+ self.overflow_blocks.remove(block)
391
+ infusion_rate = round(self.total_infused / self.total_unfinished * 100.0, 2)
392
+ log.info(
393
+ f"Total unfinished blocks: {self.total_unfinished}. "
394
+ f"Total infused blocks: {self.total_infused}. "
395
+ f"Infusion rate: {infusion_rate}%."
396
+ )
397
+
398
+ self.new_peak = None
399
+ await self._reset_chains()
400
+
401
+ async def _map_chains_with_vdf_clients(self) -> None:
402
+ while not self._shut_down:
403
+ picked_chain = None
404
+ async with self.lock:
405
+ if len(self.free_clients) == 0:
406
+ break
407
+ ip, reader, writer = self.free_clients[0]
408
+ for chain_type in self.unspawned_chains:
409
+ challenge = self.last_state.get_challenge(chain_type)
410
+ initial_form = self.last_state.get_initial_form(chain_type)
411
+ if challenge is not None and initial_form is not None:
412
+ picked_chain = chain_type
413
+ break
414
+ if picked_chain is None:
415
+ break
416
+ picked_chain = self.unspawned_chains[0]
417
+ self.chain_type_to_stream[picked_chain] = (ip, reader, writer)
418
+ self.free_clients = self.free_clients[1:]
419
+ self.unspawned_chains = self.unspawned_chains[1:]
420
+ self.chain_start_time[picked_chain] = time.time()
421
+
422
+ log.debug(f"Mapping free vdf_client with chain: {picked_chain}.")
423
+ assert challenge is not None
424
+ assert initial_form is not None
425
+ self.process_communication_tasks.append(
426
+ create_referenced_task(
427
+ self._do_process_communication(
428
+ picked_chain, challenge, initial_form, ip, reader, writer, proof_label=self.num_resets
429
+ )
430
+ )
431
+ )
432
+
433
+ async def _submit_iterations(self) -> None:
434
+ for chain in [Chain.CHALLENGE_CHAIN, Chain.REWARD_CHAIN, Chain.INFUSED_CHALLENGE_CHAIN]:
435
+ if chain in self.allows_iters:
436
+ _, _, writer = self.chain_type_to_stream[chain]
437
+ for iteration in self.iters_to_submit[chain]:
438
+ if iteration in self.iters_submitted[chain]:
439
+ continue
440
+ self.iters_submitted[chain].append(iteration)
441
+ log.debug(f"Submitting iterations to {chain}: {iteration}")
442
+ assert iteration > 0
443
+ prefix = str(len(str(iteration)))
444
+ if len(str(iteration)) < 10:
445
+ prefix = "0" + prefix
446
+ iter_str = prefix + str(iteration)
447
+ writer.write(iter_str.encode())
448
+ await writer.drain()
449
+
450
+ def _clear_proof_list(self, iters: uint64) -> list[tuple[Chain, VDFInfo, VDFProof, int]]:
451
+ return [
452
+ (chain, info, proof, label)
453
+ for chain, info, proof, label in self.proofs_finished
454
+ if info.number_of_iterations != iters
455
+ ]
456
+
457
+ async def _check_for_new_sp(self, iter_to_look_for: uint64) -> None:
458
+ signage_iters = [
459
+ iteration for iteration, t in self.iteration_to_proof_type.items() if t == IterationType.SIGNAGE_POINT
460
+ ]
461
+ if len(signage_iters) == 0:
462
+ return
463
+ to_remove = []
464
+ for potential_sp_iters, signage_point_index in self.signage_point_iters:
465
+ if potential_sp_iters not in signage_iters or potential_sp_iters != iter_to_look_for:
466
+ continue
467
+ signage_iter = potential_sp_iters
468
+ proofs_with_iter = [
469
+ (chain, info, proof)
470
+ for chain, info, proof, label in self.proofs_finished
471
+ if info.number_of_iterations == signage_iter and label == self.num_resets
472
+ ]
473
+ # Wait for both cc and rc to have the signage point.
474
+ if len(proofs_with_iter) == 2:
475
+ cc_info: Optional[VDFInfo] = None
476
+ cc_proof: Optional[VDFProof] = None
477
+ rc_info: Optional[VDFInfo] = None
478
+ rc_proof: Optional[VDFProof] = None
479
+ for chain, info, proof in proofs_with_iter:
480
+ if chain == Chain.CHALLENGE_CHAIN:
481
+ cc_info = info
482
+ cc_proof = proof
483
+ if chain == Chain.REWARD_CHAIN:
484
+ rc_info = info
485
+ rc_proof = proof
486
+ if cc_info is None or cc_proof is None or rc_info is None or rc_proof is None:
487
+ log.error(f"Insufficient signage point data {signage_iter}")
488
+ continue
489
+ self.iters_finished.add(iter_to_look_for)
490
+ self.last_active_time = time.time()
491
+
492
+ rc_challenge = self.last_state.get_challenge(Chain.REWARD_CHAIN)
493
+ if rc_info.challenge != rc_challenge:
494
+ assert rc_challenge is not None
495
+ log.warning(f"SP: Do not have correct challenge {rc_challenge.hex()} has {rc_info.challenge.hex()}")
496
+ # This proof is on an outdated challenge, so don't use it
497
+ continue
498
+ iters_from_sub_slot_start = uint64(cc_info.number_of_iterations + self.last_state.get_last_ip())
499
+ response = timelord_protocol.NewSignagePointVDF(
500
+ signage_point_index,
501
+ cc_info.replace(number_of_iterations=iters_from_sub_slot_start),
502
+ cc_proof,
503
+ rc_info,
504
+ rc_proof,
505
+ )
506
+ if self._server is not None:
507
+ msg = make_msg(ProtocolMessageTypes.new_signage_point_vdf, response)
508
+ await self.server.send_to_all([msg], NodeType.FULL_NODE)
509
+ # Cleanup the signage point from memory.
510
+ to_remove.append((signage_iter, signage_point_index))
511
+
512
+ self.proofs_finished = self._clear_proof_list(signage_iter)
513
+ # Send the next 3 signage point to the chains.
514
+ next_iters_count = 0
515
+ for next_sp, k in self.signage_point_iters:
516
+ for chain in [Chain.CHALLENGE_CHAIN, Chain.REWARD_CHAIN]:
517
+ if next_sp not in self.iters_submitted[chain] and next_sp not in self.iters_to_submit[chain]:
518
+ self.iters_to_submit[chain].append(next_sp)
519
+ self.iteration_to_proof_type[next_sp] = IterationType.SIGNAGE_POINT
520
+ next_iters_count += 1
521
+ if next_iters_count == 10:
522
+ break
523
+
524
+ # Break so we alternate between checking SP and IP
525
+ break
526
+ for r in to_remove:
527
+ self.signage_point_iters.remove(r)
528
+
529
+ async def _check_for_new_ip(self, iter_to_look_for: uint64) -> None:
530
+ if len(self.unfinished_blocks) == 0:
531
+ return
532
+ infusion_iters = [
533
+ iteration for iteration, t in self.iteration_to_proof_type.items() if t == IterationType.INFUSION_POINT
534
+ ]
535
+ for iteration in infusion_iters:
536
+ if iteration != iter_to_look_for:
537
+ continue
538
+ proofs_with_iter = [
539
+ (chain, info, proof)
540
+ for chain, info, proof, label in self.proofs_finished
541
+ if info.number_of_iterations == iteration and label == self.num_resets
542
+ ]
543
+ if self.last_state.get_challenge(Chain.INFUSED_CHALLENGE_CHAIN) is not None:
544
+ chain_count = 3
545
+ else:
546
+ chain_count = 2
547
+ if len(proofs_with_iter) == chain_count:
548
+ block = None
549
+ ip_iters = None
550
+ for unfinished_block in self.unfinished_blocks:
551
+ try:
552
+ _, ip_iters = iters_from_block(
553
+ self.constants,
554
+ unfinished_block.reward_chain_block,
555
+ self.last_state.get_sub_slot_iters(),
556
+ self.last_state.get_difficulty(),
557
+ self.get_height(),
558
+ )
559
+ except Exception as e:
560
+ log.error(f"Error {e}")
561
+ continue
562
+ if ip_iters - self.last_state.get_last_ip() == iteration:
563
+ block = unfinished_block
564
+ break
565
+ assert ip_iters is not None
566
+ if block is not None:
567
+ ip_total_iters = self.last_state.get_total_iters() + iteration
568
+ challenge = block.reward_chain_block.get_hash()
569
+ icc_info: Optional[VDFInfo] = None
570
+ icc_proof: Optional[VDFProof] = None
571
+ cc_info: Optional[VDFInfo] = None
572
+ cc_proof: Optional[VDFProof] = None
573
+ rc_info: Optional[VDFInfo] = None
574
+ rc_proof: Optional[VDFProof] = None
575
+ for chain, info, proof in proofs_with_iter:
576
+ if chain == Chain.CHALLENGE_CHAIN:
577
+ cc_info = info
578
+ cc_proof = proof
579
+ if chain == Chain.REWARD_CHAIN:
580
+ rc_info = info
581
+ rc_proof = proof
582
+ if chain == Chain.INFUSED_CHALLENGE_CHAIN:
583
+ icc_info = info
584
+ icc_proof = proof
585
+ if cc_info is None or cc_proof is None or rc_info is None or rc_proof is None:
586
+ log.error(f"Insufficient VDF proofs for infusion point ch: {challenge} iterations:{iteration}")
587
+ return
588
+
589
+ rc_challenge = self.last_state.get_challenge(Chain.REWARD_CHAIN)
590
+ if rc_info.challenge != rc_challenge:
591
+ assert rc_challenge is not None
592
+ log.warning(
593
+ f"Do not have correct challenge {rc_challenge.hex()} "
594
+ f"has {rc_info.challenge.hex()}, partial hash {block.reward_chain_block.get_hash()}"
595
+ )
596
+ # This proof is on an outdated challenge, so don't use it
597
+ continue
598
+
599
+ self.iters_finished.add(iter_to_look_for)
600
+ self.last_active_time = time.time()
601
+ log.debug(f"Generated infusion point for challenge: {challenge} iterations: {iteration}.")
602
+
603
+ overflow = is_overflow_block(self.constants, block.reward_chain_block.signage_point_index)
604
+
605
+ if not self.last_state.can_infuse_block(overflow):
606
+ log.warning("Too many blocks, or overflow in new epoch, cannot infuse, discarding")
607
+ return
608
+
609
+ cc_info = cc_info.replace(number_of_iterations=ip_iters)
610
+ response = timelord_protocol.NewInfusionPointVDF(
611
+ challenge,
612
+ cc_info,
613
+ cc_proof,
614
+ rc_info,
615
+ rc_proof,
616
+ icc_info,
617
+ icc_proof,
618
+ )
619
+ msg = make_msg(ProtocolMessageTypes.new_infusion_point_vdf, response)
620
+ if self._server is not None:
621
+ await self.server.send_to_all([msg], NodeType.FULL_NODE)
622
+
623
+ self.proofs_finished = self._clear_proof_list(iteration)
624
+
625
+ if (
626
+ self.last_state.get_last_block_total_iters() is None
627
+ and not self.last_state.state_type == StateType.FIRST_SUB_SLOT
628
+ ):
629
+ # We don't know when the last block was, so we can't make peaks
630
+ return
631
+
632
+ sp_total_iters = (
633
+ ip_total_iters
634
+ - ip_iters
635
+ + calculate_sp_iters(
636
+ self.constants,
637
+ block.sub_slot_iters,
638
+ block.reward_chain_block.signage_point_index,
639
+ )
640
+ - (block.sub_slot_iters if overflow else 0)
641
+ )
642
+ if self.last_state.state_type == StateType.FIRST_SUB_SLOT:
643
+ is_transaction_block = True
644
+ height: uint32 = uint32(0)
645
+ else:
646
+ last_block_ti = self.last_state.get_last_block_total_iters()
647
+ assert last_block_ti is not None
648
+ is_transaction_block = last_block_ti < sp_total_iters
649
+ height = uint32(self.last_state.get_height() + 1)
650
+
651
+ if height < 5:
652
+ # Don't directly update our state for the first few blocks, because we cannot validate
653
+ # whether the pre-farm is correct
654
+ return
655
+
656
+ new_reward_chain_block = RewardChainBlock(
657
+ uint128(self.last_state.get_weight() + block.difficulty),
658
+ height,
659
+ uint128(ip_total_iters),
660
+ block.reward_chain_block.signage_point_index,
661
+ block.reward_chain_block.pos_ss_cc_challenge_hash,
662
+ block.reward_chain_block.proof_of_space,
663
+ block.reward_chain_block.challenge_chain_sp_vdf,
664
+ block.reward_chain_block.challenge_chain_sp_signature,
665
+ cc_info,
666
+ block.reward_chain_block.reward_chain_sp_vdf,
667
+ block.reward_chain_block.reward_chain_sp_signature,
668
+ rc_info,
669
+ icc_info,
670
+ is_transaction_block,
671
+ )
672
+ if self.last_state.state_type == StateType.FIRST_SUB_SLOT:
673
+ # Genesis
674
+ new_deficit = self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1
675
+ elif overflow and self.last_state.deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
676
+ if self.last_state.peak is not None:
677
+ assert self.last_state.subslot_end is None
678
+ # This means the previous block is also an overflow block, and did not manage
679
+ # to lower the deficit, therefore we cannot lower it either. (new slot)
680
+ new_deficit = self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK
681
+ else:
682
+ # This means we are the first infusion in this sub-slot. This may be a new slot or not.
683
+ assert self.last_state.subslot_end is not None
684
+ if self.last_state.subslot_end.infused_challenge_chain is None:
685
+ # There is no ICC, which means we are not finishing a slot. We can reduce the deficit.
686
+ new_deficit = self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1
687
+ else:
688
+ # There is an ICC, which means we are finishing a slot. Different slot, so can't change
689
+ # the deficit
690
+ new_deficit = self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK
691
+ else:
692
+ new_deficit = max(self.last_state.deficit - 1, 0)
693
+
694
+ if new_deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1:
695
+ last_csb_or_eos = ip_total_iters
696
+ else:
697
+ last_csb_or_eos = self.last_state.last_challenge_sb_or_eos_total_iters
698
+
699
+ if self.last_state.just_infused_sub_epoch_summary():
700
+ new_sub_epoch_summary = None
701
+ passed_ses_height_but_not_yet_included = False
702
+ else:
703
+ new_sub_epoch_summary = block.sub_epoch_summary
704
+ if new_reward_chain_block.height % self.constants.SUB_EPOCH_BLOCKS == 0:
705
+ passed_ses_height_but_not_yet_included = True
706
+ else:
707
+ passed_ses_height_but_not_yet_included = (
708
+ self.last_state.get_passed_ses_height_but_not_yet_included()
709
+ )
710
+
711
+ self.new_peak = timelord_protocol.NewPeakTimelord(
712
+ new_reward_chain_block,
713
+ block.difficulty,
714
+ uint8(new_deficit),
715
+ block.sub_slot_iters,
716
+ new_sub_epoch_summary,
717
+ self.last_state.reward_challenge_cache,
718
+ uint128(last_csb_or_eos),
719
+ passed_ses_height_but_not_yet_included,
720
+ )
721
+
722
+ await self._handle_new_peak()
723
+ # Break so we alternate between checking SP and IP
724
+ break
725
+
726
+ async def _check_for_end_of_subslot(self, iter_to_look_for: uint64) -> None:
727
+ left_subslot_iters = [
728
+ iteration for iteration, t in self.iteration_to_proof_type.items() if t == IterationType.END_OF_SUBSLOT
729
+ ]
730
+ if len(left_subslot_iters) == 0:
731
+ return
732
+ if left_subslot_iters[0] != iter_to_look_for:
733
+ return
734
+ chains_finished = [
735
+ (chain, info, proof)
736
+ for chain, info, proof, label in self.proofs_finished
737
+ if info.number_of_iterations == left_subslot_iters[0] and label == self.num_resets
738
+ ]
739
+ if self.last_state.get_challenge(Chain.INFUSED_CHALLENGE_CHAIN) is not None:
740
+ chain_count = 3
741
+ else:
742
+ chain_count = 2
743
+ if len(chains_finished) == chain_count:
744
+ icc_ip_vdf: Optional[VDFInfo] = None
745
+ icc_ip_proof: Optional[VDFProof] = None
746
+ cc_vdf: Optional[VDFInfo] = None
747
+ cc_proof: Optional[VDFProof] = None
748
+ rc_vdf: Optional[VDFInfo] = None
749
+ rc_proof: Optional[VDFProof] = None
750
+ for chain, info, proof in chains_finished:
751
+ if chain == Chain.CHALLENGE_CHAIN:
752
+ cc_vdf = info
753
+ cc_proof = proof
754
+ if chain == Chain.REWARD_CHAIN:
755
+ rc_vdf = info
756
+ rc_proof = proof
757
+ if chain == Chain.INFUSED_CHALLENGE_CHAIN:
758
+ icc_ip_vdf = info
759
+ icc_ip_proof = proof
760
+ assert cc_proof is not None and rc_proof is not None and cc_vdf is not None and rc_vdf is not None
761
+
762
+ rc_challenge = self.last_state.get_challenge(Chain.REWARD_CHAIN)
763
+ if rc_vdf.challenge != rc_challenge:
764
+ assert rc_challenge is not None
765
+ log.warning(f"Do not have correct challenge {rc_challenge.hex()} has {rc_vdf.challenge.hex()}")
766
+ # This proof is on an outdated challenge, so don't use it
767
+ return
768
+ log.debug("Collected end of subslot vdfs.")
769
+ self.iters_finished.add(iter_to_look_for)
770
+ self.last_active_time = time.time()
771
+ iters_from_sub_slot_start = uint64(cc_vdf.number_of_iterations + self.last_state.get_last_ip())
772
+ cc_vdf = cc_vdf.replace(number_of_iterations=iters_from_sub_slot_start)
773
+ if icc_ip_vdf is not None:
774
+ if self.last_state.peak is not None:
775
+ total_iters = (
776
+ self.last_state.get_total_iters()
777
+ - self.last_state.get_last_ip()
778
+ + self.last_state.get_sub_slot_iters()
779
+ )
780
+ else:
781
+ total_iters = self.last_state.get_total_iters() + self.last_state.get_sub_slot_iters()
782
+ iters_from_cb = uint64(total_iters - self.last_state.last_challenge_sb_or_eos_total_iters)
783
+ if iters_from_cb > self.last_state.sub_slot_iters:
784
+ log.error(f"{self.last_state.peak}")
785
+ log.error(f"{self.last_state.subslot_end}")
786
+ assert False
787
+ assert iters_from_cb <= self.last_state.sub_slot_iters
788
+ icc_ip_vdf = icc_ip_vdf.replace(number_of_iterations=iters_from_cb)
789
+
790
+ icc_sub_slot: Optional[InfusedChallengeChainSubSlot] = (
791
+ None if icc_ip_vdf is None else InfusedChallengeChainSubSlot(icc_ip_vdf)
792
+ )
793
+ icc_sub_slot_hash: Optional[bytes32]
794
+ if self.last_state.get_deficit() == 0:
795
+ assert icc_sub_slot is not None
796
+ icc_sub_slot_hash = icc_sub_slot.get_hash()
797
+ else:
798
+ icc_sub_slot_hash = None
799
+ next_ses: Optional[SubEpochSummary] = self.last_state.get_next_sub_epoch_summary()
800
+ ses_hash: Optional[bytes32]
801
+ if next_ses is not None:
802
+ log.info(f"Including sub epoch summary{next_ses}")
803
+ ses_hash = next_ses.get_hash()
804
+ new_sub_slot_iters = next_ses.new_sub_slot_iters
805
+ new_difficulty = next_ses.new_difficulty
806
+ else:
807
+ ses_hash = None
808
+ new_sub_slot_iters = None
809
+ new_difficulty = None
810
+ cc_sub_slot = ChallengeChainSubSlot(cc_vdf, icc_sub_slot_hash, ses_hash, new_sub_slot_iters, new_difficulty)
811
+ eos_deficit: uint8 = (
812
+ self.last_state.get_deficit()
813
+ if self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK > self.last_state.get_deficit() > 0
814
+ else self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK
815
+ )
816
+ rc_sub_slot = RewardChainSubSlot(
817
+ rc_vdf,
818
+ cc_sub_slot.get_hash(),
819
+ icc_sub_slot.get_hash() if icc_sub_slot is not None else None,
820
+ eos_deficit,
821
+ )
822
+ eos_bundle = EndOfSubSlotBundle(
823
+ cc_sub_slot,
824
+ icc_sub_slot,
825
+ rc_sub_slot,
826
+ SubSlotProofs(cc_proof, icc_ip_proof, rc_proof),
827
+ )
828
+ if self._server is not None:
829
+ msg = make_msg(
830
+ ProtocolMessageTypes.new_end_of_sub_slot_vdf,
831
+ timelord_protocol.NewEndOfSubSlotVDF(eos_bundle),
832
+ )
833
+ await self.server.send_to_all([msg], NodeType.FULL_NODE)
834
+
835
+ log.info(
836
+ f"Built end of subslot bundle. cc hash: {eos_bundle.challenge_chain.get_hash()}. New_difficulty: "
837
+ f"{eos_bundle.challenge_chain.new_difficulty} New ssi: {eos_bundle.challenge_chain.new_sub_slot_iters}"
838
+ )
839
+
840
+ if next_ses is None or next_ses.new_difficulty is None:
841
+ self.unfinished_blocks = self.overflow_blocks.copy()
842
+ else:
843
+ # No overflow blocks in a new epoch
844
+ self.unfinished_blocks = []
845
+ self.overflow_blocks = []
846
+
847
+ self.last_state.set_state(eos_bundle)
848
+ for block in self.unfinished_blocks:
849
+ if self._can_infuse_unfinished_block(block) is not None:
850
+ self.total_unfinished += 1
851
+ await self._reset_chains()
852
+
853
+ async def _handle_failures(self) -> None:
854
+ if len(self.vdf_failures) > 0:
855
+ # This can happen if one of the VDF processes has an issue. In this case, we abort all other
856
+ # infusion points and signage points, and go straight to the end of slot, so we avoid potential
857
+ # issues with the number of iterations that failed.
858
+
859
+ failed_chain, proof_label = self.vdf_failures[0]
860
+ log.error(
861
+ f"Vdf clients failed {self.vdf_failures_count} times. Last failure: {failed_chain}, "
862
+ f"label {proof_label}, current: {self.num_resets}"
863
+ )
864
+ if proof_label == self.num_resets:
865
+ await self._reset_chains(only_eos=True)
866
+ self.vdf_failure_time = time.time()
867
+ self.vdf_failures = []
868
+
869
+ # If something goes wrong in the VDF client due to a failed thread, we might get stuck in a situation where we
870
+ # are waiting for that client to finish. Usually other peers will finish the VDFs and reset us. In the case that
871
+ # there are no other timelords, this reset should bring the timelord back to a running state.
872
+ if time.time() - self.vdf_failure_time < self.constants.SUB_SLOT_TIME_TARGET * 3:
873
+ # If we have recently had a failure, allow some more time to finish the slot (we can be up to 3x slower)
874
+ active_time_threshold = self.constants.SUB_SLOT_TIME_TARGET * 3
875
+ else:
876
+ # If there were no failures recently trigger a reset after 60 seconds of no activity.
877
+ # Signage points should be every 9 seconds
878
+ active_time_threshold = self.max_allowed_inactivity_time
879
+ if time.time() - self.last_active_time > active_time_threshold:
880
+ log.error(f"Not active for {active_time_threshold} seconds, restarting all chains")
881
+ self.max_allowed_inactivity_time = min(self.max_allowed_inactivity_time * 2, 1800)
882
+ await self._reset_chains()
883
+
884
+ async def _manage_chains(self) -> None:
885
+ async with self.lock:
886
+ await asyncio.sleep(5)
887
+ await self._reset_chains(first_run=True)
888
+ while not self._shut_down:
889
+ try:
890
+ await asyncio.sleep(0.1)
891
+ async with self.lock:
892
+ await self._handle_failures()
893
+ # We've got a new peak, process it.
894
+ if self.new_peak is not None:
895
+ await self._handle_new_peak()
896
+ # Map free vdf_clients to unspawned chains.
897
+ await self._map_chains_with_vdf_clients()
898
+ async with self.lock:
899
+ # Submit pending iterations.
900
+ await self._submit_iterations()
901
+
902
+ not_finished_iters = [
903
+ it for it in self.iters_submitted[Chain.REWARD_CHAIN] if it not in self.iters_finished
904
+ ]
905
+ if len(not_finished_iters) == 0:
906
+ await asyncio.sleep(0.1)
907
+ continue
908
+ selected_iter = min(not_finished_iters)
909
+
910
+ # Check for new infusion point and broadcast it if present.
911
+ await self._check_for_new_ip(selected_iter)
912
+ # Check for new signage point and broadcast it if present.
913
+ await self._check_for_new_sp(selected_iter)
914
+ # Check for end of subslot, respawn chains and build EndOfSubslotBundle.
915
+ await self._check_for_end_of_subslot(selected_iter)
916
+
917
+ except Exception:
918
+ tb = traceback.format_exc()
919
+ log.error(f"Error while handling message: {tb}")
920
+
921
+ async def _do_process_communication(
922
+ self,
923
+ chain: Chain,
924
+ challenge: bytes32,
925
+ initial_form: ClassgroupElement,
926
+ ip: str,
927
+ reader: asyncio.StreamReader,
928
+ writer: asyncio.StreamWriter,
929
+ # Data specific only when running in bluebox mode.
930
+ bluebox_iteration: Optional[uint64] = None,
931
+ header_hash: Optional[bytes32] = None,
932
+ height: Optional[uint32] = None,
933
+ field_vdf: Optional[uint8] = None,
934
+ # Labels a proof to the current state only
935
+ proof_label: Optional[int] = None,
936
+ ) -> None:
937
+ disc: int = create_discriminant(challenge, self.constants.DISCRIMINANT_SIZE_BITS)
938
+
939
+ try:
940
+ # Depending on the flags 'fast_algorithm' and 'bluebox_mode',
941
+ # the timelord tells the vdf_client what to execute.
942
+ async with self.lock:
943
+ if self.bluebox_mode:
944
+ writer.write(b"S")
945
+ else:
946
+ if self.config["fast_algorithm"]:
947
+ # Run n-wesolowski (fast) algorithm.
948
+ writer.write(b"N")
949
+ else:
950
+ # Run two-wesolowski (slow) algorithm.
951
+ writer.write(b"T")
952
+ await writer.drain()
953
+
954
+ prefix = str(len(str(disc)))
955
+ if len(prefix) == 1:
956
+ prefix = "00" + prefix
957
+ if len(prefix) == 2:
958
+ prefix = "0" + prefix
959
+ async with self.lock:
960
+ writer.write((prefix + str(disc)).encode())
961
+ await writer.drain()
962
+
963
+ # Send initial_form prefixed with its length.
964
+ async with self.lock:
965
+ writer.write(bytes([len(initial_form.data)]) + initial_form.data)
966
+ await writer.drain()
967
+ try:
968
+ ok = await reader.readexactly(2)
969
+ except (asyncio.IncompleteReadError, ConnectionResetError, Exception) as e:
970
+ log.warning(f"{type(e)} {e}")
971
+ async with self.lock:
972
+ self.vdf_failures.append((chain, proof_label))
973
+ self.vdf_failures_count += 1
974
+ return
975
+
976
+ if ok.decode() != "OK":
977
+ return
978
+
979
+ log.debug("Got handshake with VDF client.")
980
+ if not self.bluebox_mode:
981
+ async with self.lock:
982
+ self.allows_iters.append(chain)
983
+ else:
984
+ async with self.lock:
985
+ assert chain is Chain.BLUEBOX
986
+ assert bluebox_iteration is not None
987
+ prefix = str(len(str(bluebox_iteration)))
988
+ if len(str(bluebox_iteration)) < 10:
989
+ prefix = "0" + prefix
990
+ iter_str = prefix + str(bluebox_iteration)
991
+ writer.write(iter_str.encode())
992
+ await writer.drain()
993
+
994
+ # Listen to the client until "STOP" is received.
995
+ while True:
996
+ try:
997
+ data = await reader.readexactly(4)
998
+ except (
999
+ asyncio.IncompleteReadError,
1000
+ ConnectionResetError,
1001
+ Exception,
1002
+ ) as e:
1003
+ log.warning(f"{type(e)} {e}")
1004
+ async with self.lock:
1005
+ self.vdf_failures.append((chain, proof_label))
1006
+ self.vdf_failures_count += 1
1007
+ break
1008
+
1009
+ if data == b"STOP":
1010
+ log.debug(f"Stopped client running on ip {ip}.")
1011
+ async with self.lock:
1012
+ writer.write(b"ACK")
1013
+ await writer.drain()
1014
+ break
1015
+ try:
1016
+ # This must be a proof, 4 bytes is length prefix
1017
+ length = int.from_bytes(data, "big")
1018
+ proof = await reader.readexactly(length)
1019
+ stdout_bytes_io: io.BytesIO = io.BytesIO(bytes.fromhex(proof.decode()))
1020
+ except (
1021
+ asyncio.IncompleteReadError,
1022
+ ConnectionResetError,
1023
+ Exception,
1024
+ ) as e:
1025
+ log.warning(f"{type(e)} {e}")
1026
+ async with self.lock:
1027
+ self.vdf_failures.append((chain, proof_label))
1028
+ self.vdf_failures_count += 1
1029
+ break
1030
+
1031
+ iterations_needed = uint64(int.from_bytes(stdout_bytes_io.read(8), "big", signed=True))
1032
+
1033
+ y_size_bytes = stdout_bytes_io.read(8)
1034
+ y_size = uint64(int.from_bytes(y_size_bytes, "big", signed=True))
1035
+
1036
+ y_bytes = stdout_bytes_io.read(y_size)
1037
+ witness_type = uint8(int.from_bytes(stdout_bytes_io.read(1), "big", signed=True))
1038
+ proof_bytes: bytes = stdout_bytes_io.read()
1039
+
1040
+ # Verifies our own proof just in case
1041
+
1042
+ form_size = ClassgroupElement.get_size()
1043
+ output = ClassgroupElement.create(y_bytes[:form_size])
1044
+ # default value so that it's always set for state_changed later
1045
+ ips: float = 0
1046
+ if not self.bluebox_mode:
1047
+ time_taken = time.time() - self.chain_start_time[chain]
1048
+ ips = int(iterations_needed / time_taken * 10) / 10
1049
+ log.info(
1050
+ f"Finished PoT chall:{challenge[:10].hex()}.. {iterations_needed}"
1051
+ f" iters, "
1052
+ f"Estimated IPS: {ips}, Chain: {chain}"
1053
+ )
1054
+
1055
+ vdf_info: VDFInfo = VDFInfo(
1056
+ challenge,
1057
+ iterations_needed,
1058
+ output,
1059
+ )
1060
+ vdf_proof: VDFProof = VDFProof(
1061
+ witness_type,
1062
+ proof_bytes,
1063
+ self.bluebox_mode,
1064
+ )
1065
+
1066
+ if not validate_vdf(vdf_proof, self.constants, initial_form, vdf_info):
1067
+ log.error("Invalid proof of time!")
1068
+ if not self.bluebox_mode:
1069
+ async with self.lock:
1070
+ assert proof_label is not None
1071
+ self.proofs_finished.append((chain, vdf_info, vdf_proof, proof_label))
1072
+ self.state_changed(
1073
+ "finished_pot",
1074
+ {
1075
+ "estimated_ips": ips,
1076
+ "iterations_needed": iterations_needed,
1077
+ "chain": chain.value,
1078
+ "vdf_info": vdf_info,
1079
+ "vdf_proof": vdf_proof,
1080
+ },
1081
+ )
1082
+ else:
1083
+ async with self.lock:
1084
+ writer.write(b"010")
1085
+ await writer.drain()
1086
+ assert header_hash is not None
1087
+ assert field_vdf is not None
1088
+ assert height is not None
1089
+ response = timelord_protocol.RespondCompactProofOfTime(
1090
+ vdf_info, vdf_proof, header_hash, height, field_vdf
1091
+ )
1092
+ if self._server is not None:
1093
+ message = make_msg(ProtocolMessageTypes.respond_compact_proof_of_time, response)
1094
+ await self.server.send_to_all([message], NodeType.FULL_NODE)
1095
+ self.state_changed(
1096
+ "new_compact_proof", {"header_hash": header_hash, "height": height, "field_vdf": field_vdf}
1097
+ )
1098
+
1099
+ except ConnectionResetError as e:
1100
+ log.debug(f"Connection reset with VDF client {e}")
1101
+ except Exception:
1102
+ log.exception("VDF client communication terminated abruptly")
1103
+
1104
+ async def _manage_discriminant_queue_sanitizer(self) -> None:
1105
+ while not self._shut_down:
1106
+ async with self.lock:
1107
+ try:
1108
+ while len(self.pending_bluebox_info) > 0 and len(self.free_clients) > 0:
1109
+ # Select randomly the field_vdf we're creating a compact vdf for.
1110
+ # This is done because CC_SP and CC_IP are more frequent than
1111
+ # CC_EOS and ICC_EOS. This guarantees everything is picked uniformly.
1112
+ target_field_vdf = random.randint(1, 4)
1113
+ info = next(
1114
+ (info for info in self.pending_bluebox_info if info[1].field_vdf == target_field_vdf),
1115
+ None,
1116
+ )
1117
+ if info is None:
1118
+ # Nothing found with target_field_vdf, just pick the first VDFInfo.
1119
+ info = self.pending_bluebox_info[0]
1120
+ ip, reader, writer = self.free_clients[0]
1121
+ self.process_communication_tasks.append(
1122
+ create_referenced_task(
1123
+ self._do_process_communication(
1124
+ Chain.BLUEBOX,
1125
+ info[1].new_proof_of_time.challenge,
1126
+ ClassgroupElement.get_default_element(),
1127
+ ip,
1128
+ reader,
1129
+ writer,
1130
+ info[1].new_proof_of_time.number_of_iterations,
1131
+ info[1].header_hash,
1132
+ info[1].height,
1133
+ info[1].field_vdf,
1134
+ )
1135
+ )
1136
+ )
1137
+ self.pending_bluebox_info.remove(info)
1138
+ self.free_clients = self.free_clients[1:]
1139
+ except Exception as e:
1140
+ log.error(f"Exception manage discriminant queue: {e}")
1141
+ await asyncio.sleep(0.1)
1142
+
1143
+ async def _start_manage_discriminant_queue_sanitizer_slow(self, pool: ThreadPoolExecutor, counter: int) -> None:
1144
+ tasks = []
1145
+ for _ in range(counter):
1146
+ tasks.append(create_referenced_task(self._manage_discriminant_queue_sanitizer_slow(pool)))
1147
+ for task in tasks:
1148
+ await task
1149
+
1150
+ async def _manage_discriminant_queue_sanitizer_slow(self, pool: ThreadPoolExecutor) -> None:
1151
+ log.info("Started task for managing bluebox queue.")
1152
+ while not self._shut_down:
1153
+ picked_info = None
1154
+ async with self.lock:
1155
+ try:
1156
+ if len(self.pending_bluebox_info) > 0:
1157
+ # Select randomly the field_vdf we're creating a compact vdf for.
1158
+ # This is done because CC_SP and CC_IP are more frequent than
1159
+ # CC_EOS and ICC_EOS. This guarantees everything is picked uniformly.
1160
+ target_field_vdf = random.randint(1, 4)
1161
+ info = next(
1162
+ (info for info in self.pending_bluebox_info if info[1].field_vdf == target_field_vdf),
1163
+ None,
1164
+ )
1165
+ if info is None:
1166
+ # Nothing found with target_field_vdf, just pick the first VDFInfo.
1167
+ info = self.pending_bluebox_info[0]
1168
+ self.pending_bluebox_info.remove(info)
1169
+ picked_info = info[1]
1170
+ except Exception as e:
1171
+ log.error(f"Exception manage discriminant queue: {e}")
1172
+ if picked_info is not None:
1173
+ try:
1174
+ t1 = time.time()
1175
+ log.info(
1176
+ f"Working on compact proof for height: {picked_info.height}. "
1177
+ f"Iters: {picked_info.new_proof_of_time.number_of_iterations}."
1178
+ )
1179
+ bluebox_process_data = BlueboxProcessData(
1180
+ picked_info.new_proof_of_time.challenge,
1181
+ uint16(self.constants.DISCRIMINANT_SIZE_BITS),
1182
+ picked_info.new_proof_of_time.number_of_iterations,
1183
+ )
1184
+ proof = await asyncio.get_running_loop().run_in_executor(
1185
+ pool,
1186
+ prove_bluebox_slow,
1187
+ bytes(bluebox_process_data),
1188
+ "" if self._executor_shutdown_tempfile is None else self._executor_shutdown_tempfile.name,
1189
+ )
1190
+ t2 = time.time()
1191
+ delta = t2 - t1
1192
+ if delta > 0:
1193
+ ips = picked_info.new_proof_of_time.number_of_iterations / delta
1194
+ else:
1195
+ ips = 0
1196
+
1197
+ if len(proof) == 0:
1198
+ log.info(f"Empty VDF proof returned: {picked_info.height}. Time: {delta}s. IPS: {ips}.")
1199
+ return
1200
+
1201
+ log.info(f"Finished compact proof: {picked_info.height}. Time: {delta}s. IPS: {ips}.")
1202
+ output = proof[:100]
1203
+ proof_part = proof[100:200]
1204
+ if ClassgroupElement.create(output) != picked_info.new_proof_of_time.output:
1205
+ log.error("Expected vdf output different than produced one. Stopping.")
1206
+ return
1207
+ vdf_proof = VDFProof(uint8(0), proof_part, True)
1208
+ initial_form = ClassgroupElement.get_default_element()
1209
+ if not validate_vdf(vdf_proof, self.constants, initial_form, picked_info.new_proof_of_time):
1210
+ log.error("Invalid compact proof of time!")
1211
+ return
1212
+ response = timelord_protocol.RespondCompactProofOfTime(
1213
+ picked_info.new_proof_of_time,
1214
+ vdf_proof,
1215
+ picked_info.header_hash,
1216
+ picked_info.height,
1217
+ picked_info.field_vdf,
1218
+ )
1219
+ if self._server is not None:
1220
+ message = make_msg(ProtocolMessageTypes.respond_compact_proof_of_time, response)
1221
+ await self.server.send_to_all([message], NodeType.FULL_NODE)
1222
+ except Exception as e:
1223
+ log.error(f"Exception manage discriminant queue: {e}")
1224
+ tb = traceback.format_exc()
1225
+ log.error(f"Error while handling message: {tb}")
1226
+ await asyncio.sleep(0.1)