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