chia-blockchain 2.5.1rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1042) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +195 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +145 -0
  9. chia/_tests/blockchain/test_blockchain.py +4202 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
  11. chia/_tests/blockchain/test_build_chains.py +59 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
  14. chia/_tests/build-init-files.py +92 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +72 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +149 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +55 -0
  26. chia/_tests/clvm/test_message_conditions.py +184 -0
  27. chia/_tests/clvm/test_program.py +150 -0
  28. chia/_tests/clvm/test_puzzle_compression.py +143 -0
  29. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  30. chia/_tests/clvm/test_puzzles.py +242 -0
  31. chia/_tests/clvm/test_singletons.py +540 -0
  32. chia/_tests/clvm/test_spend_sim.py +181 -0
  33. chia/_tests/cmds/__init__.py +0 -0
  34. chia/_tests/cmds/cmd_test_utils.py +469 -0
  35. chia/_tests/cmds/config.py +3 -0
  36. chia/_tests/cmds/conftest.py +23 -0
  37. chia/_tests/cmds/test_click_types.py +200 -0
  38. chia/_tests/cmds/test_cmd_framework.py +620 -0
  39. chia/_tests/cmds/test_cmds_util.py +97 -0
  40. chia/_tests/cmds/test_daemon.py +92 -0
  41. chia/_tests/cmds/test_dev_gh.py +131 -0
  42. chia/_tests/cmds/test_farm_cmd.py +66 -0
  43. chia/_tests/cmds/test_show.py +116 -0
  44. chia/_tests/cmds/test_sim.py +207 -0
  45. chia/_tests/cmds/test_timelock_args.py +75 -0
  46. chia/_tests/cmds/test_tx_config_args.py +154 -0
  47. chia/_tests/cmds/testing_classes.py +59 -0
  48. chia/_tests/cmds/wallet/__init__.py +0 -0
  49. chia/_tests/cmds/wallet/test_consts.py +47 -0
  50. chia/_tests/cmds/wallet/test_dao.py +565 -0
  51. chia/_tests/cmds/wallet/test_did.py +403 -0
  52. chia/_tests/cmds/wallet/test_nft.py +471 -0
  53. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  54. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  55. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  56. chia/_tests/cmds/wallet/test_vcs.py +400 -0
  57. chia/_tests/cmds/wallet/test_wallet.py +1125 -0
  58. chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
  59. chia/_tests/conftest.py +1419 -0
  60. chia/_tests/connection_utils.py +125 -0
  61. chia/_tests/core/__init__.py +0 -0
  62. chia/_tests/core/cmds/__init__.py +0 -0
  63. chia/_tests/core/cmds/test_beta.py +382 -0
  64. chia/_tests/core/cmds/test_keys.py +1734 -0
  65. chia/_tests/core/cmds/test_wallet.py +126 -0
  66. chia/_tests/core/config.py +3 -0
  67. chia/_tests/core/consensus/__init__.py +0 -0
  68. chia/_tests/core/consensus/test_block_creation.py +54 -0
  69. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  70. chia/_tests/core/custom_types/__init__.py +0 -0
  71. chia/_tests/core/custom_types/test_coin.py +107 -0
  72. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  73. chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
  74. chia/_tests/core/daemon/__init__.py +0 -0
  75. chia/_tests/core/daemon/config.py +4 -0
  76. chia/_tests/core/daemon/test_daemon.py +2128 -0
  77. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  78. chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
  79. chia/_tests/core/data_layer/__init__.py +0 -0
  80. chia/_tests/core/data_layer/config.py +5 -0
  81. chia/_tests/core/data_layer/conftest.py +106 -0
  82. chia/_tests/core/data_layer/test_data_cli.py +56 -0
  83. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  84. chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
  85. chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
  86. chia/_tests/core/data_layer/test_data_store.py +2424 -0
  87. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  88. chia/_tests/core/data_layer/test_plugin.py +91 -0
  89. chia/_tests/core/data_layer/util.py +233 -0
  90. chia/_tests/core/farmer/__init__.py +0 -0
  91. chia/_tests/core/farmer/config.py +3 -0
  92. chia/_tests/core/farmer/test_farmer_api.py +103 -0
  93. chia/_tests/core/full_node/__init__.py +0 -0
  94. chia/_tests/core/full_node/config.py +4 -0
  95. chia/_tests/core/full_node/dos/__init__.py +0 -0
  96. chia/_tests/core/full_node/dos/config.py +3 -0
  97. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  98. chia/_tests/core/full_node/full_sync/config.py +4 -0
  99. chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
  100. chia/_tests/core/full_node/ram_db.py +27 -0
  101. chia/_tests/core/full_node/stores/__init__.py +0 -0
  102. chia/_tests/core/full_node/stores/config.py +4 -0
  103. chia/_tests/core/full_node/stores/test_block_store.py +590 -0
  104. chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
  105. chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
  106. chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
  107. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  108. chia/_tests/core/full_node/test_address_manager.py +588 -0
  109. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  110. chia/_tests/core/full_node/test_conditions.py +556 -0
  111. chia/_tests/core/full_node/test_full_node.py +2700 -0
  112. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  113. chia/_tests/core/full_node/test_hint_management.py +104 -0
  114. chia/_tests/core/full_node/test_node_load.py +34 -0
  115. chia/_tests/core/full_node/test_performance.py +179 -0
  116. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  117. chia/_tests/core/full_node/test_transactions.py +203 -0
  118. chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
  119. chia/_tests/core/large_block.py +2388 -0
  120. chia/_tests/core/make_block_generator.py +70 -0
  121. chia/_tests/core/mempool/__init__.py +0 -0
  122. chia/_tests/core/mempool/config.py +4 -0
  123. chia/_tests/core/mempool/test_mempool.py +3255 -0
  124. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  125. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  126. chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
  127. chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
  128. chia/_tests/core/mempool/test_mempool_performance.py +64 -0
  129. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  130. chia/_tests/core/node_height.py +28 -0
  131. chia/_tests/core/server/__init__.py +0 -0
  132. chia/_tests/core/server/config.py +3 -0
  133. chia/_tests/core/server/flood.py +84 -0
  134. chia/_tests/core/server/serve.py +135 -0
  135. chia/_tests/core/server/test_api_protocol.py +21 -0
  136. chia/_tests/core/server/test_capabilities.py +66 -0
  137. chia/_tests/core/server/test_dos.py +319 -0
  138. chia/_tests/core/server/test_event_loop.py +109 -0
  139. chia/_tests/core/server/test_loop.py +294 -0
  140. chia/_tests/core/server/test_node_discovery.py +73 -0
  141. chia/_tests/core/server/test_rate_limits.py +482 -0
  142. chia/_tests/core/server/test_server.py +226 -0
  143. chia/_tests/core/server/test_upnp.py +8 -0
  144. chia/_tests/core/services/__init__.py +0 -0
  145. chia/_tests/core/services/config.py +3 -0
  146. chia/_tests/core/services/test_services.py +188 -0
  147. chia/_tests/core/ssl/__init__.py +0 -0
  148. chia/_tests/core/ssl/config.py +3 -0
  149. chia/_tests/core/ssl/test_ssl.py +202 -0
  150. chia/_tests/core/test_coins.py +33 -0
  151. chia/_tests/core/test_cost_calculation.py +313 -0
  152. chia/_tests/core/test_crawler.py +175 -0
  153. chia/_tests/core/test_crawler_rpc.py +53 -0
  154. chia/_tests/core/test_daemon_rpc.py +24 -0
  155. chia/_tests/core/test_db_conversion.py +130 -0
  156. chia/_tests/core/test_db_validation.py +162 -0
  157. chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
  158. chia/_tests/core/test_filter.py +35 -0
  159. chia/_tests/core/test_full_node_rpc.py +768 -0
  160. chia/_tests/core/test_merkle_set.py +343 -0
  161. chia/_tests/core/test_program.py +47 -0
  162. chia/_tests/core/test_rpc_util.py +86 -0
  163. chia/_tests/core/test_seeder.py +420 -0
  164. chia/_tests/core/test_setproctitle.py +13 -0
  165. chia/_tests/core/util/__init__.py +0 -0
  166. chia/_tests/core/util/config.py +4 -0
  167. chia/_tests/core/util/test_block_cache.py +44 -0
  168. chia/_tests/core/util/test_cached_bls.py +57 -0
  169. chia/_tests/core/util/test_config.py +337 -0
  170. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  171. chia/_tests/core/util/test_files.py +391 -0
  172. chia/_tests/core/util/test_jsonify.py +146 -0
  173. chia/_tests/core/util/test_keychain.py +522 -0
  174. chia/_tests/core/util/test_keyring_wrapper.py +491 -0
  175. chia/_tests/core/util/test_lockfile.py +380 -0
  176. chia/_tests/core/util/test_log_exceptions.py +187 -0
  177. chia/_tests/core/util/test_lru_cache.py +56 -0
  178. chia/_tests/core/util/test_significant_bits.py +40 -0
  179. chia/_tests/core/util/test_streamable.py +883 -0
  180. chia/_tests/db/__init__.py +0 -0
  181. chia/_tests/db/test_db_wrapper.py +566 -0
  182. chia/_tests/environments/__init__.py +0 -0
  183. chia/_tests/environments/common.py +35 -0
  184. chia/_tests/environments/full_node.py +47 -0
  185. chia/_tests/environments/wallet.py +429 -0
  186. chia/_tests/ether.py +19 -0
  187. chia/_tests/farmer_harvester/__init__.py +0 -0
  188. chia/_tests/farmer_harvester/config.py +3 -0
  189. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  190. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  191. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
  192. chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
  193. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  194. chia/_tests/fee_estimation/__init__.py +0 -0
  195. chia/_tests/fee_estimation/config.py +3 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  197. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  198. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
  199. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  200. chia/_tests/generator/__init__.py +0 -0
  201. chia/_tests/generator/puzzles/__init__.py +0 -0
  202. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  203. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  204. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  205. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  206. chia/_tests/generator/test_compression.py +201 -0
  207. chia/_tests/generator/test_generator_types.py +44 -0
  208. chia/_tests/generator/test_rom.py +180 -0
  209. chia/_tests/plot_sync/__init__.py +0 -0
  210. chia/_tests/plot_sync/config.py +3 -0
  211. chia/_tests/plot_sync/test_delta.py +101 -0
  212. chia/_tests/plot_sync/test_plot_sync.py +618 -0
  213. chia/_tests/plot_sync/test_receiver.py +451 -0
  214. chia/_tests/plot_sync/test_sender.py +116 -0
  215. chia/_tests/plot_sync/test_sync_simulated.py +451 -0
  216. chia/_tests/plot_sync/util.py +68 -0
  217. chia/_tests/plotting/__init__.py +0 -0
  218. chia/_tests/plotting/config.py +3 -0
  219. chia/_tests/plotting/test_plot_manager.py +781 -0
  220. chia/_tests/plotting/util.py +12 -0
  221. chia/_tests/pools/__init__.py +0 -0
  222. chia/_tests/pools/config.py +5 -0
  223. chia/_tests/pools/test_pool_cli_parsing.py +128 -0
  224. chia/_tests/pools/test_pool_cmdline.py +1001 -0
  225. chia/_tests/pools/test_pool_config.py +42 -0
  226. chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
  227. chia/_tests/pools/test_pool_rpc.py +1123 -0
  228. chia/_tests/pools/test_pool_wallet.py +205 -0
  229. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  230. chia/_tests/process_junit.py +348 -0
  231. chia/_tests/rpc/__init__.py +0 -0
  232. chia/_tests/rpc/test_rpc_client.py +138 -0
  233. chia/_tests/rpc/test_rpc_server.py +183 -0
  234. chia/_tests/simulation/__init__.py +0 -0
  235. chia/_tests/simulation/config.py +6 -0
  236. chia/_tests/simulation/test_simulation.py +501 -0
  237. chia/_tests/simulation/test_simulator.py +232 -0
  238. chia/_tests/simulation/test_start_simulator.py +107 -0
  239. chia/_tests/testconfig.py +13 -0
  240. chia/_tests/timelord/__init__.py +0 -0
  241. chia/_tests/timelord/config.py +3 -0
  242. chia/_tests/timelord/test_new_peak.py +437 -0
  243. chia/_tests/timelord/test_timelord.py +11 -0
  244. chia/_tests/tools/1315537.json +170 -0
  245. chia/_tests/tools/1315544.json +160 -0
  246. chia/_tests/tools/1315630.json +150 -0
  247. chia/_tests/tools/300000.json +105 -0
  248. chia/_tests/tools/442734.json +140 -0
  249. chia/_tests/tools/466212.json +130 -0
  250. chia/_tests/tools/__init__.py +0 -0
  251. chia/_tests/tools/config.py +5 -0
  252. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  253. chia/_tests/tools/test_full_sync.py +30 -0
  254. chia/_tests/tools/test_legacy_keyring.py +82 -0
  255. chia/_tests/tools/test_run_block.py +128 -0
  256. chia/_tests/tools/test_virtual_project.py +591 -0
  257. chia/_tests/util/__init__.py +0 -0
  258. chia/_tests/util/benchmark_cost.py +170 -0
  259. chia/_tests/util/benchmarks.py +153 -0
  260. chia/_tests/util/bip39_test_vectors.json +148 -0
  261. chia/_tests/util/blockchain.py +134 -0
  262. chia/_tests/util/blockchain_mock.py +132 -0
  263. chia/_tests/util/build_network_protocol_files.py +302 -0
  264. chia/_tests/util/clvm_generator.bin +0 -0
  265. chia/_tests/util/config.py +3 -0
  266. chia/_tests/util/constants.py +20 -0
  267. chia/_tests/util/db_connection.py +37 -0
  268. chia/_tests/util/full_sync.py +253 -0
  269. chia/_tests/util/gen_ssl_certs.py +114 -0
  270. chia/_tests/util/generator_tools_testing.py +45 -0
  271. chia/_tests/util/get_name_puzzle_conditions.py +52 -0
  272. chia/_tests/util/key_tool.py +36 -0
  273. chia/_tests/util/misc.py +675 -0
  274. chia/_tests/util/network_protocol_data.py +1072 -0
  275. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  276. chia/_tests/util/protocol_messages_json.py +2701 -0
  277. chia/_tests/util/rpc.py +26 -0
  278. chia/_tests/util/run_block.py +163 -0
  279. chia/_tests/util/setup_nodes.py +481 -0
  280. chia/_tests/util/spend_sim.py +492 -0
  281. chia/_tests/util/split_managers.py +102 -0
  282. chia/_tests/util/temp_file.py +14 -0
  283. chia/_tests/util/test_action_scope.py +144 -0
  284. chia/_tests/util/test_async_pool.py +366 -0
  285. chia/_tests/util/test_build_job_matrix.py +42 -0
  286. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  287. chia/_tests/util/test_chia_version.py +50 -0
  288. chia/_tests/util/test_collection.py +11 -0
  289. chia/_tests/util/test_condition_tools.py +229 -0
  290. chia/_tests/util/test_config.py +426 -0
  291. chia/_tests/util/test_dump_keyring.py +60 -0
  292. chia/_tests/util/test_errors.py +10 -0
  293. chia/_tests/util/test_full_block_utils.py +279 -0
  294. chia/_tests/util/test_installed.py +20 -0
  295. chia/_tests/util/test_limited_semaphore.py +53 -0
  296. chia/_tests/util/test_logging_filter.py +42 -0
  297. chia/_tests/util/test_misc.py +445 -0
  298. chia/_tests/util/test_network.py +73 -0
  299. chia/_tests/util/test_network_protocol_files.py +578 -0
  300. chia/_tests/util/test_network_protocol_json.py +267 -0
  301. chia/_tests/util/test_network_protocol_test.py +256 -0
  302. chia/_tests/util/test_paginator.py +71 -0
  303. chia/_tests/util/test_pprint.py +17 -0
  304. chia/_tests/util/test_priority_mutex.py +488 -0
  305. chia/_tests/util/test_recursive_replace.py +116 -0
  306. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  307. chia/_tests/util/test_service_groups.py +15 -0
  308. chia/_tests/util/test_ssl_check.py +31 -0
  309. chia/_tests/util/test_testnet_overrides.py +19 -0
  310. chia/_tests/util/test_tests_misc.py +38 -0
  311. chia/_tests/util/test_timing.py +37 -0
  312. chia/_tests/util/test_trusted_peer.py +51 -0
  313. chia/_tests/util/time_out_assert.py +191 -0
  314. chia/_tests/wallet/__init__.py +0 -0
  315. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  316. chia/_tests/wallet/cat_wallet/config.py +4 -0
  317. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  318. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  319. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
  320. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  321. chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
  322. chia/_tests/wallet/clawback/__init__.py +0 -0
  323. chia/_tests/wallet/clawback/config.py +3 -0
  324. chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
  325. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  326. chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
  327. chia/_tests/wallet/config.py +4 -0
  328. chia/_tests/wallet/conftest.py +278 -0
  329. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  330. chia/_tests/wallet/dao_wallet/config.py +3 -0
  331. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
  332. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  333. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  334. chia/_tests/wallet/db_wallet/config.py +3 -0
  335. chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
  336. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  337. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  338. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  339. chia/_tests/wallet/did_wallet/config.py +4 -0
  340. chia/_tests/wallet/did_wallet/test_did.py +2284 -0
  341. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  342. chia/_tests/wallet/nft_wallet/config.py +4 -0
  343. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
  344. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
  345. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
  346. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  347. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  348. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
  349. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  350. chia/_tests/wallet/rpc/__init__.py +0 -0
  351. chia/_tests/wallet/rpc/config.py +4 -0
  352. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
  353. chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
  354. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  355. chia/_tests/wallet/simple_sync/config.py +3 -0
  356. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
  357. chia/_tests/wallet/sync/__init__.py +0 -0
  358. chia/_tests/wallet/sync/config.py +4 -0
  359. chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
  360. chia/_tests/wallet/test_address_type.py +189 -0
  361. chia/_tests/wallet/test_bech32m.py +45 -0
  362. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  363. chia/_tests/wallet/test_coin_management.py +354 -0
  364. chia/_tests/wallet/test_coin_selection.py +588 -0
  365. chia/_tests/wallet/test_conditions.py +400 -0
  366. chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
  367. chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
  368. chia/_tests/wallet/test_nft_store.py +192 -0
  369. chia/_tests/wallet/test_notifications.py +196 -0
  370. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  371. chia/_tests/wallet/test_puzzle_store.py +132 -0
  372. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  373. chia/_tests/wallet/test_signer_protocol.py +947 -0
  374. chia/_tests/wallet/test_singleton.py +122 -0
  375. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  376. chia/_tests/wallet/test_singleton_store.py +152 -0
  377. chia/_tests/wallet/test_taproot.py +19 -0
  378. chia/_tests/wallet/test_transaction_store.py +945 -0
  379. chia/_tests/wallet/test_util.py +185 -0
  380. chia/_tests/wallet/test_wallet.py +2139 -0
  381. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  382. chia/_tests/wallet/test_wallet_blockchain.py +111 -0
  383. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  384. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  385. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  386. chia/_tests/wallet/test_wallet_node.py +780 -0
  387. chia/_tests/wallet/test_wallet_retry.py +95 -0
  388. chia/_tests/wallet/test_wallet_state_manager.py +259 -0
  389. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  390. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  391. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  392. chia/_tests/wallet/test_wallet_utils.py +156 -0
  393. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  394. chia/_tests/wallet/vc_wallet/config.py +3 -0
  395. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  396. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  397. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
  398. chia/_tests/wallet/wallet_block_tools.py +327 -0
  399. chia/_tests/weight_proof/__init__.py +0 -0
  400. chia/_tests/weight_proof/config.py +3 -0
  401. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  402. chia/apis.py +19 -0
  403. chia/clvm/__init__.py +0 -0
  404. chia/cmds/__init__.py +0 -0
  405. chia/cmds/beta.py +184 -0
  406. chia/cmds/beta_funcs.py +137 -0
  407. chia/cmds/check_wallet_db.py +420 -0
  408. chia/cmds/chia.py +151 -0
  409. chia/cmds/cmd_classes.py +323 -0
  410. chia/cmds/cmd_helpers.py +242 -0
  411. chia/cmds/cmds_util.py +488 -0
  412. chia/cmds/coin_funcs.py +275 -0
  413. chia/cmds/coins.py +182 -0
  414. chia/cmds/completion.py +49 -0
  415. chia/cmds/configure.py +332 -0
  416. chia/cmds/dao.py +1064 -0
  417. chia/cmds/dao_funcs.py +598 -0
  418. chia/cmds/data.py +708 -0
  419. chia/cmds/data_funcs.py +385 -0
  420. chia/cmds/db.py +87 -0
  421. chia/cmds/db_backup_func.py +77 -0
  422. chia/cmds/db_upgrade_func.py +452 -0
  423. chia/cmds/db_validate_func.py +184 -0
  424. chia/cmds/dev.py +18 -0
  425. chia/cmds/farm.py +100 -0
  426. chia/cmds/farm_funcs.py +200 -0
  427. chia/cmds/gh.py +275 -0
  428. chia/cmds/init.py +63 -0
  429. chia/cmds/init_funcs.py +367 -0
  430. chia/cmds/installers.py +131 -0
  431. chia/cmds/keys.py +527 -0
  432. chia/cmds/keys_funcs.py +863 -0
  433. chia/cmds/netspace.py +50 -0
  434. chia/cmds/netspace_funcs.py +54 -0
  435. chia/cmds/options.py +32 -0
  436. chia/cmds/param_types.py +238 -0
  437. chia/cmds/passphrase.py +131 -0
  438. chia/cmds/passphrase_funcs.py +292 -0
  439. chia/cmds/peer.py +51 -0
  440. chia/cmds/peer_funcs.py +129 -0
  441. chia/cmds/plotnft.py +260 -0
  442. chia/cmds/plotnft_funcs.py +405 -0
  443. chia/cmds/plots.py +230 -0
  444. chia/cmds/plotters.py +18 -0
  445. chia/cmds/rpc.py +208 -0
  446. chia/cmds/show.py +72 -0
  447. chia/cmds/show_funcs.py +215 -0
  448. chia/cmds/signer.py +296 -0
  449. chia/cmds/sim.py +225 -0
  450. chia/cmds/sim_funcs.py +509 -0
  451. chia/cmds/start.py +24 -0
  452. chia/cmds/start_funcs.py +109 -0
  453. chia/cmds/stop.py +62 -0
  454. chia/cmds/units.py +9 -0
  455. chia/cmds/wallet.py +1901 -0
  456. chia/cmds/wallet_funcs.py +1874 -0
  457. chia/consensus/__init__.py +0 -0
  458. chia/consensus/block_body_validation.py +562 -0
  459. chia/consensus/block_creation.py +546 -0
  460. chia/consensus/block_header_validation.py +1059 -0
  461. chia/consensus/block_record.py +31 -0
  462. chia/consensus/block_rewards.py +53 -0
  463. chia/consensus/blockchain.py +1087 -0
  464. chia/consensus/blockchain_interface.py +56 -0
  465. chia/consensus/coinbase.py +30 -0
  466. chia/consensus/condition_costs.py +9 -0
  467. chia/consensus/constants.py +49 -0
  468. chia/consensus/cost_calculator.py +15 -0
  469. chia/consensus/default_constants.py +89 -0
  470. chia/consensus/deficit.py +55 -0
  471. chia/consensus/difficulty_adjustment.py +412 -0
  472. chia/consensus/find_fork_point.py +111 -0
  473. chia/consensus/full_block_to_block_record.py +167 -0
  474. chia/consensus/get_block_challenge.py +106 -0
  475. chia/consensus/get_block_generator.py +27 -0
  476. chia/consensus/make_sub_epoch_summary.py +210 -0
  477. chia/consensus/multiprocess_validation.py +268 -0
  478. chia/consensus/pos_quality.py +19 -0
  479. chia/consensus/pot_iterations.py +67 -0
  480. chia/consensus/puzzles/__init__.py +0 -0
  481. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  482. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  483. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  484. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  485. chia/consensus/vdf_info_computation.py +156 -0
  486. chia/daemon/__init__.py +0 -0
  487. chia/daemon/client.py +252 -0
  488. chia/daemon/keychain_proxy.py +502 -0
  489. chia/daemon/keychain_server.py +365 -0
  490. chia/daemon/server.py +1606 -0
  491. chia/daemon/windows_signal.py +56 -0
  492. chia/data_layer/__init__.py +0 -0
  493. chia/data_layer/data_layer.py +1291 -0
  494. chia/data_layer/data_layer_api.py +33 -0
  495. chia/data_layer/data_layer_errors.py +50 -0
  496. chia/data_layer/data_layer_server.py +170 -0
  497. chia/data_layer/data_layer_util.py +985 -0
  498. chia/data_layer/data_layer_wallet.py +1311 -0
  499. chia/data_layer/data_store.py +2267 -0
  500. chia/data_layer/dl_wallet_store.py +407 -0
  501. chia/data_layer/download_data.py +389 -0
  502. chia/data_layer/puzzles/__init__.py +0 -0
  503. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  504. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  505. chia/data_layer/s3_plugin_config.yml +33 -0
  506. chia/data_layer/s3_plugin_service.py +468 -0
  507. chia/data_layer/util/__init__.py +0 -0
  508. chia/data_layer/util/benchmark.py +107 -0
  509. chia/data_layer/util/plugin.py +40 -0
  510. chia/farmer/__init__.py +0 -0
  511. chia/farmer/farmer.py +923 -0
  512. chia/farmer/farmer_api.py +820 -0
  513. chia/full_node/__init__.py +0 -0
  514. chia/full_node/bitcoin_fee_estimator.py +85 -0
  515. chia/full_node/block_height_map.py +271 -0
  516. chia/full_node/block_store.py +576 -0
  517. chia/full_node/bundle_tools.py +19 -0
  518. chia/full_node/coin_store.py +647 -0
  519. chia/full_node/fee_estimate.py +54 -0
  520. chia/full_node/fee_estimate_store.py +24 -0
  521. chia/full_node/fee_estimation.py +92 -0
  522. chia/full_node/fee_estimator.py +90 -0
  523. chia/full_node/fee_estimator_constants.py +38 -0
  524. chia/full_node/fee_estimator_interface.py +42 -0
  525. chia/full_node/fee_history.py +25 -0
  526. chia/full_node/fee_tracker.py +564 -0
  527. chia/full_node/full_node.py +3327 -0
  528. chia/full_node/full_node_api.py +2025 -0
  529. chia/full_node/full_node_store.py +1033 -0
  530. chia/full_node/hint_management.py +56 -0
  531. chia/full_node/hint_store.py +93 -0
  532. chia/full_node/mempool.py +589 -0
  533. chia/full_node/mempool_check_conditions.py +146 -0
  534. chia/full_node/mempool_manager.py +853 -0
  535. chia/full_node/pending_tx_cache.py +112 -0
  536. chia/full_node/puzzles/__init__.py +0 -0
  537. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  538. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  539. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  540. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  541. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  542. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  543. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  544. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  545. chia/full_node/signage_point.py +16 -0
  546. chia/full_node/subscriptions.py +247 -0
  547. chia/full_node/sync_store.py +146 -0
  548. chia/full_node/tx_processing_queue.py +78 -0
  549. chia/full_node/util/__init__.py +0 -0
  550. chia/full_node/weight_proof.py +1720 -0
  551. chia/harvester/__init__.py +0 -0
  552. chia/harvester/harvester.py +272 -0
  553. chia/harvester/harvester_api.py +380 -0
  554. chia/introducer/__init__.py +0 -0
  555. chia/introducer/introducer.py +122 -0
  556. chia/introducer/introducer_api.py +70 -0
  557. chia/legacy/__init__.py +0 -0
  558. chia/legacy/keyring.py +155 -0
  559. chia/plot_sync/__init__.py +0 -0
  560. chia/plot_sync/delta.py +61 -0
  561. chia/plot_sync/exceptions.py +56 -0
  562. chia/plot_sync/receiver.py +386 -0
  563. chia/plot_sync/sender.py +340 -0
  564. chia/plot_sync/util.py +43 -0
  565. chia/plotters/__init__.py +0 -0
  566. chia/plotters/bladebit.py +388 -0
  567. chia/plotters/chiapos.py +63 -0
  568. chia/plotters/madmax.py +224 -0
  569. chia/plotters/plotters.py +577 -0
  570. chia/plotters/plotters_util.py +133 -0
  571. chia/plotting/__init__.py +0 -0
  572. chia/plotting/cache.py +213 -0
  573. chia/plotting/check_plots.py +283 -0
  574. chia/plotting/create_plots.py +278 -0
  575. chia/plotting/manager.py +436 -0
  576. chia/plotting/util.py +336 -0
  577. chia/pools/__init__.py +0 -0
  578. chia/pools/pool_config.py +110 -0
  579. chia/pools/pool_puzzles.py +459 -0
  580. chia/pools/pool_wallet.py +933 -0
  581. chia/pools/pool_wallet_info.py +118 -0
  582. chia/pools/puzzles/__init__.py +0 -0
  583. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  584. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  585. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  586. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  587. chia/protocols/__init__.py +0 -0
  588. chia/protocols/farmer_protocol.py +102 -0
  589. chia/protocols/full_node_protocol.py +219 -0
  590. chia/protocols/harvester_protocol.py +216 -0
  591. chia/protocols/introducer_protocol.py +25 -0
  592. chia/protocols/pool_protocol.py +177 -0
  593. chia/protocols/protocol_message_types.py +139 -0
  594. chia/protocols/protocol_state_machine.py +87 -0
  595. chia/protocols/protocol_timing.py +8 -0
  596. chia/protocols/shared_protocol.py +86 -0
  597. chia/protocols/timelord_protocol.py +93 -0
  598. chia/protocols/wallet_protocol.py +401 -0
  599. chia/py.typed +0 -0
  600. chia/rpc/__init__.py +0 -0
  601. chia/rpc/crawler_rpc_api.py +80 -0
  602. chia/rpc/data_layer_rpc_api.py +644 -0
  603. chia/rpc/data_layer_rpc_client.py +188 -0
  604. chia/rpc/data_layer_rpc_util.py +58 -0
  605. chia/rpc/farmer_rpc_api.py +365 -0
  606. chia/rpc/farmer_rpc_client.py +86 -0
  607. chia/rpc/full_node_rpc_api.py +959 -0
  608. chia/rpc/full_node_rpc_client.py +292 -0
  609. chia/rpc/harvester_rpc_api.py +141 -0
  610. chia/rpc/harvester_rpc_client.py +54 -0
  611. chia/rpc/rpc_client.py +164 -0
  612. chia/rpc/rpc_server.py +521 -0
  613. chia/rpc/timelord_rpc_api.py +32 -0
  614. chia/rpc/util.py +93 -0
  615. chia/rpc/wallet_request_types.py +904 -0
  616. chia/rpc/wallet_rpc_api.py +4943 -0
  617. chia/rpc/wallet_rpc_client.py +1814 -0
  618. chia/seeder/__init__.py +0 -0
  619. chia/seeder/crawl_store.py +425 -0
  620. chia/seeder/crawler.py +410 -0
  621. chia/seeder/crawler_api.py +135 -0
  622. chia/seeder/dns_server.py +593 -0
  623. chia/seeder/peer_record.py +146 -0
  624. chia/seeder/start_crawler.py +92 -0
  625. chia/server/__init__.py +0 -0
  626. chia/server/address_manager.py +658 -0
  627. chia/server/address_manager_store.py +237 -0
  628. chia/server/api_protocol.py +116 -0
  629. chia/server/capabilities.py +24 -0
  630. chia/server/chia_policy.py +346 -0
  631. chia/server/introducer_peers.py +76 -0
  632. chia/server/node_discovery.py +714 -0
  633. chia/server/outbound_message.py +33 -0
  634. chia/server/rate_limit_numbers.py +214 -0
  635. chia/server/rate_limits.py +153 -0
  636. chia/server/server.py +741 -0
  637. chia/server/signal_handlers.py +120 -0
  638. chia/server/ssl_context.py +32 -0
  639. chia/server/start_data_layer.py +151 -0
  640. chia/server/start_farmer.py +98 -0
  641. chia/server/start_full_node.py +112 -0
  642. chia/server/start_harvester.py +93 -0
  643. chia/server/start_introducer.py +81 -0
  644. chia/server/start_service.py +316 -0
  645. chia/server/start_timelord.py +89 -0
  646. chia/server/start_wallet.py +113 -0
  647. chia/server/upnp.py +118 -0
  648. chia/server/ws_connection.py +766 -0
  649. chia/simulator/__init__.py +0 -0
  650. chia/simulator/add_blocks_in_batches.py +54 -0
  651. chia/simulator/block_tools.py +2054 -0
  652. chia/simulator/full_node_simulator.py +794 -0
  653. chia/simulator/keyring.py +128 -0
  654. chia/simulator/setup_services.py +506 -0
  655. chia/simulator/simulator_constants.py +13 -0
  656. chia/simulator/simulator_full_node_rpc_api.py +99 -0
  657. chia/simulator/simulator_full_node_rpc_client.py +60 -0
  658. chia/simulator/simulator_protocol.py +29 -0
  659. chia/simulator/simulator_test_tools.py +164 -0
  660. chia/simulator/socket.py +24 -0
  661. chia/simulator/ssl_certs.py +114 -0
  662. chia/simulator/ssl_certs_1.py +697 -0
  663. chia/simulator/ssl_certs_10.py +697 -0
  664. chia/simulator/ssl_certs_2.py +697 -0
  665. chia/simulator/ssl_certs_3.py +697 -0
  666. chia/simulator/ssl_certs_4.py +697 -0
  667. chia/simulator/ssl_certs_5.py +697 -0
  668. chia/simulator/ssl_certs_6.py +697 -0
  669. chia/simulator/ssl_certs_7.py +697 -0
  670. chia/simulator/ssl_certs_8.py +697 -0
  671. chia/simulator/ssl_certs_9.py +697 -0
  672. chia/simulator/start_simulator.py +143 -0
  673. chia/simulator/wallet_tools.py +246 -0
  674. chia/ssl/__init__.py +0 -0
  675. chia/ssl/chia_ca.crt +19 -0
  676. chia/ssl/chia_ca.key +28 -0
  677. chia/ssl/create_ssl.py +249 -0
  678. chia/ssl/dst_root_ca.pem +20 -0
  679. chia/timelord/__init__.py +0 -0
  680. chia/timelord/iters_from_block.py +50 -0
  681. chia/timelord/timelord.py +1226 -0
  682. chia/timelord/timelord_api.py +138 -0
  683. chia/timelord/timelord_launcher.py +190 -0
  684. chia/timelord/timelord_state.py +244 -0
  685. chia/timelord/types.py +22 -0
  686. chia/types/__init__.py +0 -0
  687. chia/types/aliases.py +35 -0
  688. chia/types/block_protocol.py +20 -0
  689. chia/types/blockchain_format/__init__.py +0 -0
  690. chia/types/blockchain_format/classgroup.py +5 -0
  691. chia/types/blockchain_format/coin.py +28 -0
  692. chia/types/blockchain_format/foliage.py +8 -0
  693. chia/types/blockchain_format/pool_target.py +5 -0
  694. chia/types/blockchain_format/program.py +269 -0
  695. chia/types/blockchain_format/proof_of_space.py +135 -0
  696. chia/types/blockchain_format/reward_chain_block.py +6 -0
  697. chia/types/blockchain_format/serialized_program.py +5 -0
  698. chia/types/blockchain_format/sized_bytes.py +11 -0
  699. chia/types/blockchain_format/slots.py +9 -0
  700. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  701. chia/types/blockchain_format/tree_hash.py +72 -0
  702. chia/types/blockchain_format/vdf.py +86 -0
  703. chia/types/clvm_cost.py +13 -0
  704. chia/types/coin_record.py +43 -0
  705. chia/types/coin_spend.py +115 -0
  706. chia/types/condition_opcodes.py +73 -0
  707. chia/types/condition_with_args.py +16 -0
  708. chia/types/eligible_coin_spends.py +365 -0
  709. chia/types/end_of_slot_bundle.py +5 -0
  710. chia/types/fee_rate.py +38 -0
  711. chia/types/full_block.py +5 -0
  712. chia/types/generator_types.py +13 -0
  713. chia/types/header_block.py +5 -0
  714. chia/types/internal_mempool_item.py +18 -0
  715. chia/types/mempool_inclusion_status.py +9 -0
  716. chia/types/mempool_item.py +85 -0
  717. chia/types/mempool_submission_status.py +30 -0
  718. chia/types/mojos.py +7 -0
  719. chia/types/peer_info.py +64 -0
  720. chia/types/signing_mode.py +29 -0
  721. chia/types/spend_bundle.py +30 -0
  722. chia/types/spend_bundle_conditions.py +7 -0
  723. chia/types/transaction_queue_entry.py +55 -0
  724. chia/types/unfinished_block.py +5 -0
  725. chia/types/unfinished_header_block.py +37 -0
  726. chia/types/validation_state.py +14 -0
  727. chia/types/weight_proof.py +49 -0
  728. chia/util/__init__.py +0 -0
  729. chia/util/action_scope.py +168 -0
  730. chia/util/async_pool.py +226 -0
  731. chia/util/augmented_chain.py +134 -0
  732. chia/util/batches.py +42 -0
  733. chia/util/bech32m.py +126 -0
  734. chia/util/beta_metrics.py +119 -0
  735. chia/util/block_cache.py +56 -0
  736. chia/util/byte_types.py +12 -0
  737. chia/util/check_fork_next_block.py +33 -0
  738. chia/util/chia_logging.py +144 -0
  739. chia/util/chia_version.py +33 -0
  740. chia/util/collection.py +17 -0
  741. chia/util/condition_tools.py +201 -0
  742. chia/util/config.py +367 -0
  743. chia/util/cpu.py +22 -0
  744. chia/util/db_synchronous.py +23 -0
  745. chia/util/db_version.py +32 -0
  746. chia/util/db_wrapper.py +430 -0
  747. chia/util/default_root.py +27 -0
  748. chia/util/dump_keyring.py +93 -0
  749. chia/util/english.txt +2048 -0
  750. chia/util/errors.py +353 -0
  751. chia/util/file_keyring.py +469 -0
  752. chia/util/files.py +97 -0
  753. chia/util/full_block_utils.py +345 -0
  754. chia/util/generator_tools.py +72 -0
  755. chia/util/hash.py +31 -0
  756. chia/util/initial-config.yaml +694 -0
  757. chia/util/inline_executor.py +26 -0
  758. chia/util/ints.py +19 -0
  759. chia/util/ip_address.py +39 -0
  760. chia/util/json_util.py +37 -0
  761. chia/util/keychain.py +676 -0
  762. chia/util/keyring_wrapper.py +327 -0
  763. chia/util/limited_semaphore.py +41 -0
  764. chia/util/lock.py +49 -0
  765. chia/util/log_exceptions.py +32 -0
  766. chia/util/logging.py +36 -0
  767. chia/util/lru_cache.py +31 -0
  768. chia/util/math.py +20 -0
  769. chia/util/network.py +182 -0
  770. chia/util/paginator.py +48 -0
  771. chia/util/path.py +31 -0
  772. chia/util/permissions.py +20 -0
  773. chia/util/prev_transaction_block.py +21 -0
  774. chia/util/priority_mutex.py +95 -0
  775. chia/util/profiler.py +197 -0
  776. chia/util/recursive_replace.py +24 -0
  777. chia/util/safe_cancel_task.py +16 -0
  778. chia/util/service_groups.py +47 -0
  779. chia/util/setproctitle.py +22 -0
  780. chia/util/significant_bits.py +32 -0
  781. chia/util/ssl_check.py +213 -0
  782. chia/util/streamable.py +642 -0
  783. chia/util/task_referencer.py +59 -0
  784. chia/util/task_timing.py +382 -0
  785. chia/util/timing.py +67 -0
  786. chia/util/vdf_prover.py +30 -0
  787. chia/util/virtual_project_analysis.py +540 -0
  788. chia/util/ws_message.py +66 -0
  789. chia/wallet/__init__.py +0 -0
  790. chia/wallet/cat_wallet/__init__.py +0 -0
  791. chia/wallet/cat_wallet/cat_constants.py +75 -0
  792. chia/wallet/cat_wallet/cat_info.py +47 -0
  793. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  794. chia/wallet/cat_wallet/cat_utils.py +164 -0
  795. chia/wallet/cat_wallet/cat_wallet.py +855 -0
  796. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  797. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  798. chia/wallet/cat_wallet/lineage_store.py +74 -0
  799. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  800. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  801. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  802. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  803. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  804. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  805. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  806. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  807. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  808. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  809. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  810. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  811. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  812. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  813. chia/wallet/coin_selection.py +188 -0
  814. chia/wallet/conditions.py +1512 -0
  815. chia/wallet/dao_wallet/__init__.py +0 -0
  816. chia/wallet/dao_wallet/dao_info.py +61 -0
  817. chia/wallet/dao_wallet/dao_utils.py +811 -0
  818. chia/wallet/dao_wallet/dao_wallet.py +2119 -0
  819. chia/wallet/db_wallet/__init__.py +0 -0
  820. chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
  821. chia/wallet/derivation_record.py +30 -0
  822. chia/wallet/derive_keys.py +146 -0
  823. chia/wallet/did_wallet/__init__.py +0 -0
  824. chia/wallet/did_wallet/did_info.py +39 -0
  825. chia/wallet/did_wallet/did_wallet.py +1494 -0
  826. chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
  827. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  828. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  829. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  830. chia/wallet/driver_protocol.py +26 -0
  831. chia/wallet/key_val_store.py +55 -0
  832. chia/wallet/lineage_proof.py +58 -0
  833. chia/wallet/nft_wallet/__init__.py +0 -0
  834. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  835. chia/wallet/nft_wallet/nft_info.py +120 -0
  836. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  837. chia/wallet/nft_wallet/nft_wallet.py +1687 -0
  838. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  839. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  840. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  841. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  842. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  843. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  844. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  845. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  846. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  847. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  848. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  849. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  850. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  851. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  852. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  853. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  854. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  855. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  856. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  857. chia/wallet/notification_manager.py +117 -0
  858. chia/wallet/notification_store.py +178 -0
  859. chia/wallet/outer_puzzles.py +84 -0
  860. chia/wallet/payment.py +33 -0
  861. chia/wallet/puzzle_drivers.py +118 -0
  862. chia/wallet/puzzles/__init__.py +0 -0
  863. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  864. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  865. chia/wallet/puzzles/clawback/__init__.py +0 -0
  866. chia/wallet/puzzles/clawback/drivers.py +188 -0
  867. chia/wallet/puzzles/clawback/metadata.py +38 -0
  868. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  869. chia/wallet/puzzles/condition_codes.clib +77 -0
  870. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  871. chia/wallet/puzzles/curry.clib +135 -0
  872. chia/wallet/puzzles/curry_by_index.clib +16 -0
  873. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  874. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  876. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  877. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  878. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  879. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  880. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  881. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  882. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  883. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  884. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  885. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  886. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  887. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  888. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  889. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  890. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  891. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  892. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  893. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  894. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  895. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  896. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  897. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  898. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  899. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  900. chia/wallet/puzzles/json.clib +25 -0
  901. chia/wallet/puzzles/load_clvm.py +161 -0
  902. chia/wallet/puzzles/merkle_utils.clib +18 -0
  903. chia/wallet/puzzles/notification.clsp +7 -0
  904. chia/wallet/puzzles/notification.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  906. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  907. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  908. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  909. chia/wallet/puzzles/p2_conditions.py +26 -0
  910. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  911. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  912. chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
  913. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  914. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  915. chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
  916. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  917. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
  919. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  920. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  921. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
  922. chia/wallet/puzzles/p2_parent.clsp +19 -0
  923. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  924. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  925. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  926. chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
  927. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  928. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  929. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  930. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  931. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  932. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  933. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  934. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  935. chia/wallet/puzzles/puzzle_utils.py +34 -0
  936. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  937. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  938. chia/wallet/puzzles/sha256tree.clib +11 -0
  939. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  940. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  941. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  942. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  943. chia/wallet/puzzles/singleton_top_layer.py +296 -0
  944. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  945. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  946. chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
  947. chia/wallet/puzzles/singleton_truths.clib +21 -0
  948. chia/wallet/puzzles/tails.py +348 -0
  949. chia/wallet/puzzles/utility_macros.clib +48 -0
  950. chia/wallet/signer_protocol.py +125 -0
  951. chia/wallet/singleton.py +106 -0
  952. chia/wallet/singleton_record.py +30 -0
  953. chia/wallet/trade_manager.py +1102 -0
  954. chia/wallet/trade_record.py +67 -0
  955. chia/wallet/trading/__init__.py +0 -0
  956. chia/wallet/trading/offer.py +702 -0
  957. chia/wallet/trading/trade_status.py +13 -0
  958. chia/wallet/trading/trade_store.py +526 -0
  959. chia/wallet/transaction_record.py +158 -0
  960. chia/wallet/transaction_sorting.py +14 -0
  961. chia/wallet/uncurried_puzzle.py +17 -0
  962. chia/wallet/util/__init__.py +0 -0
  963. chia/wallet/util/address_type.py +55 -0
  964. chia/wallet/util/blind_signer_tl.py +164 -0
  965. chia/wallet/util/clvm_streamable.py +203 -0
  966. chia/wallet/util/compute_hints.py +66 -0
  967. chia/wallet/util/compute_memos.py +43 -0
  968. chia/wallet/util/curry_and_treehash.py +91 -0
  969. chia/wallet/util/debug_spend_bundle.py +232 -0
  970. chia/wallet/util/merkle_tree.py +100 -0
  971. chia/wallet/util/merkle_utils.py +102 -0
  972. chia/wallet/util/new_peak_queue.py +82 -0
  973. chia/wallet/util/notifications.py +12 -0
  974. chia/wallet/util/peer_request_cache.py +174 -0
  975. chia/wallet/util/pprint.py +39 -0
  976. chia/wallet/util/puzzle_compression.py +95 -0
  977. chia/wallet/util/puzzle_decorator.py +100 -0
  978. chia/wallet/util/puzzle_decorator_type.py +7 -0
  979. chia/wallet/util/query_filter.py +59 -0
  980. chia/wallet/util/transaction_type.py +23 -0
  981. chia/wallet/util/tx_config.py +158 -0
  982. chia/wallet/util/wallet_sync_utils.py +351 -0
  983. chia/wallet/util/wallet_types.py +72 -0
  984. chia/wallet/vc_wallet/__init__.py +0 -0
  985. chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
  986. chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
  987. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  988. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  989. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  990. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  992. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  994. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  996. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  997. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  998. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  1002. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  1003. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  1004. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  1005. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  1006. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  1007. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  1008. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  1009. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  1010. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  1011. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  1012. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  1013. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1014. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1015. chia/wallet/vc_wallet/vc_store.py +263 -0
  1016. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1017. chia/wallet/wallet.py +698 -0
  1018. chia/wallet/wallet_action_scope.py +96 -0
  1019. chia/wallet/wallet_blockchain.py +244 -0
  1020. chia/wallet/wallet_coin_record.py +72 -0
  1021. chia/wallet/wallet_coin_store.py +351 -0
  1022. chia/wallet/wallet_info.py +35 -0
  1023. chia/wallet/wallet_interested_store.py +188 -0
  1024. chia/wallet/wallet_nft_store.py +279 -0
  1025. chia/wallet/wallet_node.py +1765 -0
  1026. chia/wallet/wallet_node_api.py +207 -0
  1027. chia/wallet/wallet_pool_store.py +119 -0
  1028. chia/wallet/wallet_protocol.py +90 -0
  1029. chia/wallet/wallet_puzzle_store.py +396 -0
  1030. chia/wallet/wallet_retry_store.py +70 -0
  1031. chia/wallet/wallet_singleton_store.py +259 -0
  1032. chia/wallet/wallet_spend_bundle.py +25 -0
  1033. chia/wallet/wallet_state_manager.py +2819 -0
  1034. chia/wallet/wallet_transaction_store.py +496 -0
  1035. chia/wallet/wallet_user_store.py +110 -0
  1036. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1037. chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
  1038. chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
  1039. chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
  1040. chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
  1041. chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
  1042. mozilla-ca/cacert.pem +3611 -0
@@ -0,0 +1,1087 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import dataclasses
5
+ import enum
6
+ import logging
7
+ import traceback
8
+ from concurrent.futures import Executor, ThreadPoolExecutor
9
+ from enum import Enum
10
+ from pathlib import Path
11
+ from typing import TYPE_CHECKING, ClassVar, Optional, cast
12
+
13
+ from chia_rs import additions_and_removals, get_flags_for_height_and_constants
14
+
15
+ from chia.consensus.block_body_validation import ForkInfo, validate_block_body
16
+ from chia.consensus.block_header_validation import validate_unfinished_header_block
17
+ from chia.consensus.block_record import BlockRecord
18
+ from chia.consensus.constants import ConsensusConstants
19
+ from chia.consensus.cost_calculator import NPCResult
20
+ from chia.consensus.difficulty_adjustment import get_next_sub_slot_iters_and_difficulty
21
+ from chia.consensus.find_fork_point import lookup_fork_chain
22
+ from chia.consensus.full_block_to_block_record import block_to_block_record
23
+ from chia.consensus.get_block_generator import get_block_generator
24
+ from chia.consensus.multiprocess_validation import PreValidationResult
25
+ from chia.full_node.block_height_map import BlockHeightMap
26
+ from chia.full_node.block_store import BlockStore
27
+ from chia.full_node.coin_store import CoinStore
28
+ from chia.types.blockchain_format.coin import Coin
29
+ from chia.types.blockchain_format.sized_bytes import bytes32
30
+ from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary
31
+ from chia.types.blockchain_format.vdf import VDFInfo
32
+ from chia.types.coin_record import CoinRecord
33
+ from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
34
+ from chia.types.full_block import FullBlock
35
+ from chia.types.generator_types import BlockGenerator
36
+ from chia.types.header_block import HeaderBlock
37
+ from chia.types.unfinished_block import UnfinishedBlock
38
+ from chia.types.unfinished_header_block import UnfinishedHeaderBlock
39
+ from chia.types.validation_state import ValidationState
40
+ from chia.types.weight_proof import SubEpochChallengeSegment
41
+ from chia.util.cpu import available_logical_cores
42
+ from chia.util.errors import Err
43
+ from chia.util.generator_tools import get_block_header
44
+ from chia.util.hash import std_hash
45
+ from chia.util.inline_executor import InlineExecutor
46
+ from chia.util.ints import uint16, uint32, uint64, uint128
47
+ from chia.util.priority_mutex import PriorityMutex
48
+
49
+ log = logging.getLogger(__name__)
50
+
51
+
52
+ class AddBlockResult(Enum):
53
+ """
54
+ When Blockchain.add_block(b) is called, one of these results is returned,
55
+ showing whether the block was added to the chain (extending the peak),
56
+ and if not, why it was not added.
57
+ """
58
+
59
+ NEW_PEAK = 1 # Added to the peak of the blockchain
60
+ ADDED_AS_ORPHAN = 2 # Added as an orphan/stale block (not a new peak of the chain)
61
+ INVALID_BLOCK = 3 # Block was not added because it was invalid
62
+ ALREADY_HAVE_BLOCK = 4 # Block is already present in this blockchain
63
+ DISCONNECTED_BLOCK = 5 # Block's parent (previous pointer) is not in this blockchain
64
+
65
+
66
+ @dataclasses.dataclass
67
+ class StateChangeSummary:
68
+ peak: BlockRecord
69
+ fork_height: uint32
70
+ rolled_back_records: list[CoinRecord]
71
+ # list of coin-id, puzzle-hash pairs
72
+ removals: list[tuple[bytes32, bytes32]]
73
+ # new coin and hint
74
+ additions: list[tuple[Coin, Optional[bytes]]]
75
+ new_rewards: list[Coin]
76
+
77
+
78
+ class BlockchainMutexPriority(enum.IntEnum):
79
+ # lower values are higher priority
80
+ low = 1
81
+ high = 0
82
+
83
+
84
+ # implements BlockchainInterface
85
+ class Blockchain:
86
+ if TYPE_CHECKING:
87
+ from chia.consensus.blockchain_interface import BlockchainInterface
88
+
89
+ _protocol_check: ClassVar[BlockchainInterface] = cast("Blockchain", None)
90
+
91
+ constants: ConsensusConstants
92
+
93
+ # peak of the blockchain
94
+ _peak_height: Optional[uint32]
95
+ # All blocks in peak path are guaranteed to be included, can include orphan blocks
96
+ __block_records: dict[bytes32, BlockRecord]
97
+ # all hashes of blocks in block_record by height, used for garbage collection
98
+ __heights_in_cache: dict[uint32, set[bytes32]]
99
+ # maps block height (of the current heaviest chain) to block hash and sub
100
+ # epoch summaries
101
+ __height_map: BlockHeightMap
102
+ # Unspent Store
103
+ coin_store: CoinStore
104
+ # Store
105
+ block_store: BlockStore
106
+ # Used to verify blocks in parallel
107
+ pool: Executor
108
+ # Set holding seen compact proofs, in order to avoid duplicates.
109
+ _seen_compact_proofs: set[tuple[VDFInfo, uint32]]
110
+
111
+ # Whether blockchain is shut down or not
112
+ _shut_down: bool
113
+
114
+ # Lock to prevent simultaneous reads and writes
115
+ priority_mutex: PriorityMutex[BlockchainMutexPriority]
116
+ compact_proof_lock: asyncio.Lock
117
+
118
+ _log_coins: bool
119
+
120
+ @staticmethod
121
+ async def create(
122
+ coin_store: CoinStore,
123
+ block_store: BlockStore,
124
+ consensus_constants: ConsensusConstants,
125
+ blockchain_dir: Path,
126
+ reserved_cores: int,
127
+ *,
128
+ single_threaded: bool = False,
129
+ log_coins: bool = False,
130
+ ) -> Blockchain:
131
+ """
132
+ Initializes a blockchain with the BlockRecords from disk, assuming they have all been
133
+ validated. Uses the genesis block given in override_constants, or as a fallback,
134
+ in the consensus constants config.
135
+ """
136
+ self = Blockchain()
137
+ self._log_coins = log_coins
138
+ # Blocks are validated under high priority, and transactions under low priority. This guarantees blocks will
139
+ # be validated first.
140
+ self.priority_mutex = PriorityMutex.create(priority_type=BlockchainMutexPriority)
141
+ self.compact_proof_lock = asyncio.Lock()
142
+ if single_threaded:
143
+ self.pool = InlineExecutor()
144
+ else:
145
+ cpu_count = available_logical_cores()
146
+ num_workers = max(cpu_count - reserved_cores, 1)
147
+ self.pool = ThreadPoolExecutor(
148
+ max_workers=num_workers,
149
+ )
150
+ log.info(f"Started {num_workers} processes for block validation")
151
+
152
+ self.constants = consensus_constants
153
+ self.coin_store = coin_store
154
+ self.block_store = block_store
155
+ self._shut_down = False
156
+ await self._load_chain_from_store(blockchain_dir)
157
+ self._seen_compact_proofs = set()
158
+ return self
159
+
160
+ def shut_down(self) -> None:
161
+ self._shut_down = True
162
+ self.pool.shutdown(wait=True)
163
+
164
+ async def _load_chain_from_store(self, blockchain_dir: Path) -> None:
165
+ """
166
+ Initializes the state of the Blockchain class from the database.
167
+ """
168
+ self.__height_map = await BlockHeightMap.create(blockchain_dir, self.block_store.db_wrapper)
169
+ self.__block_records = {}
170
+ self.__heights_in_cache = {}
171
+ block_records, peak = await self.block_store.get_block_records_close_to_peak(self.constants.BLOCKS_CACHE_SIZE)
172
+ for block in block_records.values():
173
+ self.add_block_record(block)
174
+
175
+ if len(block_records) == 0:
176
+ assert peak is None
177
+ self._peak_height = None
178
+ return
179
+
180
+ assert peak is not None
181
+ self._peak_height = self.block_record(peak).height
182
+ assert self.__height_map.contains_height(self._peak_height)
183
+ assert not self.__height_map.contains_height(uint32(self._peak_height + 1))
184
+
185
+ def get_peak(self) -> Optional[BlockRecord]:
186
+ """
187
+ Return the peak of the blockchain
188
+ """
189
+ if self._peak_height is None:
190
+ return None
191
+ return self.height_to_block_record(self._peak_height)
192
+
193
+ def get_tx_peak(self) -> Optional[BlockRecord]:
194
+ """
195
+ Return the most recent transaction block. i.e. closest to the peak of the blockchain
196
+ Requires the blockchain to be initialized and there to be a peak set
197
+ """
198
+
199
+ if self._peak_height is None:
200
+ return None
201
+ tx_height = self._peak_height
202
+ tx_peak = self.height_to_block_record(tx_height)
203
+ while not tx_peak.is_transaction_block:
204
+ # it seems BlockTools only produce chains where the first block is a
205
+ # transaction block, which makes it hard to test this case
206
+ if tx_height == 0: # pragma: no cover
207
+ return None
208
+ tx_height = uint32(tx_height - 1)
209
+ tx_peak = self.height_to_block_record(tx_height)
210
+
211
+ return tx_peak
212
+
213
+ async def get_full_peak(self) -> Optional[FullBlock]:
214
+ if self._peak_height is None:
215
+ return None
216
+ """ Return list of FullBlocks that are peaks"""
217
+ peak_hash: Optional[bytes32] = self.height_to_hash(self._peak_height)
218
+ assert peak_hash is not None # Since we must have the peak block
219
+ block = await self.block_store.get_full_block(peak_hash)
220
+ assert block is not None
221
+ return block
222
+
223
+ async def get_full_block(self, header_hash: bytes32) -> Optional[FullBlock]:
224
+ return await self.block_store.get_full_block(header_hash)
225
+
226
+ async def advance_fork_info(self, block: FullBlock, fork_info: ForkInfo) -> None:
227
+ """
228
+ This function is used to advance the peak_height of fork_info given the
229
+ full block extending the chain. block is required to be the next block on
230
+ top of fork_info.peak_height. If the block is part of the main chain,
231
+ the fork_height will set to the same as the peak, making the fork_info
232
+ represent an empty fork chain.
233
+ If the block is part of a fork, we need to compute the additions and
234
+ removals, to update the fork_info object. This is an expensive operation.
235
+ """
236
+
237
+ assert fork_info.peak_height <= block.height - 1
238
+ assert fork_info.peak_hash != block.header_hash
239
+
240
+ if fork_info.peak_hash == block.prev_header_hash:
241
+ assert fork_info.peak_height == block.height - 1
242
+ return
243
+
244
+ # note that we're not technically finding a fork here, we just traverse
245
+ # from the current block down to the fork's current peak
246
+ chain, peak_hash = await lookup_fork_chain(
247
+ self,
248
+ (fork_info.peak_height, fork_info.peak_hash),
249
+ (block.height - 1, block.prev_header_hash),
250
+ self.constants,
251
+ )
252
+ # the ForkInfo object is expected to be valid, just having its peak
253
+ # behind the current block
254
+ assert peak_hash == fork_info.peak_hash
255
+ assert len(chain) == block.height - fork_info.peak_height - 1
256
+
257
+ for height in range(fork_info.peak_height + 1, block.height):
258
+ fork_block: Optional[FullBlock] = await self.block_store.get_full_block(chain[uint32(height)])
259
+ assert fork_block is not None
260
+ await self.run_single_block(fork_block, fork_info)
261
+
262
+ async def run_single_block(self, block: FullBlock, fork_info: ForkInfo) -> None:
263
+ assert fork_info.peak_height == block.height - 1
264
+ assert block.height == 0 or fork_info.peak_hash == block.prev_header_hash
265
+
266
+ additions: list[tuple[Coin, Optional[bytes]]] = []
267
+ removals: list[Coin] = []
268
+ if block.transactions_generator is not None:
269
+ block_generator: Optional[BlockGenerator] = await get_block_generator(self.lookup_block_generators, block)
270
+ assert block_generator is not None
271
+ assert block.transactions_info is not None
272
+ assert block.foliage_transaction_block is not None
273
+ flags = get_flags_for_height_and_constants(block.height, self.constants)
274
+ additions, removals = additions_and_removals(
275
+ bytes(block.transactions_generator),
276
+ block_generator.generator_refs,
277
+ flags,
278
+ self.constants,
279
+ )
280
+
281
+ fork_info.include_block(additions, removals, block, block.header_hash)
282
+
283
+ async def add_block(
284
+ self,
285
+ block: FullBlock,
286
+ pre_validation_result: PreValidationResult,
287
+ sub_slot_iters: uint64,
288
+ fork_info: ForkInfo,
289
+ prev_ses_block: Optional[BlockRecord] = None,
290
+ block_record: Optional[BlockRecord] = None,
291
+ ) -> tuple[AddBlockResult, Optional[Err], Optional[StateChangeSummary]]:
292
+ """
293
+ This method must be called under the blockchain lock
294
+ Adds a new block into the blockchain, if it's valid and connected to the current
295
+ blockchain, regardless of whether it is the child of a head, or another block.
296
+ Returns a header if block is added to head. Returns an error if the block is
297
+ invalid. Also returns the fork height, in the case of a new peak.
298
+
299
+ Args:
300
+ block: The FullBlock to be validated.
301
+ pre_validation_result: A result of successful pre validation
302
+ fork_info: Information about the fork chain this block is part of,
303
+ to make validation more efficient. This is an in-out parameter.
304
+
305
+ Returns:
306
+ The result of adding the block to the blockchain (NEW_PEAK, ADDED_AS_ORPHAN, INVALID_BLOCK,
307
+ DISCONNECTED_BLOCK, ALREDY_HAVE_BLOCK)
308
+ An optional error if the result is not NEW_PEAK or ADDED_AS_ORPHAN
309
+ A StateChangeSummary iff NEW_PEAK, with:
310
+ - A fork point if the result is NEW_PEAK
311
+ - A list of coin changes as a result of rollback
312
+ - A list of NPCResult for any new transaction block added to the chain
313
+ """
314
+
315
+ if block.height == 0 and block.prev_header_hash != self.constants.GENESIS_CHALLENGE:
316
+ return AddBlockResult.INVALID_BLOCK, Err.INVALID_PREV_BLOCK_HASH, None
317
+
318
+ peak = self.get_peak()
319
+ genesis: bool = block.height == 0
320
+ extending_main_chain: bool = genesis or peak is None or (block.prev_header_hash == peak.header_hash)
321
+
322
+ # first check if this block is disconnected from the currently known
323
+ # blocks. We can only accept blocks that are connected to another block
324
+ # we know of.
325
+ prev_block: Optional[BlockRecord] = None
326
+ if not extending_main_chain and not genesis:
327
+ prev_block = self.try_block_record(block.prev_header_hash)
328
+ if prev_block is None:
329
+ return AddBlockResult.DISCONNECTED_BLOCK, Err.INVALID_PREV_BLOCK_HASH, None
330
+
331
+ if prev_block.height + 1 != block.height:
332
+ return AddBlockResult.INVALID_BLOCK, Err.INVALID_HEIGHT, None
333
+
334
+ required_iters = pre_validation_result.required_iters
335
+ if pre_validation_result.error is not None:
336
+ return AddBlockResult.INVALID_BLOCK, Err(pre_validation_result.error), None
337
+ assert required_iters is not None
338
+
339
+ header_hash: bytes32 = block.header_hash
340
+
341
+ # passing in correct fork_info is critical for performing reorgs
342
+ # correctly, so we perform some validation of it here
343
+ assert block.height - 1 == fork_info.peak_height
344
+ assert len(fork_info.block_hashes) == fork_info.peak_height - fork_info.fork_height
345
+ if fork_info.peak_height == fork_info.fork_height:
346
+ # if fork_info is saying we're not on a fork, the previous block better
347
+ # be part of the main chain
348
+ assert block.prev_header_hash == fork_info.peak_hash
349
+ if fork_info.fork_height == -1:
350
+ assert fork_info.peak_hash == self.constants.GENESIS_CHALLENGE
351
+ else:
352
+ assert self.height_to_hash(uint32(fork_info.fork_height)) == block.prev_header_hash
353
+ else:
354
+ assert fork_info.peak_hash == block.prev_header_hash
355
+
356
+ if extending_main_chain:
357
+ fork_info.reset(block.height - 1, block.prev_header_hash)
358
+
359
+ # we dont consider block_record passed in here since it might be from
360
+ # a current sync process and not yet fully validated and commited to the DB
361
+ block_rec_from_db = await self.get_block_record_from_db(header_hash)
362
+ if block_rec_from_db is not None:
363
+ # We have already validated the block, but if it's not part of the
364
+ # main chain, we still need to re-run it to update the additions and
365
+ # removals in fork_info.
366
+ await self.advance_fork_info(block, fork_info)
367
+ fork_info.include_spends(pre_validation_result.conds, block, header_hash)
368
+ self.add_block_record(block_rec_from_db)
369
+ return AddBlockResult.ALREADY_HAVE_BLOCK, None, None
370
+
371
+ if fork_info.peak_hash != block.prev_header_hash:
372
+ await self.advance_fork_info(block, fork_info)
373
+
374
+ # if these prerequisites of the fork_info aren't met, the fork_info
375
+ # object is invalid for this block. If the caller would have passed in
376
+ # None, a valid fork_info would have been computed
377
+ assert fork_info.peak_height == block.height - 1
378
+ assert block.height == 0 or fork_info.peak_hash == block.prev_header_hash
379
+
380
+ assert block.transactions_generator is None or pre_validation_result.validated_signature
381
+ error_code = await validate_block_body(
382
+ self.constants,
383
+ self,
384
+ self.coin_store.get_coin_records,
385
+ block,
386
+ block.height,
387
+ pre_validation_result.conds,
388
+ fork_info,
389
+ log_coins=self._log_coins,
390
+ )
391
+ if error_code is not None:
392
+ return AddBlockResult.INVALID_BLOCK, error_code, None
393
+
394
+ # commit the additions and removals from this block into the ForkInfo, in
395
+ # case we're validating blocks on a fork, the next block validation will
396
+ # need to know of these additions and removals. Also, _reconsider_peak()
397
+ # will need these results
398
+ fork_info.include_spends(pre_validation_result.conds, block, header_hash)
399
+
400
+ # block_to_block_record() require the previous block in the cache
401
+ if not genesis and prev_block is not None:
402
+ self.add_block_record(prev_block)
403
+
404
+ if block_record is None:
405
+ block_record = block_to_block_record(
406
+ self.constants,
407
+ self,
408
+ required_iters,
409
+ block,
410
+ sub_slot_iters=sub_slot_iters,
411
+ prev_ses_block=prev_ses_block,
412
+ )
413
+
414
+ # in case we fail and need to restore the blockchain state, remember the
415
+ # peak height
416
+ previous_peak_height = self._peak_height
417
+ prev_fork_peak = (fork_info.peak_height, fork_info.peak_hash)
418
+
419
+ try:
420
+ # Always add the block to the database
421
+ async with self.block_store.db_wrapper.writer():
422
+ # Perform the DB operations to update the state, and rollback if something goes wrong
423
+ await self.block_store.add_full_block(header_hash, block, block_record)
424
+ records, state_change_summary = await self._reconsider_peak(block_record, genesis, fork_info)
425
+
426
+ # Then update the memory cache. It is important that this is not cancelled and does not throw
427
+ # This is done after all async/DB operations, so there is a decreased chance of failure.
428
+ self.add_block_record(block_record)
429
+
430
+ # there's a suspension point here, as we leave the async context
431
+ # manager
432
+
433
+ # make sure to update _peak_height after the transaction is committed,
434
+ # otherwise other tasks may go look for this block before it's available
435
+ if state_change_summary is not None:
436
+ self.__height_map.rollback(state_change_summary.fork_height)
437
+ for fetched_block_record in records:
438
+ self.__height_map.update_height(
439
+ fetched_block_record.height,
440
+ fetched_block_record.header_hash,
441
+ fetched_block_record.sub_epoch_summary_included,
442
+ )
443
+
444
+ if state_change_summary is not None:
445
+ self._peak_height = block_record.height
446
+
447
+ except BaseException as e:
448
+ # depending on exactly when the failure of adding the block
449
+ # happened, we may not have added it to the block record cache
450
+ try:
451
+ self.remove_block_record(header_hash)
452
+ except KeyError:
453
+ pass
454
+ # restore fork_info to the state before adding the block
455
+ fork_info.rollback(prev_fork_peak[1], prev_fork_peak[0])
456
+ self.block_store.rollback_cache_block(header_hash)
457
+ self._peak_height = previous_peak_height
458
+ log.error(
459
+ f"Error while adding block {header_hash} height {block.height},"
460
+ f" rolling back: {traceback.format_exc()} {e}"
461
+ )
462
+ raise
463
+
464
+ # This is done outside the try-except in case it fails, since we do not want to revert anything if it does
465
+ await self.__height_map.maybe_flush()
466
+
467
+ if state_change_summary is not None:
468
+ # new coin records added
469
+ return AddBlockResult.NEW_PEAK, None, state_change_summary
470
+ else:
471
+ return AddBlockResult.ADDED_AS_ORPHAN, None, None
472
+
473
+ # only to be called under short fork points
474
+ # under deep reorgs this can cause OOM
475
+ async def _reconsider_peak(
476
+ self,
477
+ block_record: BlockRecord,
478
+ genesis: bool,
479
+ fork_info: ForkInfo,
480
+ ) -> tuple[list[BlockRecord], Optional[StateChangeSummary]]:
481
+ """
482
+ When a new block is added, this is called, to check if the new block is the new peak of the chain.
483
+ This also handles reorgs by reverting blocks which are not in the heaviest chain.
484
+ It returns the summary of the applied changes, including the height of the fork between the previous chain
485
+ and the new chain, or returns None if there was no update to the heaviest chain.
486
+ """
487
+
488
+ peak = self.get_peak()
489
+ rolled_back_state: dict[bytes32, CoinRecord] = {}
490
+
491
+ if genesis and peak is not None:
492
+ return [], None
493
+
494
+ if peak is not None:
495
+ if block_record.weight < peak.weight:
496
+ # This is not a heavier block than the heaviest we have seen, so we don't change the coin set
497
+ return [], None
498
+ if block_record.weight == peak.weight and peak.total_iters <= block_record.total_iters:
499
+ # this is an equal weight block but our peak has lower iterations, so we dont change the coin set
500
+ return [], None
501
+ if block_record.weight == peak.weight:
502
+ log.info(
503
+ f"block has equal weight as our peak ({peak.weight}), but fewer "
504
+ f"total iterations {block_record.total_iters} "
505
+ f"peak: {peak.total_iters} "
506
+ f"peak-hash: {peak.header_hash}"
507
+ )
508
+
509
+ if block_record.prev_hash != peak.header_hash:
510
+ for coin_record in await self.coin_store.rollback_to_block(fork_info.fork_height):
511
+ rolled_back_state[coin_record.name] = coin_record
512
+ if self._log_coins and len(rolled_back_state) > 0:
513
+ log.info(f"rolled back {len(rolled_back_state)} coins, to fork height {fork_info.fork_height}")
514
+ log.info(
515
+ "removed: %s",
516
+ ",".join(
517
+ [
518
+ name.hex()[0:6]
519
+ for name, state in rolled_back_state.items()
520
+ if state.confirmed_block_index == 0
521
+ ]
522
+ ),
523
+ )
524
+ log.info(
525
+ "unspent: %s",
526
+ ",".join(
527
+ [
528
+ name.hex()[0:6]
529
+ for name, state in rolled_back_state.items()
530
+ if state.confirmed_block_index != 0
531
+ ]
532
+ ),
533
+ )
534
+
535
+ # Collects all blocks from fork point to new peak
536
+ records_to_add: list[BlockRecord] = []
537
+
538
+ if genesis:
539
+ records_to_add = [block_record]
540
+ elif fork_info.block_hashes == [block_record.header_hash]:
541
+ # in the common case, we just add a block on top of the chain. Check
542
+ # for that here to avoid an unnecessary database lookup.
543
+ records_to_add = [block_record]
544
+ else:
545
+ records_to_add = await self.block_store.get_block_records_by_hash(fork_info.block_hashes)
546
+
547
+ for fetched_block_record in records_to_add:
548
+ if not fetched_block_record.is_transaction_block:
549
+ # Coins are only created in TX blocks so there are no state updates for this block
550
+ continue
551
+
552
+ height = fetched_block_record.height
553
+ # We need to recompute the additions and removals, since they are
554
+ # not stored on DB. We have all the additions and removals in the
555
+ # fork_info object, we just need to pick the ones belonging to each
556
+ # individual block height
557
+
558
+ # Apply the coin store changes for each block that is now in the blockchain
559
+ included_reward_coins = [
560
+ fork_add.coin
561
+ for fork_add in fork_info.additions_since_fork.values()
562
+ if fork_add.confirmed_height == height and fork_add.is_coinbase
563
+ ]
564
+ tx_additions = [
565
+ fork_add.coin
566
+ for fork_add in fork_info.additions_since_fork.values()
567
+ if fork_add.confirmed_height == height and not fork_add.is_coinbase
568
+ ]
569
+ tx_removals = [
570
+ coin_id for coin_id, fork_rem in fork_info.removals_since_fork.items() if fork_rem.height == height
571
+ ]
572
+ assert fetched_block_record.timestamp is not None
573
+ await self.coin_store.new_block(
574
+ height,
575
+ fetched_block_record.timestamp,
576
+ included_reward_coins,
577
+ tx_additions,
578
+ tx_removals,
579
+ )
580
+ if self._log_coins and (len(tx_removals) > 0 or len(tx_additions) > 0):
581
+ log.info(
582
+ f"adding new block to coin_store "
583
+ f"(hh: {fetched_block_record.header_hash} "
584
+ f"height: {fetched_block_record.height}), {len(tx_removals)} spends"
585
+ )
586
+ log.info("rewards: %s", ",".join([add.name().hex()[0:6] for add in included_reward_coins]))
587
+ log.info("additions: %s", ",".join([add.name().hex()[0:6] for add in tx_additions]))
588
+ log.info("removals: %s", ",".join([f"{rem}"[0:6] for rem in tx_removals]))
589
+
590
+ # we made it to the end successfully
591
+ # Rollback sub_epoch_summaries
592
+ await self.block_store.rollback(fork_info.fork_height)
593
+ await self.block_store.set_in_chain([(br.header_hash,) for br in records_to_add])
594
+
595
+ # Changes the peak to be the new peak
596
+ await self.block_store.set_peak(block_record.header_hash)
597
+
598
+ return records_to_add, StateChangeSummary(
599
+ block_record,
600
+ uint32(max(fork_info.fork_height, 0)),
601
+ list(rolled_back_state.values()),
602
+ [(coin_id, fork_rem.puzzle_hash) for coin_id, fork_rem in fork_info.removals_since_fork.items()],
603
+ [
604
+ (fork_add.coin, fork_add.hint)
605
+ for fork_add in fork_info.additions_since_fork.values()
606
+ if not fork_add.is_coinbase
607
+ ],
608
+ [fork_add.coin for fork_add in fork_info.additions_since_fork.values() if fork_add.is_coinbase],
609
+ )
610
+
611
+ def get_next_difficulty(self, header_hash: bytes32, new_slot: bool) -> uint64:
612
+ assert self.contains_block(header_hash)
613
+ curr = self.block_record(header_hash)
614
+ if curr.height <= 2:
615
+ return self.constants.DIFFICULTY_STARTING
616
+
617
+ return get_next_sub_slot_iters_and_difficulty(self.constants, new_slot, curr, self)[1]
618
+
619
+ def get_next_slot_iters(self, header_hash: bytes32, new_slot: bool) -> uint64:
620
+ assert self.contains_block(header_hash)
621
+ curr = self.block_record(header_hash)
622
+ if curr.height <= 2:
623
+ return self.constants.SUB_SLOT_ITERS_STARTING
624
+ return get_next_sub_slot_iters_and_difficulty(self.constants, new_slot, curr, self)[0]
625
+
626
+ async def get_sp_and_ip_sub_slots(
627
+ self, header_hash: bytes32
628
+ ) -> Optional[tuple[Optional[EndOfSubSlotBundle], Optional[EndOfSubSlotBundle]]]:
629
+ block: Optional[FullBlock] = await self.block_store.get_full_block(header_hash)
630
+ if block is None:
631
+ return None
632
+ curr_br: BlockRecord = self.block_record(block.header_hash)
633
+ is_overflow = curr_br.overflow
634
+
635
+ curr: Optional[FullBlock] = block
636
+ assert curr is not None
637
+ while True:
638
+ if curr_br.first_in_sub_slot:
639
+ curr = await self.block_store.get_full_block(curr_br.header_hash)
640
+ assert curr is not None
641
+ break
642
+ if curr_br.height == 0:
643
+ break
644
+ curr_br = self.block_record(curr_br.prev_hash)
645
+
646
+ if len(curr.finished_sub_slots) == 0:
647
+ # This means we got to genesis and still no sub-slots
648
+ return None, None
649
+
650
+ ip_sub_slot = curr.finished_sub_slots[-1]
651
+
652
+ if not is_overflow:
653
+ # Pos sub-slot is the same as infusion sub slot
654
+ return None, ip_sub_slot
655
+
656
+ if len(curr.finished_sub_slots) > 1:
657
+ # Have both sub-slots
658
+ return curr.finished_sub_slots[-2], ip_sub_slot
659
+
660
+ prev_curr: Optional[FullBlock] = await self.block_store.get_full_block(curr.prev_header_hash)
661
+ if prev_curr is None:
662
+ assert curr.height == 0
663
+ prev_curr = curr
664
+ prev_curr_br = self.block_record(curr.header_hash)
665
+ else:
666
+ prev_curr_br = self.block_record(curr.prev_header_hash)
667
+ assert prev_curr_br is not None
668
+ while prev_curr_br.height > 0:
669
+ if prev_curr_br.first_in_sub_slot:
670
+ prev_curr = await self.block_store.get_full_block(prev_curr_br.header_hash)
671
+ assert prev_curr is not None
672
+ break
673
+ prev_curr_br = self.block_record(prev_curr_br.prev_hash)
674
+
675
+ if len(prev_curr.finished_sub_slots) == 0:
676
+ return None, ip_sub_slot
677
+ return prev_curr.finished_sub_slots[-1], ip_sub_slot
678
+
679
+ def get_recent_reward_challenges(self) -> list[tuple[bytes32, uint128]]:
680
+ peak = self.get_peak()
681
+ if peak is None:
682
+ return []
683
+ recent_rc: list[tuple[bytes32, uint128]] = []
684
+ curr: Optional[BlockRecord] = peak
685
+ while curr is not None and len(recent_rc) < 2 * self.constants.MAX_SUB_SLOT_BLOCKS:
686
+ if curr != peak:
687
+ recent_rc.append((curr.reward_infusion_new_challenge, curr.total_iters))
688
+ if curr.first_in_sub_slot:
689
+ assert curr.finished_reward_slot_hashes is not None
690
+ sub_slot_total_iters = curr.ip_sub_slot_total_iters(self.constants)
691
+ # Start from the most recent
692
+ for rc in reversed(curr.finished_reward_slot_hashes):
693
+ if sub_slot_total_iters < curr.sub_slot_iters:
694
+ break
695
+ recent_rc.append((rc, sub_slot_total_iters))
696
+ sub_slot_total_iters = uint128(sub_slot_total_iters - curr.sub_slot_iters)
697
+ curr = self.try_block_record(curr.prev_hash)
698
+ return list(reversed(recent_rc))
699
+
700
+ async def validate_unfinished_block_header(
701
+ self, block: UnfinishedBlock, skip_overflow_ss_validation: bool = True
702
+ ) -> tuple[Optional[uint64], Optional[Err]]:
703
+ if len(block.transactions_generator_ref_list) > self.constants.MAX_GENERATOR_REF_LIST_SIZE:
704
+ return None, Err.TOO_MANY_GENERATOR_REFS
705
+
706
+ if (
707
+ not self.contains_block(block.prev_header_hash)
708
+ and block.prev_header_hash != self.constants.GENESIS_CHALLENGE
709
+ ):
710
+ return None, Err.INVALID_PREV_BLOCK_HASH
711
+
712
+ if block.transactions_info is not None:
713
+ if block.transactions_generator is not None:
714
+ if std_hash(bytes(block.transactions_generator)) != block.transactions_info.generator_root:
715
+ return None, Err.INVALID_TRANSACTIONS_GENERATOR_HASH
716
+ else:
717
+ if block.transactions_info.generator_root != bytes([0] * 32):
718
+ return None, Err.INVALID_TRANSACTIONS_GENERATOR_HASH
719
+
720
+ if (
721
+ block.foliage_transaction_block is None
722
+ or block.foliage_transaction_block.transactions_info_hash != block.transactions_info.get_hash()
723
+ ):
724
+ return None, Err.INVALID_TRANSACTIONS_INFO_HASH
725
+ else:
726
+ # make sure non-tx blocks don't have these fields
727
+ if block.transactions_generator is not None:
728
+ return None, Err.INVALID_TRANSACTIONS_GENERATOR_HASH
729
+ if block.foliage_transaction_block is not None:
730
+ return None, Err.INVALID_TRANSACTIONS_INFO_HASH
731
+
732
+ unfinished_header_block = UnfinishedHeaderBlock(
733
+ block.finished_sub_slots,
734
+ block.reward_chain_block,
735
+ block.challenge_chain_sp_proof,
736
+ block.reward_chain_sp_proof,
737
+ block.foliage,
738
+ block.foliage_transaction_block,
739
+ b"",
740
+ )
741
+ prev_b = self.try_block_record(unfinished_header_block.prev_header_hash)
742
+ sub_slot_iters, difficulty = get_next_sub_slot_iters_and_difficulty(
743
+ self.constants, len(unfinished_header_block.finished_sub_slots) > 0, prev_b, self
744
+ )
745
+ expected_vs = ValidationState(sub_slot_iters, difficulty, None)
746
+ required_iters, error = validate_unfinished_header_block(
747
+ self.constants,
748
+ self,
749
+ unfinished_header_block,
750
+ False,
751
+ expected_vs,
752
+ skip_overflow_ss_validation,
753
+ )
754
+ if error is not None:
755
+ return required_iters, error.code
756
+ return required_iters, None
757
+
758
+ async def validate_unfinished_block(
759
+ self, block: UnfinishedBlock, npc_result: Optional[NPCResult], skip_overflow_ss_validation: bool = True
760
+ ) -> PreValidationResult:
761
+ required_iters, error = await self.validate_unfinished_block_header(block, skip_overflow_ss_validation)
762
+
763
+ if error is not None:
764
+ return PreValidationResult(uint16(error.value), None, None, uint32(0))
765
+
766
+ prev_height = (
767
+ -1
768
+ if block.prev_header_hash == self.constants.GENESIS_CHALLENGE
769
+ else self.block_record(block.prev_header_hash).height
770
+ )
771
+
772
+ fork_info = ForkInfo(prev_height, prev_height, block.prev_header_hash)
773
+
774
+ conds = None if npc_result is None else npc_result.conds
775
+ error_code = await validate_block_body(
776
+ self.constants,
777
+ self,
778
+ self.coin_store.get_coin_records,
779
+ block,
780
+ uint32(prev_height + 1),
781
+ conds,
782
+ fork_info,
783
+ log_coins=self._log_coins,
784
+ )
785
+
786
+ if error_code is not None:
787
+ return PreValidationResult(uint16(error_code.value), None, None, uint32(0))
788
+
789
+ return PreValidationResult(None, required_iters, conds, uint32(0))
790
+
791
+ def contains_block(self, header_hash: bytes32) -> bool:
792
+ """
793
+ True if we have already added this block to the chain. This may return false for orphan blocks
794
+ that we have added but no longer keep in memory.
795
+ """
796
+ return header_hash in self.__block_records
797
+
798
+ def block_record(self, header_hash: bytes32) -> BlockRecord:
799
+ return self.__block_records[header_hash]
800
+
801
+ def height_to_block_record(self, height: uint32) -> BlockRecord:
802
+ # Precondition: height is in the blockchain
803
+ header_hash: Optional[bytes32] = self.height_to_hash(height)
804
+ if header_hash is None:
805
+ raise ValueError(f"Height is not in blockchain: {height}")
806
+ return self.block_record(header_hash)
807
+
808
+ def get_ses_heights(self) -> list[uint32]:
809
+ return self.__height_map.get_ses_heights()
810
+
811
+ def get_ses(self, height: uint32) -> SubEpochSummary:
812
+ return self.__height_map.get_ses(height)
813
+
814
+ def height_to_hash(self, height: uint32) -> Optional[bytes32]:
815
+ if not self.__height_map.contains_height(height):
816
+ return None
817
+ return self.__height_map.get_hash(height)
818
+
819
+ def contains_height(self, height: uint32) -> bool:
820
+ return self.__height_map.contains_height(height)
821
+
822
+ def get_peak_height(self) -> Optional[uint32]:
823
+ return self._peak_height
824
+
825
+ async def warmup(self, fork_point: uint32) -> None:
826
+ """
827
+ Loads blocks into the cache. The blocks loaded include all blocks from
828
+ fork point - BLOCKS_CACHE_SIZE up to and including the fork_point.
829
+
830
+ Args:
831
+ fork_point: the last block height to load in the cache
832
+
833
+ """
834
+ if self._peak_height is None:
835
+ return None
836
+ block_records = await self.block_store.get_block_records_in_range(
837
+ max(fork_point - self.constants.BLOCKS_CACHE_SIZE, uint32(0)), fork_point
838
+ )
839
+ for block_record in block_records.values():
840
+ self.add_block_record(block_record)
841
+
842
+ def clean_block_record(self, height: int) -> None:
843
+ """
844
+ Clears all block records in the cache which have block_record < height.
845
+ Args:
846
+ height: Minimum height that we need to keep in the cache
847
+ """
848
+ if self._peak_height is not None and height > self._peak_height - self.constants.BLOCKS_CACHE_SIZE:
849
+ height = self._peak_height - self.constants.BLOCKS_CACHE_SIZE
850
+ if height < 0:
851
+ return None
852
+ blocks_to_remove = self.__heights_in_cache.get(uint32(height), None)
853
+ while blocks_to_remove is not None and height >= 0:
854
+ for header_hash in blocks_to_remove:
855
+ del self.__block_records[header_hash] # remove from blocks
856
+ del self.__heights_in_cache[uint32(height)] # remove height from heights in cache
857
+
858
+ if height == 0:
859
+ break
860
+ height -= 1
861
+ blocks_to_remove = self.__heights_in_cache.get(uint32(height), None)
862
+
863
+ def clean_block_records(self) -> None:
864
+ """
865
+ Cleans the cache so that we only maintain relevant blocks. This removes
866
+ block records that have height < peak - BLOCKS_CACHE_SIZE.
867
+ These blocks are necessary for calculating future difficulty adjustments.
868
+ """
869
+
870
+ if len(self.__block_records) < self.constants.BLOCKS_CACHE_SIZE:
871
+ return None
872
+
873
+ assert self._peak_height is not None
874
+ if self._peak_height - self.constants.BLOCKS_CACHE_SIZE < 0:
875
+ return None
876
+ self.clean_block_record(self._peak_height - self.constants.BLOCKS_CACHE_SIZE)
877
+
878
+ async def get_block_records_in_range(self, start: int, stop: int) -> dict[bytes32, BlockRecord]:
879
+ return await self.block_store.get_block_records_in_range(start, stop)
880
+
881
+ async def get_header_blocks_in_range(
882
+ self, start: int, stop: int, tx_filter: bool = True
883
+ ) -> dict[bytes32, HeaderBlock]:
884
+ hashes = []
885
+ for height in range(start, stop + 1):
886
+ header_hash: Optional[bytes32] = self.height_to_hash(uint32(height))
887
+ if header_hash is not None:
888
+ hashes.append(header_hash)
889
+
890
+ blocks: list[FullBlock] = []
891
+ for hash in hashes.copy():
892
+ block = self.block_store.block_cache.get(hash)
893
+ if block is not None:
894
+ blocks.append(block)
895
+ hashes.remove(hash)
896
+ blocks_on_disk: list[FullBlock] = await self.block_store.get_blocks_by_hash(hashes)
897
+ blocks.extend(blocks_on_disk)
898
+ header_blocks: dict[bytes32, HeaderBlock] = {}
899
+
900
+ for block in blocks:
901
+ if self.height_to_hash(block.height) != block.header_hash:
902
+ raise ValueError(f"Block at {block.header_hash} is no longer in the blockchain (it's in a fork)")
903
+ if tx_filter is False:
904
+ header = get_block_header(block)
905
+ elif block.transactions_generator is not None:
906
+ added_coins_records, removed_coins_records = await asyncio.gather(
907
+ self.coin_store.get_coins_added_at_height(block.height),
908
+ self.coin_store.get_coins_removed_at_height(block.height),
909
+ )
910
+ tx_additions = [cr.coin for cr in added_coins_records if not cr.coinbase]
911
+ removed = [cr.coin.name() for cr in removed_coins_records]
912
+ header = get_block_header(block, (removed, tx_additions))
913
+ elif block.is_transaction_block():
914
+ # This is a transaction block with just reward coins.
915
+ # We're sending empty additions and removals to signal that we
916
+ # want the transactions filter to be computed.
917
+ header = get_block_header(block, ([], []))
918
+ else:
919
+ # Non transaction block.
920
+ header = get_block_header(block)
921
+ header_blocks[header.header_hash] = header
922
+
923
+ return header_blocks
924
+
925
+ async def get_header_block_by_height(
926
+ self, height: int, header_hash: bytes32, tx_filter: bool = True
927
+ ) -> Optional[HeaderBlock]:
928
+ header_dict: dict[bytes32, HeaderBlock] = await self.get_header_blocks_in_range(height, height, tx_filter)
929
+ if len(header_dict) == 0:
930
+ return None
931
+ if header_hash not in header_dict:
932
+ return None
933
+ return header_dict[header_hash]
934
+
935
+ async def get_block_records_at(self, heights: list[uint32], batch_size: int = 900) -> list[BlockRecord]:
936
+ """
937
+ gets block records by height (only blocks that are part of the chain)
938
+ """
939
+ records: list[BlockRecord] = []
940
+ hashes: list[bytes32] = []
941
+ assert batch_size < self.block_store.db_wrapper.host_parameter_limit
942
+ for height in heights:
943
+ header_hash: Optional[bytes32] = self.height_to_hash(height)
944
+ if header_hash is None:
945
+ raise ValueError(f"Do not have block at height {height}")
946
+ hashes.append(header_hash)
947
+ if len(hashes) > batch_size:
948
+ res = await self.block_store.get_block_records_by_hash(hashes)
949
+ records.extend(res)
950
+ hashes = []
951
+
952
+ if len(hashes) > 0:
953
+ res = await self.block_store.get_block_records_by_hash(hashes)
954
+ records.extend(res)
955
+ return records
956
+
957
+ def try_block_record(self, header_hash: bytes32) -> Optional[BlockRecord]:
958
+ if self.contains_block(header_hash):
959
+ return self.block_record(header_hash)
960
+ return None
961
+
962
+ async def get_block_record_from_db(self, header_hash: bytes32) -> Optional[BlockRecord]:
963
+ ret = self.__block_records.get(header_hash)
964
+ if ret is not None:
965
+ return ret
966
+ return await self.block_store.get_block_record(header_hash)
967
+
968
+ async def prev_block_hash(self, header_hashes: list[bytes32]) -> list[bytes32]:
969
+ """
970
+ Given a list of block header hashes, returns the previous header hashes
971
+ for each block, in the order they were passed in.
972
+ """
973
+ ret = []
974
+ for h in header_hashes:
975
+ b = self.__block_records.get(h)
976
+ if b is not None:
977
+ ret.append(b.prev_hash)
978
+ else:
979
+ ret.append(await self.block_store.get_prev_hash(h))
980
+ return ret
981
+
982
+ async def contains_block_from_db(self, header_hash: bytes32) -> bool:
983
+ ret = header_hash in self.__block_records
984
+ if ret:
985
+ return True
986
+
987
+ return (await self.block_store.get_block_record(header_hash)) is not None
988
+
989
+ def remove_block_record(self, header_hash: bytes32) -> None:
990
+ sbr = self.block_record(header_hash)
991
+ del self.__block_records[header_hash]
992
+ self.__heights_in_cache[sbr.height].remove(header_hash)
993
+
994
+ def add_block_record(self, block_record: BlockRecord) -> None:
995
+ """
996
+ Adds a block record to the cache.
997
+ """
998
+
999
+ self.__block_records[block_record.header_hash] = block_record
1000
+ if block_record.height not in self.__heights_in_cache.keys():
1001
+ self.__heights_in_cache[block_record.height] = set()
1002
+ self.__heights_in_cache[block_record.height].add(block_record.header_hash)
1003
+
1004
+ async def persist_sub_epoch_challenge_segments(
1005
+ self, ses_block_hash: bytes32, segments: list[SubEpochChallengeSegment]
1006
+ ) -> None:
1007
+ await self.block_store.persist_sub_epoch_challenge_segments(ses_block_hash, segments)
1008
+
1009
+ async def get_sub_epoch_challenge_segments(
1010
+ self,
1011
+ ses_block_hash: bytes32,
1012
+ ) -> Optional[list[SubEpochChallengeSegment]]:
1013
+ segments: Optional[list[SubEpochChallengeSegment]] = await self.block_store.get_sub_epoch_challenge_segments(
1014
+ ses_block_hash
1015
+ )
1016
+ if segments is None:
1017
+ return None
1018
+ return segments
1019
+
1020
+ # Returns 'True' if the info is already in the set, otherwise returns 'False' and stores it.
1021
+ def seen_compact_proofs(self, vdf_info: VDFInfo, height: uint32) -> bool:
1022
+ pot_tuple = (vdf_info, height)
1023
+ if pot_tuple in self._seen_compact_proofs:
1024
+ return True
1025
+ # Periodically cleanup to keep size small. TODO: make this smarter, like FIFO.
1026
+ if len(self._seen_compact_proofs) > 10000:
1027
+ self._seen_compact_proofs.clear()
1028
+ self._seen_compact_proofs.add(pot_tuple)
1029
+ return False
1030
+
1031
+ async def lookup_block_generators(self, header_hash: bytes32, generator_refs: set[uint32]) -> dict[uint32, bytes]:
1032
+ generators: dict[uint32, bytes] = {}
1033
+
1034
+ # if this is empty, we shouldn't have called this function to begin with
1035
+ assert len(generator_refs)
1036
+
1037
+ # The block heights in the transactions_generator_ref_list don't
1038
+ # necessarily refer to the main chain. The generators may be found in 2
1039
+ # different places. A fork of the chain (but in the database) or in
1040
+ # the main chain.
1041
+
1042
+ # * <- header_hash
1043
+ # | :
1044
+ # peak -> * | : reorg_chain
1045
+ # \ / :
1046
+ # \ / :
1047
+ # * <- fork point
1048
+ # : |
1049
+ # main : |
1050
+ # chain : |
1051
+ # : |
1052
+ # : * <- genesis
1053
+
1054
+ # If the block is not part of the main chain, we're on a fork, and we
1055
+ # need to find the fork point
1056
+ peak_block = await self.get_block_record_from_db(header_hash)
1057
+ assert peak_block is not None
1058
+ if self.height_to_hash(peak_block.height) != header_hash:
1059
+ peak: Optional[BlockRecord] = self.get_peak()
1060
+ assert peak is not None
1061
+ reorg_chain: dict[uint32, bytes32]
1062
+ # Then we look up blocks up to fork point one at a time, backtracking
1063
+ reorg_chain, _ = await lookup_fork_chain(
1064
+ self,
1065
+ (peak.height, peak.header_hash),
1066
+ (peak_block.height, peak_block.header_hash),
1067
+ self.constants,
1068
+ )
1069
+
1070
+ remaining_refs = set()
1071
+ for ref_height in generator_refs:
1072
+ if ref_height in reorg_chain:
1073
+ gen = await self.block_store.get_generator(reorg_chain[ref_height])
1074
+ if gen is None:
1075
+ raise ValueError(Err.GENERATOR_REF_HAS_NO_GENERATOR)
1076
+ generators[ref_height] = gen
1077
+ else:
1078
+ remaining_refs.add(ref_height)
1079
+ else:
1080
+ remaining_refs = generator_refs
1081
+
1082
+ if len(remaining_refs) > 0:
1083
+ # any remaining references fall in the main chain, and can be looked up
1084
+ # in a single query
1085
+ generators.update(await self.block_store.get_generators_at(remaining_refs))
1086
+
1087
+ return generators