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,2054 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import copy
5
+ import logging
6
+ import os
7
+ import random
8
+ import shutil
9
+ import ssl
10
+ import sys
11
+ import tempfile
12
+ import time
13
+ from collections.abc import Sequence
14
+ from dataclasses import dataclass, replace
15
+ from pathlib import Path
16
+ from random import Random
17
+ from typing import Any, Callable, Optional
18
+
19
+ import anyio
20
+ from chia_rs import MEMPOOL_MODE, AugSchemeMPL, G1Element, G2Element, PrivateKey, solution_generator
21
+
22
+ from chia.consensus.block_creation import create_unfinished_block, unfinished_block_to_full_block
23
+ from chia.consensus.block_record import BlockRecord
24
+ from chia.consensus.blockchain_interface import BlockRecordsProtocol
25
+ from chia.consensus.coinbase import create_puzzlehash_for_pk
26
+ from chia.consensus.condition_costs import ConditionCost
27
+ from chia.consensus.constants import ConsensusConstants, replace_str_to_bytes
28
+ from chia.consensus.default_constants import DEFAULT_CONSTANTS
29
+ from chia.consensus.deficit import calculate_deficit
30
+ from chia.consensus.full_block_to_block_record import block_to_block_record
31
+ from chia.consensus.make_sub_epoch_summary import next_sub_epoch_summary
32
+ from chia.consensus.pot_iterations import (
33
+ calculate_ip_iters,
34
+ calculate_iterations_quality,
35
+ calculate_sp_interval_iters,
36
+ calculate_sp_iters,
37
+ is_overflow_block,
38
+ )
39
+ from chia.consensus.vdf_info_computation import get_signage_point_vdf_info
40
+ from chia.daemon.keychain_proxy import KeychainProxy, connect_to_keychain_and_validate, wrap_local_keychain
41
+ from chia.full_node.bundle_tools import simple_solution_generator, simple_solution_generator_backrefs
42
+ from chia.full_node.signage_point import SignagePoint
43
+ from chia.plotting.create_plots import PlotKeys, create_plots
44
+ from chia.plotting.manager import PlotManager
45
+ from chia.plotting.util import (
46
+ Params,
47
+ PlotRefreshEvents,
48
+ PlotRefreshResult,
49
+ PlotsRefreshParameter,
50
+ add_plot_directory,
51
+ parse_plot_info,
52
+ )
53
+ from chia.server.server import ssl_context_for_client
54
+ from chia.simulator.socket import find_available_listen_port
55
+ from chia.simulator.ssl_certs import (
56
+ SSLTestCACertAndPrivateKey,
57
+ SSLTestCollateralWrapper,
58
+ SSLTestNodeCertsAndKeys,
59
+ get_next_nodes_certs_and_keys,
60
+ get_next_private_ca_cert_and_key,
61
+ )
62
+ from chia.simulator.wallet_tools import WalletTool
63
+ from chia.ssl.create_ssl import create_all_ssl
64
+ from chia.types.blockchain_format.classgroup import ClassgroupElement
65
+ from chia.types.blockchain_format.coin import Coin
66
+ from chia.types.blockchain_format.pool_target import PoolTarget
67
+ from chia.types.blockchain_format.program import INFINITE_COST, Program
68
+ from chia.types.blockchain_format.proof_of_space import (
69
+ ProofOfSpace,
70
+ calculate_pos_challenge,
71
+ calculate_prefix_bits,
72
+ generate_plot_public_key,
73
+ generate_taproot_sk,
74
+ passes_plot_filter,
75
+ verify_and_get_quality_string,
76
+ )
77
+ from chia.types.blockchain_format.serialized_program import SerializedProgram
78
+ from chia.types.blockchain_format.sized_bytes import bytes32
79
+ from chia.types.blockchain_format.slots import (
80
+ ChallengeChainSubSlot,
81
+ InfusedChallengeChainSubSlot,
82
+ RewardChainSubSlot,
83
+ SubSlotProofs,
84
+ )
85
+ from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
86
+ from chia.types.blockchain_format.vdf import VDFInfo, VDFProof
87
+ from chia.types.condition_opcodes import ConditionOpcode
88
+ from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
89
+ from chia.types.full_block import FullBlock
90
+ from chia.types.generator_types import BlockGenerator
91
+ from chia.types.spend_bundle import SpendBundle
92
+ from chia.types.unfinished_block import UnfinishedBlock
93
+ from chia.util.bech32m import encode_puzzle_hash
94
+ from chia.util.block_cache import BlockCache
95
+ from chia.util.config import (
96
+ config_path_for_filename,
97
+ create_default_chia_config,
98
+ load_config,
99
+ lock_config,
100
+ override_config,
101
+ save_config,
102
+ )
103
+ from chia.util.default_root import DEFAULT_ROOT_PATH
104
+ from chia.util.hash import std_hash
105
+ from chia.util.ints import uint8, uint16, uint32, uint64, uint128
106
+ from chia.util.keychain import Keychain, bytes_to_mnemonic
107
+ from chia.util.ssl_check import fix_ssl
108
+ from chia.util.timing import adjusted_timeout, backoff_times
109
+ from chia.util.vdf_prover import get_vdf_info_and_proof
110
+ from chia.wallet.derive_keys import (
111
+ master_sk_to_farmer_sk,
112
+ master_sk_to_local_sk,
113
+ master_sk_to_pool_sk,
114
+ master_sk_to_wallet_sk,
115
+ )
116
+ from chia.wallet.puzzles.load_clvm import load_serialized_clvm_maybe_recompile
117
+
118
+ GENERATOR_MOD: SerializedProgram = load_serialized_clvm_maybe_recompile(
119
+ "rom_bootstrap_generator.clsp", package_or_requirement="chia.consensus.puzzles"
120
+ )
121
+
122
+ DESERIALIZE_MOD = load_serialized_clvm_maybe_recompile(
123
+ "chialisp_deserialisation.clsp", package_or_requirement="chia.consensus.puzzles"
124
+ )
125
+
126
+ test_constants = DEFAULT_CONSTANTS.replace(
127
+ MIN_PLOT_SIZE=uint8(18),
128
+ MIN_BLOCKS_PER_CHALLENGE_BLOCK=uint8(12),
129
+ DIFFICULTY_STARTING=uint64(2**10),
130
+ DISCRIMINANT_SIZE_BITS=uint16(16),
131
+ SUB_EPOCH_BLOCKS=uint32(170),
132
+ WEIGHT_PROOF_THRESHOLD=uint8(2),
133
+ WEIGHT_PROOF_RECENT_BLOCKS=uint32(380),
134
+ DIFFICULTY_CONSTANT_FACTOR=uint128(33554432),
135
+ NUM_SPS_SUB_SLOT=uint32(16), # Must be a power of 2
136
+ MAX_SUB_SLOT_BLOCKS=uint32(50),
137
+ EPOCH_BLOCKS=uint32(340),
138
+ # the block cache must contain at least 3 epochs in order for
139
+ # create_prev_sub_epoch_segments() to have access to all the blocks it needs
140
+ # from the cache
141
+ BLOCKS_CACHE_SIZE=uint32(340 * 3), # Coordinate with the above values
142
+ SUB_SLOT_TIME_TARGET=uint16(600), # The target number of seconds per slot, mainnet 600
143
+ SUB_SLOT_ITERS_STARTING=uint64(2**10), # Must be a multiple of 64
144
+ NUMBER_ZERO_BITS_PLOT_FILTER=uint8(1), # H(plot signature of the challenge) must start with these many zeroes
145
+ # Allows creating blockchains with timestamps up to 10 days in the future, for testing
146
+ MAX_FUTURE_TIME2=uint32(3600 * 24 * 10),
147
+ MEMPOOL_BLOCK_BUFFER=uint8(6),
148
+ )
149
+
150
+
151
+ def compute_additions_unchecked(sb: SpendBundle) -> list[Coin]:
152
+ ret: list[Coin] = []
153
+ for cs in sb.coin_spends:
154
+ parent_id = cs.coin.name()
155
+ _, r = cs.puzzle_reveal.run_with_cost(INFINITE_COST, cs.solution)
156
+ for cond in Program.to(r).as_iter():
157
+ atoms = cond.as_iter()
158
+ op = next(atoms).atom
159
+ if op != ConditionOpcode.CREATE_COIN.value:
160
+ continue
161
+ puzzle_hash = next(atoms).as_atom()
162
+ amount = uint64(next(atoms).as_int())
163
+ ret.append(Coin(parent_id, puzzle_hash, amount))
164
+ return ret
165
+
166
+
167
+ def make_spend_bundle(coins: list[Coin], wallet: WalletTool, rng: Random) -> tuple[SpendBundle, list[Coin]]:
168
+ """
169
+ makes a new spend bundle (block generator) spending some of the coins in the
170
+ list of coins. The list will be updated to have spent coins removed and new
171
+ coins appended.
172
+ """
173
+ new_coins: list[Coin] = []
174
+ spend_bundles: list[SpendBundle] = []
175
+ to_spend = rng.sample(coins, min(5, len(coins)))
176
+ receiver = wallet.get_new_puzzlehash()
177
+ for c in to_spend:
178
+ bundle = wallet.generate_signed_transaction(uint64(c.amount // 2), receiver, c)
179
+ new_coins.extend(bundle.additions())
180
+ spend_bundles.append(bundle)
181
+ coins.remove(c)
182
+
183
+ coins.extend(new_coins)
184
+
185
+ return SpendBundle.aggregate(spend_bundles), new_coins
186
+
187
+
188
+ class BlockTools:
189
+ """
190
+ Tools to generate blocks for testing.
191
+ """
192
+
193
+ _block_cache_header: bytes32
194
+ _block_cache_height_to_hash: dict[uint32, bytes32]
195
+ _block_cache_difficulty: uint64
196
+ _block_cache: dict[bytes32, BlockRecord]
197
+
198
+ def __init__(
199
+ self,
200
+ constants: ConsensusConstants = test_constants,
201
+ root_path: Optional[Path] = None,
202
+ keychain: Optional[Keychain] = None,
203
+ config_overrides: Optional[dict[str, Any]] = None,
204
+ automated_testing: bool = True,
205
+ plot_dir: str = "test-plots",
206
+ log: logging.Logger = logging.getLogger(__name__),
207
+ ) -> None:
208
+ self._block_cache_header = bytes32.zeros
209
+
210
+ self._tempdir = None
211
+ if root_path is None:
212
+ self._tempdir = tempfile.TemporaryDirectory()
213
+ root_path = Path(self._tempdir.name)
214
+
215
+ self.root_path = root_path
216
+ self.log = log
217
+ self.local_keychain = keychain
218
+ self.local_sk_cache: dict[bytes32, tuple[PrivateKey, Any]] = {}
219
+ self.automated_testing = automated_testing
220
+ self.plot_dir_name = plot_dir
221
+
222
+ if automated_testing:
223
+ # Hold onto the wrappers so that they can keep track of whether the certs/keys
224
+ # are in use by another BlockTools instance.
225
+ self.ssl_ca_cert_and_key_wrapper: SSLTestCollateralWrapper[SSLTestCACertAndPrivateKey] = (
226
+ get_next_private_ca_cert_and_key()
227
+ )
228
+ self.ssl_nodes_certs_and_keys_wrapper: SSLTestCollateralWrapper[SSLTestNodeCertsAndKeys] = (
229
+ get_next_nodes_certs_and_keys()
230
+ )
231
+ create_default_chia_config(root_path)
232
+ create_all_ssl(
233
+ root_path,
234
+ private_ca_crt_and_key=self.ssl_ca_cert_and_key_wrapper.collateral.cert_and_key,
235
+ node_certs_and_keys=self.ssl_nodes_certs_and_keys_wrapper.collateral.certs_and_keys,
236
+ )
237
+ fix_ssl(root_path)
238
+ with lock_config(root_path=root_path, filename="config.yaml"):
239
+ path = config_path_for_filename(root_path=root_path, filename="config.yaml")
240
+ path.write_text(path.read_text().replace("localhost", "127.0.0.1"))
241
+ self._config = load_config(self.root_path, "config.yaml")
242
+ if automated_testing:
243
+ if config_overrides is None:
244
+ config_overrides = {}
245
+ config_overrides["logging.log_stdout"] = True
246
+ config_overrides["selected_network"] = "testnet0"
247
+ for service in [
248
+ "harvester",
249
+ "farmer",
250
+ "full_node",
251
+ "wallet",
252
+ "introducer",
253
+ "timelord",
254
+ "pool",
255
+ "simulator",
256
+ ]:
257
+ config_overrides[service + ".selected_network"] = "testnet0"
258
+
259
+ # some tests start the daemon, make sure it's on a free port
260
+ config_overrides["daemon_port"] = find_available_listen_port("BlockTools daemon")
261
+
262
+ self._config = override_config(self._config, config_overrides)
263
+
264
+ with lock_config(self.root_path, "config.yaml"):
265
+ save_config(self.root_path, "config.yaml", self._config)
266
+ overrides = self._config["network_overrides"]["constants"][self._config["selected_network"]]
267
+ updated_constants = replace_str_to_bytes(constants, **overrides)
268
+ self.constants = updated_constants
269
+
270
+ self.plot_dir: Path = get_plot_dir(self.plot_dir_name, self.automated_testing)
271
+ self.temp_dir: Path = get_plot_tmp_dir(self.plot_dir_name, self.automated_testing)
272
+ self.plot_dir.mkdir(parents=True, exist_ok=True)
273
+ self.temp_dir.mkdir(parents=True, exist_ok=True)
274
+ self.expected_plots: dict[bytes32, Path] = {}
275
+ self.created_plots: int = 0
276
+ self.total_result = PlotRefreshResult()
277
+
278
+ def test_callback(event: PlotRefreshEvents, update_result: PlotRefreshResult) -> None:
279
+ assert update_result.duration < 120
280
+ if event == PlotRefreshEvents.started:
281
+ self.total_result = PlotRefreshResult()
282
+
283
+ if event == PlotRefreshEvents.batch_processed:
284
+ self.total_result.loaded += update_result.loaded
285
+ self.total_result.processed += update_result.processed
286
+ self.total_result.duration += update_result.duration
287
+ assert update_result.remaining >= len(self.expected_plots) - self.total_result.processed
288
+ assert len(update_result.loaded) <= self.plot_manager.refresh_parameter.batch_size
289
+
290
+ if event == PlotRefreshEvents.done:
291
+ assert self.total_result.loaded == update_result.loaded
292
+ assert self.total_result.processed == update_result.processed
293
+ assert self.total_result.duration == update_result.duration
294
+ assert update_result.remaining == 0
295
+ assert len(self.plot_manager.plots) == len(self.expected_plots)
296
+
297
+ self.plot_manager: PlotManager = PlotManager(
298
+ self.root_path,
299
+ refresh_parameter=PlotsRefreshParameter(batch_size=uint32(2)),
300
+ refresh_callback=test_callback,
301
+ match_str=str(self.plot_dir.relative_to(DEFAULT_ROOT_PATH.parent)) if not automated_testing else None,
302
+ )
303
+
304
+ async def setup_keys(self, fingerprint: Optional[int] = None, reward_ph: Optional[bytes32] = None) -> None:
305
+ keychain_proxy: Optional[KeychainProxy]
306
+ try:
307
+ if self.local_keychain:
308
+ keychain_proxy = wrap_local_keychain(self.local_keychain, log=self.log)
309
+ elif not self.automated_testing and fingerprint is not None:
310
+ keychain_proxy = await connect_to_keychain_and_validate(self.root_path, self.log)
311
+ else: # if we are automated testing or if we don't have a fingerprint.
312
+ keychain_proxy = await connect_to_keychain_and_validate(
313
+ self.root_path, self.log, user="testing-1.8.0", service="chia-testing-1.8.0"
314
+ )
315
+ assert keychain_proxy is not None
316
+ if fingerprint is None: # if we are not specifying an existing key
317
+ await keychain_proxy.delete_all_keys()
318
+ self.farmer_master_sk_entropy = std_hash(b"block_tools farmer key") # both entropies are only used here
319
+ self.pool_master_sk_entropy = std_hash(b"block_tools pool key")
320
+ self.farmer_master_sk = await keychain_proxy.add_key(bytes_to_mnemonic(self.farmer_master_sk_entropy))
321
+ self.pool_master_sk = await keychain_proxy.add_key(
322
+ bytes_to_mnemonic(self.pool_master_sk_entropy),
323
+ )
324
+ else:
325
+ sk = await keychain_proxy.get_key_for_fingerprint(fingerprint)
326
+ assert sk is not None
327
+ self.farmer_master_sk = sk
328
+ sk = await keychain_proxy.get_key_for_fingerprint(fingerprint)
329
+ assert sk is not None
330
+ self.pool_master_sk = sk
331
+
332
+ self.farmer_pk = master_sk_to_farmer_sk(self.farmer_master_sk).get_g1()
333
+ self.pool_pk = master_sk_to_pool_sk(self.pool_master_sk).get_g1()
334
+
335
+ if reward_ph is None:
336
+ self.farmer_ph: bytes32 = create_puzzlehash_for_pk(
337
+ master_sk_to_wallet_sk(self.farmer_master_sk, uint32(0)).get_g1()
338
+ )
339
+ self.pool_ph: bytes32 = create_puzzlehash_for_pk(
340
+ master_sk_to_wallet_sk(self.pool_master_sk, uint32(0)).get_g1()
341
+ )
342
+ else:
343
+ self.farmer_ph = reward_ph
344
+ self.pool_ph = reward_ph
345
+ if self.automated_testing:
346
+ self.all_sks: list[PrivateKey] = [sk for sk, _ in await keychain_proxy.get_all_private_keys()]
347
+ else:
348
+ self.all_sks = [self.farmer_master_sk] # we only want to include plots under the same fingerprint
349
+ self.pool_pubkeys: list[G1Element] = [master_sk_to_pool_sk(sk).get_g1() for sk in self.all_sks]
350
+
351
+ self.farmer_pubkeys: list[G1Element] = [master_sk_to_farmer_sk(sk).get_g1() for sk in self.all_sks]
352
+ if len(self.pool_pubkeys) == 0 or len(self.farmer_pubkeys) == 0:
353
+ raise RuntimeError("Keys not generated. Run `chia keys generate`")
354
+
355
+ self.plot_manager.set_public_keys(self.farmer_pubkeys, self.pool_pubkeys)
356
+ finally:
357
+ if keychain_proxy is not None:
358
+ await keychain_proxy.close() # close the keychain proxy
359
+
360
+ def change_config(self, new_config: dict[str, Any]) -> None:
361
+ self._config = new_config
362
+ overrides = self._config["network_overrides"]["constants"][self._config["selected_network"]]
363
+ updated_constants = replace_str_to_bytes(self.constants, **overrides)
364
+ self.constants = updated_constants
365
+ with lock_config(self.root_path, "config.yaml"):
366
+ save_config(self.root_path, "config.yaml", self._config)
367
+
368
+ def add_plot_directory(self, path: Path) -> None:
369
+ # don't add to config if block_tools is user run and the directory is already in the config.
370
+ if str(path.resolve()) not in self._config["harvester"]["plot_directories"] or self.automated_testing:
371
+ self._config = add_plot_directory(self.root_path, str(path))
372
+
373
+ async def setup_plots(
374
+ self,
375
+ num_og_plots: int = 15,
376
+ num_pool_plots: int = 5,
377
+ num_non_keychain_plots: int = 3,
378
+ plot_size: int = 20,
379
+ bitfield: bool = True,
380
+ ) -> bool:
381
+ self.add_plot_directory(self.plot_dir)
382
+ assert self.created_plots == 0
383
+ existing_plots: bool = True
384
+ # OG Plots
385
+ for i in range(num_og_plots):
386
+ plot = await self.new_plot(plot_size=plot_size, bitfield=bitfield)
387
+ if plot.new_plot:
388
+ existing_plots = False
389
+ # Pool Plots
390
+ for i in range(num_pool_plots):
391
+ plot = await self.new_plot(self.pool_ph, plot_size=plot_size, bitfield=bitfield)
392
+ if plot.new_plot:
393
+ existing_plots = False
394
+ # Some plots with keys that are not in the keychain
395
+ for i in range(num_non_keychain_plots):
396
+ plot = await self.new_plot(
397
+ path=self.plot_dir / "not_in_keychain",
398
+ plot_keys=PlotKeys(G1Element(), G1Element(), None),
399
+ exclude_plots=True,
400
+ plot_size=plot_size,
401
+ bitfield=bitfield,
402
+ )
403
+ if plot.new_plot:
404
+ existing_plots = False
405
+ await self.refresh_plots()
406
+ assert len(self.plot_manager.plots) == len(self.expected_plots)
407
+ return existing_plots
408
+
409
+ async def new_plot(
410
+ self,
411
+ pool_contract_puzzle_hash: Optional[bytes32] = None,
412
+ path: Optional[Path] = None,
413
+ tmp_dir: Optional[Path] = None,
414
+ plot_keys: Optional[PlotKeys] = None,
415
+ exclude_plots: bool = False,
416
+ plot_size: int = 20,
417
+ bitfield: bool = True,
418
+ ) -> BlockToolsNewPlotResult:
419
+ final_dir = self.plot_dir
420
+ if path is not None:
421
+ final_dir = path
422
+ final_dir.mkdir(parents=True, exist_ok=True)
423
+ if tmp_dir is None:
424
+ tmp_dir = self.temp_dir
425
+ params = Params(
426
+ # Can't go much lower than 20, since plots start having no solutions and more buggy
427
+ size=plot_size,
428
+ # Uses many plots for testing, in order to guarantee proofs of space at every height
429
+ num=1,
430
+ buffer=100,
431
+ tmp_dir=Path(tmp_dir),
432
+ tmp2_dir=Path(tmp_dir),
433
+ final_dir=Path(final_dir),
434
+ plotid=None,
435
+ memo=None,
436
+ buckets=0,
437
+ stripe_size=2000,
438
+ num_threads=0,
439
+ nobitfield=not bitfield,
440
+ )
441
+ try:
442
+ if plot_keys is None:
443
+ pool_pk: Optional[G1Element] = None
444
+ pool_address: Optional[str] = None
445
+ if pool_contract_puzzle_hash is None:
446
+ pool_pk = self.pool_pk
447
+ else:
448
+ pool_address = encode_puzzle_hash(pool_contract_puzzle_hash, "xch")
449
+
450
+ plot_keys = PlotKeys(self.farmer_pk, pool_pk, pool_address)
451
+ # No datetime in the filename, to get deterministic filenames and not re-plot
452
+ created, existed = await create_plots(
453
+ params,
454
+ plot_keys,
455
+ use_datetime=False,
456
+ test_private_keys=[AugSchemeMPL.key_gen(std_hash(self.created_plots.to_bytes(2, "big")))],
457
+ )
458
+ self.created_plots += 1
459
+
460
+ plot_id_new: Optional[bytes32] = None
461
+ path_new: Optional[Path] = None
462
+ new_plot: bool = True
463
+
464
+ if len(created):
465
+ assert len(existed) == 0
466
+ plot_id_new, path_new = next(iter(created.items()))
467
+
468
+ if len(existed):
469
+ assert len(created) == 0
470
+ plot_id_new, path_new = next(iter(existed.items()))
471
+ new_plot = False
472
+ assert plot_id_new is not None
473
+ assert path_new is not None
474
+
475
+ if not exclude_plots:
476
+ self.expected_plots[plot_id_new] = path_new
477
+
478
+ return BlockToolsNewPlotResult(plot_id_new, new_plot)
479
+
480
+ except KeyboardInterrupt:
481
+ shutil.rmtree(self.temp_dir, ignore_errors=True)
482
+ sys.exit(1)
483
+
484
+ async def refresh_plots(self) -> None:
485
+ self.plot_manager.refresh_parameter = replace(
486
+ self.plot_manager.refresh_parameter, batch_size=uint32(4 if len(self.expected_plots) % 3 == 0 else 3)
487
+ ) # Make sure we have at least some batches + a remainder
488
+ self.plot_manager.trigger_refresh()
489
+ assert self.plot_manager.needs_refresh()
490
+ self.plot_manager.start_refreshing(sleep_interval_ms=1)
491
+
492
+ with anyio.fail_after(delay=adjusted_timeout(120)):
493
+ for backoff in backoff_times():
494
+ if not self.plot_manager.needs_refresh():
495
+ break
496
+
497
+ await asyncio.sleep(backoff)
498
+
499
+ self.plot_manager.stop_refreshing()
500
+ assert not self.plot_manager.needs_refresh()
501
+
502
+ async def delete_plot(self, plot_id: bytes32) -> None:
503
+ assert plot_id in self.expected_plots
504
+ self.expected_plots[plot_id].unlink()
505
+ del self.expected_plots[plot_id]
506
+ await self.refresh_plots()
507
+
508
+ @property
509
+ def config(self) -> dict[str, Any]:
510
+ return copy.deepcopy(self._config)
511
+
512
+ def get_daemon_ssl_context(self) -> ssl.SSLContext:
513
+ crt_path = self.root_path / self.config["daemon_ssl"]["private_crt"]
514
+ key_path = self.root_path / self.config["daemon_ssl"]["private_key"]
515
+ ca_cert_path = self.root_path / self.config["private_ssl_ca"]["crt"]
516
+ ca_key_path = self.root_path / self.config["private_ssl_ca"]["key"]
517
+ return ssl_context_for_client(ca_cert_path, ca_key_path, crt_path, key_path)
518
+
519
+ def get_plot_signature(self, m: bytes32, plot_pk: G1Element) -> G2Element:
520
+ """
521
+ Returns the plot signature of the header data.
522
+ """
523
+ farmer_sk = master_sk_to_farmer_sk(self.all_sks[0])
524
+ for plot_info in self.plot_manager.plots.values():
525
+ if plot_pk == plot_info.plot_public_key:
526
+ # Look up local_sk from plot to save locked memory
527
+ if plot_info.prover.get_id() in self.local_sk_cache:
528
+ local_master_sk, pool_pk_or_ph = self.local_sk_cache[plot_info.prover.get_id()]
529
+ else:
530
+ pool_pk_or_ph, _, local_master_sk = parse_plot_info(plot_info.prover.get_memo())
531
+ self.local_sk_cache[plot_info.prover.get_id()] = (local_master_sk, pool_pk_or_ph)
532
+ if isinstance(pool_pk_or_ph, G1Element):
533
+ include_taproot = False
534
+ else:
535
+ assert isinstance(pool_pk_or_ph, bytes32)
536
+ include_taproot = True
537
+ local_sk = master_sk_to_local_sk(local_master_sk)
538
+ agg_pk = generate_plot_public_key(local_sk.get_g1(), farmer_sk.get_g1(), include_taproot)
539
+ assert agg_pk == plot_pk
540
+ harv_share = AugSchemeMPL.sign(local_sk, m, agg_pk)
541
+ farm_share = AugSchemeMPL.sign(farmer_sk, m, agg_pk)
542
+ if include_taproot:
543
+ taproot_sk: PrivateKey = generate_taproot_sk(local_sk.get_g1(), farmer_sk.get_g1())
544
+ taproot_share: G2Element = AugSchemeMPL.sign(taproot_sk, m, agg_pk)
545
+ else:
546
+ taproot_share = G2Element()
547
+ return AugSchemeMPL.aggregate([harv_share, farm_share, taproot_share])
548
+
549
+ raise ValueError(f"Do not have key {plot_pk}")
550
+
551
+ def get_pool_key_signature(self, pool_target: PoolTarget, pool_pk: Optional[G1Element]) -> Optional[G2Element]:
552
+ # Returns the pool signature for the corresponding pk. If no pk is provided, returns None.
553
+ if pool_pk is None:
554
+ return None
555
+
556
+ for sk in self.all_sks:
557
+ sk_child = master_sk_to_pool_sk(sk)
558
+ if sk_child.get_g1() == pool_pk:
559
+ return AugSchemeMPL.sign(sk_child, bytes(pool_target))
560
+ raise ValueError(f"Do not have key {pool_pk}")
561
+
562
+ def get_farmer_wallet_tool(self) -> WalletTool:
563
+ return WalletTool(self.constants, self.farmer_master_sk)
564
+
565
+ def get_pool_wallet_tool(self) -> WalletTool:
566
+ return WalletTool(self.constants, self.pool_master_sk)
567
+
568
+ def get_consecutive_blocks(
569
+ self,
570
+ num_blocks: int,
571
+ block_list_input: Optional[list[FullBlock]] = None,
572
+ *,
573
+ farmer_reward_puzzle_hash: Optional[bytes32] = None,
574
+ pool_reward_puzzle_hash: Optional[bytes32] = None,
575
+ transaction_data: Optional[SpendBundle] = None,
576
+ seed: bytes = b"",
577
+ time_per_block: Optional[float] = None,
578
+ force_overflow: bool = False,
579
+ skip_slots: int = 0, # Force at least this number of empty slots before the first SB
580
+ guarantee_transaction_block: bool = False, # Force that this block must be a tx block
581
+ keep_going_until_tx_block: bool = False, # keep making new blocks until we find a tx block
582
+ normalized_to_identity_cc_eos: bool = False,
583
+ normalized_to_identity_icc_eos: bool = False,
584
+ normalized_to_identity_cc_sp: bool = False,
585
+ normalized_to_identity_cc_ip: bool = False,
586
+ current_time: bool = False,
587
+ block_refs: list[uint32] = [],
588
+ genesis_timestamp: Optional[uint64] = None,
589
+ force_plot_id: Optional[bytes32] = None,
590
+ dummy_block_references: bool = False,
591
+ include_transactions: bool = False,
592
+ skip_overflow: bool = False,
593
+ min_signage_point: int = -1,
594
+ ) -> list[FullBlock]:
595
+ assert num_blocks > 0
596
+ if block_list_input is not None:
597
+ block_list = block_list_input.copy()
598
+ else:
599
+ block_list = []
600
+
601
+ tx_block_heights: list[uint32] = []
602
+ if dummy_block_references:
603
+ # block references can only point to transaction blocks, so we need
604
+ # to record which ones are
605
+ for b in block_list:
606
+ if b.transactions_generator is not None:
607
+ tx_block_heights.append(b.height)
608
+
609
+ constants = self.constants
610
+ transaction_data_included = False
611
+ if time_per_block is None:
612
+ time_per_block = float(constants.SUB_SLOT_TIME_TARGET) / float(constants.SLOT_BLOCKS_TARGET)
613
+
614
+ available_coins: list[Coin] = []
615
+ pending_rewards: list[Coin] = []
616
+ wallet: Optional[WalletTool] = None
617
+ rng: Optional[Random] = None
618
+ if include_transactions:
619
+ # when we generate transactions in the chain, the caller cannot also
620
+ # have ownership of the rewards and control the transactions
621
+ assert farmer_reward_puzzle_hash is None
622
+ assert pool_reward_puzzle_hash is None
623
+ assert transaction_data is None
624
+
625
+ for b in block_list:
626
+ for coin in b.get_included_reward_coins():
627
+ if coin.puzzle_hash == self.farmer_ph:
628
+ available_coins.append(coin)
629
+ print(
630
+ f"found {len(available_coins)} reward coins in existing chain."
631
+ "for simplicity, we assume the rewards are all unspent in the original chain"
632
+ )
633
+ wallet = self.get_farmer_wallet_tool()
634
+ rng = Random()
635
+ rng.seed(seed)
636
+
637
+ if farmer_reward_puzzle_hash is None:
638
+ farmer_reward_puzzle_hash = self.farmer_ph
639
+
640
+ if len(block_list) == 0:
641
+ if force_plot_id is not None:
642
+ raise ValueError("Cannot specify plot_id for genesis block")
643
+ initial_block_list_len = 0
644
+ genesis = self.create_genesis_block(
645
+ constants,
646
+ seed,
647
+ force_overflow=force_overflow,
648
+ skip_slots=skip_slots,
649
+ timestamp=(uint64(int(time.time())) if genesis_timestamp is None else genesis_timestamp),
650
+ )
651
+ self.log.info(f"Created block 0 iters: {genesis.total_iters}")
652
+ num_empty_slots_added = skip_slots
653
+ block_list = [genesis]
654
+ num_blocks -= 1
655
+ else:
656
+ initial_block_list_len = len(block_list)
657
+ num_empty_slots_added = uint32(0) # Allows forcing empty slots in the beginning, for testing purposes
658
+
659
+ if num_blocks == 0:
660
+ return block_list
661
+
662
+ blocks: dict[bytes32, BlockRecord]
663
+ if block_list[-1].header_hash == self._block_cache_header:
664
+ height_to_hash = self._block_cache_height_to_hash
665
+ difficulty = self._block_cache_difficulty
666
+ blocks = self._block_cache
667
+ else:
668
+ height_to_hash, difficulty, blocks = load_block_list(block_list, constants)
669
+
670
+ latest_block: BlockRecord = blocks[block_list[-1].header_hash]
671
+ curr = latest_block
672
+ while not curr.is_transaction_block:
673
+ curr = blocks[curr.prev_hash]
674
+ assert curr.timestamp is not None
675
+ last_timestamp = float(curr.timestamp)
676
+ start_height = curr.height
677
+
678
+ curr = latest_block
679
+ blocks_added_this_sub_slot = 1
680
+
681
+ while not curr.first_in_sub_slot:
682
+ curr = blocks[curr.prev_hash]
683
+ blocks_added_this_sub_slot += 1
684
+
685
+ finished_sub_slots_at_sp: list[EndOfSubSlotBundle] = [] # Sub-slots since last block, up to signage point
686
+ finished_sub_slots_at_ip: list[EndOfSubSlotBundle] = [] # Sub-slots since last block, up to infusion point
687
+ sub_slot_iters: uint64 = latest_block.sub_slot_iters # The number of iterations in one sub-slot
688
+ same_slot_as_last = True # Only applies to first slot, to prevent old blocks from being added
689
+ sub_slot_start_total_iters: uint128 = latest_block.ip_sub_slot_total_iters(constants)
690
+ sub_slots_finished = 0
691
+ # this variable is true whenever there is a pending sub-epoch or epoch that needs to be added in the next block.
692
+ pending_ses: bool = False
693
+
694
+ # Start at the last block in block list
695
+ # Get the challenge for that slot
696
+ while True:
697
+ slot_cc_challenge, slot_rc_challenge = get_challenges(
698
+ constants,
699
+ blocks,
700
+ finished_sub_slots_at_sp,
701
+ latest_block.header_hash,
702
+ )
703
+ prev_num_of_blocks = num_blocks
704
+ if num_empty_slots_added < skip_slots:
705
+ # If did not reach the target slots to skip, don't make any proofs for this sub-slot
706
+ num_empty_slots_added += 1
707
+ else:
708
+ # Loop over every signage point (Except for the last ones, which are used for overflows)
709
+ for signage_point_index in range(0, constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA):
710
+ curr = latest_block
711
+ while curr.total_iters > sub_slot_start_total_iters + calculate_sp_iters(
712
+ constants, sub_slot_iters, uint8(signage_point_index)
713
+ ):
714
+ if curr.height == 0:
715
+ break
716
+ curr = blocks[curr.prev_hash]
717
+ if curr.total_iters > sub_slot_start_total_iters:
718
+ finished_sub_slots_at_sp = []
719
+
720
+ if same_slot_as_last:
721
+ if signage_point_index < latest_block.signage_point_index:
722
+ # Ignore this signage_point because it's in the past
723
+ continue
724
+
725
+ if signage_point_index <= min_signage_point:
726
+ # start farming blocks after min_signage_point
727
+ continue
728
+
729
+ signage_point: SignagePoint = get_signage_point(
730
+ constants,
731
+ BlockCache(blocks),
732
+ latest_block,
733
+ sub_slot_start_total_iters,
734
+ uint8(signage_point_index),
735
+ finished_sub_slots_at_sp,
736
+ sub_slot_iters,
737
+ normalized_to_identity_cc_sp,
738
+ )
739
+ if signage_point_index == 0:
740
+ cc_sp_output_hash: bytes32 = slot_cc_challenge
741
+ else:
742
+ assert signage_point.cc_vdf is not None
743
+ cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
744
+
745
+ qualified_proofs: list[tuple[uint64, ProofOfSpace]] = self.get_pospaces_for_challenge(
746
+ constants,
747
+ slot_cc_challenge,
748
+ cc_sp_output_hash,
749
+ seed,
750
+ difficulty,
751
+ sub_slot_iters,
752
+ curr.height,
753
+ force_plot_id=force_plot_id,
754
+ )
755
+
756
+ for required_iters, proof_of_space in sorted(qualified_proofs, key=lambda t: t[0]):
757
+ if blocks_added_this_sub_slot == constants.MAX_SUB_SLOT_BLOCKS or force_overflow:
758
+ break
759
+ if same_slot_as_last:
760
+ if signage_point_index == latest_block.signage_point_index:
761
+ # Ignore this block because it's in the past
762
+ if required_iters <= latest_block.required_iters:
763
+ continue
764
+
765
+ assert latest_block.header_hash in blocks
766
+ additions = None
767
+ removals = None
768
+ if transaction_data_included:
769
+ transaction_data = None
770
+ block_refs = []
771
+ if transaction_data is not None:
772
+ additions = compute_additions_unchecked(transaction_data)
773
+ removals = transaction_data.removals()
774
+ elif include_transactions:
775
+ assert wallet is not None
776
+ assert rng is not None
777
+ transaction_data, additions = make_spend_bundle(available_coins, wallet, rng)
778
+ removals = transaction_data.removals()
779
+ transaction_data_included = False
780
+
781
+ assert last_timestamp is not None
782
+ if proof_of_space.pool_contract_puzzle_hash is not None:
783
+ if pool_reward_puzzle_hash is not None:
784
+ # The caller wants to be paid to a specific address, but this PoSpace is tied to an
785
+ # address, so continue until a proof of space tied to a pk is found
786
+ continue
787
+ pool_target = PoolTarget(proof_of_space.pool_contract_puzzle_hash, uint32(0))
788
+ else:
789
+ if pool_reward_puzzle_hash is not None:
790
+ pool_target = PoolTarget(pool_reward_puzzle_hash, uint32(0))
791
+ else:
792
+ pool_target = PoolTarget(self.pool_ph, uint32(0))
793
+
794
+ block_generator: Optional[BlockGenerator]
795
+ if transaction_data is not None:
796
+ if start_height >= constants.HARD_FORK_HEIGHT:
797
+ block_generator = simple_solution_generator_backrefs(transaction_data)
798
+ block_refs = []
799
+ else:
800
+ block_generator = simple_solution_generator(transaction_data)
801
+
802
+ aggregate_signature = transaction_data.aggregated_signature
803
+ else:
804
+ block_generator = None
805
+ aggregate_signature = G2Element()
806
+
807
+ if dummy_block_references:
808
+ if block_generator is None:
809
+ program = SerializedProgram.from_bytes(solution_generator([]))
810
+ block_generator = BlockGenerator(program, [])
811
+
812
+ if len(tx_block_heights) > 4:
813
+ block_refs.extend(
814
+ [
815
+ tx_block_heights[1],
816
+ tx_block_heights[len(tx_block_heights) // 2],
817
+ tx_block_heights[-2],
818
+ ]
819
+ )
820
+ (
821
+ full_block,
822
+ block_record,
823
+ new_timestamp,
824
+ ) = get_full_block_and_block_record(
825
+ constants,
826
+ blocks,
827
+ sub_slot_start_total_iters,
828
+ uint8(signage_point_index),
829
+ proof_of_space,
830
+ slot_cc_challenge,
831
+ slot_rc_challenge,
832
+ farmer_reward_puzzle_hash,
833
+ pool_target,
834
+ last_timestamp,
835
+ start_height,
836
+ time_per_block,
837
+ block_generator,
838
+ aggregate_signature,
839
+ additions,
840
+ removals,
841
+ height_to_hash,
842
+ difficulty,
843
+ required_iters,
844
+ sub_slot_iters,
845
+ self.get_plot_signature,
846
+ self.get_pool_key_signature,
847
+ finished_sub_slots_at_ip,
848
+ signage_point,
849
+ latest_block,
850
+ seed,
851
+ normalized_to_identity_cc_ip=normalized_to_identity_cc_ip,
852
+ current_time=current_time,
853
+ block_refs=block_refs,
854
+ )
855
+ if block_record.is_transaction_block:
856
+ transaction_data_included = True
857
+ block_refs = []
858
+ keep_going_until_tx_block = False
859
+ assert full_block.foliage_transaction_block is not None
860
+ elif guarantee_transaction_block:
861
+ continue
862
+ # print(f"{full_block.height:4}: difficulty {difficulty} "
863
+ # f"time: {new_timestamp - last_timestamp:0.2f} "
864
+ # f"additions: {len(additions) if block_record.is_transaction_block else 0:2} "
865
+ # f"removals: {len(removals) if block_record.is_transaction_block else 0:2} "
866
+ # f"refs: {len(full_block.transactions_generator_ref_list):3} "
867
+ # f"tx: {block_record.is_transaction_block}")
868
+ last_timestamp = new_timestamp
869
+ block_list.append(full_block)
870
+
871
+ if include_transactions:
872
+ for coin in full_block.get_included_reward_coins():
873
+ if coin.puzzle_hash == self.farmer_ph:
874
+ pending_rewards.append(coin)
875
+ if full_block.is_transaction_block():
876
+ available_coins.extend(pending_rewards)
877
+ pending_rewards = []
878
+
879
+ if full_block.transactions_generator is not None:
880
+ tx_block_heights.append(full_block.height)
881
+
882
+ blocks_added_this_sub_slot += 1
883
+
884
+ blocks[full_block.header_hash] = block_record
885
+ self.log.info(
886
+ f"Created block {block_record.height} ove=False, iters {block_record.total_iters}"
887
+ )
888
+ height_to_hash[uint32(full_block.height)] = full_block.header_hash
889
+ latest_block = blocks[full_block.header_hash]
890
+ finished_sub_slots_at_ip = []
891
+ num_blocks -= 1
892
+ if num_blocks <= 0 and not keep_going_until_tx_block:
893
+ self._block_cache_header = block_list[-1].header_hash
894
+ self._block_cache_height_to_hash = height_to_hash
895
+ self._block_cache_difficulty = difficulty
896
+ self._block_cache = blocks
897
+ return block_list
898
+
899
+ # Finish the end of sub-slot and try again next sub-slot
900
+ # End of sub-slot logic
901
+ if len(finished_sub_slots_at_ip) == 0:
902
+ # Block has been created within this sub-slot
903
+ eos_iters: uint64 = uint64(sub_slot_iters - (latest_block.total_iters - sub_slot_start_total_iters))
904
+ cc_input: ClassgroupElement = latest_block.challenge_vdf_output
905
+ rc_challenge: bytes32 = latest_block.reward_infusion_new_challenge
906
+ else:
907
+ # No blocks were successfully created within this sub-slot
908
+ eos_iters = sub_slot_iters
909
+ cc_input = ClassgroupElement.get_default_element()
910
+ rc_challenge = slot_rc_challenge
911
+ cc_vdf, cc_proof = get_vdf_info_and_proof(
912
+ constants,
913
+ cc_input,
914
+ slot_cc_challenge,
915
+ eos_iters,
916
+ )
917
+ rc_vdf, rc_proof = get_vdf_info_and_proof(
918
+ constants,
919
+ ClassgroupElement.get_default_element(),
920
+ rc_challenge,
921
+ eos_iters,
922
+ )
923
+
924
+ eos_deficit: uint8 = (
925
+ latest_block.deficit if latest_block.deficit > 0 else constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK
926
+ )
927
+ icc_eos_vdf, icc_ip_proof = get_icc(
928
+ constants,
929
+ uint128(sub_slot_start_total_iters + sub_slot_iters),
930
+ finished_sub_slots_at_ip,
931
+ latest_block,
932
+ blocks,
933
+ sub_slot_start_total_iters,
934
+ eos_deficit,
935
+ )
936
+ # End of slot vdf info for icc and cc have to be from challenge block or start of slot, respectively,
937
+ # in order for light clients to validate.
938
+ cc_vdf = VDFInfo(cc_vdf.challenge, sub_slot_iters, cc_vdf.output)
939
+ if normalized_to_identity_cc_eos:
940
+ _, cc_proof = get_vdf_info_and_proof(
941
+ constants,
942
+ ClassgroupElement.get_default_element(),
943
+ cc_vdf.challenge,
944
+ sub_slot_iters,
945
+ True,
946
+ )
947
+ # generate sub_epoch_summary, and if the last block was the last block of the sub-epoch or epoch
948
+ # include the hash in the next sub-slot
949
+ sub_epoch_summary: Optional[SubEpochSummary] = None
950
+ if not pending_ses: # if we just created a sub-epoch summary, we can at least skip another sub-slot
951
+ sub_epoch_summary = next_sub_epoch_summary(
952
+ constants,
953
+ BlockCache(blocks),
954
+ latest_block.required_iters,
955
+ block_list[-1],
956
+ False,
957
+ )
958
+ if sub_epoch_summary is not None: # the previous block is the last block of the sub-epoch or epoch
959
+ pending_ses = True
960
+ ses_hash: Optional[bytes32] = sub_epoch_summary.get_hash()
961
+ # if the last block is the last block of the epoch, we set the new sub-slot iters and difficulty
962
+ new_sub_slot_iters: Optional[uint64] = sub_epoch_summary.new_sub_slot_iters
963
+ new_difficulty: Optional[uint64] = sub_epoch_summary.new_difficulty
964
+
965
+ self.log.info(f"Sub epoch summary: {sub_epoch_summary} for block {latest_block.height + 1}")
966
+ else: # the previous block is not the last block of the sub-epoch or epoch
967
+ pending_ses = False
968
+ ses_hash = None
969
+ new_sub_slot_iters = None
970
+ new_difficulty = None
971
+
972
+ if icc_eos_vdf is not None:
973
+ # Icc vdf (Deficit of latest block is <= 4)
974
+ if len(finished_sub_slots_at_ip) == 0:
975
+ # This means there are blocks in this sub-slot
976
+ curr = latest_block
977
+ while not curr.is_challenge_block(constants) and not curr.first_in_sub_slot:
978
+ curr = blocks[curr.prev_hash]
979
+ if curr.is_challenge_block(constants):
980
+ icc_eos_iters = uint64(sub_slot_start_total_iters + sub_slot_iters - curr.total_iters)
981
+ else:
982
+ icc_eos_iters = sub_slot_iters
983
+ else:
984
+ # This means there are no blocks in this sub-slot
985
+ icc_eos_iters = sub_slot_iters
986
+ icc_eos_vdf = VDFInfo(
987
+ icc_eos_vdf.challenge,
988
+ icc_eos_iters,
989
+ icc_eos_vdf.output,
990
+ )
991
+ if normalized_to_identity_icc_eos:
992
+ _, icc_ip_proof = get_vdf_info_and_proof(
993
+ constants,
994
+ ClassgroupElement.get_default_element(),
995
+ icc_eos_vdf.challenge,
996
+ icc_eos_iters,
997
+ True,
998
+ )
999
+ icc_sub_slot: Optional[InfusedChallengeChainSubSlot] = InfusedChallengeChainSubSlot(icc_eos_vdf)
1000
+ assert icc_sub_slot is not None
1001
+ icc_sub_slot_hash = icc_sub_slot.get_hash() if latest_block.deficit == 0 else None
1002
+ cc_sub_slot = ChallengeChainSubSlot(
1003
+ cc_vdf,
1004
+ icc_sub_slot_hash,
1005
+ ses_hash,
1006
+ new_sub_slot_iters,
1007
+ new_difficulty,
1008
+ )
1009
+ else:
1010
+ # No icc
1011
+ icc_sub_slot = None
1012
+ cc_sub_slot = ChallengeChainSubSlot(cc_vdf, None, ses_hash, new_sub_slot_iters, new_difficulty)
1013
+
1014
+ finished_sub_slots_at_ip.append(
1015
+ EndOfSubSlotBundle(
1016
+ cc_sub_slot,
1017
+ icc_sub_slot,
1018
+ RewardChainSubSlot(
1019
+ rc_vdf,
1020
+ cc_sub_slot.get_hash(),
1021
+ icc_sub_slot.get_hash() if icc_sub_slot is not None else None,
1022
+ eos_deficit,
1023
+ ),
1024
+ SubSlotProofs(cc_proof, icc_ip_proof, rc_proof),
1025
+ )
1026
+ )
1027
+
1028
+ finished_sub_slots_eos = finished_sub_slots_at_ip.copy()
1029
+ latest_block_eos = latest_block
1030
+ overflow_cc_challenge = finished_sub_slots_at_ip[-1].challenge_chain.get_hash()
1031
+ overflow_rc_challenge = finished_sub_slots_at_ip[-1].reward_chain.get_hash()
1032
+ additions = None
1033
+ removals = None
1034
+ if transaction_data_included:
1035
+ transaction_data = None
1036
+ if transaction_data is not None:
1037
+ additions = compute_additions_unchecked(transaction_data)
1038
+ removals = transaction_data.removals()
1039
+ elif include_transactions:
1040
+ assert wallet is not None
1041
+ assert rng is not None
1042
+ transaction_data, additions = make_spend_bundle(available_coins, wallet, rng)
1043
+ removals = transaction_data.removals()
1044
+ transaction_data_included = False
1045
+ sub_slots_finished += 1
1046
+ self.log.info(
1047
+ f"Sub slot finished. blocks included: {blocks_added_this_sub_slot} blocks_per_slot: "
1048
+ f"{(len(block_list) - initial_block_list_len) / sub_slots_finished}"
1049
+ f"Sub Epoch Summary Included: {sub_epoch_summary is not None} "
1050
+ )
1051
+ blocks_added_this_sub_slot = 0 # Sub slot ended, overflows are in next sub slot
1052
+
1053
+ # Handle overflows: No overflows on new epoch or sub-epoch
1054
+
1055
+ if (
1056
+ new_sub_slot_iters is None
1057
+ and num_empty_slots_added >= skip_slots
1058
+ and not pending_ses
1059
+ and not skip_overflow
1060
+ ):
1061
+ for signage_point_index in range(
1062
+ constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA,
1063
+ constants.NUM_SPS_SUB_SLOT,
1064
+ ):
1065
+ if same_slot_as_last and signage_point_index <= min_signage_point:
1066
+ # start farming blocks after min_signage_point
1067
+ continue
1068
+ # note that we are passing in the finished slots which include the last slot
1069
+ signage_point = get_signage_point(
1070
+ constants,
1071
+ BlockCache(blocks),
1072
+ latest_block_eos,
1073
+ sub_slot_start_total_iters,
1074
+ uint8(signage_point_index),
1075
+ finished_sub_slots_eos,
1076
+ sub_slot_iters,
1077
+ normalized_to_identity_cc_sp,
1078
+ )
1079
+ if signage_point_index == 0:
1080
+ cc_sp_output_hash = slot_cc_challenge
1081
+ else:
1082
+ assert signage_point is not None
1083
+ assert signage_point.cc_vdf is not None
1084
+ cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
1085
+
1086
+ # If did not reach the target slots to skip, don't make any proofs for this sub-slot
1087
+ qualified_proofs = self.get_pospaces_for_challenge(
1088
+ constants,
1089
+ slot_cc_challenge,
1090
+ cc_sp_output_hash,
1091
+ seed,
1092
+ difficulty,
1093
+ sub_slot_iters,
1094
+ curr.height,
1095
+ force_plot_id=force_plot_id,
1096
+ )
1097
+ for required_iters, proof_of_space in sorted(qualified_proofs, key=lambda t: t[0]):
1098
+ if blocks_added_this_sub_slot == constants.MAX_SUB_SLOT_BLOCKS:
1099
+ break
1100
+ assert last_timestamp is not None
1101
+ if proof_of_space.pool_contract_puzzle_hash is not None:
1102
+ if pool_reward_puzzle_hash is not None:
1103
+ # The caller wants to be paid to a specific address, but this PoSpace is tied to an
1104
+ # address, so continue until a proof of space tied to a pk is found
1105
+ continue
1106
+ pool_target = PoolTarget(proof_of_space.pool_contract_puzzle_hash, uint32(0))
1107
+ else:
1108
+ if pool_reward_puzzle_hash is not None:
1109
+ pool_target = PoolTarget(pool_reward_puzzle_hash, uint32(0))
1110
+ else:
1111
+ pool_target = PoolTarget(self.pool_ph, uint32(0))
1112
+ if transaction_data is not None:
1113
+ if start_height >= constants.HARD_FORK_HEIGHT:
1114
+ block_generator = simple_solution_generator_backrefs(transaction_data)
1115
+ block_refs = []
1116
+ else:
1117
+ block_generator = simple_solution_generator(transaction_data)
1118
+ aggregate_signature = transaction_data.aggregated_signature
1119
+ else:
1120
+ block_generator = None
1121
+ aggregate_signature = G2Element()
1122
+
1123
+ if dummy_block_references:
1124
+ if block_generator is None:
1125
+ program = SerializedProgram.from_bytes(solution_generator([]))
1126
+ block_generator = BlockGenerator(program, [])
1127
+
1128
+ if len(tx_block_heights) > 4:
1129
+ block_refs.extend(
1130
+ [
1131
+ tx_block_heights[1],
1132
+ tx_block_heights[len(tx_block_heights) // 2],
1133
+ tx_block_heights[-2],
1134
+ ]
1135
+ )
1136
+
1137
+ (
1138
+ full_block,
1139
+ block_record,
1140
+ new_timestamp,
1141
+ ) = get_full_block_and_block_record(
1142
+ constants,
1143
+ blocks,
1144
+ sub_slot_start_total_iters,
1145
+ uint8(signage_point_index),
1146
+ proof_of_space,
1147
+ slot_cc_challenge,
1148
+ slot_rc_challenge,
1149
+ farmer_reward_puzzle_hash,
1150
+ pool_target,
1151
+ last_timestamp,
1152
+ start_height,
1153
+ time_per_block,
1154
+ block_generator,
1155
+ aggregate_signature,
1156
+ additions,
1157
+ removals,
1158
+ height_to_hash,
1159
+ difficulty,
1160
+ required_iters,
1161
+ sub_slot_iters,
1162
+ self.get_plot_signature,
1163
+ self.get_pool_key_signature,
1164
+ finished_sub_slots_at_ip,
1165
+ signage_point,
1166
+ latest_block,
1167
+ seed,
1168
+ overflow_cc_challenge=overflow_cc_challenge,
1169
+ overflow_rc_challenge=overflow_rc_challenge,
1170
+ normalized_to_identity_cc_ip=normalized_to_identity_cc_ip,
1171
+ current_time=current_time,
1172
+ block_refs=block_refs,
1173
+ )
1174
+
1175
+ if block_record.is_transaction_block:
1176
+ transaction_data_included = True
1177
+ block_refs = []
1178
+ keep_going_until_tx_block = False
1179
+ assert full_block.foliage_transaction_block is not None
1180
+ elif guarantee_transaction_block:
1181
+ continue
1182
+ # print(f"{full_block.height:4}: difficulty {difficulty} "
1183
+ # f"time: {new_timestamp - last_timestamp:0.2f} "
1184
+ # f"additions: {len(additions) if block_record.is_transaction_block else 0:2} "
1185
+ # f"removals: {len(removals) if block_record.is_transaction_block else 0:2} "
1186
+ # f"refs: {len(full_block.transactions_generator_ref_list):3} "
1187
+ # f"tx: {block_record.is_transaction_block}")
1188
+ last_timestamp = new_timestamp
1189
+
1190
+ block_list.append(full_block)
1191
+
1192
+ if include_transactions:
1193
+ for coin in full_block.get_included_reward_coins():
1194
+ if coin.puzzle_hash == self.farmer_ph:
1195
+ pending_rewards.append(coin)
1196
+ if full_block.is_transaction_block():
1197
+ available_coins.extend(pending_rewards)
1198
+ pending_rewards = []
1199
+
1200
+ if full_block.transactions_generator is not None:
1201
+ tx_block_heights.append(full_block.height)
1202
+
1203
+ blocks_added_this_sub_slot += 1
1204
+ self.log.info(f"Created block {block_record.height} ov=True, iters {block_record.total_iters}")
1205
+ num_blocks -= 1
1206
+
1207
+ blocks[full_block.header_hash] = block_record
1208
+ height_to_hash[uint32(full_block.height)] = full_block.header_hash
1209
+ latest_block = blocks[full_block.header_hash]
1210
+ finished_sub_slots_at_ip = []
1211
+
1212
+ if num_blocks <= 0 and not keep_going_until_tx_block:
1213
+ self._block_cache_header = block_list[-1].header_hash
1214
+ self._block_cache_height_to_hash = height_to_hash
1215
+ self._block_cache_difficulty = difficulty
1216
+ self._block_cache = blocks
1217
+ return block_list
1218
+
1219
+ finished_sub_slots_at_sp = finished_sub_slots_eos.copy()
1220
+ same_slot_as_last = False
1221
+ sub_slot_start_total_iters = uint128(sub_slot_start_total_iters + sub_slot_iters)
1222
+ if num_blocks < prev_num_of_blocks:
1223
+ num_empty_slots_added += 1
1224
+
1225
+ if new_sub_slot_iters is not None and new_difficulty is not None: # new epoch
1226
+ sub_slot_iters = new_sub_slot_iters
1227
+ difficulty = new_difficulty
1228
+
1229
+ def create_genesis_block(
1230
+ self,
1231
+ constants: ConsensusConstants,
1232
+ seed: bytes = b"",
1233
+ timestamp: Optional[uint64] = None,
1234
+ force_overflow: bool = False,
1235
+ skip_slots: int = 0,
1236
+ ) -> FullBlock:
1237
+ if timestamp is None:
1238
+ timestamp = uint64(int(time.time()))
1239
+
1240
+ finished_sub_slots: list[EndOfSubSlotBundle] = []
1241
+ unfinished_block: Optional[UnfinishedBlock] = None
1242
+ ip_iters: uint64 = uint64(0)
1243
+ sub_slot_total_iters: uint128 = uint128(0)
1244
+
1245
+ # Keep trying until we get a good proof of space that also passes sp filter
1246
+ while True:
1247
+ cc_challenge, rc_challenge = get_challenges(constants, {}, finished_sub_slots, None)
1248
+ for signage_point_index in range(0, constants.NUM_SPS_SUB_SLOT):
1249
+ signage_point: SignagePoint = get_signage_point(
1250
+ constants,
1251
+ BlockCache({}),
1252
+ None,
1253
+ sub_slot_total_iters,
1254
+ uint8(signage_point_index),
1255
+ finished_sub_slots,
1256
+ constants.SUB_SLOT_ITERS_STARTING,
1257
+ )
1258
+ if signage_point_index == 0:
1259
+ cc_sp_output_hash: bytes32 = cc_challenge
1260
+ else:
1261
+ assert signage_point is not None
1262
+ assert signage_point.cc_vdf is not None
1263
+ cc_sp_output_hash = signage_point.cc_vdf.output.get_hash()
1264
+ # If did not reach the target slots to skip, don't make any proofs for this sub-slot
1265
+ # we're creating the genesis block, its height is always 0
1266
+ qualified_proofs: list[tuple[uint64, ProofOfSpace]] = self.get_pospaces_for_challenge(
1267
+ constants,
1268
+ cc_challenge,
1269
+ cc_sp_output_hash,
1270
+ seed,
1271
+ constants.DIFFICULTY_STARTING,
1272
+ constants.SUB_SLOT_ITERS_STARTING,
1273
+ uint32(0),
1274
+ )
1275
+
1276
+ # Try each of the proofs of space
1277
+ for required_iters, proof_of_space in qualified_proofs:
1278
+ sp_iters: uint64 = calculate_sp_iters(
1279
+ constants,
1280
+ uint64(constants.SUB_SLOT_ITERS_STARTING),
1281
+ uint8(signage_point_index),
1282
+ )
1283
+ ip_iters = calculate_ip_iters(
1284
+ constants,
1285
+ uint64(constants.SUB_SLOT_ITERS_STARTING),
1286
+ uint8(signage_point_index),
1287
+ required_iters,
1288
+ )
1289
+ is_overflow = is_overflow_block(constants, uint8(signage_point_index))
1290
+ if force_overflow and not is_overflow:
1291
+ continue
1292
+ if len(finished_sub_slots) < skip_slots:
1293
+ continue
1294
+
1295
+ unfinished_block = create_unfinished_block(
1296
+ constants,
1297
+ sub_slot_total_iters,
1298
+ constants.SUB_SLOT_ITERS_STARTING,
1299
+ uint8(signage_point_index),
1300
+ sp_iters,
1301
+ ip_iters,
1302
+ proof_of_space,
1303
+ cc_challenge,
1304
+ constants.GENESIS_PRE_FARM_FARMER_PUZZLE_HASH,
1305
+ PoolTarget(constants.GENESIS_PRE_FARM_POOL_PUZZLE_HASH, uint32(0)),
1306
+ self.get_plot_signature,
1307
+ self.get_pool_key_signature,
1308
+ signage_point,
1309
+ timestamp,
1310
+ BlockCache({}),
1311
+ seed=seed,
1312
+ finished_sub_slots_input=finished_sub_slots,
1313
+ compute_cost=compute_cost_test,
1314
+ compute_fees=compute_fee_test,
1315
+ )
1316
+ assert unfinished_block is not None
1317
+ if not is_overflow:
1318
+ cc_ip_vdf, cc_ip_proof = get_vdf_info_and_proof(
1319
+ constants,
1320
+ ClassgroupElement.get_default_element(),
1321
+ cc_challenge,
1322
+ ip_iters,
1323
+ )
1324
+ cc_ip_vdf = cc_ip_vdf.replace(number_of_iterations=ip_iters)
1325
+ rc_ip_vdf, rc_ip_proof = get_vdf_info_and_proof(
1326
+ constants,
1327
+ ClassgroupElement.get_default_element(),
1328
+ rc_challenge,
1329
+ ip_iters,
1330
+ )
1331
+ assert unfinished_block is not None
1332
+ total_iters_sp = uint128(sub_slot_total_iters + sp_iters)
1333
+ return unfinished_block_to_full_block(
1334
+ unfinished_block,
1335
+ cc_ip_vdf,
1336
+ cc_ip_proof,
1337
+ rc_ip_vdf,
1338
+ rc_ip_proof,
1339
+ None,
1340
+ None,
1341
+ finished_sub_slots,
1342
+ None,
1343
+ BlockCache({}),
1344
+ total_iters_sp,
1345
+ constants.DIFFICULTY_STARTING,
1346
+ )
1347
+
1348
+ if signage_point_index == constants.NUM_SPS_SUB_SLOT - constants.NUM_SP_INTERVALS_EXTRA - 1:
1349
+ # Finish the end of sub-slot and try again next sub-slot
1350
+ cc_vdf, cc_proof = get_vdf_info_and_proof(
1351
+ constants,
1352
+ ClassgroupElement.get_default_element(),
1353
+ cc_challenge,
1354
+ constants.SUB_SLOT_ITERS_STARTING,
1355
+ )
1356
+ rc_vdf, rc_proof = get_vdf_info_and_proof(
1357
+ constants,
1358
+ ClassgroupElement.get_default_element(),
1359
+ rc_challenge,
1360
+ constants.SUB_SLOT_ITERS_STARTING,
1361
+ )
1362
+ cc_slot = ChallengeChainSubSlot(cc_vdf, None, None, None, None)
1363
+ finished_sub_slots.append(
1364
+ EndOfSubSlotBundle(
1365
+ cc_slot,
1366
+ None,
1367
+ RewardChainSubSlot(
1368
+ rc_vdf,
1369
+ cc_slot.get_hash(),
1370
+ None,
1371
+ uint8(constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK),
1372
+ ),
1373
+ SubSlotProofs(cc_proof, None, rc_proof),
1374
+ )
1375
+ )
1376
+
1377
+ if unfinished_block is not None:
1378
+ cc_ip_vdf, cc_ip_proof = get_vdf_info_and_proof(
1379
+ constants,
1380
+ ClassgroupElement.get_default_element(),
1381
+ finished_sub_slots[-1].challenge_chain.get_hash(),
1382
+ ip_iters,
1383
+ )
1384
+ rc_ip_vdf, rc_ip_proof = get_vdf_info_and_proof(
1385
+ constants,
1386
+ ClassgroupElement.get_default_element(),
1387
+ finished_sub_slots[-1].reward_chain.get_hash(),
1388
+ ip_iters,
1389
+ )
1390
+ total_iters_sp = uint128(
1391
+ sub_slot_total_iters
1392
+ + calculate_sp_iters(
1393
+ self.constants,
1394
+ self.constants.SUB_SLOT_ITERS_STARTING,
1395
+ unfinished_block.reward_chain_block.signage_point_index,
1396
+ )
1397
+ )
1398
+ return unfinished_block_to_full_block(
1399
+ unfinished_block,
1400
+ cc_ip_vdf,
1401
+ cc_ip_proof,
1402
+ rc_ip_vdf,
1403
+ rc_ip_proof,
1404
+ None,
1405
+ None,
1406
+ finished_sub_slots,
1407
+ None,
1408
+ BlockCache({}),
1409
+ total_iters_sp,
1410
+ constants.DIFFICULTY_STARTING,
1411
+ )
1412
+ sub_slot_total_iters = uint128(sub_slot_total_iters + constants.SUB_SLOT_ITERS_STARTING)
1413
+
1414
+ def get_pospaces_for_challenge(
1415
+ self,
1416
+ constants: ConsensusConstants,
1417
+ challenge_hash: bytes32,
1418
+ signage_point: bytes32,
1419
+ seed: bytes,
1420
+ difficulty: uint64,
1421
+ sub_slot_iters: uint64,
1422
+ height: uint32,
1423
+ force_plot_id: Optional[bytes32] = None,
1424
+ ) -> list[tuple[uint64, ProofOfSpace]]:
1425
+ found_proofs: list[tuple[uint64, ProofOfSpace]] = []
1426
+ rng = random.Random()
1427
+ rng.seed(seed)
1428
+ for plot_info in self.plot_manager.plots.values():
1429
+ plot_id: bytes32 = plot_info.prover.get_id()
1430
+ if force_plot_id is not None and plot_id != force_plot_id:
1431
+ continue
1432
+ prefix_bits = calculate_prefix_bits(constants, height)
1433
+ if passes_plot_filter(prefix_bits, plot_id, challenge_hash, signage_point):
1434
+ new_challenge: bytes32 = calculate_pos_challenge(plot_id, challenge_hash, signage_point)
1435
+ qualities = plot_info.prover.get_qualities_for_challenge(new_challenge)
1436
+
1437
+ for proof_index, quality_str in enumerate(qualities):
1438
+ required_iters = calculate_iterations_quality(
1439
+ constants.DIFFICULTY_CONSTANT_FACTOR,
1440
+ quality_str,
1441
+ plot_info.prover.get_size(),
1442
+ difficulty,
1443
+ signage_point,
1444
+ )
1445
+ if required_iters < calculate_sp_interval_iters(constants, sub_slot_iters):
1446
+ proof_xs: bytes = plot_info.prover.get_full_proof(new_challenge, proof_index)
1447
+
1448
+ # Look up local_sk from plot to save locked memory
1449
+ (
1450
+ pool_public_key_or_puzzle_hash,
1451
+ farmer_public_key,
1452
+ local_master_sk,
1453
+ ) = parse_plot_info(plot_info.prover.get_memo())
1454
+ local_sk = master_sk_to_local_sk(local_master_sk)
1455
+
1456
+ if isinstance(pool_public_key_or_puzzle_hash, G1Element):
1457
+ include_taproot = False
1458
+ else:
1459
+ assert isinstance(pool_public_key_or_puzzle_hash, bytes32)
1460
+ include_taproot = True
1461
+ plot_pk = generate_plot_public_key(local_sk.get_g1(), farmer_public_key, include_taproot)
1462
+ proof_of_space: ProofOfSpace = ProofOfSpace(
1463
+ new_challenge,
1464
+ plot_info.pool_public_key,
1465
+ plot_info.pool_contract_puzzle_hash,
1466
+ plot_pk,
1467
+ plot_info.prover.get_size(),
1468
+ proof_xs,
1469
+ )
1470
+ found_proofs.append((required_iters, proof_of_space))
1471
+ random_sample = found_proofs
1472
+ if len(found_proofs) >= 1:
1473
+ if rng.random() < 0.1:
1474
+ # Removes some proofs of space to create "random" chains, based on the seed
1475
+ random_sample = rng.sample(found_proofs, len(found_proofs) - 1)
1476
+ return random_sample
1477
+
1478
+
1479
+ def get_signage_point(
1480
+ constants: ConsensusConstants,
1481
+ blocks: BlockRecordsProtocol,
1482
+ latest_block: Optional[BlockRecord],
1483
+ sub_slot_start_total_iters: uint128,
1484
+ signage_point_index: uint8,
1485
+ finished_sub_slots: list[EndOfSubSlotBundle],
1486
+ sub_slot_iters: uint64,
1487
+ normalized_to_identity_cc_sp: bool = False,
1488
+ ) -> SignagePoint:
1489
+ if signage_point_index == 0:
1490
+ return SignagePoint(None, None, None, None)
1491
+ sp_iters = calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
1492
+ overflow = is_overflow_block(constants, signage_point_index)
1493
+ sp_total_iters = uint128(
1494
+ sub_slot_start_total_iters + calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
1495
+ )
1496
+
1497
+ (
1498
+ cc_vdf_challenge,
1499
+ rc_vdf_challenge,
1500
+ cc_vdf_input,
1501
+ rc_vdf_input,
1502
+ cc_vdf_iters,
1503
+ rc_vdf_iters,
1504
+ ) = get_signage_point_vdf_info(
1505
+ constants,
1506
+ finished_sub_slots,
1507
+ overflow,
1508
+ latest_block,
1509
+ blocks,
1510
+ sp_total_iters,
1511
+ sp_iters,
1512
+ )
1513
+
1514
+ cc_sp_vdf, cc_sp_proof = get_vdf_info_and_proof(
1515
+ constants,
1516
+ cc_vdf_input,
1517
+ cc_vdf_challenge,
1518
+ cc_vdf_iters,
1519
+ )
1520
+ rc_sp_vdf, rc_sp_proof = get_vdf_info_and_proof(
1521
+ constants,
1522
+ rc_vdf_input,
1523
+ rc_vdf_challenge,
1524
+ rc_vdf_iters,
1525
+ )
1526
+ cc_sp_vdf = cc_sp_vdf.replace(number_of_iterations=sp_iters)
1527
+ if normalized_to_identity_cc_sp:
1528
+ _, cc_sp_proof = get_vdf_info_and_proof(
1529
+ constants,
1530
+ ClassgroupElement.get_default_element(),
1531
+ cc_sp_vdf.challenge,
1532
+ sp_iters,
1533
+ True,
1534
+ )
1535
+ return SignagePoint(cc_sp_vdf, cc_sp_proof, rc_sp_vdf, rc_sp_proof)
1536
+
1537
+
1538
+ def finish_block(
1539
+ constants: ConsensusConstants,
1540
+ blocks: dict[bytes32, BlockRecord],
1541
+ height_to_hash: dict[uint32, bytes32],
1542
+ finished_sub_slots: list[EndOfSubSlotBundle],
1543
+ sub_slot_start_total_iters: uint128,
1544
+ signage_point_index: uint8,
1545
+ unfinished_block: UnfinishedBlock,
1546
+ required_iters: uint64,
1547
+ ip_iters: uint64,
1548
+ slot_cc_challenge: bytes32,
1549
+ slot_rc_challenge: bytes32,
1550
+ latest_block: BlockRecord,
1551
+ sub_slot_iters: uint64,
1552
+ difficulty: uint64,
1553
+ normalized_to_identity_cc_ip: bool = False,
1554
+ ) -> tuple[FullBlock, BlockRecord]:
1555
+ is_overflow = is_overflow_block(constants, signage_point_index)
1556
+ cc_vdf_challenge = slot_cc_challenge
1557
+ if len(finished_sub_slots) == 0:
1558
+ new_ip_iters = uint64(unfinished_block.total_iters - latest_block.total_iters)
1559
+ cc_vdf_input = latest_block.challenge_vdf_output
1560
+ rc_vdf_challenge = latest_block.reward_infusion_new_challenge
1561
+ else:
1562
+ new_ip_iters = ip_iters
1563
+ cc_vdf_input = ClassgroupElement.get_default_element()
1564
+ rc_vdf_challenge = slot_rc_challenge
1565
+ cc_ip_vdf, cc_ip_proof = get_vdf_info_and_proof(
1566
+ constants,
1567
+ cc_vdf_input,
1568
+ cc_vdf_challenge,
1569
+ new_ip_iters,
1570
+ )
1571
+ cc_ip_vdf = cc_ip_vdf.replace(number_of_iterations=ip_iters)
1572
+ if normalized_to_identity_cc_ip:
1573
+ _, cc_ip_proof = get_vdf_info_and_proof(
1574
+ constants,
1575
+ ClassgroupElement.get_default_element(),
1576
+ cc_ip_vdf.challenge,
1577
+ ip_iters,
1578
+ True,
1579
+ )
1580
+ deficit = calculate_deficit(
1581
+ constants,
1582
+ uint32(latest_block.height + 1),
1583
+ latest_block,
1584
+ is_overflow,
1585
+ len(finished_sub_slots),
1586
+ )
1587
+
1588
+ icc_ip_vdf, icc_ip_proof = get_icc(
1589
+ constants,
1590
+ unfinished_block.total_iters,
1591
+ finished_sub_slots,
1592
+ latest_block,
1593
+ blocks,
1594
+ uint128(sub_slot_start_total_iters + sub_slot_iters) if is_overflow else sub_slot_start_total_iters,
1595
+ deficit,
1596
+ )
1597
+
1598
+ rc_ip_vdf, rc_ip_proof = get_vdf_info_and_proof(
1599
+ constants,
1600
+ ClassgroupElement.get_default_element(),
1601
+ rc_vdf_challenge,
1602
+ new_ip_iters,
1603
+ )
1604
+ assert unfinished_block is not None
1605
+ sp_total_iters = uint128(
1606
+ sub_slot_start_total_iters + calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
1607
+ )
1608
+ full_block: FullBlock = unfinished_block_to_full_block(
1609
+ unfinished_block,
1610
+ cc_ip_vdf,
1611
+ cc_ip_proof,
1612
+ rc_ip_vdf,
1613
+ rc_ip_proof,
1614
+ icc_ip_vdf,
1615
+ icc_ip_proof,
1616
+ finished_sub_slots,
1617
+ latest_block,
1618
+ BlockCache(blocks),
1619
+ sp_total_iters,
1620
+ difficulty,
1621
+ )
1622
+
1623
+ block_record = block_to_block_record(
1624
+ constants, BlockCache(blocks), required_iters, full_block, sub_slot_iters=sub_slot_iters
1625
+ )
1626
+ return full_block, block_record
1627
+
1628
+
1629
+ def get_challenges(
1630
+ constants: ConsensusConstants,
1631
+ blocks: dict[bytes32, BlockRecord],
1632
+ finished_sub_slots: list[EndOfSubSlotBundle],
1633
+ prev_header_hash: Optional[bytes32],
1634
+ ) -> tuple[bytes32, bytes32]:
1635
+ if len(finished_sub_slots) == 0:
1636
+ if prev_header_hash is None:
1637
+ return constants.GENESIS_CHALLENGE, constants.GENESIS_CHALLENGE
1638
+ curr: BlockRecord = blocks[prev_header_hash]
1639
+ while not curr.first_in_sub_slot:
1640
+ curr = blocks[curr.prev_hash]
1641
+ assert curr.finished_challenge_slot_hashes is not None
1642
+ assert curr.finished_reward_slot_hashes is not None
1643
+ cc_challenge = curr.finished_challenge_slot_hashes[-1]
1644
+ rc_challenge = curr.finished_reward_slot_hashes[-1]
1645
+ else:
1646
+ cc_challenge = finished_sub_slots[-1].challenge_chain.get_hash()
1647
+ rc_challenge = finished_sub_slots[-1].reward_chain.get_hash()
1648
+ return cc_challenge, rc_challenge
1649
+
1650
+
1651
+ def get_plot_dir(plot_dir_name: str = "test-plots", automated_testing: bool = True) -> Path:
1652
+ root_dir = DEFAULT_ROOT_PATH.parent
1653
+ if not automated_testing: # make sure we don't accidentally stack directories.
1654
+ root_dir = (
1655
+ root_dir.parent
1656
+ if root_dir.parts[-1] == plot_dir_name.split("/")[0] or root_dir.parts[-1] == plot_dir_name.split("\\")[0]
1657
+ else root_dir
1658
+ )
1659
+ cache_path = root_dir.joinpath(plot_dir_name)
1660
+
1661
+ ci = os.environ.get("CI")
1662
+ if ci is not None and not cache_path.exists() and automated_testing:
1663
+ raise Exception(f"Running in CI and expected path not found: {cache_path!r}")
1664
+
1665
+ cache_path.mkdir(parents=True, exist_ok=True)
1666
+ return cache_path
1667
+
1668
+
1669
+ def get_plot_tmp_dir(plot_dir_name: str = "test-plots", automated_testing: bool = True) -> Path:
1670
+ return get_plot_dir(plot_dir_name, automated_testing) / "tmp"
1671
+
1672
+
1673
+ def load_block_list(
1674
+ block_list: list[FullBlock], constants: ConsensusConstants
1675
+ ) -> tuple[dict[uint32, bytes32], uint64, dict[bytes32, BlockRecord]]:
1676
+ difficulty = uint64(constants.DIFFICULTY_STARTING)
1677
+ sub_slot_iters = uint64(constants.SUB_SLOT_ITERS_STARTING)
1678
+ height_to_hash: dict[uint32, bytes32] = {}
1679
+ blocks: dict[bytes32, BlockRecord] = {}
1680
+ for full_block in block_list:
1681
+ if full_block.height != 0:
1682
+ if len(full_block.finished_sub_slots) > 0:
1683
+ if full_block.finished_sub_slots[0].challenge_chain.new_difficulty is not None:
1684
+ difficulty = full_block.finished_sub_slots[0].challenge_chain.new_difficulty
1685
+ if full_block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters is not None:
1686
+ sub_slot_iters = full_block.finished_sub_slots[0].challenge_chain.new_sub_slot_iters
1687
+ if full_block.reward_chain_block.signage_point_index == 0:
1688
+ challenge = full_block.reward_chain_block.pos_ss_cc_challenge_hash
1689
+ sp_hash = challenge
1690
+ else:
1691
+ assert full_block.reward_chain_block.challenge_chain_sp_vdf is not None
1692
+ challenge = full_block.reward_chain_block.challenge_chain_sp_vdf.challenge
1693
+ sp_hash = full_block.reward_chain_block.challenge_chain_sp_vdf.output.get_hash()
1694
+ quality_str = verify_and_get_quality_string(
1695
+ full_block.reward_chain_block.proof_of_space, constants, challenge, sp_hash, height=full_block.height
1696
+ )
1697
+ assert quality_str is not None
1698
+ required_iters: uint64 = calculate_iterations_quality(
1699
+ constants.DIFFICULTY_CONSTANT_FACTOR,
1700
+ quality_str,
1701
+ full_block.reward_chain_block.proof_of_space.size,
1702
+ uint64(difficulty),
1703
+ sp_hash,
1704
+ )
1705
+
1706
+ blocks[full_block.header_hash] = block_to_block_record(
1707
+ constants,
1708
+ BlockCache(blocks),
1709
+ required_iters,
1710
+ full_block,
1711
+ sub_slot_iters,
1712
+ )
1713
+ height_to_hash[uint32(full_block.height)] = full_block.header_hash
1714
+ return height_to_hash, uint64(difficulty), blocks
1715
+
1716
+
1717
+ def get_icc(
1718
+ constants: ConsensusConstants,
1719
+ vdf_end_total_iters: uint128,
1720
+ finished_sub_slots: list[EndOfSubSlotBundle],
1721
+ latest_block: BlockRecord,
1722
+ blocks: dict[bytes32, BlockRecord],
1723
+ sub_slot_start_total_iters: uint128,
1724
+ deficit: uint8,
1725
+ ) -> tuple[Optional[VDFInfo], Optional[VDFProof]]:
1726
+ if len(finished_sub_slots) == 0:
1727
+ prev_deficit = latest_block.deficit
1728
+ else:
1729
+ prev_deficit = finished_sub_slots[-1].reward_chain.deficit
1730
+
1731
+ if deficit == prev_deficit == constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
1732
+ # new slot / overflow sb to new slot / overflow sb
1733
+ return None, None
1734
+
1735
+ if deficit == (prev_deficit - 1) == (constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1):
1736
+ # new slot / overflow sb to challenge sb
1737
+ return None, None
1738
+
1739
+ if len(finished_sub_slots) != 0:
1740
+ last_ss = finished_sub_slots[-1]
1741
+ assert last_ss.infused_challenge_chain is not None
1742
+ assert finished_sub_slots[-1].reward_chain.deficit <= (constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1)
1743
+ return get_vdf_info_and_proof(
1744
+ constants,
1745
+ ClassgroupElement.get_default_element(),
1746
+ last_ss.infused_challenge_chain.get_hash(),
1747
+ uint64(vdf_end_total_iters - sub_slot_start_total_iters),
1748
+ )
1749
+
1750
+ curr = latest_block # curr deficit is 0, 1, 2, 3, or 4
1751
+ while not curr.is_challenge_block(constants) and not curr.first_in_sub_slot:
1752
+ curr = blocks[curr.prev_hash]
1753
+ icc_iters = uint64(vdf_end_total_iters - latest_block.total_iters)
1754
+ if latest_block.is_challenge_block(constants):
1755
+ icc_input: Optional[ClassgroupElement] = ClassgroupElement.get_default_element()
1756
+ else:
1757
+ icc_input = latest_block.infused_challenge_vdf_output
1758
+ assert icc_input is not None
1759
+
1760
+ if curr.is_challenge_block(constants): # Deficit 4
1761
+ icc_challenge_hash = curr.challenge_block_info_hash
1762
+ else:
1763
+ assert curr.finished_infused_challenge_slot_hashes is not None
1764
+ # First block in sub slot has deficit 0,1,2 or 3
1765
+ icc_challenge_hash = curr.finished_infused_challenge_slot_hashes[-1]
1766
+ return get_vdf_info_and_proof(
1767
+ constants,
1768
+ icc_input,
1769
+ icc_challenge_hash,
1770
+ icc_iters,
1771
+ )
1772
+
1773
+
1774
+ def get_full_block_and_block_record(
1775
+ constants: ConsensusConstants,
1776
+ blocks: dict[bytes32, BlockRecord],
1777
+ sub_slot_start_total_iters: uint128,
1778
+ signage_point_index: uint8,
1779
+ proof_of_space: ProofOfSpace,
1780
+ slot_cc_challenge: bytes32,
1781
+ slot_rc_challenge: bytes32,
1782
+ farmer_reward_puzzle_hash: bytes32,
1783
+ pool_target: PoolTarget,
1784
+ last_timestamp: float,
1785
+ start_height: uint32,
1786
+ time_per_block: float,
1787
+ block_generator: Optional[BlockGenerator],
1788
+ aggregate_signature: G2Element,
1789
+ additions: Optional[list[Coin]],
1790
+ removals: Optional[list[Coin]],
1791
+ height_to_hash: dict[uint32, bytes32],
1792
+ difficulty: uint64,
1793
+ required_iters: uint64,
1794
+ sub_slot_iters: uint64,
1795
+ get_plot_signature: Callable[[bytes32, G1Element], G2Element],
1796
+ get_pool_signature: Callable[[PoolTarget, Optional[G1Element]], Optional[G2Element]],
1797
+ finished_sub_slots: list[EndOfSubSlotBundle],
1798
+ signage_point: SignagePoint,
1799
+ prev_block: BlockRecord,
1800
+ seed: bytes = b"",
1801
+ *,
1802
+ block_refs: list[uint32] = [],
1803
+ overflow_cc_challenge: Optional[bytes32] = None,
1804
+ overflow_rc_challenge: Optional[bytes32] = None,
1805
+ normalized_to_identity_cc_ip: bool = False,
1806
+ current_time: bool = False,
1807
+ ) -> tuple[FullBlock, BlockRecord, float]:
1808
+ # we're simulating time between blocks here. The more VDF iterations the
1809
+ # blocks advances, the longer it should have taken (and vice versa). This
1810
+ # formula is meant to converge at 1024 iters per the specified
1811
+ # time_per_block (which defaults to 18.75 seconds)
1812
+ time_per_block *= (((sub_slot_iters / 1024) - 1) * 0.2) + 1
1813
+ if current_time is True:
1814
+ timestamp = max(int(time.time()), last_timestamp + time_per_block)
1815
+ else:
1816
+ timestamp = last_timestamp + time_per_block
1817
+ sp_iters = calculate_sp_iters(constants, sub_slot_iters, signage_point_index)
1818
+ ip_iters = calculate_ip_iters(constants, sub_slot_iters, signage_point_index, required_iters)
1819
+
1820
+ unfinished_block = create_unfinished_block(
1821
+ constants,
1822
+ sub_slot_start_total_iters,
1823
+ sub_slot_iters,
1824
+ signage_point_index,
1825
+ sp_iters,
1826
+ ip_iters,
1827
+ proof_of_space,
1828
+ slot_cc_challenge,
1829
+ farmer_reward_puzzle_hash,
1830
+ pool_target,
1831
+ get_plot_signature,
1832
+ get_pool_signature,
1833
+ signage_point,
1834
+ uint64(timestamp),
1835
+ BlockCache(blocks),
1836
+ seed,
1837
+ block_generator,
1838
+ aggregate_signature,
1839
+ additions,
1840
+ removals,
1841
+ prev_block,
1842
+ finished_sub_slots,
1843
+ compute_cost=compute_cost_test,
1844
+ compute_fees=compute_fee_test,
1845
+ )
1846
+
1847
+ if (overflow_cc_challenge is not None) and (overflow_rc_challenge is not None):
1848
+ slot_cc_challenge = overflow_cc_challenge
1849
+ slot_rc_challenge = overflow_rc_challenge
1850
+
1851
+ full_block, block_record = finish_block(
1852
+ constants,
1853
+ blocks,
1854
+ height_to_hash,
1855
+ finished_sub_slots,
1856
+ sub_slot_start_total_iters,
1857
+ signage_point_index,
1858
+ unfinished_block,
1859
+ required_iters,
1860
+ ip_iters,
1861
+ slot_cc_challenge,
1862
+ slot_rc_challenge,
1863
+ prev_block,
1864
+ sub_slot_iters,
1865
+ difficulty,
1866
+ normalized_to_identity_cc_ip,
1867
+ )
1868
+
1869
+ return full_block, block_record, timestamp
1870
+
1871
+
1872
+ # these are the costs of unknown conditions, as defined chia_rs here:
1873
+ # https://github.com/Chia-Network/chia_rs/pull/181
1874
+ def compute_cost_table() -> list[int]:
1875
+ A = 17
1876
+ B = 16
1877
+ s = []
1878
+ NUM = 100
1879
+ DEN = 1
1880
+ MAX = 1 << 59
1881
+ for i in range(256):
1882
+ v = str(NUM // DEN)
1883
+ v1 = v[:3] + ("0" * (len(v) - 3))
1884
+ s.append(int(v1))
1885
+ NUM *= A
1886
+ DEN *= B
1887
+ assert NUM < 1 << 64
1888
+ assert DEN < 1 << 64
1889
+ if NUM > MAX:
1890
+ NUM >>= 5
1891
+ DEN >>= 5
1892
+ return s
1893
+
1894
+
1895
+ CONDITION_COSTS = compute_cost_table()
1896
+
1897
+
1898
+ def conditions_cost(conds: Program) -> uint64:
1899
+ condition_cost = 0
1900
+ for cond in conds.as_iter():
1901
+ condition = cond.first().as_atom()
1902
+ if condition == ConditionOpcode.CREATE_COIN:
1903
+ condition_cost += ConditionCost.CREATE_COIN.value
1904
+ # after the 2.0 hard fork, two byte conditions (with no leading 0)
1905
+ # have costs. Account for that.
1906
+ elif len(condition) == 2 and condition[0] != 0:
1907
+ condition_cost += CONDITION_COSTS[condition[1]]
1908
+ elif condition == ConditionOpcode.SOFTFORK.value:
1909
+ arg = cond.rest().first().as_int()
1910
+ condition_cost += arg * 10000
1911
+ elif condition in {
1912
+ ConditionOpcode.AGG_SIG_UNSAFE,
1913
+ ConditionOpcode.AGG_SIG_ME,
1914
+ ConditionOpcode.AGG_SIG_PARENT,
1915
+ ConditionOpcode.AGG_SIG_PUZZLE,
1916
+ ConditionOpcode.AGG_SIG_AMOUNT,
1917
+ ConditionOpcode.AGG_SIG_PUZZLE_AMOUNT,
1918
+ ConditionOpcode.AGG_SIG_PARENT_AMOUNT,
1919
+ ConditionOpcode.AGG_SIG_PARENT_PUZZLE,
1920
+ }:
1921
+ condition_cost += ConditionCost.AGG_SIG.value
1922
+ return uint64(condition_cost)
1923
+
1924
+
1925
+ def compute_fee_test(additions: Sequence[Coin], removals: Sequence[Coin]) -> uint64:
1926
+ removal_amount = 0
1927
+ addition_amount = 0
1928
+ for coin in removals:
1929
+ removal_amount += coin.amount
1930
+ for coin in additions:
1931
+ addition_amount += coin.amount
1932
+
1933
+ ret = removal_amount - addition_amount
1934
+ # in order to allow creating blocks that mint coins, clamp the fee
1935
+ # to 0, if it ends up being negative
1936
+ ret = max(ret, 0)
1937
+ return uint64(ret)
1938
+
1939
+
1940
+ def compute_cost_test(generator: BlockGenerator, constants: ConsensusConstants, height: uint32) -> uint64:
1941
+ # this function cannot *validate* the block or any of the transactions. We
1942
+ # deliberately create invalid blocks as parts of the tests, and we still
1943
+ # need to be able to compute the cost of it
1944
+
1945
+ condition_cost = 0
1946
+ clvm_cost = 0
1947
+
1948
+ if height >= constants.HARD_FORK_HEIGHT:
1949
+ blocks = generator.generator_refs
1950
+ cost, result = generator.program._run(INFINITE_COST, MEMPOOL_MODE, [DESERIALIZE_MOD, blocks])
1951
+ clvm_cost += cost
1952
+
1953
+ for spend in result.first().as_iter():
1954
+ # each spend is a list of:
1955
+ # (parent-coin-id puzzle amount solution)
1956
+ puzzle = spend.at("rf")
1957
+ solution = spend.at("rrrf")
1958
+
1959
+ cost, result = puzzle._run(INFINITE_COST, MEMPOOL_MODE, solution)
1960
+ clvm_cost += cost
1961
+ condition_cost += conditions_cost(result)
1962
+
1963
+ else:
1964
+ block_program_args = SerializedProgram.to([generator.generator_refs])
1965
+ clvm_cost, result = GENERATOR_MOD._run(INFINITE_COST, MEMPOOL_MODE, [generator.program, block_program_args])
1966
+
1967
+ for res in result.first().as_iter():
1968
+ # each condition item is:
1969
+ # (parent-coin-id puzzle-hash amount conditions)
1970
+ conditions = res.at("rrrf")
1971
+ condition_cost += conditions_cost(conditions)
1972
+
1973
+ size_cost = len(bytes(generator.program)) * constants.COST_PER_BYTE
1974
+
1975
+ return uint64(clvm_cost + size_cost + condition_cost)
1976
+
1977
+
1978
+ @dataclass
1979
+ class BlockToolsNewPlotResult:
1980
+ plot_id: bytes32
1981
+ new_plot: bool
1982
+
1983
+
1984
+ # Remove these counters when `create_block_tools` and `create_block_tools_async` are removed
1985
+ create_block_tools_async_count = 0
1986
+ create_block_tools_count = 0
1987
+
1988
+ # Note: tests that still use `create_block_tools` and `create_block_tools_async` should probably be
1989
+ # moved to the bt fixture in conftest.py. Take special care to find out if the users of these functions
1990
+ # need different BlockTools instances
1991
+
1992
+ # All tests need different root directories containing different config.yaml files.
1993
+ # The daemon's listen port is configured in the config.yaml, and the only way a test can control which
1994
+ # listen port it uses is to write it to the config file.
1995
+
1996
+
1997
+ async def create_block_tools_async(
1998
+ constants: ConsensusConstants = test_constants,
1999
+ root_path: Optional[Path] = None,
2000
+ keychain: Optional[Keychain] = None,
2001
+ config_overrides: Optional[dict[str, Any]] = None,
2002
+ num_og_plots: int = 15,
2003
+ num_pool_plots: int = 5,
2004
+ num_non_keychain_plots: int = 3,
2005
+ ) -> BlockTools:
2006
+ global create_block_tools_async_count
2007
+ create_block_tools_async_count += 1
2008
+ print(f" create_block_tools_async called {create_block_tools_async_count} times")
2009
+ bt = BlockTools(constants, root_path, keychain, config_overrides=config_overrides)
2010
+ await bt.setup_keys()
2011
+ await bt.setup_plots(
2012
+ num_og_plots=num_og_plots,
2013
+ num_pool_plots=num_pool_plots,
2014
+ num_non_keychain_plots=num_non_keychain_plots,
2015
+ )
2016
+
2017
+ return bt
2018
+
2019
+
2020
+ def create_block_tools(
2021
+ constants: ConsensusConstants = test_constants,
2022
+ root_path: Optional[Path] = None,
2023
+ keychain: Optional[Keychain] = None,
2024
+ config_overrides: Optional[dict[str, Any]] = None,
2025
+ ) -> BlockTools:
2026
+ global create_block_tools_count
2027
+ create_block_tools_count += 1
2028
+ print(f" create_block_tools called {create_block_tools_count} times")
2029
+ bt = BlockTools(constants, root_path, keychain, config_overrides=config_overrides)
2030
+
2031
+ asyncio.get_event_loop().run_until_complete(bt.setup_keys())
2032
+ asyncio.get_event_loop().run_until_complete(bt.setup_plots())
2033
+ return bt
2034
+
2035
+
2036
+ def make_unfinished_block(
2037
+ block: FullBlock, constants: ConsensusConstants, *, force_overflow: bool = False
2038
+ ) -> UnfinishedBlock:
2039
+ if force_overflow or is_overflow_block(constants, block.reward_chain_block.signage_point_index):
2040
+ finished_ss = block.finished_sub_slots[:-1]
2041
+ else:
2042
+ finished_ss = block.finished_sub_slots
2043
+
2044
+ return UnfinishedBlock(
2045
+ finished_ss,
2046
+ block.reward_chain_block.get_unfinished(),
2047
+ block.challenge_chain_sp_proof,
2048
+ block.reward_chain_sp_proof,
2049
+ block.foliage,
2050
+ block.foliage_transaction_block,
2051
+ block.transactions_info,
2052
+ block.transactions_generator,
2053
+ block.transactions_generator_ref_list,
2054
+ )