chia-blockchain 2.5.1rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1042) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +195 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +145 -0
  9. chia/_tests/blockchain/test_blockchain.py +4202 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1031 -0
  11. chia/_tests/blockchain/test_build_chains.py +59 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +194 -0
  14. chia/_tests/build-init-files.py +92 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +72 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +149 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +55 -0
  26. chia/_tests/clvm/test_message_conditions.py +184 -0
  27. chia/_tests/clvm/test_program.py +150 -0
  28. chia/_tests/clvm/test_puzzle_compression.py +143 -0
  29. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  30. chia/_tests/clvm/test_puzzles.py +242 -0
  31. chia/_tests/clvm/test_singletons.py +540 -0
  32. chia/_tests/clvm/test_spend_sim.py +181 -0
  33. chia/_tests/cmds/__init__.py +0 -0
  34. chia/_tests/cmds/cmd_test_utils.py +469 -0
  35. chia/_tests/cmds/config.py +3 -0
  36. chia/_tests/cmds/conftest.py +23 -0
  37. chia/_tests/cmds/test_click_types.py +200 -0
  38. chia/_tests/cmds/test_cmd_framework.py +620 -0
  39. chia/_tests/cmds/test_cmds_util.py +97 -0
  40. chia/_tests/cmds/test_daemon.py +92 -0
  41. chia/_tests/cmds/test_dev_gh.py +131 -0
  42. chia/_tests/cmds/test_farm_cmd.py +66 -0
  43. chia/_tests/cmds/test_show.py +116 -0
  44. chia/_tests/cmds/test_sim.py +207 -0
  45. chia/_tests/cmds/test_timelock_args.py +75 -0
  46. chia/_tests/cmds/test_tx_config_args.py +154 -0
  47. chia/_tests/cmds/testing_classes.py +59 -0
  48. chia/_tests/cmds/wallet/__init__.py +0 -0
  49. chia/_tests/cmds/wallet/test_consts.py +47 -0
  50. chia/_tests/cmds/wallet/test_dao.py +565 -0
  51. chia/_tests/cmds/wallet/test_did.py +403 -0
  52. chia/_tests/cmds/wallet/test_nft.py +471 -0
  53. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  54. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  55. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  56. chia/_tests/cmds/wallet/test_vcs.py +400 -0
  57. chia/_tests/cmds/wallet/test_wallet.py +1125 -0
  58. chia/_tests/cmds/wallet/test_wallet_check.py +109 -0
  59. chia/_tests/conftest.py +1419 -0
  60. chia/_tests/connection_utils.py +125 -0
  61. chia/_tests/core/__init__.py +0 -0
  62. chia/_tests/core/cmds/__init__.py +0 -0
  63. chia/_tests/core/cmds/test_beta.py +382 -0
  64. chia/_tests/core/cmds/test_keys.py +1734 -0
  65. chia/_tests/core/cmds/test_wallet.py +126 -0
  66. chia/_tests/core/config.py +3 -0
  67. chia/_tests/core/consensus/__init__.py +0 -0
  68. chia/_tests/core/consensus/test_block_creation.py +54 -0
  69. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  70. chia/_tests/core/custom_types/__init__.py +0 -0
  71. chia/_tests/core/custom_types/test_coin.py +107 -0
  72. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  73. chia/_tests/core/custom_types/test_spend_bundle.py +70 -0
  74. chia/_tests/core/daemon/__init__.py +0 -0
  75. chia/_tests/core/daemon/config.py +4 -0
  76. chia/_tests/core/daemon/test_daemon.py +2128 -0
  77. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  78. chia/_tests/core/daemon/test_keychain_proxy.py +101 -0
  79. chia/_tests/core/data_layer/__init__.py +0 -0
  80. chia/_tests/core/data_layer/config.py +5 -0
  81. chia/_tests/core/data_layer/conftest.py +106 -0
  82. chia/_tests/core/data_layer/test_data_cli.py +56 -0
  83. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  84. chia/_tests/core/data_layer/test_data_layer_util.py +218 -0
  85. chia/_tests/core/data_layer/test_data_rpc.py +3847 -0
  86. chia/_tests/core/data_layer/test_data_store.py +2424 -0
  87. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  88. chia/_tests/core/data_layer/test_plugin.py +91 -0
  89. chia/_tests/core/data_layer/util.py +233 -0
  90. chia/_tests/core/farmer/__init__.py +0 -0
  91. chia/_tests/core/farmer/config.py +3 -0
  92. chia/_tests/core/farmer/test_farmer_api.py +103 -0
  93. chia/_tests/core/full_node/__init__.py +0 -0
  94. chia/_tests/core/full_node/config.py +4 -0
  95. chia/_tests/core/full_node/dos/__init__.py +0 -0
  96. chia/_tests/core/full_node/dos/config.py +3 -0
  97. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  98. chia/_tests/core/full_node/full_sync/config.py +4 -0
  99. chia/_tests/core/full_node/full_sync/test_full_sync.py +443 -0
  100. chia/_tests/core/full_node/ram_db.py +27 -0
  101. chia/_tests/core/full_node/stores/__init__.py +0 -0
  102. chia/_tests/core/full_node/stores/config.py +4 -0
  103. chia/_tests/core/full_node/stores/test_block_store.py +590 -0
  104. chia/_tests/core/full_node/stores/test_coin_store.py +897 -0
  105. chia/_tests/core/full_node/stores/test_full_node_store.py +1219 -0
  106. chia/_tests/core/full_node/stores/test_hint_store.py +229 -0
  107. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  108. chia/_tests/core/full_node/test_address_manager.py +588 -0
  109. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  110. chia/_tests/core/full_node/test_conditions.py +556 -0
  111. chia/_tests/core/full_node/test_full_node.py +2700 -0
  112. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  113. chia/_tests/core/full_node/test_hint_management.py +104 -0
  114. chia/_tests/core/full_node/test_node_load.py +34 -0
  115. chia/_tests/core/full_node/test_performance.py +179 -0
  116. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  117. chia/_tests/core/full_node/test_transactions.py +203 -0
  118. chia/_tests/core/full_node/test_tx_processing_queue.py +155 -0
  119. chia/_tests/core/large_block.py +2388 -0
  120. chia/_tests/core/make_block_generator.py +70 -0
  121. chia/_tests/core/mempool/__init__.py +0 -0
  122. chia/_tests/core/mempool/config.py +4 -0
  123. chia/_tests/core/mempool/test_mempool.py +3255 -0
  124. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  125. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  126. chia/_tests/core/mempool/test_mempool_item_queries.py +190 -0
  127. chia/_tests/core/mempool/test_mempool_manager.py +2084 -0
  128. chia/_tests/core/mempool/test_mempool_performance.py +64 -0
  129. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  130. chia/_tests/core/node_height.py +28 -0
  131. chia/_tests/core/server/__init__.py +0 -0
  132. chia/_tests/core/server/config.py +3 -0
  133. chia/_tests/core/server/flood.py +84 -0
  134. chia/_tests/core/server/serve.py +135 -0
  135. chia/_tests/core/server/test_api_protocol.py +21 -0
  136. chia/_tests/core/server/test_capabilities.py +66 -0
  137. chia/_tests/core/server/test_dos.py +319 -0
  138. chia/_tests/core/server/test_event_loop.py +109 -0
  139. chia/_tests/core/server/test_loop.py +294 -0
  140. chia/_tests/core/server/test_node_discovery.py +73 -0
  141. chia/_tests/core/server/test_rate_limits.py +482 -0
  142. chia/_tests/core/server/test_server.py +226 -0
  143. chia/_tests/core/server/test_upnp.py +8 -0
  144. chia/_tests/core/services/__init__.py +0 -0
  145. chia/_tests/core/services/config.py +3 -0
  146. chia/_tests/core/services/test_services.py +188 -0
  147. chia/_tests/core/ssl/__init__.py +0 -0
  148. chia/_tests/core/ssl/config.py +3 -0
  149. chia/_tests/core/ssl/test_ssl.py +202 -0
  150. chia/_tests/core/test_coins.py +33 -0
  151. chia/_tests/core/test_cost_calculation.py +313 -0
  152. chia/_tests/core/test_crawler.py +175 -0
  153. chia/_tests/core/test_crawler_rpc.py +53 -0
  154. chia/_tests/core/test_daemon_rpc.py +24 -0
  155. chia/_tests/core/test_db_conversion.py +130 -0
  156. chia/_tests/core/test_db_validation.py +162 -0
  157. chia/_tests/core/test_farmer_harvester_rpc.py +505 -0
  158. chia/_tests/core/test_filter.py +35 -0
  159. chia/_tests/core/test_full_node_rpc.py +768 -0
  160. chia/_tests/core/test_merkle_set.py +343 -0
  161. chia/_tests/core/test_program.py +47 -0
  162. chia/_tests/core/test_rpc_util.py +86 -0
  163. chia/_tests/core/test_seeder.py +420 -0
  164. chia/_tests/core/test_setproctitle.py +13 -0
  165. chia/_tests/core/util/__init__.py +0 -0
  166. chia/_tests/core/util/config.py +4 -0
  167. chia/_tests/core/util/test_block_cache.py +44 -0
  168. chia/_tests/core/util/test_cached_bls.py +57 -0
  169. chia/_tests/core/util/test_config.py +337 -0
  170. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  171. chia/_tests/core/util/test_files.py +391 -0
  172. chia/_tests/core/util/test_jsonify.py +146 -0
  173. chia/_tests/core/util/test_keychain.py +522 -0
  174. chia/_tests/core/util/test_keyring_wrapper.py +491 -0
  175. chia/_tests/core/util/test_lockfile.py +380 -0
  176. chia/_tests/core/util/test_log_exceptions.py +187 -0
  177. chia/_tests/core/util/test_lru_cache.py +56 -0
  178. chia/_tests/core/util/test_significant_bits.py +40 -0
  179. chia/_tests/core/util/test_streamable.py +883 -0
  180. chia/_tests/db/__init__.py +0 -0
  181. chia/_tests/db/test_db_wrapper.py +566 -0
  182. chia/_tests/environments/__init__.py +0 -0
  183. chia/_tests/environments/common.py +35 -0
  184. chia/_tests/environments/full_node.py +47 -0
  185. chia/_tests/environments/wallet.py +429 -0
  186. chia/_tests/ether.py +19 -0
  187. chia/_tests/farmer_harvester/__init__.py +0 -0
  188. chia/_tests/farmer_harvester/config.py +3 -0
  189. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  190. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  191. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +131 -0
  192. chia/_tests/farmer_harvester/test_third_party_harvesters.py +528 -0
  193. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  194. chia/_tests/fee_estimation/__init__.py +0 -0
  195. chia/_tests/fee_estimation/config.py +3 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  197. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  198. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +144 -0
  199. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  200. chia/_tests/generator/__init__.py +0 -0
  201. chia/_tests/generator/puzzles/__init__.py +0 -0
  202. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  203. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  204. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  205. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  206. chia/_tests/generator/test_compression.py +201 -0
  207. chia/_tests/generator/test_generator_types.py +44 -0
  208. chia/_tests/generator/test_rom.py +180 -0
  209. chia/_tests/plot_sync/__init__.py +0 -0
  210. chia/_tests/plot_sync/config.py +3 -0
  211. chia/_tests/plot_sync/test_delta.py +101 -0
  212. chia/_tests/plot_sync/test_plot_sync.py +618 -0
  213. chia/_tests/plot_sync/test_receiver.py +451 -0
  214. chia/_tests/plot_sync/test_sender.py +116 -0
  215. chia/_tests/plot_sync/test_sync_simulated.py +451 -0
  216. chia/_tests/plot_sync/util.py +68 -0
  217. chia/_tests/plotting/__init__.py +0 -0
  218. chia/_tests/plotting/config.py +3 -0
  219. chia/_tests/plotting/test_plot_manager.py +781 -0
  220. chia/_tests/plotting/util.py +12 -0
  221. chia/_tests/pools/__init__.py +0 -0
  222. chia/_tests/pools/config.py +5 -0
  223. chia/_tests/pools/test_pool_cli_parsing.py +128 -0
  224. chia/_tests/pools/test_pool_cmdline.py +1001 -0
  225. chia/_tests/pools/test_pool_config.py +42 -0
  226. chia/_tests/pools/test_pool_puzzles_lifecycle.py +397 -0
  227. chia/_tests/pools/test_pool_rpc.py +1123 -0
  228. chia/_tests/pools/test_pool_wallet.py +205 -0
  229. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  230. chia/_tests/process_junit.py +348 -0
  231. chia/_tests/rpc/__init__.py +0 -0
  232. chia/_tests/rpc/test_rpc_client.py +138 -0
  233. chia/_tests/rpc/test_rpc_server.py +183 -0
  234. chia/_tests/simulation/__init__.py +0 -0
  235. chia/_tests/simulation/config.py +6 -0
  236. chia/_tests/simulation/test_simulation.py +501 -0
  237. chia/_tests/simulation/test_simulator.py +232 -0
  238. chia/_tests/simulation/test_start_simulator.py +107 -0
  239. chia/_tests/testconfig.py +13 -0
  240. chia/_tests/timelord/__init__.py +0 -0
  241. chia/_tests/timelord/config.py +3 -0
  242. chia/_tests/timelord/test_new_peak.py +437 -0
  243. chia/_tests/timelord/test_timelord.py +11 -0
  244. chia/_tests/tools/1315537.json +170 -0
  245. chia/_tests/tools/1315544.json +160 -0
  246. chia/_tests/tools/1315630.json +150 -0
  247. chia/_tests/tools/300000.json +105 -0
  248. chia/_tests/tools/442734.json +140 -0
  249. chia/_tests/tools/466212.json +130 -0
  250. chia/_tests/tools/__init__.py +0 -0
  251. chia/_tests/tools/config.py +5 -0
  252. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  253. chia/_tests/tools/test_full_sync.py +30 -0
  254. chia/_tests/tools/test_legacy_keyring.py +82 -0
  255. chia/_tests/tools/test_run_block.py +128 -0
  256. chia/_tests/tools/test_virtual_project.py +591 -0
  257. chia/_tests/util/__init__.py +0 -0
  258. chia/_tests/util/benchmark_cost.py +170 -0
  259. chia/_tests/util/benchmarks.py +153 -0
  260. chia/_tests/util/bip39_test_vectors.json +148 -0
  261. chia/_tests/util/blockchain.py +134 -0
  262. chia/_tests/util/blockchain_mock.py +132 -0
  263. chia/_tests/util/build_network_protocol_files.py +302 -0
  264. chia/_tests/util/clvm_generator.bin +0 -0
  265. chia/_tests/util/config.py +3 -0
  266. chia/_tests/util/constants.py +20 -0
  267. chia/_tests/util/db_connection.py +37 -0
  268. chia/_tests/util/full_sync.py +253 -0
  269. chia/_tests/util/gen_ssl_certs.py +114 -0
  270. chia/_tests/util/generator_tools_testing.py +45 -0
  271. chia/_tests/util/get_name_puzzle_conditions.py +52 -0
  272. chia/_tests/util/key_tool.py +36 -0
  273. chia/_tests/util/misc.py +675 -0
  274. chia/_tests/util/network_protocol_data.py +1072 -0
  275. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  276. chia/_tests/util/protocol_messages_json.py +2701 -0
  277. chia/_tests/util/rpc.py +26 -0
  278. chia/_tests/util/run_block.py +163 -0
  279. chia/_tests/util/setup_nodes.py +481 -0
  280. chia/_tests/util/spend_sim.py +492 -0
  281. chia/_tests/util/split_managers.py +102 -0
  282. chia/_tests/util/temp_file.py +14 -0
  283. chia/_tests/util/test_action_scope.py +144 -0
  284. chia/_tests/util/test_async_pool.py +366 -0
  285. chia/_tests/util/test_build_job_matrix.py +42 -0
  286. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  287. chia/_tests/util/test_chia_version.py +50 -0
  288. chia/_tests/util/test_collection.py +11 -0
  289. chia/_tests/util/test_condition_tools.py +229 -0
  290. chia/_tests/util/test_config.py +426 -0
  291. chia/_tests/util/test_dump_keyring.py +60 -0
  292. chia/_tests/util/test_errors.py +10 -0
  293. chia/_tests/util/test_full_block_utils.py +279 -0
  294. chia/_tests/util/test_installed.py +20 -0
  295. chia/_tests/util/test_limited_semaphore.py +53 -0
  296. chia/_tests/util/test_logging_filter.py +42 -0
  297. chia/_tests/util/test_misc.py +445 -0
  298. chia/_tests/util/test_network.py +73 -0
  299. chia/_tests/util/test_network_protocol_files.py +578 -0
  300. chia/_tests/util/test_network_protocol_json.py +267 -0
  301. chia/_tests/util/test_network_protocol_test.py +256 -0
  302. chia/_tests/util/test_paginator.py +71 -0
  303. chia/_tests/util/test_pprint.py +17 -0
  304. chia/_tests/util/test_priority_mutex.py +488 -0
  305. chia/_tests/util/test_recursive_replace.py +116 -0
  306. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  307. chia/_tests/util/test_service_groups.py +15 -0
  308. chia/_tests/util/test_ssl_check.py +31 -0
  309. chia/_tests/util/test_testnet_overrides.py +19 -0
  310. chia/_tests/util/test_tests_misc.py +38 -0
  311. chia/_tests/util/test_timing.py +37 -0
  312. chia/_tests/util/test_trusted_peer.py +51 -0
  313. chia/_tests/util/time_out_assert.py +191 -0
  314. chia/_tests/wallet/__init__.py +0 -0
  315. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  316. chia/_tests/wallet/cat_wallet/config.py +4 -0
  317. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  318. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  319. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1826 -0
  320. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  321. chia/_tests/wallet/cat_wallet/test_trades.py +2600 -0
  322. chia/_tests/wallet/clawback/__init__.py +0 -0
  323. chia/_tests/wallet/clawback/config.py +3 -0
  324. chia/_tests/wallet/clawback/test_clawback_decorator.py +78 -0
  325. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  326. chia/_tests/wallet/clawback/test_clawback_metadata.py +50 -0
  327. chia/_tests/wallet/config.py +4 -0
  328. chia/_tests/wallet/conftest.py +278 -0
  329. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  330. chia/_tests/wallet/dao_wallet/config.py +3 -0
  331. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1330 -0
  332. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  333. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  334. chia/_tests/wallet/db_wallet/config.py +3 -0
  335. chia/_tests/wallet/db_wallet/test_db_graftroot.py +141 -0
  336. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  337. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  338. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  339. chia/_tests/wallet/did_wallet/config.py +4 -0
  340. chia/_tests/wallet/did_wallet/test_did.py +2284 -0
  341. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  342. chia/_tests/wallet/nft_wallet/config.py +4 -0
  343. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1493 -0
  344. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1024 -0
  345. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +375 -0
  346. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  347. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  348. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2584 -0
  349. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  350. chia/_tests/wallet/rpc/__init__.py +0 -0
  351. chia/_tests/wallet/rpc/config.py +4 -0
  352. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +285 -0
  353. chia/_tests/wallet/rpc/test_wallet_rpc.py +3153 -0
  354. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  355. chia/_tests/wallet/simple_sync/config.py +3 -0
  356. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +718 -0
  357. chia/_tests/wallet/sync/__init__.py +0 -0
  358. chia/_tests/wallet/sync/config.py +4 -0
  359. chia/_tests/wallet/sync/test_wallet_sync.py +1692 -0
  360. chia/_tests/wallet/test_address_type.py +189 -0
  361. chia/_tests/wallet/test_bech32m.py +45 -0
  362. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  363. chia/_tests/wallet/test_coin_management.py +354 -0
  364. chia/_tests/wallet/test_coin_selection.py +588 -0
  365. chia/_tests/wallet/test_conditions.py +400 -0
  366. chia/_tests/wallet/test_debug_spend_bundle.py +218 -0
  367. chia/_tests/wallet/test_new_wallet_protocol.py +1174 -0
  368. chia/_tests/wallet/test_nft_store.py +192 -0
  369. chia/_tests/wallet/test_notifications.py +196 -0
  370. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  371. chia/_tests/wallet/test_puzzle_store.py +132 -0
  372. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  373. chia/_tests/wallet/test_signer_protocol.py +947 -0
  374. chia/_tests/wallet/test_singleton.py +122 -0
  375. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  376. chia/_tests/wallet/test_singleton_store.py +152 -0
  377. chia/_tests/wallet/test_taproot.py +19 -0
  378. chia/_tests/wallet/test_transaction_store.py +945 -0
  379. chia/_tests/wallet/test_util.py +185 -0
  380. chia/_tests/wallet/test_wallet.py +2139 -0
  381. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  382. chia/_tests/wallet/test_wallet_blockchain.py +111 -0
  383. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  384. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  385. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  386. chia/_tests/wallet/test_wallet_node.py +780 -0
  387. chia/_tests/wallet/test_wallet_retry.py +95 -0
  388. chia/_tests/wallet/test_wallet_state_manager.py +259 -0
  389. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  390. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  391. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  392. chia/_tests/wallet/test_wallet_utils.py +156 -0
  393. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  394. chia/_tests/wallet/vc_wallet/config.py +3 -0
  395. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  396. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  397. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +830 -0
  398. chia/_tests/wallet/wallet_block_tools.py +327 -0
  399. chia/_tests/weight_proof/__init__.py +0 -0
  400. chia/_tests/weight_proof/config.py +3 -0
  401. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  402. chia/apis.py +19 -0
  403. chia/clvm/__init__.py +0 -0
  404. chia/cmds/__init__.py +0 -0
  405. chia/cmds/beta.py +184 -0
  406. chia/cmds/beta_funcs.py +137 -0
  407. chia/cmds/check_wallet_db.py +420 -0
  408. chia/cmds/chia.py +151 -0
  409. chia/cmds/cmd_classes.py +323 -0
  410. chia/cmds/cmd_helpers.py +242 -0
  411. chia/cmds/cmds_util.py +488 -0
  412. chia/cmds/coin_funcs.py +275 -0
  413. chia/cmds/coins.py +182 -0
  414. chia/cmds/completion.py +49 -0
  415. chia/cmds/configure.py +332 -0
  416. chia/cmds/dao.py +1064 -0
  417. chia/cmds/dao_funcs.py +598 -0
  418. chia/cmds/data.py +708 -0
  419. chia/cmds/data_funcs.py +385 -0
  420. chia/cmds/db.py +87 -0
  421. chia/cmds/db_backup_func.py +77 -0
  422. chia/cmds/db_upgrade_func.py +452 -0
  423. chia/cmds/db_validate_func.py +184 -0
  424. chia/cmds/dev.py +18 -0
  425. chia/cmds/farm.py +100 -0
  426. chia/cmds/farm_funcs.py +200 -0
  427. chia/cmds/gh.py +275 -0
  428. chia/cmds/init.py +63 -0
  429. chia/cmds/init_funcs.py +367 -0
  430. chia/cmds/installers.py +131 -0
  431. chia/cmds/keys.py +527 -0
  432. chia/cmds/keys_funcs.py +863 -0
  433. chia/cmds/netspace.py +50 -0
  434. chia/cmds/netspace_funcs.py +54 -0
  435. chia/cmds/options.py +32 -0
  436. chia/cmds/param_types.py +238 -0
  437. chia/cmds/passphrase.py +131 -0
  438. chia/cmds/passphrase_funcs.py +292 -0
  439. chia/cmds/peer.py +51 -0
  440. chia/cmds/peer_funcs.py +129 -0
  441. chia/cmds/plotnft.py +260 -0
  442. chia/cmds/plotnft_funcs.py +405 -0
  443. chia/cmds/plots.py +230 -0
  444. chia/cmds/plotters.py +18 -0
  445. chia/cmds/rpc.py +208 -0
  446. chia/cmds/show.py +72 -0
  447. chia/cmds/show_funcs.py +215 -0
  448. chia/cmds/signer.py +296 -0
  449. chia/cmds/sim.py +225 -0
  450. chia/cmds/sim_funcs.py +509 -0
  451. chia/cmds/start.py +24 -0
  452. chia/cmds/start_funcs.py +109 -0
  453. chia/cmds/stop.py +62 -0
  454. chia/cmds/units.py +9 -0
  455. chia/cmds/wallet.py +1901 -0
  456. chia/cmds/wallet_funcs.py +1874 -0
  457. chia/consensus/__init__.py +0 -0
  458. chia/consensus/block_body_validation.py +562 -0
  459. chia/consensus/block_creation.py +546 -0
  460. chia/consensus/block_header_validation.py +1059 -0
  461. chia/consensus/block_record.py +31 -0
  462. chia/consensus/block_rewards.py +53 -0
  463. chia/consensus/blockchain.py +1087 -0
  464. chia/consensus/blockchain_interface.py +56 -0
  465. chia/consensus/coinbase.py +30 -0
  466. chia/consensus/condition_costs.py +9 -0
  467. chia/consensus/constants.py +49 -0
  468. chia/consensus/cost_calculator.py +15 -0
  469. chia/consensus/default_constants.py +89 -0
  470. chia/consensus/deficit.py +55 -0
  471. chia/consensus/difficulty_adjustment.py +412 -0
  472. chia/consensus/find_fork_point.py +111 -0
  473. chia/consensus/full_block_to_block_record.py +167 -0
  474. chia/consensus/get_block_challenge.py +106 -0
  475. chia/consensus/get_block_generator.py +27 -0
  476. chia/consensus/make_sub_epoch_summary.py +210 -0
  477. chia/consensus/multiprocess_validation.py +268 -0
  478. chia/consensus/pos_quality.py +19 -0
  479. chia/consensus/pot_iterations.py +67 -0
  480. chia/consensus/puzzles/__init__.py +0 -0
  481. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  482. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  483. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  484. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  485. chia/consensus/vdf_info_computation.py +156 -0
  486. chia/daemon/__init__.py +0 -0
  487. chia/daemon/client.py +252 -0
  488. chia/daemon/keychain_proxy.py +502 -0
  489. chia/daemon/keychain_server.py +365 -0
  490. chia/daemon/server.py +1606 -0
  491. chia/daemon/windows_signal.py +56 -0
  492. chia/data_layer/__init__.py +0 -0
  493. chia/data_layer/data_layer.py +1291 -0
  494. chia/data_layer/data_layer_api.py +33 -0
  495. chia/data_layer/data_layer_errors.py +50 -0
  496. chia/data_layer/data_layer_server.py +170 -0
  497. chia/data_layer/data_layer_util.py +985 -0
  498. chia/data_layer/data_layer_wallet.py +1311 -0
  499. chia/data_layer/data_store.py +2267 -0
  500. chia/data_layer/dl_wallet_store.py +407 -0
  501. chia/data_layer/download_data.py +389 -0
  502. chia/data_layer/puzzles/__init__.py +0 -0
  503. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  504. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  505. chia/data_layer/s3_plugin_config.yml +33 -0
  506. chia/data_layer/s3_plugin_service.py +468 -0
  507. chia/data_layer/util/__init__.py +0 -0
  508. chia/data_layer/util/benchmark.py +107 -0
  509. chia/data_layer/util/plugin.py +40 -0
  510. chia/farmer/__init__.py +0 -0
  511. chia/farmer/farmer.py +923 -0
  512. chia/farmer/farmer_api.py +820 -0
  513. chia/full_node/__init__.py +0 -0
  514. chia/full_node/bitcoin_fee_estimator.py +85 -0
  515. chia/full_node/block_height_map.py +271 -0
  516. chia/full_node/block_store.py +576 -0
  517. chia/full_node/bundle_tools.py +19 -0
  518. chia/full_node/coin_store.py +647 -0
  519. chia/full_node/fee_estimate.py +54 -0
  520. chia/full_node/fee_estimate_store.py +24 -0
  521. chia/full_node/fee_estimation.py +92 -0
  522. chia/full_node/fee_estimator.py +90 -0
  523. chia/full_node/fee_estimator_constants.py +38 -0
  524. chia/full_node/fee_estimator_interface.py +42 -0
  525. chia/full_node/fee_history.py +25 -0
  526. chia/full_node/fee_tracker.py +564 -0
  527. chia/full_node/full_node.py +3327 -0
  528. chia/full_node/full_node_api.py +2025 -0
  529. chia/full_node/full_node_store.py +1033 -0
  530. chia/full_node/hint_management.py +56 -0
  531. chia/full_node/hint_store.py +93 -0
  532. chia/full_node/mempool.py +589 -0
  533. chia/full_node/mempool_check_conditions.py +146 -0
  534. chia/full_node/mempool_manager.py +853 -0
  535. chia/full_node/pending_tx_cache.py +112 -0
  536. chia/full_node/puzzles/__init__.py +0 -0
  537. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  538. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  539. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  540. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  541. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  542. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  543. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  544. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  545. chia/full_node/signage_point.py +16 -0
  546. chia/full_node/subscriptions.py +247 -0
  547. chia/full_node/sync_store.py +146 -0
  548. chia/full_node/tx_processing_queue.py +78 -0
  549. chia/full_node/util/__init__.py +0 -0
  550. chia/full_node/weight_proof.py +1720 -0
  551. chia/harvester/__init__.py +0 -0
  552. chia/harvester/harvester.py +272 -0
  553. chia/harvester/harvester_api.py +380 -0
  554. chia/introducer/__init__.py +0 -0
  555. chia/introducer/introducer.py +122 -0
  556. chia/introducer/introducer_api.py +70 -0
  557. chia/legacy/__init__.py +0 -0
  558. chia/legacy/keyring.py +155 -0
  559. chia/plot_sync/__init__.py +0 -0
  560. chia/plot_sync/delta.py +61 -0
  561. chia/plot_sync/exceptions.py +56 -0
  562. chia/plot_sync/receiver.py +386 -0
  563. chia/plot_sync/sender.py +340 -0
  564. chia/plot_sync/util.py +43 -0
  565. chia/plotters/__init__.py +0 -0
  566. chia/plotters/bladebit.py +388 -0
  567. chia/plotters/chiapos.py +63 -0
  568. chia/plotters/madmax.py +224 -0
  569. chia/plotters/plotters.py +577 -0
  570. chia/plotters/plotters_util.py +133 -0
  571. chia/plotting/__init__.py +0 -0
  572. chia/plotting/cache.py +213 -0
  573. chia/plotting/check_plots.py +283 -0
  574. chia/plotting/create_plots.py +278 -0
  575. chia/plotting/manager.py +436 -0
  576. chia/plotting/util.py +336 -0
  577. chia/pools/__init__.py +0 -0
  578. chia/pools/pool_config.py +110 -0
  579. chia/pools/pool_puzzles.py +459 -0
  580. chia/pools/pool_wallet.py +933 -0
  581. chia/pools/pool_wallet_info.py +118 -0
  582. chia/pools/puzzles/__init__.py +0 -0
  583. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  584. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  585. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  586. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  587. chia/protocols/__init__.py +0 -0
  588. chia/protocols/farmer_protocol.py +102 -0
  589. chia/protocols/full_node_protocol.py +219 -0
  590. chia/protocols/harvester_protocol.py +216 -0
  591. chia/protocols/introducer_protocol.py +25 -0
  592. chia/protocols/pool_protocol.py +177 -0
  593. chia/protocols/protocol_message_types.py +139 -0
  594. chia/protocols/protocol_state_machine.py +87 -0
  595. chia/protocols/protocol_timing.py +8 -0
  596. chia/protocols/shared_protocol.py +86 -0
  597. chia/protocols/timelord_protocol.py +93 -0
  598. chia/protocols/wallet_protocol.py +401 -0
  599. chia/py.typed +0 -0
  600. chia/rpc/__init__.py +0 -0
  601. chia/rpc/crawler_rpc_api.py +80 -0
  602. chia/rpc/data_layer_rpc_api.py +644 -0
  603. chia/rpc/data_layer_rpc_client.py +188 -0
  604. chia/rpc/data_layer_rpc_util.py +58 -0
  605. chia/rpc/farmer_rpc_api.py +365 -0
  606. chia/rpc/farmer_rpc_client.py +86 -0
  607. chia/rpc/full_node_rpc_api.py +959 -0
  608. chia/rpc/full_node_rpc_client.py +292 -0
  609. chia/rpc/harvester_rpc_api.py +141 -0
  610. chia/rpc/harvester_rpc_client.py +54 -0
  611. chia/rpc/rpc_client.py +164 -0
  612. chia/rpc/rpc_server.py +521 -0
  613. chia/rpc/timelord_rpc_api.py +32 -0
  614. chia/rpc/util.py +93 -0
  615. chia/rpc/wallet_request_types.py +904 -0
  616. chia/rpc/wallet_rpc_api.py +4943 -0
  617. chia/rpc/wallet_rpc_client.py +1814 -0
  618. chia/seeder/__init__.py +0 -0
  619. chia/seeder/crawl_store.py +425 -0
  620. chia/seeder/crawler.py +410 -0
  621. chia/seeder/crawler_api.py +135 -0
  622. chia/seeder/dns_server.py +593 -0
  623. chia/seeder/peer_record.py +146 -0
  624. chia/seeder/start_crawler.py +92 -0
  625. chia/server/__init__.py +0 -0
  626. chia/server/address_manager.py +658 -0
  627. chia/server/address_manager_store.py +237 -0
  628. chia/server/api_protocol.py +116 -0
  629. chia/server/capabilities.py +24 -0
  630. chia/server/chia_policy.py +346 -0
  631. chia/server/introducer_peers.py +76 -0
  632. chia/server/node_discovery.py +714 -0
  633. chia/server/outbound_message.py +33 -0
  634. chia/server/rate_limit_numbers.py +214 -0
  635. chia/server/rate_limits.py +153 -0
  636. chia/server/server.py +741 -0
  637. chia/server/signal_handlers.py +120 -0
  638. chia/server/ssl_context.py +32 -0
  639. chia/server/start_data_layer.py +151 -0
  640. chia/server/start_farmer.py +98 -0
  641. chia/server/start_full_node.py +112 -0
  642. chia/server/start_harvester.py +93 -0
  643. chia/server/start_introducer.py +81 -0
  644. chia/server/start_service.py +316 -0
  645. chia/server/start_timelord.py +89 -0
  646. chia/server/start_wallet.py +113 -0
  647. chia/server/upnp.py +118 -0
  648. chia/server/ws_connection.py +766 -0
  649. chia/simulator/__init__.py +0 -0
  650. chia/simulator/add_blocks_in_batches.py +54 -0
  651. chia/simulator/block_tools.py +2054 -0
  652. chia/simulator/full_node_simulator.py +794 -0
  653. chia/simulator/keyring.py +128 -0
  654. chia/simulator/setup_services.py +506 -0
  655. chia/simulator/simulator_constants.py +13 -0
  656. chia/simulator/simulator_full_node_rpc_api.py +99 -0
  657. chia/simulator/simulator_full_node_rpc_client.py +60 -0
  658. chia/simulator/simulator_protocol.py +29 -0
  659. chia/simulator/simulator_test_tools.py +164 -0
  660. chia/simulator/socket.py +24 -0
  661. chia/simulator/ssl_certs.py +114 -0
  662. chia/simulator/ssl_certs_1.py +697 -0
  663. chia/simulator/ssl_certs_10.py +697 -0
  664. chia/simulator/ssl_certs_2.py +697 -0
  665. chia/simulator/ssl_certs_3.py +697 -0
  666. chia/simulator/ssl_certs_4.py +697 -0
  667. chia/simulator/ssl_certs_5.py +697 -0
  668. chia/simulator/ssl_certs_6.py +697 -0
  669. chia/simulator/ssl_certs_7.py +697 -0
  670. chia/simulator/ssl_certs_8.py +697 -0
  671. chia/simulator/ssl_certs_9.py +697 -0
  672. chia/simulator/start_simulator.py +143 -0
  673. chia/simulator/wallet_tools.py +246 -0
  674. chia/ssl/__init__.py +0 -0
  675. chia/ssl/chia_ca.crt +19 -0
  676. chia/ssl/chia_ca.key +28 -0
  677. chia/ssl/create_ssl.py +249 -0
  678. chia/ssl/dst_root_ca.pem +20 -0
  679. chia/timelord/__init__.py +0 -0
  680. chia/timelord/iters_from_block.py +50 -0
  681. chia/timelord/timelord.py +1226 -0
  682. chia/timelord/timelord_api.py +138 -0
  683. chia/timelord/timelord_launcher.py +190 -0
  684. chia/timelord/timelord_state.py +244 -0
  685. chia/timelord/types.py +22 -0
  686. chia/types/__init__.py +0 -0
  687. chia/types/aliases.py +35 -0
  688. chia/types/block_protocol.py +20 -0
  689. chia/types/blockchain_format/__init__.py +0 -0
  690. chia/types/blockchain_format/classgroup.py +5 -0
  691. chia/types/blockchain_format/coin.py +28 -0
  692. chia/types/blockchain_format/foliage.py +8 -0
  693. chia/types/blockchain_format/pool_target.py +5 -0
  694. chia/types/blockchain_format/program.py +269 -0
  695. chia/types/blockchain_format/proof_of_space.py +135 -0
  696. chia/types/blockchain_format/reward_chain_block.py +6 -0
  697. chia/types/blockchain_format/serialized_program.py +5 -0
  698. chia/types/blockchain_format/sized_bytes.py +11 -0
  699. chia/types/blockchain_format/slots.py +9 -0
  700. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  701. chia/types/blockchain_format/tree_hash.py +72 -0
  702. chia/types/blockchain_format/vdf.py +86 -0
  703. chia/types/clvm_cost.py +13 -0
  704. chia/types/coin_record.py +43 -0
  705. chia/types/coin_spend.py +115 -0
  706. chia/types/condition_opcodes.py +73 -0
  707. chia/types/condition_with_args.py +16 -0
  708. chia/types/eligible_coin_spends.py +365 -0
  709. chia/types/end_of_slot_bundle.py +5 -0
  710. chia/types/fee_rate.py +38 -0
  711. chia/types/full_block.py +5 -0
  712. chia/types/generator_types.py +13 -0
  713. chia/types/header_block.py +5 -0
  714. chia/types/internal_mempool_item.py +18 -0
  715. chia/types/mempool_inclusion_status.py +9 -0
  716. chia/types/mempool_item.py +85 -0
  717. chia/types/mempool_submission_status.py +30 -0
  718. chia/types/mojos.py +7 -0
  719. chia/types/peer_info.py +64 -0
  720. chia/types/signing_mode.py +29 -0
  721. chia/types/spend_bundle.py +30 -0
  722. chia/types/spend_bundle_conditions.py +7 -0
  723. chia/types/transaction_queue_entry.py +55 -0
  724. chia/types/unfinished_block.py +5 -0
  725. chia/types/unfinished_header_block.py +37 -0
  726. chia/types/validation_state.py +14 -0
  727. chia/types/weight_proof.py +49 -0
  728. chia/util/__init__.py +0 -0
  729. chia/util/action_scope.py +168 -0
  730. chia/util/async_pool.py +226 -0
  731. chia/util/augmented_chain.py +134 -0
  732. chia/util/batches.py +42 -0
  733. chia/util/bech32m.py +126 -0
  734. chia/util/beta_metrics.py +119 -0
  735. chia/util/block_cache.py +56 -0
  736. chia/util/byte_types.py +12 -0
  737. chia/util/check_fork_next_block.py +33 -0
  738. chia/util/chia_logging.py +144 -0
  739. chia/util/chia_version.py +33 -0
  740. chia/util/collection.py +17 -0
  741. chia/util/condition_tools.py +201 -0
  742. chia/util/config.py +367 -0
  743. chia/util/cpu.py +22 -0
  744. chia/util/db_synchronous.py +23 -0
  745. chia/util/db_version.py +32 -0
  746. chia/util/db_wrapper.py +430 -0
  747. chia/util/default_root.py +27 -0
  748. chia/util/dump_keyring.py +93 -0
  749. chia/util/english.txt +2048 -0
  750. chia/util/errors.py +353 -0
  751. chia/util/file_keyring.py +469 -0
  752. chia/util/files.py +97 -0
  753. chia/util/full_block_utils.py +345 -0
  754. chia/util/generator_tools.py +72 -0
  755. chia/util/hash.py +31 -0
  756. chia/util/initial-config.yaml +694 -0
  757. chia/util/inline_executor.py +26 -0
  758. chia/util/ints.py +19 -0
  759. chia/util/ip_address.py +39 -0
  760. chia/util/json_util.py +37 -0
  761. chia/util/keychain.py +676 -0
  762. chia/util/keyring_wrapper.py +327 -0
  763. chia/util/limited_semaphore.py +41 -0
  764. chia/util/lock.py +49 -0
  765. chia/util/log_exceptions.py +32 -0
  766. chia/util/logging.py +36 -0
  767. chia/util/lru_cache.py +31 -0
  768. chia/util/math.py +20 -0
  769. chia/util/network.py +182 -0
  770. chia/util/paginator.py +48 -0
  771. chia/util/path.py +31 -0
  772. chia/util/permissions.py +20 -0
  773. chia/util/prev_transaction_block.py +21 -0
  774. chia/util/priority_mutex.py +95 -0
  775. chia/util/profiler.py +197 -0
  776. chia/util/recursive_replace.py +24 -0
  777. chia/util/safe_cancel_task.py +16 -0
  778. chia/util/service_groups.py +47 -0
  779. chia/util/setproctitle.py +22 -0
  780. chia/util/significant_bits.py +32 -0
  781. chia/util/ssl_check.py +213 -0
  782. chia/util/streamable.py +642 -0
  783. chia/util/task_referencer.py +59 -0
  784. chia/util/task_timing.py +382 -0
  785. chia/util/timing.py +67 -0
  786. chia/util/vdf_prover.py +30 -0
  787. chia/util/virtual_project_analysis.py +540 -0
  788. chia/util/ws_message.py +66 -0
  789. chia/wallet/__init__.py +0 -0
  790. chia/wallet/cat_wallet/__init__.py +0 -0
  791. chia/wallet/cat_wallet/cat_constants.py +75 -0
  792. chia/wallet/cat_wallet/cat_info.py +47 -0
  793. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  794. chia/wallet/cat_wallet/cat_utils.py +164 -0
  795. chia/wallet/cat_wallet/cat_wallet.py +855 -0
  796. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  797. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  798. chia/wallet/cat_wallet/lineage_store.py +74 -0
  799. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  800. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  801. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  802. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  803. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  804. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  805. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  806. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  807. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  808. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  809. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  810. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  811. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  812. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  813. chia/wallet/coin_selection.py +188 -0
  814. chia/wallet/conditions.py +1512 -0
  815. chia/wallet/dao_wallet/__init__.py +0 -0
  816. chia/wallet/dao_wallet/dao_info.py +61 -0
  817. chia/wallet/dao_wallet/dao_utils.py +811 -0
  818. chia/wallet/dao_wallet/dao_wallet.py +2119 -0
  819. chia/wallet/db_wallet/__init__.py +0 -0
  820. chia/wallet/db_wallet/db_wallet_puzzles.py +111 -0
  821. chia/wallet/derivation_record.py +30 -0
  822. chia/wallet/derive_keys.py +146 -0
  823. chia/wallet/did_wallet/__init__.py +0 -0
  824. chia/wallet/did_wallet/did_info.py +39 -0
  825. chia/wallet/did_wallet/did_wallet.py +1494 -0
  826. chia/wallet/did_wallet/did_wallet_puzzles.py +221 -0
  827. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  828. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  829. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  830. chia/wallet/driver_protocol.py +26 -0
  831. chia/wallet/key_val_store.py +55 -0
  832. chia/wallet/lineage_proof.py +58 -0
  833. chia/wallet/nft_wallet/__init__.py +0 -0
  834. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  835. chia/wallet/nft_wallet/nft_info.py +120 -0
  836. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  837. chia/wallet/nft_wallet/nft_wallet.py +1687 -0
  838. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  839. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  840. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  841. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  842. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  843. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  844. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  845. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  846. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  847. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  848. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  849. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  850. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  851. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  852. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  853. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  854. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  855. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  856. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  857. chia/wallet/notification_manager.py +117 -0
  858. chia/wallet/notification_store.py +178 -0
  859. chia/wallet/outer_puzzles.py +84 -0
  860. chia/wallet/payment.py +33 -0
  861. chia/wallet/puzzle_drivers.py +118 -0
  862. chia/wallet/puzzles/__init__.py +0 -0
  863. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  864. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  865. chia/wallet/puzzles/clawback/__init__.py +0 -0
  866. chia/wallet/puzzles/clawback/drivers.py +188 -0
  867. chia/wallet/puzzles/clawback/metadata.py +38 -0
  868. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  869. chia/wallet/puzzles/condition_codes.clib +77 -0
  870. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  871. chia/wallet/puzzles/curry.clib +135 -0
  872. chia/wallet/puzzles/curry_by_index.clib +16 -0
  873. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  874. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  876. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  877. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  878. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  879. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  880. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  881. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  882. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  883. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  884. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  885. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  886. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  887. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  888. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  889. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  890. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  891. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  892. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  893. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  894. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  895. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  896. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  897. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  898. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  899. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  900. chia/wallet/puzzles/json.clib +25 -0
  901. chia/wallet/puzzles/load_clvm.py +161 -0
  902. chia/wallet/puzzles/merkle_utils.clib +18 -0
  903. chia/wallet/puzzles/notification.clsp +7 -0
  904. chia/wallet/puzzles/notification.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  906. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  907. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  908. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  909. chia/wallet/puzzles/p2_conditions.py +26 -0
  910. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  911. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  912. chia/wallet/puzzles/p2_delegated_conditions.py +21 -0
  913. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  914. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  915. chia/wallet/puzzles/p2_delegated_puzzle.py +34 -0
  916. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  917. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +160 -0
  919. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  920. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  921. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +21 -0
  922. chia/wallet/puzzles/p2_parent.clsp +19 -0
  923. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  924. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  925. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  926. chia/wallet/puzzles/p2_puzzle_hash.py +27 -0
  927. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  928. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  929. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  930. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  931. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  932. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  933. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  934. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  935. chia/wallet/puzzles/puzzle_utils.py +34 -0
  936. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  937. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  938. chia/wallet/puzzles/sha256tree.clib +11 -0
  939. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  940. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  941. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  942. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  943. chia/wallet/puzzles/singleton_top_layer.py +296 -0
  944. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  945. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  946. chia/wallet/puzzles/singleton_top_layer_v1_1.py +345 -0
  947. chia/wallet/puzzles/singleton_truths.clib +21 -0
  948. chia/wallet/puzzles/tails.py +348 -0
  949. chia/wallet/puzzles/utility_macros.clib +48 -0
  950. chia/wallet/signer_protocol.py +125 -0
  951. chia/wallet/singleton.py +106 -0
  952. chia/wallet/singleton_record.py +30 -0
  953. chia/wallet/trade_manager.py +1102 -0
  954. chia/wallet/trade_record.py +67 -0
  955. chia/wallet/trading/__init__.py +0 -0
  956. chia/wallet/trading/offer.py +702 -0
  957. chia/wallet/trading/trade_status.py +13 -0
  958. chia/wallet/trading/trade_store.py +526 -0
  959. chia/wallet/transaction_record.py +158 -0
  960. chia/wallet/transaction_sorting.py +14 -0
  961. chia/wallet/uncurried_puzzle.py +17 -0
  962. chia/wallet/util/__init__.py +0 -0
  963. chia/wallet/util/address_type.py +55 -0
  964. chia/wallet/util/blind_signer_tl.py +164 -0
  965. chia/wallet/util/clvm_streamable.py +203 -0
  966. chia/wallet/util/compute_hints.py +66 -0
  967. chia/wallet/util/compute_memos.py +43 -0
  968. chia/wallet/util/curry_and_treehash.py +91 -0
  969. chia/wallet/util/debug_spend_bundle.py +232 -0
  970. chia/wallet/util/merkle_tree.py +100 -0
  971. chia/wallet/util/merkle_utils.py +102 -0
  972. chia/wallet/util/new_peak_queue.py +82 -0
  973. chia/wallet/util/notifications.py +12 -0
  974. chia/wallet/util/peer_request_cache.py +174 -0
  975. chia/wallet/util/pprint.py +39 -0
  976. chia/wallet/util/puzzle_compression.py +95 -0
  977. chia/wallet/util/puzzle_decorator.py +100 -0
  978. chia/wallet/util/puzzle_decorator_type.py +7 -0
  979. chia/wallet/util/query_filter.py +59 -0
  980. chia/wallet/util/transaction_type.py +23 -0
  981. chia/wallet/util/tx_config.py +158 -0
  982. chia/wallet/util/wallet_sync_utils.py +351 -0
  983. chia/wallet/util/wallet_types.py +72 -0
  984. chia/wallet/vc_wallet/__init__.py +0 -0
  985. chia/wallet/vc_wallet/cr_cat_drivers.py +664 -0
  986. chia/wallet/vc_wallet/cr_cat_wallet.py +877 -0
  987. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  988. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  989. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  990. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  992. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  994. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  996. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  997. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  998. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  1002. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  1003. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  1004. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  1005. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  1006. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  1007. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  1008. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  1009. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  1010. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  1011. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  1012. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  1013. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1014. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1015. chia/wallet/vc_wallet/vc_store.py +263 -0
  1016. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1017. chia/wallet/wallet.py +698 -0
  1018. chia/wallet/wallet_action_scope.py +96 -0
  1019. chia/wallet/wallet_blockchain.py +244 -0
  1020. chia/wallet/wallet_coin_record.py +72 -0
  1021. chia/wallet/wallet_coin_store.py +351 -0
  1022. chia/wallet/wallet_info.py +35 -0
  1023. chia/wallet/wallet_interested_store.py +188 -0
  1024. chia/wallet/wallet_nft_store.py +279 -0
  1025. chia/wallet/wallet_node.py +1765 -0
  1026. chia/wallet/wallet_node_api.py +207 -0
  1027. chia/wallet/wallet_pool_store.py +119 -0
  1028. chia/wallet/wallet_protocol.py +90 -0
  1029. chia/wallet/wallet_puzzle_store.py +396 -0
  1030. chia/wallet/wallet_retry_store.py +70 -0
  1031. chia/wallet/wallet_singleton_store.py +259 -0
  1032. chia/wallet/wallet_spend_bundle.py +25 -0
  1033. chia/wallet/wallet_state_manager.py +2819 -0
  1034. chia/wallet/wallet_transaction_store.py +496 -0
  1035. chia/wallet/wallet_user_store.py +110 -0
  1036. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1037. chia_blockchain-2.5.1rc1.dist-info/LICENSE +201 -0
  1038. chia_blockchain-2.5.1rc1.dist-info/METADATA +156 -0
  1039. chia_blockchain-2.5.1rc1.dist-info/RECORD +1042 -0
  1040. chia_blockchain-2.5.1rc1.dist-info/WHEEL +4 -0
  1041. chia_blockchain-2.5.1rc1.dist-info/entry_points.txt +17 -0
  1042. mozilla-ca/cacert.pem +3611 -0
@@ -0,0 +1,1033 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ import dataclasses
5
+ import logging
6
+ import time
7
+ from typing import Optional
8
+
9
+ from chia.consensus.block_record import BlockRecord
10
+ from chia.consensus.blockchain_interface import BlockRecordsProtocol
11
+ from chia.consensus.constants import ConsensusConstants
12
+ from chia.consensus.difficulty_adjustment import can_finish_sub_and_full_epoch
13
+ from chia.consensus.make_sub_epoch_summary import make_sub_epoch_summary
14
+ from chia.consensus.multiprocess_validation import PreValidationResult
15
+ from chia.consensus.pot_iterations import calculate_sp_interval_iters
16
+ from chia.full_node.signage_point import SignagePoint
17
+ from chia.protocols import timelord_protocol
18
+ from chia.server.outbound_message import Message
19
+ from chia.types.blockchain_format.classgroup import ClassgroupElement
20
+ from chia.types.blockchain_format.sized_bytes import bytes32
21
+ from chia.types.blockchain_format.vdf import VDFInfo, validate_vdf
22
+ from chia.types.end_of_slot_bundle import EndOfSubSlotBundle
23
+ from chia.types.full_block import FullBlock
24
+ from chia.types.unfinished_block import UnfinishedBlock
25
+ from chia.util.ints import uint8, uint32, uint64, uint128
26
+ from chia.util.lru_cache import LRUCache
27
+ from chia.util.streamable import Streamable, streamable
28
+
29
+ log = logging.getLogger(__name__)
30
+
31
+
32
+ @streamable
33
+ @dataclasses.dataclass(frozen=True)
34
+ class FullNodeStorePeakResult(Streamable):
35
+ added_eos: Optional[EndOfSubSlotBundle]
36
+ new_signage_points: list[tuple[uint8, SignagePoint]]
37
+ new_infusion_points: list[timelord_protocol.NewInfusionPointVDF]
38
+
39
+
40
+ @dataclasses.dataclass
41
+ class UnfinishedBlockEntry:
42
+ # if this is None, it means we've requested this block but not yet received
43
+ # it
44
+ unfinished_block: Optional[UnfinishedBlock]
45
+ # If this is None, it means we've initiated validation of this block, but it
46
+ # hasn't completed yet
47
+ result: Optional[PreValidationResult]
48
+ height: uint32
49
+
50
+
51
+ def find_best_block(
52
+ result: dict[Optional[bytes32], UnfinishedBlockEntry],
53
+ ) -> tuple[Optional[bytes32], Optional[UnfinishedBlock]]:
54
+ """
55
+ Given a collection of UnfinishedBlocks (all with the same reward block
56
+ hash), return the "best" one. i.e. the one with the smallest foliage hash.
57
+ """
58
+ if len(result) == 0:
59
+ return None, None
60
+
61
+ all_blocks = list(result.items())
62
+ if len(all_blocks) == 1:
63
+ foliage_hash, entry = all_blocks[0]
64
+ # this means we don't have the block yet
65
+ if entry.unfinished_block is None:
66
+ return None, None
67
+ else:
68
+ return foliage_hash, entry.unfinished_block
69
+
70
+ def include_block(item: tuple[Optional[bytes32], UnfinishedBlockEntry]) -> bool:
71
+ foliage_hash, entry = item
72
+ return foliage_hash is not None and entry.unfinished_block is not None
73
+
74
+ # if there are unfinished blocks with foliage (i.e. not None) we prefer
75
+ # those, so drop the first element
76
+ all_blocks = [e for e in all_blocks if include_block(e)]
77
+ all_blocks = sorted(all_blocks)
78
+
79
+ # we may have filtered out some blocks that we have only requested, but not
80
+ # yet received.
81
+ if len(all_blocks) == 0:
82
+ return None, None
83
+
84
+ return all_blocks[0][0], all_blocks[0][1].unfinished_block
85
+
86
+
87
+ class FullNodeStore:
88
+ constants: ConsensusConstants
89
+
90
+ # Blocks which we have created, but don't have plot signatures yet, so not yet "unfinished blocks"
91
+ candidate_blocks: dict[bytes32, tuple[uint32, UnfinishedBlock]]
92
+ candidate_backup_blocks: dict[bytes32, tuple[uint32, UnfinishedBlock]]
93
+
94
+ # Block hashes of unfinished blocks that we have seen recently. This is
95
+ # effectively a set[bytes32] but in order to evict the oldest items first,
96
+ # we use a Dict that preserves insertion order, and remove from the
97
+ # beginning
98
+ seen_unfinished_blocks: dict[bytes32, None]
99
+
100
+ # Unfinished blocks, keyed from reward hash
101
+ # There may be multiple different unfinished blocks with the same partial
102
+ # hash (reward chain block hash). They are stored under their partial hash
103
+ # though. The inner dictionary uses the foliage hash as the key
104
+ # The UnfinishedBlockEntry is a placeholder for UnfinishedBlocks we have
105
+ # requested (but don't have yet) or that we have but haven't completed
106
+ # validation of (yet).
107
+ # The inner key (the foliage hash) is Optional, where None either means
108
+ # it's not a transaction block, or it's a block we learned about via the old
109
+ # protocol, where all we get is the reward block hash.
110
+ _unfinished_blocks: dict[bytes32, dict[Optional[bytes32], UnfinishedBlockEntry]]
111
+
112
+ # Finished slots and sps from the peak's slot onwards
113
+ # We store all 32 SPs for each slot, starting as 32 Nones and filling them as we go
114
+ # Also stores the total iters at the end of slot
115
+ # For the first sub-slot, EndOfSlotBundle is None
116
+ finished_sub_slots: list[tuple[Optional[EndOfSubSlotBundle], list[Optional[SignagePoint]], uint128]]
117
+
118
+ # These caches maintain objects which depend on infused blocks in the reward chain, that we
119
+ # might receive before the blocks themselves. The dict keys are the reward chain challenge hashes.
120
+
121
+ # End of slots which depend on infusions that we don't have
122
+ future_eos_cache: dict[bytes32, list[EndOfSubSlotBundle]]
123
+
124
+ # Signage points which depend on infusions that we don't have
125
+ future_sp_cache: dict[bytes32, list[tuple[uint8, SignagePoint]]]
126
+
127
+ # Infusion point VDFs which depend on infusions that we don't have
128
+ future_ip_cache: dict[bytes32, list[timelord_protocol.NewInfusionPointVDF]]
129
+
130
+ # This stores the time that each key was added to the future cache, so we can clear old keys
131
+ future_cache_key_times: dict[bytes32, int]
132
+
133
+ # These recent caches are for pooling support
134
+ recent_signage_points: LRUCache[bytes32, tuple[SignagePoint, float]]
135
+ recent_eos: LRUCache[bytes32, tuple[EndOfSubSlotBundle, float]]
136
+
137
+ pending_tx_request: dict[bytes32, bytes32] # tx_id: peer_id
138
+ peers_with_tx: dict[bytes32, set[bytes32]] # tx_id: set[peer_ids}
139
+ tx_fetch_tasks: dict[bytes32, asyncio.Task[None]] # Task id: task
140
+ serialized_wp_message: Optional[Message]
141
+ serialized_wp_message_tip: Optional[bytes32]
142
+
143
+ max_seen_unfinished_blocks: int
144
+
145
+ def __init__(self, constants: ConsensusConstants):
146
+ self.candidate_blocks = {}
147
+ self.candidate_backup_blocks = {}
148
+ self.seen_unfinished_blocks = {}
149
+ self._unfinished_blocks = {}
150
+ self.finished_sub_slots = []
151
+ self.future_eos_cache = {}
152
+ self.future_sp_cache = {}
153
+ self.future_ip_cache = {}
154
+ self.recent_signage_points = LRUCache(500)
155
+ self.recent_eos = LRUCache(50)
156
+ self.future_cache_key_times = {}
157
+ self.constants = constants
158
+ self.clear_slots()
159
+ self.initialize_genesis_sub_slot()
160
+ self.pending_tx_request = {}
161
+ self.peers_with_tx = {}
162
+ self.tx_fetch_tasks = {}
163
+ self.serialized_wp_message = None
164
+ self.serialized_wp_message_tip = None
165
+ self.max_seen_unfinished_blocks = 1000
166
+
167
+ def is_requesting_unfinished_block(
168
+ self, reward_block_hash: bytes32, foliage_hash: Optional[bytes32]
169
+ ) -> tuple[bool, int]:
170
+ """
171
+ Asks if we are already requesting this specific unfinished block (given
172
+ the reward block hash and foliage hash). The returned bool is true if we
173
+ are and false otherwise. The function also returns the number of
174
+ variants of an unfinished block with this reward block hash we are
175
+ currently requesting. This is useful to ensure we limit the number of
176
+ variants we request.
177
+ """
178
+ ents = self._unfinished_blocks.get(reward_block_hash)
179
+ if ents is None:
180
+ return (False, 0)
181
+ elif foliage_hash is None:
182
+ return (len(ents) > 0, len(ents))
183
+ else:
184
+ return (foliage_hash in ents, len(ents))
185
+
186
+ def mark_requesting_unfinished_block(self, reward_block_hash: bytes32, foliage_hash: Optional[bytes32]) -> None:
187
+ ents = self._unfinished_blocks.setdefault(reward_block_hash, {})
188
+ ents.setdefault(foliage_hash, UnfinishedBlockEntry(None, None, uint32(0)))
189
+
190
+ def remove_requesting_unfinished_block(self, reward_block_hash: bytes32, foliage_hash: Optional[bytes32]) -> None:
191
+ reward_ents = self._unfinished_blocks.get(reward_block_hash)
192
+ if reward_ents is None:
193
+ return
194
+ foliage_ent = reward_ents.get(foliage_hash)
195
+ if foliage_ent is None:
196
+ return
197
+ if foliage_ent.unfinished_block is not None:
198
+ # in this case we've successfully received the unfinished block,
199
+ # it's already considered "not requesting", but actually downloaded
200
+ return
201
+ del reward_ents[foliage_hash]
202
+ if len(reward_ents) == 0:
203
+ del self._unfinished_blocks[reward_block_hash]
204
+
205
+ def add_candidate_block(
206
+ self, quality_string: bytes32, height: uint32, unfinished_block: UnfinishedBlock, backup: bool = False
207
+ ) -> None:
208
+ if backup:
209
+ self.candidate_backup_blocks[quality_string] = (height, unfinished_block)
210
+ else:
211
+ self.candidate_blocks[quality_string] = (height, unfinished_block)
212
+
213
+ def get_candidate_block(
214
+ self, quality_string: bytes32, backup: bool = False
215
+ ) -> Optional[tuple[uint32, UnfinishedBlock]]:
216
+ if backup:
217
+ return self.candidate_backup_blocks.get(quality_string, None)
218
+ else:
219
+ return self.candidate_blocks.get(quality_string, None)
220
+
221
+ def clear_candidate_blocks_below(self, height: uint32) -> None:
222
+ del_keys = []
223
+ for key, value in self.candidate_blocks.items():
224
+ if value[0] < height:
225
+ del_keys.append(key)
226
+ for key in del_keys:
227
+ try:
228
+ del self.candidate_blocks[key]
229
+ except KeyError:
230
+ pass
231
+ del_keys = []
232
+ for key, value in self.candidate_backup_blocks.items():
233
+ if value[0] < height:
234
+ del_keys.append(key)
235
+ for key in del_keys:
236
+ try:
237
+ del self.candidate_backup_blocks[key]
238
+ except KeyError:
239
+ pass
240
+
241
+ def seen_unfinished_block(self, object_hash: bytes32) -> bool:
242
+ if object_hash in self.seen_unfinished_blocks:
243
+ return True
244
+ self.seen_unfinished_blocks[object_hash] = None
245
+ if len(self.seen_unfinished_blocks) > self.max_seen_unfinished_blocks:
246
+ # remove the least recently added hash
247
+ to_remove = next(iter(self.seen_unfinished_blocks))
248
+ del self.seen_unfinished_blocks[to_remove]
249
+ return False
250
+
251
+ def add_unfinished_block(
252
+ self, height: uint32, unfinished_block: UnfinishedBlock, result: PreValidationResult
253
+ ) -> None:
254
+ partial_hash = unfinished_block.partial_hash
255
+ entry = self._unfinished_blocks.setdefault(partial_hash, {})
256
+ entry[unfinished_block.foliage.foliage_transaction_block_hash] = UnfinishedBlockEntry(
257
+ unfinished_block, result, height
258
+ )
259
+
260
+ def get_unfinished_block(self, unfinished_reward_hash: bytes32) -> Optional[UnfinishedBlock]:
261
+ result = self._unfinished_blocks.get(unfinished_reward_hash, None)
262
+ if result is None:
263
+ return None
264
+ # The old API doesn't distinguish between duplicate UnfinishedBlocks,
265
+ # return the *best* UnfinishedBlock. This is the path taken when the
266
+ # timelord sends us an infusion point with this specific reward block
267
+ # hash. We pick one of the unfinished blocks based on an arbitrary but
268
+ # deterministic property.
269
+ # this sorts the UnfinishedBlocks by the foliage hash, and picks the
270
+ # smallest hash
271
+ _foliage_hash, block = find_best_block(result)
272
+ return block
273
+
274
+ def get_unfinished_block2(
275
+ self, unfinished_reward_hash: bytes32, unfinished_foliage_hash: Optional[bytes32]
276
+ ) -> tuple[Optional[UnfinishedBlock], int, bool]:
277
+ """
278
+ Looks up an UnfinishedBlock by its reward block hash and foliage hash.
279
+ If the foliage hash is None (e.g. it's not a transaction block), we fall
280
+ back to the original function that looks up unfinished blocks just by
281
+ their reward block hash.
282
+ Returns:
283
+ 1. the (optional) UnfinishedBlock
284
+ 2. the number of other candidate blocks we know of with the same
285
+ reward block hash
286
+ 3. whether we already have a "better" UnfinishedBlock candidate than
287
+ this
288
+ """
289
+ result = self._unfinished_blocks.get(unfinished_reward_hash, None)
290
+ if result is None:
291
+ return None, 0, False
292
+ if unfinished_foliage_hash is None:
293
+ foliage_hash, block = find_best_block(result)
294
+ return block, len(result), False
295
+
296
+ foliage_hash, block = find_best_block(result)
297
+ has_better: bool = foliage_hash is not None and foliage_hash < unfinished_foliage_hash
298
+
299
+ entry = result.get(unfinished_foliage_hash)
300
+
301
+ if entry is None:
302
+ return None, len(result), has_better
303
+ else:
304
+ return entry.unfinished_block, len(result), has_better
305
+
306
+ # we only have PreValidationResults for transaction blocks, and they all
307
+ # have a foliage hash. That's why unfinished_foliage_hash is not Optional.
308
+ def get_unfinished_block_result(
309
+ self, unfinished_reward_hash: bytes32, unfinished_foliage_hash: bytes32
310
+ ) -> Optional[UnfinishedBlockEntry]:
311
+ result = self._unfinished_blocks.get(unfinished_reward_hash, None)
312
+ if result is None:
313
+ return None
314
+ else:
315
+ return result.get(unfinished_foliage_hash)
316
+
317
+ # returns all unfinished blocks for the specified height
318
+ def get_unfinished_blocks(self, height: uint32) -> list[UnfinishedBlock]:
319
+ ret: list[UnfinishedBlock] = []
320
+ for entry in self._unfinished_blocks.values():
321
+ for ube in entry.values():
322
+ if ube.height == height and ube.unfinished_block is not None:
323
+ ret.append(ube.unfinished_block)
324
+ return ret
325
+
326
+ def clear_unfinished_blocks_below(self, height: uint32) -> None:
327
+ del_partial: list[bytes32] = []
328
+ for partial_hash, entry in self._unfinished_blocks.items():
329
+ del_foliage: list[Optional[bytes32]] = []
330
+ for foliage_hash, ube in entry.items():
331
+ if ube.height < height:
332
+ del_foliage.append(foliage_hash)
333
+ for fh in del_foliage:
334
+ del entry[fh]
335
+ if len(entry) == 0:
336
+ del_partial.append(partial_hash)
337
+ for ph in del_partial:
338
+ del self._unfinished_blocks[ph]
339
+
340
+ # TODO: this should be removed. It's only used by a test
341
+ def remove_unfinished_block(self, partial_reward_hash: bytes32) -> None:
342
+ if partial_reward_hash in self._unfinished_blocks:
343
+ del self._unfinished_blocks[partial_reward_hash]
344
+
345
+ def add_to_future_ip(self, infusion_point: timelord_protocol.NewInfusionPointVDF) -> None:
346
+ ch: bytes32 = infusion_point.reward_chain_ip_vdf.challenge
347
+ if ch not in self.future_ip_cache:
348
+ self.future_ip_cache[ch] = []
349
+ self.future_ip_cache[ch].append(infusion_point)
350
+
351
+ def in_future_sp_cache(self, signage_point: SignagePoint, index: uint8) -> bool:
352
+ if signage_point.rc_vdf is None:
353
+ return False
354
+
355
+ if signage_point.rc_vdf.challenge not in self.future_sp_cache:
356
+ return False
357
+ for cache_index, cache_sp in self.future_sp_cache[signage_point.rc_vdf.challenge]:
358
+ if cache_index == index and cache_sp.rc_vdf == signage_point.rc_vdf:
359
+ return True
360
+ return False
361
+
362
+ def add_to_future_sp(self, signage_point: SignagePoint, index: uint8) -> None:
363
+ # We are missing a block here
364
+ if (
365
+ signage_point.cc_vdf is None
366
+ or signage_point.rc_vdf is None
367
+ or signage_point.cc_proof is None
368
+ or signage_point.rc_proof is None
369
+ ):
370
+ return None
371
+ if signage_point.rc_vdf.challenge not in self.future_sp_cache:
372
+ self.future_sp_cache[signage_point.rc_vdf.challenge] = []
373
+ if self.in_future_sp_cache(signage_point, index):
374
+ return None
375
+
376
+ self.future_cache_key_times[signage_point.rc_vdf.challenge] = int(time.time())
377
+ self.future_sp_cache[signage_point.rc_vdf.challenge].append((index, signage_point))
378
+ log.info(f"Don't have rc hash {signage_point.rc_vdf.challenge.hex()}. caching signage point {index}.")
379
+
380
+ def get_future_ip(self, rc_challenge_hash: bytes32) -> list[timelord_protocol.NewInfusionPointVDF]:
381
+ return self.future_ip_cache.get(rc_challenge_hash, [])
382
+
383
+ def clear_old_cache_entries(self) -> None:
384
+ current_time: int = int(time.time())
385
+ remove_keys: list[bytes32] = []
386
+ for rc_hash, time_added in self.future_cache_key_times.items():
387
+ if current_time - time_added > 3600:
388
+ remove_keys.append(rc_hash)
389
+ for k in remove_keys:
390
+ self.future_cache_key_times.pop(k, None)
391
+ self.future_ip_cache.pop(k, [])
392
+ self.future_eos_cache.pop(k, [])
393
+ self.future_sp_cache.pop(k, [])
394
+
395
+ def clear_slots(self) -> None:
396
+ self.finished_sub_slots.clear()
397
+
398
+ def get_sub_slot(self, challenge_hash: bytes32) -> Optional[tuple[EndOfSubSlotBundle, int, uint128]]:
399
+ assert len(self.finished_sub_slots) >= 1
400
+ for index, (sub_slot, _, total_iters) in enumerate(self.finished_sub_slots):
401
+ if sub_slot is not None and sub_slot.challenge_chain.get_hash() == challenge_hash:
402
+ return sub_slot, index, total_iters
403
+ return None
404
+
405
+ def initialize_genesis_sub_slot(self) -> None:
406
+ self.clear_slots()
407
+ self.finished_sub_slots = [(None, [None] * self.constants.NUM_SPS_SUB_SLOT, uint128(0))]
408
+
409
+ def new_finished_sub_slot(
410
+ self,
411
+ eos: EndOfSubSlotBundle,
412
+ blocks: BlockRecordsProtocol,
413
+ peak: Optional[BlockRecord],
414
+ next_sub_slot_iters: uint64,
415
+ next_difficulty: uint64,
416
+ peak_full_block: Optional[FullBlock],
417
+ ) -> Optional[list[timelord_protocol.NewInfusionPointVDF]]:
418
+ """
419
+ Returns false if not added. Returns a list if added. The list contains all infusion points that depended
420
+ on this sub slot
421
+ """
422
+ assert len(self.finished_sub_slots) >= 1
423
+ assert (peak is None) == (peak_full_block is None)
424
+
425
+ last_slot, _, last_slot_iters = self.finished_sub_slots[-1]
426
+
427
+ cc_challenge: bytes32 = (
428
+ last_slot.challenge_chain.get_hash() if last_slot is not None else self.constants.GENESIS_CHALLENGE
429
+ )
430
+ rc_challenge: bytes32 = (
431
+ last_slot.reward_chain.get_hash() if last_slot is not None else self.constants.GENESIS_CHALLENGE
432
+ )
433
+ icc_challenge: Optional[bytes32] = None
434
+ icc_iters: Optional[uint64] = None
435
+
436
+ # Skip if already present
437
+ for slot, _, _ in self.finished_sub_slots:
438
+ if slot == eos:
439
+ return []
440
+
441
+ if eos.challenge_chain.challenge_chain_end_of_slot_vdf.challenge != cc_challenge:
442
+ # This slot does not append to our next slot
443
+ # This prevent other peers from appending fake VDFs to our cache
444
+ log.error(
445
+ f"bad cc_challenge in new_finished_sub_slot, "
446
+ f"got {eos.challenge_chain.challenge_chain_end_of_slot_vdf.challenge.hex()}"
447
+ f"expected {cc_challenge}"
448
+ )
449
+ return None
450
+
451
+ if peak is None:
452
+ sub_slot_iters = self.constants.SUB_SLOT_ITERS_STARTING
453
+ else:
454
+ sub_slot_iters = peak.sub_slot_iters
455
+
456
+ total_iters = uint128(last_slot_iters + sub_slot_iters)
457
+
458
+ if peak is not None and peak.total_iters > last_slot_iters:
459
+ # Peak is in this slot
460
+
461
+ # Note: Adding an end of subslot does not lock the blockchain, for performance reasons. Only the
462
+ # timelord_lock is used. Therefore, it's possible that we add a new peak at the same time as seeing
463
+ # the finished subslot, and the peak is not fully added yet, so it looks like we still need the subslot.
464
+ # In that case, we will exit here and let the new_peak code add the subslot.
465
+ if total_iters < peak.total_iters:
466
+ log.debug("dont add slot, total_iters < peak.total_iters")
467
+ return None
468
+
469
+ rc_challenge = bytes32(eos.reward_chain.end_of_slot_vdf.challenge)
470
+ cc_start_element = peak.challenge_vdf_output
471
+ iters = uint64(total_iters - peak.total_iters)
472
+ if peak.reward_infusion_new_challenge != rc_challenge:
473
+ # We don't have this challenge hash yet
474
+ if rc_challenge not in self.future_eos_cache:
475
+ self.future_eos_cache[rc_challenge] = []
476
+ self.future_eos_cache[rc_challenge].append(eos)
477
+ self.future_cache_key_times[rc_challenge] = int(time.time())
478
+ log.info(f"Don't have challenge hash {rc_challenge}, caching EOS")
479
+ return None
480
+
481
+ if peak.deficit == 0:
482
+ if eos.reward_chain.deficit != self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
483
+ log.error(
484
+ f"eos reward_chain deficit got {eos.reward_chain.deficit} "
485
+ f"expected {self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK}"
486
+ )
487
+ return None
488
+ elif eos.reward_chain.deficit != peak.deficit:
489
+ log.error(f"wrong eos reward_chain deficit got {eos.reward_chain.deficit} expected {peak.deficit}")
490
+ return None
491
+
492
+ if peak.deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
493
+ icc_start_element = None
494
+ elif peak.deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK - 1:
495
+ icc_start_element = ClassgroupElement.get_default_element()
496
+ else:
497
+ icc_start_element = peak.infused_challenge_vdf_output
498
+
499
+ if peak.deficit < self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
500
+ curr = peak
501
+ while not curr.first_in_sub_slot and not curr.is_challenge_block(self.constants):
502
+ curr = blocks.block_record(curr.prev_hash)
503
+ if curr.is_challenge_block(self.constants):
504
+ icc_challenge = curr.challenge_block_info_hash
505
+ icc_iters = uint64(total_iters - curr.total_iters)
506
+ else:
507
+ assert curr.finished_infused_challenge_slot_hashes is not None
508
+ icc_challenge = curr.finished_infused_challenge_slot_hashes[-1]
509
+ icc_iters = sub_slot_iters
510
+ assert icc_challenge is not None
511
+
512
+ finish_se, finish_epoch = can_finish_sub_and_full_epoch(
513
+ self.constants,
514
+ blocks,
515
+ peak.height,
516
+ peak.prev_hash,
517
+ peak.deficit,
518
+ peak.sub_epoch_summary_included is not None,
519
+ )
520
+ if finish_se:
521
+ # this is the first slot in a new sub epoch, should include SES
522
+ expected_sub_epoch_summary = make_sub_epoch_summary(
523
+ self.constants,
524
+ blocks,
525
+ peak.height,
526
+ blocks.block_record(blocks.block_record(peak.prev_hash).prev_hash),
527
+ next_difficulty if finish_epoch else None,
528
+ next_sub_slot_iters if finish_epoch else None,
529
+ )
530
+
531
+ if eos.challenge_chain.subepoch_summary_hash is None:
532
+ log.warning("SES should not be None")
533
+ return None
534
+
535
+ if eos.challenge_chain.subepoch_summary_hash != expected_sub_epoch_summary.get_hash():
536
+ log.warning(
537
+ f"Bad SES, expected {expected_sub_epoch_summary} "
538
+ f"expected hash {expected_sub_epoch_summary.get_hash()}, got {eos.challenge_chain}"
539
+ )
540
+ return None
541
+
542
+ if finish_epoch:
543
+ # this is the first slot in a new epoch check diff and iterations
544
+ if (
545
+ eos.challenge_chain.new_sub_slot_iters is None
546
+ or eos.challenge_chain.new_sub_slot_iters != next_sub_slot_iters
547
+ ):
548
+ log.error("wrong new iterations at end of slot bundle")
549
+ return None
550
+
551
+ if (
552
+ eos.challenge_chain.new_difficulty is None
553
+ or eos.challenge_chain.new_difficulty != next_difficulty
554
+ ):
555
+ log.info("wrong new difficulty at end of slot bundle")
556
+ return None
557
+
558
+ else:
559
+ if eos.challenge_chain.new_sub_slot_iters is not None:
560
+ log.error("got new iterations at end of slot bundle when it should be None")
561
+ return None
562
+
563
+ if eos.challenge_chain.new_difficulty is not None:
564
+ log.info("got new difficulty at end of slot bundle when it should be None")
565
+ return None
566
+
567
+ else:
568
+ # empty slots dont have sub_epoch_summary
569
+ if eos.challenge_chain.subepoch_summary_hash is not None:
570
+ log.warning("SES not correct, should be None in an empty slot")
571
+ return None
572
+
573
+ # This is on an empty slot
574
+ cc_start_element = ClassgroupElement.get_default_element()
575
+ icc_start_element = ClassgroupElement.get_default_element()
576
+ iters = sub_slot_iters
577
+ icc_iters = sub_slot_iters
578
+
579
+ # The icc should only be present if the previous slot had an icc too, and not deficit 0 (just finished slot)
580
+ icc_challenge = (
581
+ last_slot.infused_challenge_chain.get_hash()
582
+ if last_slot is not None
583
+ and last_slot.infused_challenge_chain is not None
584
+ and last_slot.reward_chain.deficit != self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK
585
+ else None
586
+ )
587
+
588
+ # Validate cc VDF
589
+ partial_cc_vdf_info = VDFInfo(
590
+ cc_challenge,
591
+ iters,
592
+ eos.challenge_chain.challenge_chain_end_of_slot_vdf.output,
593
+ )
594
+ # The EOS will have the whole sub-slot iters, but the proof is only the delta, from the last peak
595
+ if eos.challenge_chain.challenge_chain_end_of_slot_vdf != partial_cc_vdf_info.replace(
596
+ number_of_iterations=sub_slot_iters
597
+ ):
598
+ return None
599
+ if not eos.proofs.challenge_chain_slot_proof.normalized_to_identity and not validate_vdf(
600
+ eos.proofs.challenge_chain_slot_proof,
601
+ self.constants,
602
+ cc_start_element,
603
+ partial_cc_vdf_info,
604
+ ):
605
+ return None
606
+ if eos.proofs.challenge_chain_slot_proof.normalized_to_identity and not validate_vdf(
607
+ eos.proofs.challenge_chain_slot_proof,
608
+ self.constants,
609
+ ClassgroupElement.get_default_element(),
610
+ eos.challenge_chain.challenge_chain_end_of_slot_vdf,
611
+ ):
612
+ return None
613
+
614
+ # Validate reward chain VDF
615
+ if not validate_vdf(
616
+ eos.proofs.reward_chain_slot_proof,
617
+ self.constants,
618
+ ClassgroupElement.get_default_element(),
619
+ eos.reward_chain.end_of_slot_vdf,
620
+ VDFInfo(rc_challenge, iters, eos.reward_chain.end_of_slot_vdf.output),
621
+ ):
622
+ return None
623
+
624
+ if icc_challenge is not None:
625
+ assert icc_start_element is not None
626
+ assert icc_iters is not None
627
+ assert eos.infused_challenge_chain is not None
628
+ assert eos.infused_challenge_chain is not None
629
+ assert eos.proofs.infused_challenge_chain_slot_proof is not None
630
+ if eos.reward_chain.deficit == self.constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK:
631
+ # only at the end of a challenge slot
632
+ if eos.infused_challenge_chain.get_hash() != eos.challenge_chain.infused_challenge_chain_sub_slot_hash:
633
+ log.error("infused_challenge_chain mismatch in challenge_chain")
634
+ return None
635
+ else:
636
+ assert eos.challenge_chain.infused_challenge_chain_sub_slot_hash is None
637
+ assert eos.infused_challenge_chain.get_hash() == eos.reward_chain.infused_challenge_chain_sub_slot_hash
638
+
639
+ partial_icc_vdf_info = VDFInfo(
640
+ icc_challenge,
641
+ iters,
642
+ eos.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf.output,
643
+ )
644
+ # The EOS will have the whole sub-slot iters, but the proof is only the delta, from the last peak
645
+ if eos.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf != partial_icc_vdf_info.replace(
646
+ number_of_iterations=icc_iters
647
+ ):
648
+ return None
649
+ if not eos.proofs.infused_challenge_chain_slot_proof.normalized_to_identity and not validate_vdf(
650
+ eos.proofs.infused_challenge_chain_slot_proof, self.constants, icc_start_element, partial_icc_vdf_info
651
+ ):
652
+ return None
653
+ if eos.proofs.infused_challenge_chain_slot_proof.normalized_to_identity and not validate_vdf(
654
+ eos.proofs.infused_challenge_chain_slot_proof,
655
+ self.constants,
656
+ ClassgroupElement.get_default_element(),
657
+ eos.infused_challenge_chain.infused_challenge_chain_end_of_slot_vdf,
658
+ ):
659
+ return None
660
+ else:
661
+ # This is the first sub slot and it's empty, therefore there is no ICC
662
+ if eos.infused_challenge_chain is not None or eos.proofs.infused_challenge_chain_slot_proof is not None:
663
+ return None
664
+ if eos.challenge_chain.infused_challenge_chain_sub_slot_hash is not None:
665
+ return None
666
+ if eos.reward_chain.infused_challenge_chain_sub_slot_hash is not None:
667
+ return None
668
+
669
+ self.finished_sub_slots.append((eos, [None] * self.constants.NUM_SPS_SUB_SLOT, total_iters))
670
+
671
+ new_cc_hash = eos.challenge_chain.get_hash()
672
+ self.recent_eos.put(new_cc_hash, (eos, time.time()))
673
+
674
+ new_ips: list[timelord_protocol.NewInfusionPointVDF] = []
675
+ for ip in self.future_ip_cache.get(eos.reward_chain.get_hash(), []):
676
+ new_ips.append(ip)
677
+
678
+ return new_ips
679
+
680
+ def new_signage_point(
681
+ self,
682
+ index: uint8,
683
+ blocks: BlockRecordsProtocol,
684
+ peak: Optional[BlockRecord],
685
+ next_sub_slot_iters: uint64,
686
+ signage_point: SignagePoint,
687
+ skip_vdf_validation: bool = False,
688
+ ) -> bool:
689
+ """
690
+ Returns true if sp successfully added
691
+ """
692
+ assert len(self.finished_sub_slots) >= 1
693
+
694
+ if peak is None or peak.height < 2:
695
+ sub_slot_iters = self.constants.SUB_SLOT_ITERS_STARTING
696
+ else:
697
+ sub_slot_iters = peak.sub_slot_iters
698
+
699
+ # If we don't have this slot, return False
700
+ if index == 0 or index >= self.constants.NUM_SPS_SUB_SLOT:
701
+ return False
702
+ assert (
703
+ signage_point.cc_vdf is not None
704
+ and signage_point.cc_proof is not None
705
+ and signage_point.rc_vdf is not None
706
+ and signage_point.rc_proof is not None
707
+ )
708
+ for sub_slot, sp_arr, start_ss_total_iters in self.finished_sub_slots:
709
+ if sub_slot is None:
710
+ assert start_ss_total_iters == 0
711
+ ss_challenge_hash = self.constants.GENESIS_CHALLENGE
712
+ ss_reward_hash = self.constants.GENESIS_CHALLENGE
713
+ else:
714
+ ss_challenge_hash = sub_slot.challenge_chain.get_hash()
715
+ ss_reward_hash = sub_slot.reward_chain.get_hash()
716
+ if ss_challenge_hash == signage_point.cc_vdf.challenge:
717
+ # If we do have this slot, find the Prev block from SP and validate SP
718
+ if peak is not None and start_ss_total_iters > peak.total_iters:
719
+ # We are in a future sub slot from the peak, so maybe there is a new SSI
720
+ checkpoint_size: uint64 = uint64(next_sub_slot_iters // self.constants.NUM_SPS_SUB_SLOT)
721
+ delta_iters: uint64 = uint64(checkpoint_size * index)
722
+ future_sub_slot: bool = True
723
+ else:
724
+ # We are not in a future sub slot from the peak, so there is no new SSI
725
+ checkpoint_size = uint64(sub_slot_iters // self.constants.NUM_SPS_SUB_SLOT)
726
+ delta_iters = uint64(checkpoint_size * index)
727
+ future_sub_slot = False
728
+ sp_total_iters = start_ss_total_iters + delta_iters
729
+
730
+ curr = peak
731
+ if peak is None or future_sub_slot:
732
+ check_from_start_of_ss = True
733
+ else:
734
+ check_from_start_of_ss = False
735
+ while (
736
+ curr is not None
737
+ and curr.total_iters > start_ss_total_iters
738
+ and curr.total_iters > sp_total_iters
739
+ ):
740
+ if curr.first_in_sub_slot:
741
+ # Did not find a block where it's iters are before our sp_total_iters, in this ss
742
+ check_from_start_of_ss = True
743
+ break
744
+ curr = blocks.block_record(curr.prev_hash)
745
+
746
+ if check_from_start_of_ss:
747
+ # Check VDFs from start of sub slot
748
+ cc_vdf_info_expected = VDFInfo(
749
+ ss_challenge_hash,
750
+ delta_iters,
751
+ signage_point.cc_vdf.output,
752
+ )
753
+
754
+ rc_vdf_info_expected = VDFInfo(
755
+ ss_reward_hash,
756
+ delta_iters,
757
+ signage_point.rc_vdf.output,
758
+ )
759
+ else:
760
+ # Check VDFs from curr
761
+ assert curr is not None
762
+ cc_vdf_info_expected = VDFInfo(
763
+ ss_challenge_hash,
764
+ uint64(sp_total_iters - curr.total_iters),
765
+ signage_point.cc_vdf.output,
766
+ )
767
+ rc_vdf_info_expected = VDFInfo(
768
+ curr.reward_infusion_new_challenge,
769
+ uint64(sp_total_iters - curr.total_iters),
770
+ signage_point.rc_vdf.output,
771
+ )
772
+ if not signage_point.cc_vdf == cc_vdf_info_expected.replace(number_of_iterations=delta_iters):
773
+ self.add_to_future_sp(signage_point, index)
774
+ return False
775
+ if check_from_start_of_ss:
776
+ start_ele = ClassgroupElement.get_default_element()
777
+ else:
778
+ assert curr is not None
779
+ start_ele = curr.challenge_vdf_output
780
+ if not skip_vdf_validation:
781
+ if not signage_point.cc_proof.normalized_to_identity and not validate_vdf(
782
+ signage_point.cc_proof,
783
+ self.constants,
784
+ start_ele,
785
+ cc_vdf_info_expected,
786
+ ):
787
+ self.add_to_future_sp(signage_point, index)
788
+ return False
789
+ if signage_point.cc_proof.normalized_to_identity and not validate_vdf(
790
+ signage_point.cc_proof,
791
+ self.constants,
792
+ ClassgroupElement.get_default_element(),
793
+ signage_point.cc_vdf,
794
+ ):
795
+ self.add_to_future_sp(signage_point, index)
796
+ return False
797
+
798
+ if rc_vdf_info_expected.challenge != signage_point.rc_vdf.challenge:
799
+ # This signage point is probably outdated
800
+ self.add_to_future_sp(signage_point, index)
801
+ return False
802
+
803
+ if not skip_vdf_validation:
804
+ if not validate_vdf(
805
+ signage_point.rc_proof,
806
+ self.constants,
807
+ ClassgroupElement.get_default_element(),
808
+ signage_point.rc_vdf,
809
+ rc_vdf_info_expected,
810
+ ):
811
+ self.add_to_future_sp(signage_point, index)
812
+ return False
813
+
814
+ sp_arr[index] = signage_point
815
+ self.recent_signage_points.put(signage_point.cc_vdf.output.get_hash(), (signage_point, time.time()))
816
+ return True
817
+ self.add_to_future_sp(signage_point, index)
818
+ return False
819
+
820
+ def get_signage_point(self, cc_signage_point: bytes32) -> Optional[SignagePoint]:
821
+ assert len(self.finished_sub_slots) >= 1
822
+ if cc_signage_point == self.constants.GENESIS_CHALLENGE:
823
+ return SignagePoint(None, None, None, None)
824
+
825
+ for sub_slot, sps, _ in self.finished_sub_slots:
826
+ if sub_slot is not None and sub_slot.challenge_chain.get_hash() == cc_signage_point:
827
+ return SignagePoint(None, None, None, None)
828
+ for sp in sps:
829
+ if sp is not None:
830
+ assert sp.cc_vdf is not None
831
+ if sp.cc_vdf.output.get_hash() == cc_signage_point:
832
+ return sp
833
+ return None
834
+
835
+ def get_signage_point_by_index(
836
+ self, challenge_hash: bytes32, index: uint8, last_rc_infusion: bytes32
837
+ ) -> Optional[SignagePoint]:
838
+ assert len(self.finished_sub_slots) >= 1
839
+ for sub_slot, sps, _ in self.finished_sub_slots:
840
+ if sub_slot is not None:
841
+ cc_hash = sub_slot.challenge_chain.get_hash()
842
+ else:
843
+ cc_hash = self.constants.GENESIS_CHALLENGE
844
+
845
+ if cc_hash == challenge_hash:
846
+ if index == 0:
847
+ return SignagePoint(None, None, None, None)
848
+ sp: Optional[SignagePoint] = sps[index]
849
+ if sp is not None:
850
+ assert sp.rc_vdf is not None
851
+ if sp.rc_vdf.challenge == last_rc_infusion:
852
+ return sp
853
+ return None
854
+ return None
855
+
856
+ def have_newer_signage_point(self, challenge_hash: bytes32, index: uint8, last_rc_infusion: bytes32) -> bool:
857
+ """
858
+ Returns true if we have a signage point at this index which is based on a newer infusion.
859
+ """
860
+ assert len(self.finished_sub_slots) >= 1
861
+ for sub_slot, sps, _ in self.finished_sub_slots:
862
+ if sub_slot is not None:
863
+ cc_hash = sub_slot.challenge_chain.get_hash()
864
+ else:
865
+ cc_hash = self.constants.GENESIS_CHALLENGE
866
+
867
+ if cc_hash == challenge_hash:
868
+ found_rc_hash = False
869
+ for i in range(0, index):
870
+ sp: Optional[SignagePoint] = sps[i]
871
+ if sp is not None and sp.rc_vdf is not None and sp.rc_vdf.challenge == last_rc_infusion:
872
+ found_rc_hash = True
873
+ sp = sps[index]
874
+ if (
875
+ found_rc_hash
876
+ and sp is not None
877
+ and sp.rc_vdf is not None
878
+ and sp.rc_vdf.challenge != last_rc_infusion
879
+ ):
880
+ return True
881
+ return False
882
+
883
+ def new_peak(
884
+ self,
885
+ peak: BlockRecord,
886
+ peak_full_block: FullBlock,
887
+ sp_sub_slot: Optional[EndOfSubSlotBundle], # None if not overflow, or in first/second slot
888
+ ip_sub_slot: Optional[EndOfSubSlotBundle], # None if in first slot
889
+ fork_block: Optional[BlockRecord],
890
+ blocks: BlockRecordsProtocol,
891
+ next_sub_slot_iters: uint64,
892
+ next_difficulty: uint64,
893
+ ) -> FullNodeStorePeakResult:
894
+ """
895
+ If the peak is an overflow block, must provide two sub-slots: one for the current sub-slot and one for
896
+ the prev sub-slot (since we still might get more blocks with an sp in the previous sub-slot)
897
+
898
+ Results in either one or two sub-slots in finished_sub_slots.
899
+ """
900
+ assert len(self.finished_sub_slots) >= 1
901
+
902
+ if ip_sub_slot is None:
903
+ # We are still in the first sub-slot, no new sub slots ey
904
+ self.initialize_genesis_sub_slot()
905
+ else:
906
+ # This is not the first sub-slot in the chain
907
+ sp_sub_slot_sps: list[Optional[SignagePoint]] = [None] * self.constants.NUM_SPS_SUB_SLOT
908
+ ip_sub_slot_sps: list[Optional[SignagePoint]] = [None] * self.constants.NUM_SPS_SUB_SLOT
909
+
910
+ if fork_block is not None and fork_block.sub_slot_iters != peak.sub_slot_iters:
911
+ # If there was a reorg and a difficulty adjustment, just clear all the slots
912
+ self.clear_slots()
913
+ else:
914
+ interval_iters = calculate_sp_interval_iters(self.constants, peak.sub_slot_iters)
915
+ # If it's not a reorg, or there is a reorg on the same difficulty, we can keep signage points
916
+ # that we had before, in the cache
917
+ for index, (sub_slot, sps, total_iters) in enumerate(self.finished_sub_slots):
918
+ if sub_slot is None:
919
+ continue
920
+
921
+ if fork_block is None:
922
+ # If this is not a reorg, we still want to remove signage points after the new peak
923
+ fork_block = peak
924
+ replaced_sps: list[Optional[SignagePoint]] = [] # index 0 is the end of sub slot
925
+ for i, sp in enumerate(sps):
926
+ if (total_iters + i * interval_iters) < fork_block.total_iters:
927
+ # Sps before the fork point as still valid
928
+ replaced_sps.append(sp)
929
+ else:
930
+ if sp is not None:
931
+ log.debug(
932
+ f"Reverting {i} {(total_iters + i * interval_iters)} {fork_block.total_iters}"
933
+ )
934
+ # Sps after the fork point should be removed
935
+ replaced_sps.append(None)
936
+ assert len(sps) == len(replaced_sps)
937
+
938
+ if sub_slot == sp_sub_slot:
939
+ sp_sub_slot_sps = replaced_sps
940
+ if sub_slot == ip_sub_slot:
941
+ ip_sub_slot_sps = replaced_sps
942
+
943
+ self.clear_slots()
944
+
945
+ prev_sub_slot_total_iters = peak.sp_sub_slot_total_iters(self.constants)
946
+ if sp_sub_slot is not None or prev_sub_slot_total_iters == 0:
947
+ assert peak.overflow or prev_sub_slot_total_iters
948
+ self.finished_sub_slots.append((sp_sub_slot, sp_sub_slot_sps, prev_sub_slot_total_iters))
949
+
950
+ ip_sub_slot_total_iters = peak.ip_sub_slot_total_iters(self.constants)
951
+ self.finished_sub_slots.append((ip_sub_slot, ip_sub_slot_sps, ip_sub_slot_total_iters))
952
+
953
+ new_eos: Optional[EndOfSubSlotBundle] = None
954
+ new_sps: list[tuple[uint8, SignagePoint]] = []
955
+ new_ips: list[timelord_protocol.NewInfusionPointVDF] = []
956
+
957
+ future_eos: list[EndOfSubSlotBundle] = self.future_eos_cache.get(peak.reward_infusion_new_challenge, []).copy()
958
+ for eos in future_eos:
959
+ if (
960
+ self.new_finished_sub_slot(eos, blocks, peak, next_sub_slot_iters, next_difficulty, peak_full_block)
961
+ is not None
962
+ ):
963
+ new_eos = eos
964
+ break
965
+
966
+ future_sps: list[tuple[uint8, SignagePoint]] = self.future_sp_cache.get(
967
+ peak.reward_infusion_new_challenge, []
968
+ ).copy()
969
+ for index, sp in future_sps:
970
+ assert sp.cc_vdf is not None
971
+ if self.new_signage_point(index, blocks, peak, peak.sub_slot_iters, sp):
972
+ new_sps.append((index, sp))
973
+
974
+ for ip in self.future_ip_cache.get(peak.reward_infusion_new_challenge, []):
975
+ new_ips.append(ip)
976
+
977
+ self.future_eos_cache.pop(peak.reward_infusion_new_challenge, [])
978
+ self.future_sp_cache.pop(peak.reward_infusion_new_challenge, [])
979
+ self.future_ip_cache.pop(peak.reward_infusion_new_challenge, [])
980
+
981
+ for eos_op, _, _ in self.finished_sub_slots:
982
+ if eos_op is not None:
983
+ self.recent_eos.put(eos_op.challenge_chain.get_hash(), (eos_op, time.time()))
984
+
985
+ # Only forward the last 4 SPs that we have cached, as others will be too old
986
+ return FullNodeStorePeakResult(new_eos, sorted(new_sps)[-4:], new_ips)
987
+
988
+ def get_finished_sub_slots(
989
+ self,
990
+ block_records: BlockRecordsProtocol,
991
+ prev_b: Optional[BlockRecord],
992
+ last_challenge_to_add: bytes32,
993
+ ) -> Optional[list[EndOfSubSlotBundle]]:
994
+ """
995
+ Retrieves the EndOfSubSlotBundles that are in the store either:
996
+ 1. From the starting challenge if prev_b is None
997
+ 2. That are not included in the blockchain with peak of prev_b if prev_b is not None
998
+
999
+ Stops at last_challenge
1000
+ """
1001
+
1002
+ if prev_b is None:
1003
+ # The first sub slot must be None
1004
+ assert self.finished_sub_slots[0][0] is None
1005
+ challenge_in_chain: bytes32 = self.constants.GENESIS_CHALLENGE
1006
+ else:
1007
+ curr: BlockRecord = prev_b
1008
+ while not curr.first_in_sub_slot:
1009
+ curr = block_records.block_record(curr.prev_hash)
1010
+ assert curr is not None
1011
+ assert curr.finished_challenge_slot_hashes is not None
1012
+ challenge_in_chain = curr.finished_challenge_slot_hashes[-1]
1013
+
1014
+ if last_challenge_to_add == challenge_in_chain:
1015
+ # No additional slots to add
1016
+ return []
1017
+
1018
+ collected_sub_slots: list[EndOfSubSlotBundle] = []
1019
+ found_last_challenge = False
1020
+ found_connecting_challenge = False
1021
+ for sub_slot, sps, total_iters in self.finished_sub_slots[1:]:
1022
+ assert sub_slot is not None
1023
+ if sub_slot.challenge_chain.challenge_chain_end_of_slot_vdf.challenge == challenge_in_chain:
1024
+ found_connecting_challenge = True
1025
+ if found_connecting_challenge:
1026
+ collected_sub_slots.append(sub_slot)
1027
+ if found_connecting_challenge and sub_slot.challenge_chain.get_hash() == last_challenge_to_add:
1028
+ found_last_challenge = True
1029
+ break
1030
+ if not found_last_challenge:
1031
+ log.warning(f"Did not find hash {last_challenge_to_add} connected to {challenge_in_chain}")
1032
+ return None
1033
+ return collected_sub_slots