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,1719 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import logging
5
+ import math
6
+ import pathlib
7
+ import random
8
+ import tempfile
9
+ from concurrent.futures.process import ProcessPoolExecutor
10
+ from multiprocessing.context import BaseContext
11
+ from typing import IO, Dict, List, Optional, Tuple
12
+
13
+ from chia.consensus.block_header_validation import validate_finished_header_block
14
+ from chia.consensus.block_record import BlockRecord
15
+ from chia.consensus.blockchain_interface import BlockchainInterface
16
+ from chia.consensus.constants import ConsensusConstants
17
+ from chia.consensus.deficit import calculate_deficit
18
+ from chia.consensus.full_block_to_block_record import header_block_to_sub_block_record
19
+ from chia.consensus.pot_iterations import (
20
+ calculate_ip_iters,
21
+ calculate_iterations_quality,
22
+ calculate_sp_iters,
23
+ is_overflow_block,
24
+ )
25
+ from chia.consensus.vdf_info_computation import get_signage_point_vdf_info
26
+ from chia.types.blockchain_format.classgroup import ClassgroupElement
27
+ from chia.types.blockchain_format.proof_of_space import verify_and_get_quality_string
28
+ from chia.types.blockchain_format.sized_bytes import bytes32
29
+ from chia.types.blockchain_format.slots import ChallengeChainSubSlot, RewardChainSubSlot
30
+ from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
31
+ from chia.types.blockchain_format.vdf import VDFInfo, VDFProof, validate_vdf
32
+ from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
33
+ from chia.types.header_block import HeaderBlock
34
+ from chia.types.weight_proof import (
35
+ RecentChainData,
36
+ SubEpochChallengeSegment,
37
+ SubEpochData,
38
+ SubEpochSegments,
39
+ SubSlotData,
40
+ WeightProof,
41
+ )
42
+ from chia.util.batches import to_batches
43
+ from chia.util.block_cache import BlockCache
44
+ from chia.util.hash import std_hash
45
+ from chia.util.ints import uint8, uint32, uint64, uint128
46
+ from chia.util.setproctitle import getproctitle, setproctitle
47
+
48
+ log = logging.getLogger(__name__)
49
+
50
+
51
+ def _create_shutdown_file() -> IO[bytes]:
52
+ return tempfile.NamedTemporaryFile(prefix="chia_full_node_weight_proof_handler_executor_shutdown_trigger")
53
+
54
+
55
+ class WeightProofHandler:
56
+ LAMBDA_L = 100
57
+ C = 0.5
58
+ MAX_SAMPLES = 20
59
+
60
+ def __init__(
61
+ self,
62
+ constants: ConsensusConstants,
63
+ blockchain: BlockchainInterface,
64
+ multiprocessing_context: Optional[BaseContext] = None,
65
+ ):
66
+ self.tip: Optional[bytes32] = None
67
+ self.proof: Optional[WeightProof] = None
68
+ self.constants = constants
69
+ self.blockchain = blockchain
70
+ self.lock = asyncio.Lock()
71
+ self._num_processes = 4
72
+ self.multiprocessing_context = multiprocessing_context
73
+
74
+ async def get_proof_of_weight(self, tip: bytes32) -> Optional[WeightProof]:
75
+ tip_rec = self.blockchain.try_block_record(tip)
76
+ if tip_rec is None:
77
+ log.error("unknown tip")
78
+ return None
79
+
80
+ if tip_rec.height < self.constants.WEIGHT_PROOF_RECENT_BLOCKS:
81
+ log.debug("chain to short for weight proof")
82
+ return None
83
+
84
+ async with self.lock:
85
+ if self.proof is not None:
86
+ if self.proof.recent_chain_data[-1].header_hash == tip:
87
+ return self.proof
88
+ wp = await self._create_proof_of_weight(tip)
89
+ if wp is None:
90
+ return None
91
+ self.proof = wp
92
+ self.tip = tip
93
+ return wp
94
+
95
+ def get_sub_epoch_data(self, tip_height: uint32, summary_heights: List[uint32]) -> List[SubEpochData]:
96
+ sub_epoch_data: List[SubEpochData] = []
97
+ for sub_epoch_n, ses_height in enumerate(summary_heights):
98
+ if ses_height > tip_height:
99
+ break
100
+ ses = self.blockchain.get_ses(ses_height)
101
+ log.debug("handle sub epoch summary %s at height: %s ses %s", sub_epoch_n, ses_height, ses)
102
+ sub_epoch_data.append(_create_sub_epoch_data(ses))
103
+ return sub_epoch_data
104
+
105
+ async def _create_proof_of_weight(self, tip: bytes32) -> Optional[WeightProof]:
106
+ """
107
+ Creates a weight proof object
108
+ """
109
+ assert self.blockchain is not None
110
+ sub_epoch_segments: List[SubEpochChallengeSegment] = []
111
+ tip_rec = self.blockchain.try_block_record(tip)
112
+ if tip_rec is None:
113
+ log.error("failed not tip in cache")
114
+ return None
115
+ log.info(f"create weight proof peak {tip} {tip_rec.height}")
116
+ recent_chain = await self._get_recent_chain(tip_rec.height)
117
+ if recent_chain is None:
118
+ return None
119
+
120
+ summary_heights = self.blockchain.get_ses_heights()
121
+ zero_hash = self.blockchain.height_to_hash(uint32(0))
122
+ assert zero_hash is not None
123
+ prev_ses_block = await self.blockchain.get_block_record_from_db(zero_hash)
124
+ if prev_ses_block is None:
125
+ return None
126
+ sub_epoch_data = self.get_sub_epoch_data(tip_rec.height, summary_heights)
127
+ # use second to last ses as seed
128
+ seed = self.get_seed_for_proof(summary_heights, tip_rec.height)
129
+ rng = random.Random(seed)
130
+ weight_to_check = _get_weights_for_sampling(rng, tip_rec.weight, recent_chain)
131
+ sample_n = 0
132
+ ses_blocks = await self.blockchain.get_block_records_at(summary_heights)
133
+ if ses_blocks is None:
134
+ return None
135
+
136
+ for sub_epoch_n, ses_height in enumerate(summary_heights):
137
+ if ses_height > tip_rec.height:
138
+ break
139
+
140
+ # if we have enough sub_epoch samples, dont sample
141
+ if sample_n >= self.MAX_SAMPLES:
142
+ log.debug("reached sampled sub epoch cap")
143
+ break
144
+ # sample sub epoch
145
+ # next sub block
146
+ ses_block = ses_blocks[sub_epoch_n]
147
+ if ses_block is None or ses_block.sub_epoch_summary_included is None:
148
+ log.error("error while building proof")
149
+ return None
150
+
151
+ if _sample_sub_epoch(prev_ses_block.weight, ses_block.weight, weight_to_check):
152
+ sample_n += 1
153
+ segments = await self.blockchain.get_sub_epoch_challenge_segments(ses_block.header_hash)
154
+ if segments is None:
155
+ segments = await self.__create_sub_epoch_segments(ses_block, prev_ses_block, uint32(sub_epoch_n))
156
+ if segments is None:
157
+ log.error(
158
+ f"failed while building segments for sub epoch {sub_epoch_n}, ses height {ses_height} "
159
+ )
160
+ return None
161
+ await self.blockchain.persist_sub_epoch_challenge_segments(ses_block.header_hash, segments)
162
+ sub_epoch_segments.extend(segments)
163
+ prev_ses_block = ses_block
164
+ log.debug(f"sub_epochs: {len(sub_epoch_data)}")
165
+ return WeightProof(sub_epoch_data, sub_epoch_segments, recent_chain)
166
+
167
+ def get_seed_for_proof(self, summary_heights: List[uint32], tip_height: uint32) -> bytes32:
168
+ count = 0
169
+ ses = None
170
+ for sub_epoch_n, ses_height in enumerate(reversed(summary_heights)):
171
+ if ses_height <= tip_height:
172
+ count += 1
173
+ if count == 2:
174
+ ses = self.blockchain.get_ses(ses_height)
175
+ break
176
+ assert ses is not None
177
+ seed = ses.get_hash()
178
+ return seed
179
+
180
+ async def _get_recent_chain(self, tip_height: uint32) -> Optional[List[HeaderBlock]]:
181
+ recent_chain: List[HeaderBlock] = []
182
+ ses_heights = self.blockchain.get_ses_heights()
183
+ min_height = 0
184
+ count_ses = 0
185
+ for ses_height in reversed(ses_heights):
186
+ if ses_height <= tip_height:
187
+ count_ses += 1
188
+ if count_ses == 2:
189
+ min_height = ses_height - 1
190
+ break
191
+ log.debug(f"start {min_height} end {tip_height}")
192
+ headers = await self.blockchain.get_header_blocks_in_range(min_height, tip_height, tx_filter=False)
193
+ blocks = await self.blockchain.get_block_records_in_range(min_height, tip_height)
194
+ ses_count = 0
195
+ curr_height = tip_height
196
+ blocks_n = 0
197
+ while ses_count < 2:
198
+ if curr_height == 0:
199
+ break
200
+ # add to needed reward chain recent blocks
201
+ header_hash = self.blockchain.height_to_hash(curr_height)
202
+ assert header_hash is not None
203
+ header_block = headers[header_hash]
204
+ block_rec = blocks[header_block.header_hash]
205
+ if header_block is None:
206
+ log.error("creating recent chain failed")
207
+ return None
208
+ recent_chain.insert(0, header_block)
209
+ if block_rec.sub_epoch_summary_included:
210
+ ses_count += 1
211
+ curr_height = uint32(curr_height - 1)
212
+ blocks_n += 1
213
+
214
+ header_hash = self.blockchain.height_to_hash(curr_height)
215
+ assert header_hash is not None
216
+ header_block = headers[header_hash]
217
+ recent_chain.insert(0, header_block)
218
+
219
+ log.info(
220
+ f"recent chain, "
221
+ f"start: {recent_chain[0].reward_chain_block.height} "
222
+ f"end: {recent_chain[-1].reward_chain_block.height} "
223
+ )
224
+ return recent_chain
225
+
226
+ async def create_prev_sub_epoch_segments(self) -> None:
227
+ log.debug("create prev sub_epoch_segments")
228
+ heights = self.blockchain.get_ses_heights()
229
+ if len(heights) < 3:
230
+ return None
231
+ count = len(heights) - 2
232
+ ses_sub_block = self.blockchain.height_to_block_record(heights[-2])
233
+ prev_ses_sub_block = self.blockchain.height_to_block_record(heights[-3])
234
+ assert prev_ses_sub_block.sub_epoch_summary_included is not None
235
+ segments = await self.__create_sub_epoch_segments(ses_sub_block, prev_ses_sub_block, uint32(count))
236
+ assert segments is not None
237
+ await self.blockchain.persist_sub_epoch_challenge_segments(ses_sub_block.header_hash, segments)
238
+ log.debug("sub_epoch_segments done")
239
+ return None
240
+
241
+ async def create_sub_epoch_segments(self) -> None:
242
+ log.debug("check segments in db")
243
+ """
244
+ Creates a weight proof object
245
+ """
246
+ assert self.blockchain is not None
247
+ peak_height = self.blockchain.get_peak_height()
248
+ if peak_height is None:
249
+ log.error("no peak yet")
250
+ return None
251
+
252
+ summary_heights = self.blockchain.get_ses_heights()
253
+ h_hash: Optional[bytes32] = self.blockchain.height_to_hash(uint32(0))
254
+ if h_hash is None:
255
+ return None
256
+ prev_ses_block: Optional[BlockRecord] = await self.blockchain.get_block_record_from_db(h_hash)
257
+ if prev_ses_block is None:
258
+ return None
259
+
260
+ ses_blocks = await self.blockchain.get_block_records_at(summary_heights)
261
+ if ses_blocks is None:
262
+ return None
263
+
264
+ for sub_epoch_n, ses_height in enumerate(summary_heights):
265
+ log.debug(f"check db for sub epoch {sub_epoch_n}")
266
+ if ses_height > peak_height:
267
+ break
268
+ ses_block = ses_blocks[sub_epoch_n]
269
+ if ses_block is None or ses_block.sub_epoch_summary_included is None:
270
+ log.error("error while building proof")
271
+ return None
272
+ await self.__create_persist_segment(prev_ses_block, ses_block, ses_height, sub_epoch_n)
273
+ prev_ses_block = ses_block
274
+ await asyncio.sleep(2)
275
+ log.debug("done checking segments")
276
+ return None
277
+
278
+ async def __create_persist_segment(
279
+ self, prev_ses_block: BlockRecord, ses_block: BlockRecord, ses_height: uint32, sub_epoch_n: int
280
+ ) -> None:
281
+ segments = await self.blockchain.get_sub_epoch_challenge_segments(ses_block.header_hash)
282
+ if segments is None:
283
+ segments = await self.__create_sub_epoch_segments(ses_block, prev_ses_block, uint32(sub_epoch_n))
284
+ if segments is None:
285
+ log.error(f"failed while building segments for sub epoch {sub_epoch_n}, ses height {ses_height} ")
286
+ return None
287
+ await self.blockchain.persist_sub_epoch_challenge_segments(ses_block.header_hash, segments)
288
+
289
+ async def __create_sub_epoch_segments(
290
+ self, ses_block: BlockRecord, se_start: BlockRecord, sub_epoch_n: uint32
291
+ ) -> Optional[List[SubEpochChallengeSegment]]:
292
+ segments: List[SubEpochChallengeSegment] = []
293
+ start_height = await self.get_prev_two_slots_height(se_start)
294
+
295
+ blocks = await self.blockchain.get_block_records_in_range(
296
+ start_height, ses_block.height + self.constants.MAX_SUB_SLOT_BLOCKS
297
+ )
298
+ header_blocks = await self.blockchain.get_header_blocks_in_range(
299
+ start_height, ses_block.height + self.constants.MAX_SUB_SLOT_BLOCKS, tx_filter=False
300
+ )
301
+ curr: Optional[HeaderBlock] = header_blocks[se_start.header_hash]
302
+ height = se_start.height
303
+ assert curr is not None
304
+ first = True
305
+ idx = 0
306
+ while curr.height < ses_block.height:
307
+ if blocks[curr.header_hash].is_challenge_block(self.constants):
308
+ log.debug(f"challenge segment {idx}, starts at {curr.height} ")
309
+ seg, height = await self._create_challenge_segment(curr, sub_epoch_n, header_blocks, blocks, first)
310
+ if seg is None:
311
+ log.error(f"failed creating segment {curr.header_hash} ")
312
+ return None
313
+ segments.append(seg)
314
+ idx += 1
315
+ first = False
316
+ else:
317
+ height = uint32(height + 1)
318
+ header_hash = self.blockchain.height_to_hash(height)
319
+ assert header_hash is not None
320
+ curr = header_blocks[header_hash]
321
+ if curr is None:
322
+ return None
323
+ log.debug(f"next sub epoch starts at {height}")
324
+ return segments
325
+
326
+ async def get_prev_two_slots_height(self, se_start: BlockRecord) -> uint32:
327
+ # find prev 2 slots height
328
+ slot = 0
329
+ batch_size = 50
330
+ curr_rec = se_start
331
+ blocks = await self.blockchain.get_block_records_in_range(curr_rec.height - batch_size, curr_rec.height)
332
+ end = curr_rec.height
333
+ while slot < 2 and curr_rec.height > 0:
334
+ if curr_rec.first_in_sub_slot:
335
+ slot += 1
336
+ if end - curr_rec.height == batch_size - 1:
337
+ blocks = await self.blockchain.get_block_records_in_range(curr_rec.height - batch_size, curr_rec.height)
338
+ end = curr_rec.height
339
+ header_hash = self.blockchain.height_to_hash(uint32(curr_rec.height - 1))
340
+ assert header_hash is not None
341
+ curr_rec = blocks[header_hash]
342
+ return curr_rec.height
343
+
344
+ async def _create_challenge_segment(
345
+ self,
346
+ header_block: HeaderBlock,
347
+ sub_epoch_n: uint32,
348
+ header_blocks: Dict[bytes32, HeaderBlock],
349
+ blocks: Dict[bytes32, BlockRecord],
350
+ first_segment_in_sub_epoch: bool,
351
+ ) -> Tuple[Optional[SubEpochChallengeSegment], uint32]:
352
+ assert self.blockchain is not None
353
+ sub_slots: List[SubSlotData] = []
354
+ log.debug(f"create challenge segment block {header_block.header_hash} block height {header_block.height} ")
355
+ # VDFs from sub slots before challenge block
356
+ first_sub_slots, first_rc_end_of_slot_vdf = await self.__first_sub_slot_vdfs(
357
+ header_block, header_blocks, blocks, first_segment_in_sub_epoch
358
+ )
359
+ if first_sub_slots is None:
360
+ log.error("failed building first sub slots")
361
+ return None, uint32(0)
362
+
363
+ sub_slots.extend(first_sub_slots)
364
+
365
+ ssd = await _challenge_block_vdfs(
366
+ self.constants,
367
+ header_block,
368
+ blocks[header_block.header_hash],
369
+ blocks,
370
+ )
371
+
372
+ sub_slots.append(ssd)
373
+
374
+ # # VDFs from slot after challenge block to end of slot
375
+ log.debug(f"create slot end vdf for block {header_block.header_hash} height {header_block.height} ")
376
+
377
+ challenge_slot_end_sub_slots, end_height = await self.__slot_end_vdf(
378
+ uint32(header_block.height + 1), header_blocks, blocks
379
+ )
380
+ if challenge_slot_end_sub_slots is None:
381
+ log.error("failed building slot end ")
382
+ return None, uint32(0)
383
+ sub_slots.extend(challenge_slot_end_sub_slots)
384
+ if first_segment_in_sub_epoch and sub_epoch_n != 0:
385
+ return (
386
+ SubEpochChallengeSegment(sub_epoch_n, sub_slots, first_rc_end_of_slot_vdf),
387
+ end_height,
388
+ )
389
+ return SubEpochChallengeSegment(sub_epoch_n, sub_slots, None), end_height
390
+
391
+ # returns a challenge chain vdf from slot start to signage point
392
+ async def __first_sub_slot_vdfs(
393
+ self,
394
+ header_block: HeaderBlock,
395
+ header_blocks: Dict[bytes32, HeaderBlock],
396
+ blocks: Dict[bytes32, BlockRecord],
397
+ first_in_sub_epoch: bool,
398
+ ) -> Tuple[Optional[List[SubSlotData]], Optional[VDFInfo]]:
399
+ # combine cc vdfs of all reward blocks from the start of the sub slot to end
400
+ header_block_sub_rec = blocks[header_block.header_hash]
401
+ # find slot start
402
+ curr_sub_rec = header_block_sub_rec
403
+ first_rc_end_of_slot_vdf = None
404
+ if first_in_sub_epoch and curr_sub_rec.height > 0:
405
+ while not curr_sub_rec.sub_epoch_summary_included:
406
+ curr_sub_rec = blocks[curr_sub_rec.prev_hash]
407
+ first_rc_end_of_slot_vdf = self.first_rc_end_of_slot_vdf(header_block, blocks, header_blocks)
408
+ else:
409
+ if header_block_sub_rec.overflow and header_block_sub_rec.first_in_sub_slot:
410
+ sub_slots_num = 2
411
+ while sub_slots_num > 0 and curr_sub_rec.height > 0:
412
+ if curr_sub_rec.first_in_sub_slot:
413
+ assert curr_sub_rec.finished_challenge_slot_hashes is not None
414
+ sub_slots_num -= len(curr_sub_rec.finished_challenge_slot_hashes)
415
+ curr_sub_rec = blocks[curr_sub_rec.prev_hash]
416
+ else:
417
+ while not curr_sub_rec.first_in_sub_slot and curr_sub_rec.height > 0:
418
+ curr_sub_rec = blocks[curr_sub_rec.prev_hash]
419
+
420
+ curr = header_blocks[curr_sub_rec.header_hash]
421
+ sub_slots_data: List[SubSlotData] = []
422
+ tmp_sub_slots_data: List[SubSlotData] = []
423
+ while curr.height < header_block.height:
424
+ if curr is None:
425
+ log.error("failed fetching block")
426
+ return None, None
427
+ if curr.first_in_sub_slot:
428
+ # if not blue boxed
429
+ if not blue_boxed_end_of_slot(curr.finished_sub_slots[0]):
430
+ sub_slots_data.extend(tmp_sub_slots_data)
431
+
432
+ for idx, sub_slot in enumerate(curr.finished_sub_slots):
433
+ curr_icc_info = None
434
+ if sub_slot.infused_challenge_chain is not None:
435
+ curr_icc_info = sub_slot.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf
436
+ sub_slots_data.append(handle_finished_slots(sub_slot, curr_icc_info))
437
+ tmp_sub_slots_data = []
438
+ ssd = SubSlotData(
439
+ None,
440
+ None,
441
+ None,
442
+ None,
443
+ None,
444
+ curr.reward_chain_block.signage_point_index,
445
+ None,
446
+ None,
447
+ None,
448
+ None,
449
+ curr.reward_chain_block.challenge_chain_ip_vdf,
450
+ curr.reward_chain_block.infused_challenge_chain_ip_vdf,
451
+ curr.total_iters,
452
+ )
453
+ tmp_sub_slots_data.append(ssd)
454
+ header_hash = self.blockchain.height_to_hash(uint32(curr.height + 1))
455
+ assert header_hash is not None
456
+ curr = header_blocks[header_hash]
457
+
458
+ if len(tmp_sub_slots_data) > 0:
459
+ sub_slots_data.extend(tmp_sub_slots_data)
460
+
461
+ for idx, sub_slot in enumerate(header_block.finished_sub_slots):
462
+ curr_icc_info = None
463
+ if sub_slot.infused_challenge_chain is not None:
464
+ curr_icc_info = sub_slot.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf
465
+ sub_slots_data.append(handle_finished_slots(sub_slot, curr_icc_info))
466
+
467
+ return sub_slots_data, first_rc_end_of_slot_vdf
468
+
469
+ def first_rc_end_of_slot_vdf(
470
+ self,
471
+ header_block: HeaderBlock,
472
+ blocks: Dict[bytes32, BlockRecord],
473
+ header_blocks: Dict[bytes32, HeaderBlock],
474
+ ) -> Optional[VDFInfo]:
475
+ curr = blocks[header_block.header_hash]
476
+ while curr.height > 0 and not curr.sub_epoch_summary_included:
477
+ curr = blocks[curr.prev_hash]
478
+ return header_blocks[curr.header_hash].finished_sub_slots[-1].reward_chain.end_of_slot_vdf
479
+
480
+ async def __slot_end_vdf(
481
+ self, start_height: uint32, header_blocks: Dict[bytes32, HeaderBlock], blocks: Dict[bytes32, BlockRecord]
482
+ ) -> Tuple[Optional[List[SubSlotData]], uint32]:
483
+ # gets all vdfs first sub slot after challenge block to last sub slot
484
+ log.debug(f"slot end vdf start height {start_height}")
485
+ header_hash = self.blockchain.height_to_hash(start_height)
486
+ assert header_hash is not None
487
+ curr = header_blocks[header_hash]
488
+ curr_header_hash = curr.header_hash
489
+ sub_slots_data: List[SubSlotData] = []
490
+ tmp_sub_slots_data: List[SubSlotData] = []
491
+ while not blocks[curr_header_hash].is_challenge_block(self.constants):
492
+ if curr.first_in_sub_slot:
493
+ sub_slots_data.extend(tmp_sub_slots_data)
494
+
495
+ curr_prev_header_hash = curr.prev_header_hash
496
+ # add collected vdfs
497
+ for idx, sub_slot in enumerate(curr.finished_sub_slots):
498
+ prev_rec = blocks[curr_prev_header_hash]
499
+ eos_vdf_iters = prev_rec.sub_slot_iters
500
+ if idx == 0:
501
+ eos_vdf_iters = uint64(prev_rec.sub_slot_iters - prev_rec.ip_iters(self.constants))
502
+ sub_slots_data.append(handle_end_of_slot(sub_slot, eos_vdf_iters))
503
+ tmp_sub_slots_data = []
504
+ tmp_sub_slots_data.append(self.handle_block_vdfs(curr, blocks))
505
+ header_hash = self.blockchain.height_to_hash(uint32(curr.height + 1))
506
+ assert header_hash is not None
507
+ curr = header_blocks[header_hash]
508
+ curr_header_hash = curr.header_hash
509
+
510
+ if len(tmp_sub_slots_data) > 0:
511
+ sub_slots_data.extend(tmp_sub_slots_data)
512
+ log.debug(f"slot end vdf end height {curr.height} slots {len(sub_slots_data)} ")
513
+ return sub_slots_data, curr.height
514
+
515
+ def handle_block_vdfs(self, curr: HeaderBlock, blocks: Dict[bytes32, BlockRecord]) -> SubSlotData:
516
+ cc_sp_proof = None
517
+ icc_ip_proof = None
518
+ cc_sp_info = None
519
+ icc_ip_info = None
520
+ block_record = blocks[curr.header_hash]
521
+ if curr.infused_challenge_chain_ip_proof is not None:
522
+ assert curr.reward_chain_block.infused_challenge_chain_ip_vdf
523
+ icc_ip_proof = curr.infused_challenge_chain_ip_proof
524
+ icc_ip_info = curr.reward_chain_block.infused_challenge_chain_ip_vdf
525
+ if curr.challenge_chain_sp_proof is not None:
526
+ assert curr.reward_chain_block.challenge_chain_sp_vdf
527
+ cc_sp_vdf_info = curr.reward_chain_block.challenge_chain_sp_vdf
528
+ if not curr.challenge_chain_sp_proof.normalized_to_identity:
529
+ (_, _, _, _, cc_vdf_iters, _) = get_signage_point_vdf_info(
530
+ self.constants,
531
+ curr.finished_sub_slots,
532
+ block_record.overflow,
533
+ None if curr.height == 0 else blocks[curr.prev_header_hash],
534
+ BlockCache(blocks),
535
+ block_record.sp_total_iters(self.constants),
536
+ block_record.sp_iters(self.constants),
537
+ )
538
+ cc_sp_vdf_info = VDFInfo(
539
+ curr.reward_chain_block.challenge_chain_sp_vdf.challenge,
540
+ cc_vdf_iters,
541
+ curr.reward_chain_block.challenge_chain_sp_vdf.output,
542
+ )
543
+ cc_sp_proof = curr.challenge_chain_sp_proof
544
+ cc_sp_info = cc_sp_vdf_info
545
+ return SubSlotData(
546
+ None,
547
+ cc_sp_proof,
548
+ curr.challenge_chain_ip_proof,
549
+ icc_ip_proof,
550
+ cc_sp_info,
551
+ curr.reward_chain_block.signage_point_index,
552
+ None,
553
+ None,
554
+ None,
555
+ None,
556
+ curr.reward_chain_block.challenge_chain_ip_vdf,
557
+ icc_ip_info,
558
+ curr.total_iters,
559
+ )
560
+
561
+ def validate_weight_proof_single_proc(self, weight_proof: WeightProof) -> Tuple[bool, uint32]:
562
+ assert self.blockchain is not None
563
+ assert len(weight_proof.sub_epochs) > 0
564
+ if len(weight_proof.sub_epochs) == 0:
565
+ return False, uint32(0)
566
+
567
+ peak_height = weight_proof.recent_chain_data[-1].reward_chain_block.height
568
+ log.info(f"validate weight proof peak height {peak_height}")
569
+ summaries, sub_epoch_weight_list = _validate_sub_epoch_summaries(self.constants, weight_proof)
570
+ if summaries is None:
571
+ log.warning("weight proof failed sub epoch data validation")
572
+ return False, uint32(0)
573
+ summary_bytes, wp_segment_bytes, wp_recent_chain_bytes = vars_to_bytes(summaries, weight_proof)
574
+ log.info("validate sub epoch challenge segments")
575
+ seed = summaries[-2].get_hash()
576
+ rng = random.Random(seed)
577
+ assert sub_epoch_weight_list is not None
578
+ if not validate_sub_epoch_sampling(rng, sub_epoch_weight_list, weight_proof):
579
+ log.error("failed weight proof sub epoch sample validation")
580
+ return False, uint32(0)
581
+
582
+ if _validate_sub_epoch_segments(self.constants, rng, wp_segment_bytes, summary_bytes, peak_height) is None:
583
+ return False, uint32(0)
584
+ log.info("validate weight proof recent blocks")
585
+ success, _ = validate_recent_blocks(self.constants, wp_recent_chain_bytes, summary_bytes)
586
+ if not success:
587
+ return False, uint32(0)
588
+ fork_point, _ = self.get_fork_point(summaries)
589
+ return True, fork_point
590
+
591
+ async def validate_weight_proof(self, weight_proof: WeightProof) -> Tuple[bool, uint32, List[SubEpochSummary]]:
592
+ assert self.blockchain is not None
593
+ if len(weight_proof.sub_epochs) == 0:
594
+ return False, uint32(0), []
595
+
596
+ # timing reference: start
597
+ summaries, sub_epoch_weight_list = _validate_sub_epoch_summaries(self.constants, weight_proof)
598
+ await asyncio.sleep(0) # break up otherwise multi-second sync code
599
+ # timing reference: 1 second
600
+ if summaries is None or sub_epoch_weight_list is None:
601
+ log.error("weight proof failed sub epoch data validation")
602
+ return False, uint32(0), []
603
+
604
+ fork_point, ses_fork_idx = self.get_fork_point(summaries)
605
+ # timing reference: 1 second
606
+ # TODO: Consider implementing an async polling closer for the executor.
607
+ with ProcessPoolExecutor(
608
+ max_workers=self._num_processes,
609
+ mp_context=self.multiprocessing_context,
610
+ initializer=setproctitle,
611
+ initargs=(f"{getproctitle()}_weight_proof_worker",),
612
+ ) as executor:
613
+ # The shutdown file manager must be inside of the executor manager so that
614
+ # we request the workers close prior to waiting for them to close.
615
+ with _create_shutdown_file() as shutdown_file:
616
+ task = asyncio.create_task(
617
+ validate_weight_proof_inner(
618
+ self.constants,
619
+ executor,
620
+ shutdown_file.name,
621
+ self._num_processes,
622
+ weight_proof,
623
+ summaries,
624
+ sub_epoch_weight_list,
625
+ False,
626
+ ses_fork_idx,
627
+ )
628
+ )
629
+ valid, _ = await task
630
+ return valid, fork_point, summaries
631
+
632
+ def get_fork_point(self, received_summaries: List[SubEpochSummary]) -> Tuple[uint32, int]:
633
+ # returns the fork height and ses index
634
+ # iterate through sub epoch summaries to find fork point
635
+ fork_point_index = 0
636
+ ses_heights = self.blockchain.get_ses_heights()
637
+ for idx, summary_height in enumerate(ses_heights):
638
+ log.debug(f"check summary {idx} height {summary_height}")
639
+ local_ses = self.blockchain.get_ses(summary_height)
640
+ if idx == len(received_summaries) - 1:
641
+ # end of wp summaries, local chain is longer or equal to wp chain
642
+ break
643
+ if local_ses is None or local_ses.get_hash() != received_summaries[idx].get_hash():
644
+ break
645
+ fork_point_index = idx
646
+
647
+ if fork_point_index <= 2:
648
+ # Two summeries can have different blocks and still be identical
649
+ # This gets resolved after one full sub epoch
650
+ return uint32(0), 0
651
+
652
+ return ses_heights[fork_point_index - 2], fork_point_index
653
+
654
+
655
+ def _get_weights_for_sampling(
656
+ rng: random.Random, total_weight: uint128, recent_chain: List[HeaderBlock]
657
+ ) -> Optional[List[uint128]]:
658
+ weight_to_check = []
659
+ last_l_weight = recent_chain[-1].reward_chain_block.weight - recent_chain[0].reward_chain_block.weight
660
+ delta = last_l_weight / total_weight
661
+ prob_of_adv_succeeding = 1 - math.log(WeightProofHandler.C, delta)
662
+ if prob_of_adv_succeeding <= 0:
663
+ return None
664
+ queries = -WeightProofHandler.LAMBDA_L * math.log(2, prob_of_adv_succeeding)
665
+ for i in range(int(queries) + 1):
666
+ u = rng.random()
667
+ q = 1 - delta**u
668
+ # todo check division and type conversions
669
+ weight = q * float(total_weight)
670
+ weight_to_check.append(uint128(int(weight)))
671
+ weight_to_check.sort()
672
+ return weight_to_check
673
+
674
+
675
+ def _sample_sub_epoch(
676
+ start_of_epoch_weight: uint128,
677
+ end_of_epoch_weight: uint128,
678
+ weight_to_check: Optional[List[uint128]],
679
+ ) -> bool:
680
+ """
681
+ weight_to_check: List[uint128] is expected to be sorted
682
+ """
683
+ if weight_to_check is None:
684
+ return True
685
+ if weight_to_check[-1] < start_of_epoch_weight:
686
+ return False
687
+ if weight_to_check[0] > end_of_epoch_weight:
688
+ return False
689
+ choose = False
690
+ for weight in weight_to_check:
691
+ if weight > end_of_epoch_weight:
692
+ return False
693
+ if start_of_epoch_weight < weight < end_of_epoch_weight:
694
+ log.debug(f"start weight: {start_of_epoch_weight}")
695
+ log.debug(f"weight to check {weight}")
696
+ log.debug(f"end weight: {end_of_epoch_weight}")
697
+ choose = True
698
+ break
699
+
700
+ return choose
701
+
702
+
703
+ # wp creation methods
704
+ def _create_sub_epoch_data(
705
+ sub_epoch_summary: SubEpochSummary,
706
+ ) -> SubEpochData:
707
+ reward_chain_hash: bytes32 = sub_epoch_summary.reward_chain_hash
708
+ # Number of subblocks overflow in previous slot
709
+ previous_sub_epoch_overflows = sub_epoch_summary.num_blocks_overflow # total in sub epoch - expected
710
+ # New work difficulty and iterations per sub-slot
711
+ sub_slot_iters = sub_epoch_summary.new_sub_slot_iters
712
+ new_difficulty = sub_epoch_summary.new_difficulty
713
+ return SubEpochData(reward_chain_hash, previous_sub_epoch_overflows, sub_slot_iters, new_difficulty)
714
+
715
+
716
+ async def _challenge_block_vdfs(
717
+ constants: ConsensusConstants,
718
+ header_block: HeaderBlock,
719
+ block_rec: BlockRecord,
720
+ sub_blocks: Dict[bytes32, BlockRecord],
721
+ ) -> SubSlotData:
722
+ (_, _, _, _, cc_vdf_iters, _) = get_signage_point_vdf_info(
723
+ constants,
724
+ header_block.finished_sub_slots,
725
+ block_rec.overflow,
726
+ None if header_block.height == 0 else sub_blocks[header_block.prev_header_hash],
727
+ BlockCache(sub_blocks),
728
+ block_rec.sp_total_iters(constants),
729
+ block_rec.sp_iters(constants),
730
+ )
731
+
732
+ cc_sp_info = None
733
+ if header_block.reward_chain_block.challenge_chain_sp_vdf:
734
+ cc_sp_info = header_block.reward_chain_block.challenge_chain_sp_vdf
735
+ assert header_block.challenge_chain_sp_proof
736
+ if not header_block.challenge_chain_sp_proof.normalized_to_identity:
737
+ cc_sp_info = VDFInfo(
738
+ header_block.reward_chain_block.challenge_chain_sp_vdf.challenge,
739
+ cc_vdf_iters,
740
+ header_block.reward_chain_block.challenge_chain_sp_vdf.output,
741
+ )
742
+ ssd = SubSlotData(
743
+ header_block.reward_chain_block.proof_of_space,
744
+ header_block.challenge_chain_sp_proof,
745
+ header_block.challenge_chain_ip_proof,
746
+ None,
747
+ cc_sp_info,
748
+ header_block.reward_chain_block.signage_point_index,
749
+ None,
750
+ None,
751
+ None,
752
+ None,
753
+ header_block.reward_chain_block.challenge_chain_ip_vdf,
754
+ header_block.reward_chain_block.infused_challenge_chain_ip_vdf,
755
+ block_rec.total_iters,
756
+ )
757
+ return ssd
758
+
759
+
760
+ def handle_finished_slots(end_of_slot: EndOfSubSlotBundle, icc_end_of_slot_info: Optional[VDFInfo]) -> SubSlotData:
761
+ return SubSlotData(
762
+ None,
763
+ None,
764
+ None,
765
+ None,
766
+ None,
767
+ None,
768
+ (
769
+ None
770
+ if end_of_slot.proofs.challenge_chain_slot_proof is None
771
+ else end_of_slot.proofs.challenge_chain_slot_proof
772
+ ),
773
+ (
774
+ None
775
+ if end_of_slot.proofs.infused_challenge_chain_slot_proof is None
776
+ else end_of_slot.proofs.infused_challenge_chain_slot_proof
777
+ ),
778
+ end_of_slot.challenge_chain.challenge_chain_end_of_slot_vdf,
779
+ icc_end_of_slot_info,
780
+ None,
781
+ None,
782
+ None,
783
+ )
784
+
785
+
786
+ def handle_end_of_slot(
787
+ sub_slot: EndOfSubSlotBundle,
788
+ eos_vdf_iters: uint64,
789
+ ) -> SubSlotData:
790
+ assert sub_slot.infused_challenge_chain
791
+ assert sub_slot.proofs.infused_challenge_chain_slot_proof
792
+ if sub_slot.proofs.infused_challenge_chain_slot_proof.normalized_to_identity:
793
+ icc_info = sub_slot.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf
794
+ else:
795
+ icc_info = VDFInfo(
796
+ sub_slot.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf.challenge,
797
+ eos_vdf_iters,
798
+ sub_slot.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf.output,
799
+ )
800
+ if sub_slot.proofs.challenge_chain_slot_proof.normalized_to_identity:
801
+ cc_info = sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf
802
+ else:
803
+ cc_info = VDFInfo(
804
+ sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf.challenge,
805
+ eos_vdf_iters,
806
+ sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf.output,
807
+ )
808
+
809
+ assert sub_slot.proofs.infused_challenge_chain_slot_proof is not None
810
+ return SubSlotData(
811
+ None,
812
+ None,
813
+ None,
814
+ None,
815
+ None,
816
+ None,
817
+ sub_slot.proofs.challenge_chain_slot_proof,
818
+ sub_slot.proofs.infused_challenge_chain_slot_proof,
819
+ cc_info,
820
+ icc_info,
821
+ None,
822
+ None,
823
+ None,
824
+ )
825
+
826
+
827
+ # wp validation methods
828
+ def _validate_sub_epoch_summaries(
829
+ constants: ConsensusConstants,
830
+ weight_proof: WeightProof,
831
+ ) -> Tuple[Optional[List[SubEpochSummary]], Optional[List[uint128]]]:
832
+ last_ses_hash, last_ses_sub_height = _get_last_ses_hash(constants, weight_proof.recent_chain_data)
833
+ if last_ses_hash is None:
834
+ log.warning("could not find last ses block")
835
+ return None, None
836
+
837
+ summaries, total, sub_epoch_weight_list = _map_sub_epoch_summaries(
838
+ constants.SUB_EPOCH_BLOCKS,
839
+ constants.GENESIS_CHALLENGE,
840
+ weight_proof.sub_epochs,
841
+ constants.DIFFICULTY_STARTING,
842
+ )
843
+
844
+ log.info(f"validating {len(summaries)} sub epochs")
845
+
846
+ # validate weight
847
+ if not _validate_summaries_weight(constants, total, summaries, weight_proof):
848
+ log.error("failed validating weight")
849
+ return None, None
850
+
851
+ last_ses = summaries[-1]
852
+ log.debug(f"last ses sub height {last_ses_sub_height}")
853
+ # validate last ses_hash
854
+ if last_ses.get_hash() != last_ses_hash:
855
+ log.error(f"failed to validate ses hashes block height {last_ses_sub_height}")
856
+ return None, None
857
+
858
+ return summaries, sub_epoch_weight_list
859
+
860
+
861
+ def _map_sub_epoch_summaries(
862
+ sub_blocks_for_se: uint32,
863
+ ses_hash: bytes32,
864
+ sub_epoch_data: List[SubEpochData],
865
+ curr_difficulty: uint64,
866
+ ) -> Tuple[List[SubEpochSummary], uint128, List[uint128]]:
867
+ total_weight: uint128 = uint128(0)
868
+ summaries: List[SubEpochSummary] = []
869
+ sub_epoch_weight_list: List[uint128] = []
870
+ for idx, data in enumerate(sub_epoch_data):
871
+ ses = SubEpochSummary(
872
+ ses_hash,
873
+ data.reward_chain_hash,
874
+ data.num_blocks_overflow,
875
+ data.new_difficulty,
876
+ data.new_sub_slot_iters,
877
+ )
878
+
879
+ if idx < len(sub_epoch_data) - 1:
880
+ delta = 0
881
+ if idx > 0:
882
+ delta = sub_epoch_data[idx].num_blocks_overflow
883
+ log.debug(f"sub epoch {idx} start weight is {total_weight+curr_difficulty} ")
884
+ sub_epoch_weight_list.append(uint128(total_weight + curr_difficulty))
885
+ total_weight = uint128(
886
+ total_weight
887
+ + curr_difficulty * (sub_blocks_for_se + sub_epoch_data[idx + 1].num_blocks_overflow - delta)
888
+ )
889
+
890
+ # if new epoch update diff and iters
891
+ if data.new_difficulty is not None:
892
+ curr_difficulty = data.new_difficulty
893
+
894
+ # add to dict
895
+ summaries.append(ses)
896
+ ses_hash = std_hash(ses)
897
+ # add last sub epoch weight
898
+ sub_epoch_weight_list.append(uint128(total_weight + curr_difficulty))
899
+ return summaries, total_weight, sub_epoch_weight_list
900
+
901
+
902
+ def _validate_summaries_weight(
903
+ constants: ConsensusConstants,
904
+ sub_epoch_data_weight: uint128,
905
+ summaries: List[SubEpochSummary],
906
+ weight_proof: WeightProof,
907
+ ) -> bool:
908
+ num_over = summaries[-1].num_blocks_overflow
909
+ ses_end_height = (len(summaries) - 1) * constants.SUB_EPOCH_BLOCKS + num_over - 1
910
+ curr = None
911
+ for block in weight_proof.recent_chain_data:
912
+ if block.reward_chain_block.height == ses_end_height:
913
+ curr = block
914
+ if curr is None:
915
+ return False
916
+
917
+ return curr.reward_chain_block.weight == sub_epoch_data_weight
918
+
919
+
920
+ def _validate_sub_epoch_segments(
921
+ constants: ConsensusConstants,
922
+ rng: random.Random,
923
+ weight_proof_bytes: bytes,
924
+ summaries_bytes: List[bytes],
925
+ height: uint32,
926
+ validate_from: int = 0,
927
+ ) -> Optional[List[Tuple[VDFProof, ClassgroupElement, VDFInfo]]]:
928
+ summaries = summaries_from_bytes(summaries_bytes)
929
+ sub_epoch_segments: SubEpochSegments = SubEpochSegments.from_bytes(weight_proof_bytes)
930
+ rc_sub_slot_hash = constants.GENESIS_CHALLENGE
931
+ total_blocks, total_ip_iters = 0, 0
932
+ total_slot_iters, total_slots = 0, 0
933
+ total_ip_iters = 0
934
+ prev_ses: Optional[SubEpochSummary] = None
935
+ segments_by_sub_epoch = map_segments_by_sub_epoch(sub_epoch_segments.challenge_segments)
936
+ curr_ssi = constants.SUB_SLOT_ITERS_STARTING
937
+ vdfs_to_validate = []
938
+ for sub_epoch_n, segments in segments_by_sub_epoch.items():
939
+ prev_ssi = curr_ssi
940
+ curr_difficulty, curr_ssi = _get_curr_diff_ssi(constants, sub_epoch_n, summaries)
941
+ log.debug(f"validate sub epoch {sub_epoch_n}")
942
+ # recreate RewardChainSubSlot for next ses rc_hash
943
+ sampled_seg_index = rng.choice(range(len(segments)))
944
+ if sub_epoch_n > 0:
945
+ rc_sub_slot = __get_rc_sub_slot(constants, segments[0], summaries, curr_ssi)
946
+ prev_ses = summaries[sub_epoch_n - 1]
947
+ rc_sub_slot_hash = rc_sub_slot.get_hash()
948
+ if not summaries[sub_epoch_n].reward_chain_hash == rc_sub_slot_hash:
949
+ log.error(f"failed reward_chain_hash validation sub_epoch {sub_epoch_n}")
950
+ return None
951
+
952
+ # skip validation up to fork height
953
+ if sub_epoch_n < validate_from:
954
+ continue
955
+
956
+ for idx, segment in enumerate(segments):
957
+ valid_segment, ip_iters, slot_iters, slots, vdf_list = _validate_segment(
958
+ constants,
959
+ segment,
960
+ curr_ssi,
961
+ prev_ssi,
962
+ curr_difficulty,
963
+ prev_ses,
964
+ idx == 0,
965
+ sampled_seg_index == idx,
966
+ height,
967
+ )
968
+ vdfs_to_validate.extend(vdf_list)
969
+ if not valid_segment:
970
+ log.error(f"failed to validate sub_epoch {segment.sub_epoch_n} segment {idx} slots")
971
+ return None
972
+ prev_ses = None
973
+ total_blocks += 1
974
+ total_slot_iters += slot_iters
975
+ total_slots += slots
976
+ total_ip_iters += ip_iters
977
+ return vdfs_to_validate
978
+
979
+
980
+ def _validate_segment(
981
+ constants: ConsensusConstants,
982
+ segment: SubEpochChallengeSegment,
983
+ curr_ssi: uint64,
984
+ prev_ssi: uint64,
985
+ curr_difficulty: uint64,
986
+ ses: Optional[SubEpochSummary],
987
+ first_segment_in_se: bool,
988
+ sampled: bool,
989
+ height: uint32,
990
+ ) -> Tuple[bool, int, int, int, List[Tuple[VDFProof, ClassgroupElement, VDFInfo]]]:
991
+ ip_iters, slot_iters, slots = 0, 0, 0
992
+ after_challenge = False
993
+ to_validate = []
994
+ for idx, sub_slot_data in enumerate(segment.sub_slots):
995
+ if sampled and sub_slot_data.is_challenge():
996
+ after_challenge = True
997
+ required_iters = __validate_pospace(
998
+ constants, segment, idx, curr_difficulty, ses, first_segment_in_se, height
999
+ )
1000
+ if required_iters is None:
1001
+ return False, uint64(0), uint64(0), uint64(0), []
1002
+ assert sub_slot_data.signage_point_index is not None
1003
+ ip_iters = ip_iters + calculate_ip_iters(
1004
+ constants, curr_ssi, sub_slot_data.signage_point_index, required_iters
1005
+ )
1006
+ vdf_list = _get_challenge_block_vdfs(constants, idx, segment.sub_slots, curr_ssi)
1007
+ to_validate.extend(vdf_list)
1008
+ elif sampled and after_challenge:
1009
+ validated, vdf_list = _validate_sub_slot_data(constants, idx, segment.sub_slots, curr_ssi)
1010
+ if not validated:
1011
+ log.error(f"failed to validate sub slot data {idx} vdfs")
1012
+ return False, uint64(0), uint64(0), uint64(0), []
1013
+ to_validate.extend(vdf_list)
1014
+ slot_iters = slot_iters + curr_ssi
1015
+ slots = slots + uint64(1)
1016
+ return True, ip_iters, slot_iters, slots, to_validate
1017
+
1018
+
1019
+ def _get_challenge_block_vdfs(
1020
+ constants: ConsensusConstants,
1021
+ sub_slot_idx: int,
1022
+ sub_slots: List[SubSlotData],
1023
+ ssi: uint64,
1024
+ ) -> List[Tuple[VDFProof, ClassgroupElement, VDFInfo]]:
1025
+ to_validate = []
1026
+ sub_slot_data = sub_slots[sub_slot_idx]
1027
+ if sub_slot_data.cc_signage_point is not None and sub_slot_data.cc_sp_vdf_info:
1028
+ assert sub_slot_data.signage_point_index
1029
+ sp_input = ClassgroupElement.get_default_element()
1030
+ if not sub_slot_data.cc_signage_point.normalized_to_identity and sub_slot_idx >= 1:
1031
+ is_overflow = is_overflow_block(constants, sub_slot_data.signage_point_index)
1032
+ prev_ssd = sub_slots[sub_slot_idx - 1]
1033
+ sp_input = sub_slot_data_vdf_input(
1034
+ constants, sub_slot_data, sub_slot_idx, sub_slots, is_overflow, prev_ssd.is_end_of_slot(), ssi
1035
+ )
1036
+ to_validate.append((sub_slot_data.cc_signage_point, sp_input, sub_slot_data.cc_sp_vdf_info))
1037
+
1038
+ assert sub_slot_data.cc_infusion_point
1039
+ assert sub_slot_data.cc_ip_vdf_info
1040
+ ip_input = ClassgroupElement.get_default_element()
1041
+ cc_ip_vdf_info = sub_slot_data.cc_ip_vdf_info
1042
+ if not sub_slot_data.cc_infusion_point.normalized_to_identity and sub_slot_idx >= 1:
1043
+ prev_ssd = sub_slots[sub_slot_idx - 1]
1044
+ if prev_ssd.cc_slot_end is None:
1045
+ assert prev_ssd.cc_ip_vdf_info
1046
+ assert prev_ssd.total_iters
1047
+ assert sub_slot_data.total_iters
1048
+ ip_input = prev_ssd.cc_ip_vdf_info.output
1049
+ ip_vdf_iters = uint64(sub_slot_data.total_iters - prev_ssd.total_iters)
1050
+ cc_ip_vdf_info = VDFInfo(
1051
+ sub_slot_data.cc_ip_vdf_info.challenge, ip_vdf_iters, sub_slot_data.cc_ip_vdf_info.output
1052
+ )
1053
+ to_validate.append((sub_slot_data.cc_infusion_point, ip_input, cc_ip_vdf_info))
1054
+
1055
+ return to_validate
1056
+
1057
+
1058
+ def _validate_sub_slot_data(
1059
+ constants: ConsensusConstants,
1060
+ sub_slot_idx: int,
1061
+ sub_slots: List[SubSlotData],
1062
+ ssi: uint64,
1063
+ ) -> Tuple[bool, List[Tuple[VDFProof, ClassgroupElement, VDFInfo]]]:
1064
+ sub_slot_data = sub_slots[sub_slot_idx]
1065
+ assert sub_slot_idx > 0
1066
+ prev_ssd = sub_slots[sub_slot_idx - 1]
1067
+ to_validate = []
1068
+ if sub_slot_data.is_end_of_slot():
1069
+ if sub_slot_data.icc_slot_end is not None:
1070
+ input = ClassgroupElement.get_default_element()
1071
+ if not sub_slot_data.icc_slot_end.normalized_to_identity and prev_ssd.icc_ip_vdf_info is not None:
1072
+ assert prev_ssd.icc_ip_vdf_info
1073
+ input = prev_ssd.icc_ip_vdf_info.output
1074
+ assert sub_slot_data.icc_slot_end_info
1075
+ to_validate.append((sub_slot_data.icc_slot_end, input, sub_slot_data.icc_slot_end_info))
1076
+ assert sub_slot_data.cc_slot_end_info
1077
+ assert sub_slot_data.cc_slot_end
1078
+ input = ClassgroupElement.get_default_element()
1079
+ if (not prev_ssd.is_end_of_slot()) and (not sub_slot_data.cc_slot_end.normalized_to_identity):
1080
+ assert prev_ssd.cc_ip_vdf_info
1081
+ input = prev_ssd.cc_ip_vdf_info.output
1082
+ if not validate_vdf(sub_slot_data.cc_slot_end, constants, input, sub_slot_data.cc_slot_end_info):
1083
+ log.error(f"failed cc slot end validation {sub_slot_data.cc_slot_end_info}")
1084
+ return False, []
1085
+ else:
1086
+ # find end of slot
1087
+ idx = sub_slot_idx
1088
+ while idx < len(sub_slots) - 1:
1089
+ curr_slot = sub_slots[idx]
1090
+ if curr_slot.is_end_of_slot():
1091
+ # dont validate intermediate vdfs if slot is blue boxed
1092
+ assert curr_slot.cc_slot_end
1093
+ if curr_slot.cc_slot_end.normalized_to_identity is True:
1094
+ log.debug(f"skip intermediate vdfs slot {sub_slot_idx}")
1095
+ return True, to_validate
1096
+ else:
1097
+ break
1098
+ idx += 1
1099
+ if sub_slot_data.icc_infusion_point is not None and sub_slot_data.icc_ip_vdf_info is not None:
1100
+ input = ClassgroupElement.get_default_element()
1101
+ if not prev_ssd.is_challenge() and prev_ssd.icc_ip_vdf_info is not None:
1102
+ input = prev_ssd.icc_ip_vdf_info.output
1103
+ to_validate.append((sub_slot_data.icc_infusion_point, input, sub_slot_data.icc_ip_vdf_info))
1104
+ assert sub_slot_data.signage_point_index is not None
1105
+ if sub_slot_data.cc_signage_point:
1106
+ assert sub_slot_data.cc_sp_vdf_info
1107
+ input = ClassgroupElement.get_default_element()
1108
+ if not sub_slot_data.cc_signage_point.normalized_to_identity:
1109
+ is_overflow = is_overflow_block(constants, sub_slot_data.signage_point_index)
1110
+ input = sub_slot_data_vdf_input(
1111
+ constants, sub_slot_data, sub_slot_idx, sub_slots, is_overflow, prev_ssd.is_end_of_slot(), ssi
1112
+ )
1113
+ to_validate.append((sub_slot_data.cc_signage_point, input, sub_slot_data.cc_sp_vdf_info))
1114
+
1115
+ input = ClassgroupElement.get_default_element()
1116
+ assert sub_slot_data.cc_ip_vdf_info
1117
+ assert sub_slot_data.cc_infusion_point
1118
+ cc_ip_vdf_info = sub_slot_data.cc_ip_vdf_info
1119
+ if not sub_slot_data.cc_infusion_point.normalized_to_identity and prev_ssd.cc_slot_end is None:
1120
+ assert prev_ssd.cc_ip_vdf_info
1121
+ input = prev_ssd.cc_ip_vdf_info.output
1122
+ assert sub_slot_data.total_iters
1123
+ assert prev_ssd.total_iters
1124
+ ip_vdf_iters = uint64(sub_slot_data.total_iters - prev_ssd.total_iters)
1125
+ cc_ip_vdf_info = VDFInfo(
1126
+ sub_slot_data.cc_ip_vdf_info.challenge, ip_vdf_iters, sub_slot_data.cc_ip_vdf_info.output
1127
+ )
1128
+ to_validate.append((sub_slot_data.cc_infusion_point, input, cc_ip_vdf_info))
1129
+
1130
+ return True, to_validate
1131
+
1132
+
1133
+ def sub_slot_data_vdf_input(
1134
+ constants: ConsensusConstants,
1135
+ sub_slot_data: SubSlotData,
1136
+ sub_slot_idx: int,
1137
+ sub_slots: List[SubSlotData],
1138
+ is_overflow: bool,
1139
+ new_sub_slot: bool,
1140
+ ssi: uint64,
1141
+ ) -> ClassgroupElement:
1142
+ cc_input = ClassgroupElement.get_default_element()
1143
+ sp_total_iters = get_sp_total_iters(constants, is_overflow, ssi, sub_slot_data)
1144
+ ssd: Optional[SubSlotData] = None
1145
+ if is_overflow and new_sub_slot:
1146
+ if sub_slot_idx >= 2:
1147
+ if sub_slots[sub_slot_idx - 2].cc_slot_end_info is None:
1148
+ for ssd_idx in reversed(range(0, sub_slot_idx - 1)):
1149
+ ssd = sub_slots[ssd_idx]
1150
+ if ssd.cc_slot_end_info is not None:
1151
+ ssd = sub_slots[ssd_idx + 1]
1152
+ break
1153
+ assert ssd.total_iters is not None
1154
+ if not (ssd.total_iters > sp_total_iters):
1155
+ break
1156
+ if ssd and ssd.cc_ip_vdf_info is not None:
1157
+ assert ssd.total_iters is not None
1158
+ if ssd.total_iters < sp_total_iters:
1159
+ cc_input = ssd.cc_ip_vdf_info.output
1160
+ return cc_input
1161
+
1162
+ elif not is_overflow and not new_sub_slot:
1163
+ for ssd_idx in reversed(range(0, sub_slot_idx)):
1164
+ ssd = sub_slots[ssd_idx]
1165
+ if ssd.cc_slot_end_info is not None:
1166
+ ssd = sub_slots[ssd_idx + 1]
1167
+ break
1168
+ assert ssd.total_iters is not None
1169
+ if not (ssd.total_iters > sp_total_iters):
1170
+ break
1171
+ assert ssd is not None
1172
+ if ssd.cc_ip_vdf_info is not None:
1173
+ assert ssd.total_iters is not None
1174
+ if ssd.total_iters < sp_total_iters:
1175
+ cc_input = ssd.cc_ip_vdf_info.output
1176
+ return cc_input
1177
+
1178
+ elif not new_sub_slot and is_overflow:
1179
+ slots_seen = 0
1180
+ for ssd_idx in reversed(range(0, sub_slot_idx)):
1181
+ ssd = sub_slots[ssd_idx]
1182
+ if ssd.cc_slot_end_info is not None:
1183
+ slots_seen += 1
1184
+ if slots_seen == 2:
1185
+ return ClassgroupElement.get_default_element()
1186
+ if ssd.cc_slot_end_info is None:
1187
+ assert ssd.total_iters is not None
1188
+ if not (ssd.total_iters > sp_total_iters):
1189
+ break
1190
+ assert ssd is not None
1191
+ if ssd.cc_ip_vdf_info is not None:
1192
+ assert ssd.total_iters is not None
1193
+ if ssd.total_iters < sp_total_iters:
1194
+ cc_input = ssd.cc_ip_vdf_info.output
1195
+ return cc_input
1196
+
1197
+
1198
+ def validate_recent_blocks(
1199
+ constants: ConsensusConstants,
1200
+ recent_chain_bytes: bytes,
1201
+ summaries_bytes: List[bytes],
1202
+ shutdown_file_path: Optional[pathlib.Path] = None,
1203
+ ) -> Tuple[bool, List[bytes]]:
1204
+ recent_chain: RecentChainData = RecentChainData.from_bytes(recent_chain_bytes)
1205
+ summaries = summaries_from_bytes(summaries_bytes)
1206
+ sub_blocks = BlockCache({})
1207
+ first_ses_idx = _get_ses_idx(recent_chain.recent_chain_data)
1208
+ ses_idx = len(summaries) - len(first_ses_idx)
1209
+ ssi: uint64 = constants.SUB_SLOT_ITERS_STARTING
1210
+ diff: uint64 = constants.DIFFICULTY_STARTING
1211
+ last_blocks_to_validate = 100 # todo remove cap after benchmarks
1212
+ for summary in summaries[:ses_idx]:
1213
+ if summary.new_sub_slot_iters is not None:
1214
+ ssi = summary.new_sub_slot_iters
1215
+ if summary.new_difficulty is not None:
1216
+ diff = summary.new_difficulty
1217
+
1218
+ ses_blocks, sub_slots, transaction_blocks = 0, 0, 0
1219
+ challenge, prev_challenge = recent_chain.recent_chain_data[0].reward_chain_block.pos_ss_cc_challenge_hash, None
1220
+ tip_height = recent_chain.recent_chain_data[-1].height
1221
+ prev_block_record: Optional[BlockRecord] = None
1222
+ deficit = uint8(0)
1223
+ adjusted = False
1224
+ validated_block_count = 0
1225
+ for idx, block in enumerate(recent_chain.recent_chain_data):
1226
+ required_iters = uint64(0)
1227
+ overflow = False
1228
+ ses = False
1229
+ height = block.height
1230
+ for sub_slot in block.finished_sub_slots:
1231
+ prev_challenge = sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf.challenge
1232
+ challenge = sub_slot.challenge_chain.get_hash()
1233
+ deficit = sub_slot.reward_chain.deficit
1234
+ if sub_slot.challenge_chain.subepoch_summary_hash is not None:
1235
+ ses = True
1236
+ if summaries[ses_idx].get_hash() != sub_slot.challenge_chain.subepoch_summary_hash:
1237
+ log.info("sub epoch summary mismatch")
1238
+ return False, []
1239
+ ses_idx += 1
1240
+ if sub_slot.challenge_chain.new_sub_slot_iters is not None:
1241
+ ssi = sub_slot.challenge_chain.new_sub_slot_iters
1242
+ if sub_slot.challenge_chain.new_difficulty is not None:
1243
+ diff = sub_slot.challenge_chain.new_difficulty
1244
+
1245
+ if (challenge is not None) and (prev_challenge is not None):
1246
+ overflow = is_overflow_block(constants, block.reward_chain_block.signage_point_index)
1247
+ if not adjusted:
1248
+ assert prev_block_record is not None
1249
+ prev_block_record = prev_block_record.replace(
1250
+ deficit=uint8(deficit % constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK)
1251
+ )
1252
+ sub_blocks.add_block(prev_block_record)
1253
+ adjusted = True
1254
+ deficit = get_deficit(constants, deficit, prev_block_record, overflow, len(block.finished_sub_slots))
1255
+ if sub_slots > 2 and transaction_blocks > 11 and (tip_height - block.height < last_blocks_to_validate):
1256
+ caluclated_required_iters, error = validate_finished_header_block(
1257
+ constants, sub_blocks, block, False, diff, ssi, ses_blocks > 2
1258
+ )
1259
+ if error is not None:
1260
+ log.error(f"block {block.header_hash} failed validation {error}")
1261
+ return False, []
1262
+ assert caluclated_required_iters is not None
1263
+ required_iters = caluclated_required_iters
1264
+ else:
1265
+ ret = _validate_pospace_recent_chain(constants, block, challenge, diff, overflow, prev_challenge)
1266
+ if ret is None:
1267
+ return False, []
1268
+ required_iters = ret
1269
+ validated_block_count = validated_block_count + 1
1270
+
1271
+ curr_block_ses = None if not ses else summaries[ses_idx - 1]
1272
+ block_record = header_block_to_sub_block_record(
1273
+ constants, required_iters, block, ssi, overflow, deficit, height, curr_block_ses
1274
+ )
1275
+ log.debug(f"add block {block_record.height} to tmp sub blocks")
1276
+ sub_blocks.add_block(block_record)
1277
+
1278
+ if block.first_in_sub_slot:
1279
+ sub_slots += 1
1280
+ if block.is_transaction_block:
1281
+ transaction_blocks += 1
1282
+ if ses:
1283
+ ses_blocks += 1
1284
+ prev_block_record = block_record
1285
+
1286
+ if shutdown_file_path is not None and not shutdown_file_path.is_file():
1287
+ log.info(f"cancelling block {block.header_hash} validation, shutdown requested")
1288
+ return False, []
1289
+
1290
+ if len(summaries) > 2 and prev_challenge is None:
1291
+ log.info("did not find two challenges in recent chain")
1292
+ return False, []
1293
+
1294
+ if len(summaries) > 2 and validated_block_count < constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
1295
+ log.info("did not validate enough blocks in recent chain part")
1296
+ return False, []
1297
+
1298
+ return True, [bytes(sub) for sub in sub_blocks._block_records.values()]
1299
+
1300
+
1301
+ def _validate_pospace_recent_chain(
1302
+ constants: ConsensusConstants,
1303
+ block: HeaderBlock,
1304
+ challenge: bytes32,
1305
+ diff: uint64,
1306
+ overflow: bool,
1307
+ prev_challenge: bytes32,
1308
+ ) -> Optional[uint64]:
1309
+ if block.reward_chain_block.challenge_chain_sp_vdf is None:
1310
+ # Edge case of first sp (start of slot), where sp_iters == 0
1311
+ cc_sp_hash: bytes32 = challenge
1312
+ else:
1313
+ cc_sp_hash = block.reward_chain_block.challenge_chain_sp_vdf.output.get_hash()
1314
+ assert cc_sp_hash is not None
1315
+ q_str = verify_and_get_quality_string(
1316
+ block.reward_chain_block.proof_of_space,
1317
+ constants,
1318
+ challenge if not overflow else prev_challenge,
1319
+ cc_sp_hash,
1320
+ height=block.height,
1321
+ )
1322
+ if q_str is None:
1323
+ log.error(f"could not verify proof of space block {block.height} {overflow}")
1324
+ return None
1325
+ required_iters = calculate_iterations_quality(
1326
+ constants.DIFFICULTY_CONSTANT_FACTOR,
1327
+ q_str,
1328
+ block.reward_chain_block.proof_of_space.size,
1329
+ diff,
1330
+ cc_sp_hash,
1331
+ )
1332
+ return required_iters
1333
+
1334
+
1335
+ def __validate_pospace(
1336
+ constants: ConsensusConstants,
1337
+ segment: SubEpochChallengeSegment,
1338
+ idx: int,
1339
+ curr_diff: uint64,
1340
+ ses: Optional[SubEpochSummary],
1341
+ first_in_sub_epoch: bool,
1342
+ height: uint32,
1343
+ ) -> Optional[uint64]:
1344
+ if first_in_sub_epoch and segment.sub_epoch_n == 0 and idx == 0:
1345
+ cc_sub_slot_hash = constants.GENESIS_CHALLENGE
1346
+ else:
1347
+ cc_sub_slot_hash = __get_cc_sub_slot(segment.sub_slots, idx, ses).get_hash()
1348
+
1349
+ sub_slot_data: SubSlotData = segment.sub_slots[idx]
1350
+
1351
+ if sub_slot_data.signage_point_index and is_overflow_block(constants, sub_slot_data.signage_point_index):
1352
+ curr_slot = segment.sub_slots[idx - 1]
1353
+ assert curr_slot.cc_slot_end_info
1354
+ challenge = curr_slot.cc_slot_end_info.challenge
1355
+ else:
1356
+ challenge = cc_sub_slot_hash
1357
+
1358
+ if sub_slot_data.cc_sp_vdf_info is None:
1359
+ cc_sp_hash = cc_sub_slot_hash
1360
+ else:
1361
+ cc_sp_hash = sub_slot_data.cc_sp_vdf_info.output.get_hash()
1362
+
1363
+ # validate proof of space
1364
+ assert sub_slot_data.proof_of_space is not None
1365
+ q_str = verify_and_get_quality_string(
1366
+ sub_slot_data.proof_of_space,
1367
+ constants,
1368
+ challenge,
1369
+ cc_sp_hash,
1370
+ height=height,
1371
+ )
1372
+ if q_str is None:
1373
+ log.error("could not verify proof of space")
1374
+ return None
1375
+ return calculate_iterations_quality(
1376
+ constants.DIFFICULTY_CONSTANT_FACTOR,
1377
+ q_str,
1378
+ sub_slot_data.proof_of_space.size,
1379
+ curr_diff,
1380
+ cc_sp_hash,
1381
+ )
1382
+
1383
+
1384
+ def __get_rc_sub_slot(
1385
+ constants: ConsensusConstants,
1386
+ segment: SubEpochChallengeSegment,
1387
+ summaries: List[SubEpochSummary],
1388
+ curr_ssi: uint64,
1389
+ ) -> RewardChainSubSlot:
1390
+ ses = summaries[uint32(segment.sub_epoch_n - 1)]
1391
+ # find first challenge in sub epoch
1392
+ first_idx = None
1393
+ first = None
1394
+ for idx, curr in enumerate(segment.sub_slots):
1395
+ if curr.cc_slot_end is None:
1396
+ first_idx = idx
1397
+ first = curr
1398
+ break
1399
+
1400
+ assert first_idx
1401
+ idx = first_idx
1402
+ slots = segment.sub_slots
1403
+
1404
+ # number of slots to look for
1405
+ slots_n = 1
1406
+ assert first
1407
+ assert first.signage_point_index is not None
1408
+ if is_overflow_block(constants, first.signage_point_index):
1409
+ if idx >= 2 and slots[idx - 2].cc_slot_end is None:
1410
+ slots_n = 2
1411
+
1412
+ new_diff = None if ses is None else ses.new_difficulty
1413
+ new_ssi = None if ses is None else ses.new_sub_slot_iters
1414
+ ses_hash: Optional[bytes32] = None if ses is None else ses.get_hash()
1415
+ overflow = is_overflow_block(constants, first.signage_point_index)
1416
+ if overflow:
1417
+ if idx >= 2 and slots[idx - 2].cc_slot_end is not None and slots[idx - 1].cc_slot_end is not None:
1418
+ ses_hash = None
1419
+ new_ssi = None
1420
+ new_diff = None
1421
+
1422
+ sub_slot = slots[idx]
1423
+ while True:
1424
+ if sub_slot.cc_slot_end:
1425
+ slots_n -= 1
1426
+ if slots_n == 0:
1427
+ break
1428
+ idx -= 1
1429
+ sub_slot = slots[idx]
1430
+
1431
+ icc_sub_slot_hash: Optional[bytes32] = None
1432
+ assert sub_slot is not None
1433
+ assert sub_slot.cc_slot_end_info is not None
1434
+
1435
+ assert segment.rc_slot_end_info is not None
1436
+ if idx != 0:
1437
+ # this is not the first slot, ses details should not be included
1438
+ ses_hash = None
1439
+ new_ssi = None
1440
+ new_diff = None
1441
+ cc_vdf_info = VDFInfo(sub_slot.cc_slot_end_info.challenge, curr_ssi, sub_slot.cc_slot_end_info.output)
1442
+ if sub_slot.icc_slot_end_info is not None:
1443
+ icc_slot_end_info = VDFInfo(
1444
+ sub_slot.icc_slot_end_info.challenge, curr_ssi, sub_slot.icc_slot_end_info.output
1445
+ )
1446
+ icc_sub_slot_hash = icc_slot_end_info.get_hash()
1447
+ else:
1448
+ cc_vdf_info = sub_slot.cc_slot_end_info
1449
+ if sub_slot.icc_slot_end_info is not None:
1450
+ icc_sub_slot_hash = sub_slot.icc_slot_end_info.get_hash()
1451
+ cc_sub_slot = ChallengeChainSubSlot(
1452
+ cc_vdf_info,
1453
+ icc_sub_slot_hash,
1454
+ ses_hash,
1455
+ new_ssi,
1456
+ new_diff,
1457
+ )
1458
+
1459
+ rc_sub_slot = RewardChainSubSlot(
1460
+ segment.rc_slot_end_info,
1461
+ cc_sub_slot.get_hash(),
1462
+ icc_sub_slot_hash,
1463
+ constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK,
1464
+ )
1465
+ return rc_sub_slot
1466
+
1467
+
1468
+ def __get_cc_sub_slot(sub_slots: List[SubSlotData], idx: int, ses: Optional[SubEpochSummary]) -> ChallengeChainSubSlot:
1469
+ sub_slot: Optional[SubSlotData] = None
1470
+ for i in reversed(range(0, idx)):
1471
+ sub_slot = sub_slots[i]
1472
+ if sub_slot.cc_slot_end_info is not None:
1473
+ break
1474
+
1475
+ assert sub_slot is not None
1476
+ assert sub_slot.cc_slot_end_info is not None
1477
+
1478
+ icc_vdf = sub_slot.icc_slot_end_info
1479
+ icc_vdf_hash: Optional[bytes32] = None
1480
+ if icc_vdf is not None:
1481
+ icc_vdf_hash = icc_vdf.get_hash()
1482
+ cc_sub_slot = ChallengeChainSubSlot(
1483
+ sub_slot.cc_slot_end_info,
1484
+ icc_vdf_hash,
1485
+ None if ses is None else ses.get_hash(),
1486
+ None if ses is None else ses.new_sub_slot_iters,
1487
+ None if ses is None else ses.new_difficulty,
1488
+ )
1489
+
1490
+ return cc_sub_slot
1491
+
1492
+
1493
+ def _get_curr_diff_ssi(
1494
+ constants: ConsensusConstants, idx: int, summaries: List[SubEpochSummary]
1495
+ ) -> Tuple[uint64, uint64]:
1496
+ curr_difficulty = constants.DIFFICULTY_STARTING
1497
+ curr_ssi = constants.SUB_SLOT_ITERS_STARTING
1498
+ for ses in reversed(summaries[0:idx]):
1499
+ if ses.new_sub_slot_iters is not None:
1500
+ curr_ssi = ses.new_sub_slot_iters
1501
+ assert ses.new_difficulty is not None
1502
+ curr_difficulty = ses.new_difficulty
1503
+ break
1504
+
1505
+ return curr_difficulty, curr_ssi
1506
+
1507
+
1508
+ def vars_to_bytes(summaries: List[SubEpochSummary], weight_proof: WeightProof) -> Tuple[List[bytes], bytes, bytes]:
1509
+ wp_recent_chain_bytes = bytes(RecentChainData(weight_proof.recent_chain_data))
1510
+ wp_segment_bytes = bytes(SubEpochSegments(weight_proof.sub_epoch_segments))
1511
+ summary_bytes = []
1512
+ for summary in summaries:
1513
+ summary_bytes.append(bytes(summary))
1514
+ return summary_bytes, wp_segment_bytes, wp_recent_chain_bytes
1515
+
1516
+
1517
+ def summaries_from_bytes(summaries_bytes: List[bytes]) -> List[SubEpochSummary]:
1518
+ summaries = []
1519
+ for summary in summaries_bytes:
1520
+ summaries.append(SubEpochSummary.from_bytes(summary))
1521
+ return summaries
1522
+
1523
+
1524
+ def _get_last_ses_hash(
1525
+ constants: ConsensusConstants, recent_reward_chain: List[HeaderBlock]
1526
+ ) -> Tuple[Optional[bytes32], uint32]:
1527
+ for idx, block in enumerate(reversed(recent_reward_chain)):
1528
+ if (block.reward_chain_block.height % constants.SUB_EPOCH_BLOCKS) == 0:
1529
+ idx = len(recent_reward_chain) - 1 - idx # reverse
1530
+ # find first block after sub slot end
1531
+ while idx < len(recent_reward_chain):
1532
+ curr = recent_reward_chain[idx]
1533
+ if len(curr.finished_sub_slots) > 0:
1534
+ for slot in curr.finished_sub_slots:
1535
+ if slot.challenge_chain.subepoch_summary_hash is not None:
1536
+ return (
1537
+ slot.challenge_chain.subepoch_summary_hash,
1538
+ curr.reward_chain_block.height,
1539
+ )
1540
+ idx += 1
1541
+ return None, uint32(0)
1542
+
1543
+
1544
+ def _get_ses_idx(recent_reward_chain: List[HeaderBlock]) -> List[int]:
1545
+ idxs: List[int] = []
1546
+ for idx, curr in enumerate(recent_reward_chain):
1547
+ if len(curr.finished_sub_slots) > 0:
1548
+ for slot in curr.finished_sub_slots:
1549
+ if slot.challenge_chain.subepoch_summary_hash is not None:
1550
+ idxs.append(idx)
1551
+ return idxs
1552
+
1553
+
1554
+ def get_deficit(
1555
+ constants: ConsensusConstants,
1556
+ curr_deficit: uint8,
1557
+ prev_block: Optional[BlockRecord],
1558
+ overflow: bool,
1559
+ num_finished_sub_slots: int,
1560
+ ) -> uint8:
1561
+ if prev_block is None:
1562
+ if curr_deficit >= 1 and not (overflow and curr_deficit == constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK):
1563
+ curr_deficit = uint8(curr_deficit - 1)
1564
+ return curr_deficit
1565
+
1566
+ return calculate_deficit(constants, uint32(prev_block.height + 1), prev_block, overflow, num_finished_sub_slots)
1567
+
1568
+
1569
+ def get_sp_total_iters(
1570
+ constants: ConsensusConstants, is_overflow: bool, ssi: uint64, sub_slot_data: SubSlotData
1571
+ ) -> int:
1572
+ assert sub_slot_data.cc_ip_vdf_info is not None
1573
+ assert sub_slot_data.total_iters is not None
1574
+ assert sub_slot_data.signage_point_index is not None
1575
+ sp_iters = calculate_sp_iters(constants, ssi, sub_slot_data.signage_point_index)
1576
+ ip_iters = sub_slot_data.cc_ip_vdf_info.number_of_iterations
1577
+ sp_sub_slot_total_iters = uint128(sub_slot_data.total_iters - ip_iters)
1578
+ if is_overflow:
1579
+ sp_sub_slot_total_iters = uint128(sp_sub_slot_total_iters - ssi)
1580
+ return sp_sub_slot_total_iters + sp_iters
1581
+
1582
+
1583
+ def blue_boxed_end_of_slot(sub_slot: EndOfSubSlotBundle) -> bool:
1584
+ if sub_slot.proofs.challenge_chain_slot_proof.normalized_to_identity:
1585
+ if sub_slot.proofs.infused_challenge_chain_slot_proof is not None:
1586
+ if sub_slot.proofs.infused_challenge_chain_slot_proof.normalized_to_identity:
1587
+ return True
1588
+ else:
1589
+ return True
1590
+ return False
1591
+
1592
+
1593
+ def validate_sub_epoch_sampling(
1594
+ rng: random.Random, sub_epoch_weight_list: List[uint128], weight_proof: WeightProof
1595
+ ) -> bool:
1596
+ tip = weight_proof.recent_chain_data[-1]
1597
+ weight_to_check = _get_weights_for_sampling(rng, tip.weight, weight_proof.recent_chain_data)
1598
+ sampled_sub_epochs: Dict[int, bool] = {}
1599
+ for idx in range(1, len(sub_epoch_weight_list)):
1600
+ if _sample_sub_epoch(sub_epoch_weight_list[idx - 1], sub_epoch_weight_list[idx], weight_to_check):
1601
+ sampled_sub_epochs[idx - 1] = True
1602
+ if len(sampled_sub_epochs) == WeightProofHandler.MAX_SAMPLES:
1603
+ break
1604
+ curr_sub_epoch_n = -1
1605
+ for sub_epoch_segment in weight_proof.sub_epoch_segments:
1606
+ if curr_sub_epoch_n < sub_epoch_segment.sub_epoch_n:
1607
+ if sub_epoch_segment.sub_epoch_n in sampled_sub_epochs:
1608
+ del sampled_sub_epochs[sub_epoch_segment.sub_epoch_n]
1609
+ curr_sub_epoch_n = sub_epoch_segment.sub_epoch_n
1610
+ if len(sampled_sub_epochs) > 0:
1611
+ return False
1612
+ return True
1613
+
1614
+
1615
+ def map_segments_by_sub_epoch(
1616
+ sub_epoch_segments: List[SubEpochChallengeSegment],
1617
+ ) -> Dict[int, List[SubEpochChallengeSegment]]:
1618
+ segments: Dict[int, List[SubEpochChallengeSegment]] = {}
1619
+ curr_sub_epoch_n = -1
1620
+ for idx, segment in enumerate(sub_epoch_segments):
1621
+ if curr_sub_epoch_n < segment.sub_epoch_n:
1622
+ curr_sub_epoch_n = segment.sub_epoch_n
1623
+ segments[curr_sub_epoch_n] = []
1624
+ segments[curr_sub_epoch_n].append(segment)
1625
+ return segments
1626
+
1627
+
1628
+ def _validate_vdf_batch(
1629
+ constants: ConsensusConstants,
1630
+ vdf_list: List[Tuple[bytes, bytes, bytes]],
1631
+ shutdown_file_path: Optional[pathlib.Path] = None,
1632
+ ) -> bool:
1633
+ for vdf_proof_bytes, class_group_bytes, info in vdf_list:
1634
+ vdf = VDFProof.from_bytes(vdf_proof_bytes)
1635
+ class_group = ClassgroupElement.create(class_group_bytes)
1636
+ vdf_info = VDFInfo.from_bytes(info)
1637
+ if not validate_vdf(vdf, constants, class_group, vdf_info):
1638
+ return False
1639
+
1640
+ if shutdown_file_path is not None and not shutdown_file_path.is_file():
1641
+ log.info("cancelling VDF validation, shutdown requested")
1642
+ return False
1643
+
1644
+ return True
1645
+
1646
+
1647
+ async def validate_weight_proof_inner(
1648
+ constants: ConsensusConstants,
1649
+ executor: ProcessPoolExecutor,
1650
+ shutdown_file_name: str,
1651
+ num_processes: int,
1652
+ weight_proof: WeightProof,
1653
+ summaries: List[SubEpochSummary],
1654
+ sub_epoch_weight_list: List[uint128],
1655
+ skip_segment_validation: bool,
1656
+ validate_from: int,
1657
+ ) -> Tuple[bool, List[BlockRecord]]:
1658
+ assert len(weight_proof.sub_epochs) > 0
1659
+ if len(weight_proof.sub_epochs) == 0:
1660
+ return False, []
1661
+
1662
+ peak_height = weight_proof.recent_chain_data[-1].reward_chain_block.height
1663
+ log.info(f"validate weight proof peak height {peak_height}")
1664
+ seed = summaries[-2].get_hash()
1665
+ rng = random.Random(seed)
1666
+ if not validate_sub_epoch_sampling(rng, sub_epoch_weight_list, weight_proof):
1667
+ log.error("failed weight proof sub epoch sample validation")
1668
+ return False, []
1669
+
1670
+ loop = asyncio.get_running_loop()
1671
+ summary_bytes, wp_segment_bytes, wp_recent_chain_bytes = vars_to_bytes(summaries, weight_proof)
1672
+ recent_blocks_validation_task = loop.run_in_executor(
1673
+ executor,
1674
+ validate_recent_blocks,
1675
+ constants,
1676
+ wp_recent_chain_bytes,
1677
+ summary_bytes,
1678
+ pathlib.Path(shutdown_file_name),
1679
+ )
1680
+
1681
+ if not skip_segment_validation:
1682
+ vdfs_to_validate = _validate_sub_epoch_segments(
1683
+ constants, rng, wp_segment_bytes, summary_bytes, peak_height, validate_from
1684
+ )
1685
+ await asyncio.sleep(0) # break up otherwise multi-second sync code
1686
+
1687
+ if vdfs_to_validate is None:
1688
+ return False, []
1689
+
1690
+ vdf_tasks = []
1691
+ for batch in to_batches(vdfs_to_validate, num_processes):
1692
+ byte_chunks = []
1693
+ for vdf_proof, classgroup, vdf_info in batch.entries:
1694
+ byte_chunks.append((bytes(vdf_proof), bytes(classgroup), bytes(vdf_info)))
1695
+ vdf_task = asyncio.get_running_loop().run_in_executor(
1696
+ executor,
1697
+ _validate_vdf_batch,
1698
+ constants,
1699
+ byte_chunks,
1700
+ pathlib.Path(shutdown_file_name),
1701
+ )
1702
+ vdf_tasks.append(vdf_task)
1703
+ # give other stuff a turn
1704
+ await asyncio.sleep(0)
1705
+
1706
+ for vdf_task in asyncio.as_completed(fs=vdf_tasks):
1707
+ validated = await vdf_task
1708
+ if not validated:
1709
+ return False, []
1710
+
1711
+ valid_recent_blocks, records_bytes = await recent_blocks_validation_task
1712
+
1713
+ if not valid_recent_blocks or records_bytes is None:
1714
+ log.error("failed validating weight proof recent blocks")
1715
+ # Verify the data
1716
+ return False, []
1717
+
1718
+ records = [BlockRecord.from_bytes(b) for b in records_bytes]
1719
+ return True, records