chia-blockchain 2.4.4__py3-none-any.whl

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