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,897 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+ import pytest
9
+ from clvm.casts import int_to_bytes
10
+
11
+ from chia._tests.blockchain.blockchain_test_utils import _validate_and_add_block
12
+ from chia._tests.util.db_connection import DBConnection
13
+ from chia._tests.util.get_name_puzzle_conditions import get_name_puzzle_conditions
14
+ from chia._tests.util.misc import Marks, datacases
15
+ from chia.consensus.block_body_validation import ForkInfo
16
+ from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
17
+ from chia.consensus.blockchain import AddBlockResult, Blockchain
18
+ from chia.consensus.coinbase import create_farmer_coin, create_pool_coin
19
+ from chia.full_node.block_store import BlockStore
20
+ from chia.full_node.coin_store import CoinStore
21
+ from chia.full_node.hint_store import HintStore
22
+ from chia.protocols.wallet_protocol import CoinState
23
+ from chia.simulator.block_tools import BlockTools, test_constants
24
+ from chia.simulator.wallet_tools import WalletTool
25
+ from chia.types.blockchain_format.coin import Coin
26
+ from chia.types.blockchain_format.sized_bytes import bytes32
27
+ from chia.types.coin_record import CoinRecord
28
+ from chia.types.eligible_coin_spends import UnspentLineageInfo
29
+ from chia.types.full_block import FullBlock
30
+ from chia.types.generator_types import BlockGenerator
31
+ from chia.util.generator_tools import tx_removals_and_additions
32
+ from chia.util.hash import std_hash
33
+ from chia.util.ints import uint32, uint64
34
+
35
+ constants = test_constants
36
+
37
+ WALLET_A = WalletTool(constants)
38
+
39
+ log = logging.getLogger(__name__)
40
+
41
+
42
+ def get_future_reward_coins(block: FullBlock) -> tuple[Coin, Coin]:
43
+ pool_amount = calculate_pool_reward(block.height)
44
+ farmer_amount = calculate_base_farmer_reward(block.height)
45
+ if block.is_transaction_block():
46
+ assert block.transactions_info is not None
47
+ farmer_amount = uint64(farmer_amount + block.transactions_info.fees)
48
+ pool_coin: Coin = create_pool_coin(
49
+ block.height, block.foliage.foliage_block_data.pool_target.puzzle_hash, pool_amount, constants.GENESIS_CHALLENGE
50
+ )
51
+ farmer_coin: Coin = create_farmer_coin(
52
+ block.height,
53
+ block.foliage.foliage_block_data.farmer_reward_puzzle_hash,
54
+ farmer_amount,
55
+ constants.GENESIS_CHALLENGE,
56
+ )
57
+ return pool_coin, farmer_coin
58
+
59
+
60
+ @pytest.mark.limit_consensus_modes(reason="save time")
61
+ @pytest.mark.anyio
62
+ async def test_basic_coin_store(db_version: int, softfork_height: uint32, bt: BlockTools) -> None:
63
+ wallet_a = WALLET_A
64
+ reward_ph = wallet_a.get_new_puzzlehash()
65
+
66
+ # Generate some coins
67
+ blocks = bt.get_consecutive_blocks(
68
+ 10,
69
+ [],
70
+ farmer_reward_puzzle_hash=reward_ph,
71
+ pool_reward_puzzle_hash=reward_ph,
72
+ )
73
+
74
+ coins_to_spend: list[Coin] = []
75
+ for block in blocks:
76
+ if block.is_transaction_block():
77
+ for coin in block.get_included_reward_coins():
78
+ if coin.puzzle_hash == reward_ph:
79
+ coins_to_spend.append(coin)
80
+
81
+ spend_bundle = wallet_a.generate_signed_transaction(uint64(1000), wallet_a.get_new_puzzlehash(), coins_to_spend[0])
82
+
83
+ async with DBConnection(db_version) as db_wrapper:
84
+ coin_store = await CoinStore.create(db_wrapper)
85
+
86
+ blocks = bt.get_consecutive_blocks(
87
+ 10,
88
+ blocks,
89
+ farmer_reward_puzzle_hash=reward_ph,
90
+ pool_reward_puzzle_hash=reward_ph,
91
+ transaction_data=spend_bundle,
92
+ )
93
+
94
+ # Adding blocks to the coin store
95
+ should_be_included_prev: set[Coin] = set()
96
+ should_be_included: set[Coin] = set()
97
+ for block in blocks:
98
+ farmer_coin, pool_coin = get_future_reward_coins(block)
99
+ should_be_included.add(farmer_coin)
100
+ should_be_included.add(pool_coin)
101
+ if block.is_transaction_block():
102
+ if block.transactions_generator is not None:
103
+ assert block.transactions_info is not None
104
+ block_gen: BlockGenerator = BlockGenerator(block.transactions_generator, [])
105
+ npc_result = get_name_puzzle_conditions(
106
+ block_gen,
107
+ bt.constants.MAX_BLOCK_COST_CLVM,
108
+ mempool_mode=False,
109
+ height=softfork_height,
110
+ constants=bt.constants,
111
+ )
112
+ tx_removals, tx_additions = tx_removals_and_additions(npc_result.conds)
113
+ else:
114
+ tx_removals, tx_additions = [], []
115
+
116
+ assert set(block.get_included_reward_coins()) == should_be_included_prev
117
+
118
+ if block.is_transaction_block():
119
+ assert block.foliage_transaction_block is not None
120
+ await coin_store.new_block(
121
+ block.height,
122
+ block.foliage_transaction_block.timestamp,
123
+ block.get_included_reward_coins(),
124
+ tx_additions,
125
+ tx_removals,
126
+ )
127
+
128
+ if block.height != 0:
129
+ with pytest.raises(Exception):
130
+ await coin_store.new_block(
131
+ block.height,
132
+ block.foliage_transaction_block.timestamp,
133
+ block.get_included_reward_coins(),
134
+ tx_additions,
135
+ tx_removals,
136
+ )
137
+
138
+ all_records = set()
139
+ for expected_coin in should_be_included_prev:
140
+ # Check that the coinbase rewards are added
141
+ record = await coin_store.get_coin_record(expected_coin.name())
142
+ assert record is not None
143
+ assert not record.spent
144
+ assert record.coin == expected_coin
145
+ all_records.add(record)
146
+ for coin_name in tx_removals:
147
+ # Check that the removed coins are set to spent
148
+ record = await coin_store.get_coin_record(coin_name)
149
+ assert record is not None
150
+ assert record.spent
151
+ all_records.add(record)
152
+ for coin in tx_additions:
153
+ # Check that the added coins are added
154
+ record = await coin_store.get_coin_record(coin.name())
155
+ assert record is not None
156
+ assert not record.spent
157
+ assert coin == record.coin
158
+ all_records.add(record)
159
+
160
+ db_records = await coin_store.get_coin_records(
161
+ [c.name() for c in list(should_be_included_prev) + tx_additions] + tx_removals
162
+ )
163
+ assert len(db_records) == len(should_be_included_prev) + len(tx_removals) + len(tx_additions)
164
+ assert len(db_records) == len(all_records)
165
+ for record in db_records:
166
+ assert record in all_records
167
+
168
+ should_be_included_prev = should_be_included.copy()
169
+ should_be_included = set()
170
+
171
+
172
+ @pytest.mark.limit_consensus_modes(reason="save time")
173
+ @pytest.mark.anyio
174
+ async def test_set_spent(db_version: int, bt: BlockTools) -> None:
175
+ blocks = bt.get_consecutive_blocks(9, [])
176
+
177
+ async with DBConnection(db_version) as db_wrapper:
178
+ coin_store = await CoinStore.create(db_wrapper)
179
+
180
+ # Save/get block
181
+ for block in blocks:
182
+ if block.is_transaction_block():
183
+ removals: list[bytes32] = []
184
+ additions: list[Coin] = []
185
+ async with db_wrapper.writer():
186
+ if block.is_transaction_block():
187
+ assert block.foliage_transaction_block is not None
188
+ await coin_store.new_block(
189
+ block.height,
190
+ block.foliage_transaction_block.timestamp,
191
+ block.get_included_reward_coins(),
192
+ additions,
193
+ removals,
194
+ )
195
+
196
+ coins = block.get_included_reward_coins()
197
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
198
+
199
+ await coin_store._set_spent([r.name for r in records if r is not None], block.height)
200
+
201
+ if len(records) > 0:
202
+ for r in records:
203
+ assert r is not None
204
+ assert (await coin_store.get_coin_record(r.name)) is not None
205
+
206
+ # Check that we can't spend a coin twice in DB
207
+ with pytest.raises(ValueError, match="Invalid operation to set spent"):
208
+ await coin_store._set_spent([r.name for r in records if r is not None], block.height)
209
+
210
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
211
+ for record in records:
212
+ assert record is not None
213
+ assert record.spent
214
+ assert record.spent_block_index == block.height
215
+
216
+
217
+ @pytest.mark.limit_consensus_modes(reason="save time")
218
+ @pytest.mark.anyio
219
+ async def test_num_unspent(bt: BlockTools, db_version: int) -> None:
220
+ blocks = bt.get_consecutive_blocks(37, [])
221
+
222
+ expect_unspent = 0
223
+ test_excercised = False
224
+
225
+ async with DBConnection(db_version) as db_wrapper:
226
+ coin_store = await CoinStore.create(db_wrapper)
227
+
228
+ for block in blocks:
229
+ if not block.is_transaction_block():
230
+ continue
231
+
232
+ if block.is_transaction_block():
233
+ assert block.foliage_transaction_block is not None
234
+ removals: list[bytes32] = []
235
+ additions: list[Coin] = []
236
+ await coin_store.new_block(
237
+ block.height,
238
+ block.foliage_transaction_block.timestamp,
239
+ block.get_included_reward_coins(),
240
+ additions,
241
+ removals,
242
+ )
243
+
244
+ expect_unspent += len(block.get_included_reward_coins())
245
+ assert await coin_store.num_unspent() == expect_unspent
246
+ test_excercised = expect_unspent > 0
247
+
248
+ assert test_excercised
249
+
250
+
251
+ @pytest.mark.limit_consensus_modes(reason="save time")
252
+ @pytest.mark.anyio
253
+ async def test_rollback(db_version: int, bt: BlockTools) -> None:
254
+ blocks = bt.get_consecutive_blocks(20)
255
+
256
+ async with DBConnection(db_version) as db_wrapper:
257
+ coin_store = await CoinStore.create(db_wrapper)
258
+
259
+ selected_coin: Optional[CoinRecord] = None
260
+ all_coins: list[Coin] = []
261
+
262
+ for block in blocks:
263
+ all_coins += list(block.get_included_reward_coins())
264
+ if block.is_transaction_block():
265
+ removals: list[bytes32] = []
266
+ additions: list[Coin] = []
267
+ assert block.foliage_transaction_block is not None
268
+ await coin_store.new_block(
269
+ block.height,
270
+ block.foliage_transaction_block.timestamp,
271
+ block.get_included_reward_coins(),
272
+ additions,
273
+ removals,
274
+ )
275
+ coins = block.get_included_reward_coins()
276
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
277
+
278
+ spend_selected_coin = selected_coin is not None
279
+ if block.height != 0 and selected_coin is None:
280
+ # Select the first CoinRecord which will be spent at the next transaction block.
281
+ selected_coin = records[0]
282
+ await coin_store._set_spent([r.name for r in records[1:] if r is not None], block.height)
283
+ else:
284
+ await coin_store._set_spent([r.name for r in records if r is not None], block.height)
285
+
286
+ if spend_selected_coin:
287
+ assert selected_coin is not None
288
+ await coin_store._set_spent([selected_coin.name], block.height)
289
+
290
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins] # update coin records
291
+ for record in records:
292
+ assert record is not None
293
+ if (
294
+ selected_coin is not None
295
+ and selected_coin.name == record.name
296
+ and not selected_coin.confirmed_block_index < block.height
297
+ ):
298
+ assert not record.spent
299
+ else:
300
+ assert record.spent
301
+ assert record.spent_block_index == block.height
302
+
303
+ if spend_selected_coin:
304
+ break
305
+
306
+ assert selected_coin is not None
307
+ reorg_index = selected_coin.confirmed_block_index
308
+
309
+ # Get all CoinRecords.
310
+ all_records = [await coin_store.get_coin_record(coin.name()) for coin in all_coins]
311
+
312
+ # The reorg will revert the creation and spend of many coins. It will also revert the spend (but not the
313
+ # creation) of the selected coin.
314
+ changed_records = await coin_store.rollback_to_block(reorg_index)
315
+ changed_coin_records = [cr.coin for cr in changed_records]
316
+ assert selected_coin in changed_records
317
+ for coin_record in all_records:
318
+ assert coin_record is not None
319
+ if coin_record.confirmed_block_index > reorg_index:
320
+ assert coin_record.coin in changed_coin_records
321
+ if coin_record.spent_block_index > reorg_index:
322
+ assert coin_record.coin in changed_coin_records
323
+
324
+ for block in blocks:
325
+ if block.is_transaction_block():
326
+ coins = block.get_included_reward_coins()
327
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
328
+
329
+ if block.height <= reorg_index:
330
+ for record in records:
331
+ assert record is not None
332
+ assert record.spent == (record.name != selected_coin.name)
333
+ else:
334
+ for record in records:
335
+ assert record is None
336
+
337
+
338
+ @pytest.mark.anyio
339
+ async def test_basic_reorg(tmp_dir: Path, db_version: int, bt: BlockTools) -> None:
340
+ async with DBConnection(db_version) as db_wrapper:
341
+ initial_block_count = 30
342
+ reorg_length = 15
343
+ blocks = bt.get_consecutive_blocks(initial_block_count)
344
+ coin_store = await CoinStore.create(db_wrapper)
345
+ store = await BlockStore.create(db_wrapper)
346
+ b: Blockchain = await Blockchain.create(coin_store, store, bt.constants, tmp_dir, 2)
347
+ try:
348
+ records: list[Optional[CoinRecord]] = []
349
+
350
+ for block in blocks:
351
+ await _validate_and_add_block(b, block)
352
+ peak = b.get_peak()
353
+ assert peak is not None
354
+ assert peak.height == initial_block_count - 1
355
+
356
+ for c, block in enumerate(blocks):
357
+ if block.is_transaction_block():
358
+ coins = block.get_included_reward_coins()
359
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
360
+ for record in records:
361
+ assert record is not None
362
+ assert not record.spent
363
+ assert record.confirmed_block_index == block.height
364
+ assert record.spent_block_index == 0
365
+
366
+ blocks_reorg_chain = bt.get_consecutive_blocks(reorg_length, blocks[: initial_block_count - 10], seed=b"2")
367
+
368
+ fork_info = ForkInfo(-1, -1, bt.constants.GENESIS_CHALLENGE)
369
+ for reorg_block in blocks_reorg_chain:
370
+ if reorg_block.height < initial_block_count - 10:
371
+ await _validate_and_add_block(
372
+ b, reorg_block, expected_result=AddBlockResult.ALREADY_HAVE_BLOCK, fork_info=fork_info
373
+ )
374
+ elif reorg_block.height < initial_block_count:
375
+ await _validate_and_add_block(
376
+ b, reorg_block, expected_result=AddBlockResult.ADDED_AS_ORPHAN, fork_info=fork_info
377
+ )
378
+ elif reorg_block.height >= initial_block_count:
379
+ await _validate_and_add_block(
380
+ b, reorg_block, expected_result=AddBlockResult.NEW_PEAK, fork_info=fork_info
381
+ )
382
+ if reorg_block.is_transaction_block():
383
+ coins = reorg_block.get_included_reward_coins()
384
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
385
+ for record in records:
386
+ assert record is not None
387
+ assert not record.spent
388
+ assert record.confirmed_block_index == reorg_block.height
389
+ assert record.spent_block_index == 0
390
+ peak = b.get_peak()
391
+ assert peak is not None
392
+ assert peak.height == initial_block_count - 10 + reorg_length - 1
393
+ finally:
394
+ b.shut_down()
395
+
396
+
397
+ @pytest.mark.limit_consensus_modes(reason="save time")
398
+ @pytest.mark.anyio
399
+ async def test_get_puzzle_hash(tmp_dir: Path, db_version: int, bt: BlockTools) -> None:
400
+ async with DBConnection(db_version) as db_wrapper:
401
+ num_blocks = 20
402
+ farmer_ph = bytes32(32 * b"0")
403
+ pool_ph = bytes32(32 * b"1")
404
+ blocks = bt.get_consecutive_blocks(
405
+ num_blocks,
406
+ farmer_reward_puzzle_hash=farmer_ph,
407
+ pool_reward_puzzle_hash=pool_ph,
408
+ guarantee_transaction_block=True,
409
+ )
410
+ coin_store = await CoinStore.create(db_wrapper)
411
+ store = await BlockStore.create(db_wrapper)
412
+ b: Blockchain = await Blockchain.create(coin_store, store, bt.constants, tmp_dir, 2)
413
+ for block in blocks:
414
+ await _validate_and_add_block(b, block)
415
+ peak = b.get_peak()
416
+ assert peak is not None
417
+ assert peak.height == num_blocks - 1
418
+
419
+ coins_farmer = await coin_store.get_coin_records_by_puzzle_hash(True, pool_ph)
420
+ coins_pool = await coin_store.get_coin_records_by_puzzle_hash(True, farmer_ph)
421
+
422
+ assert len(coins_farmer) == num_blocks - 2
423
+ assert len(coins_pool) == num_blocks - 2
424
+
425
+ b.shut_down()
426
+
427
+
428
+ @pytest.mark.anyio
429
+ async def test_get_coin_states(db_version: int) -> None:
430
+ async with DBConnection(db_version) as db_wrapper:
431
+ crs = [
432
+ CoinRecord(
433
+ Coin(std_hash(i.to_bytes(4, byteorder="big")), std_hash(b"2"), uint64(100)),
434
+ uint32(i),
435
+ uint32(2 * i),
436
+ False,
437
+ uint64(12321312),
438
+ )
439
+ for i in range(1, 301)
440
+ ]
441
+ crs += [
442
+ CoinRecord(
443
+ Coin(std_hash(b"X" + i.to_bytes(4, byteorder="big")), std_hash(b"3"), uint64(100)),
444
+ uint32(i),
445
+ uint32(2 * i),
446
+ False,
447
+ uint64(12321312),
448
+ )
449
+ for i in range(1, 301)
450
+ ]
451
+ coin_store = await CoinStore.create(db_wrapper)
452
+ await coin_store._add_coin_records(crs)
453
+
454
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(0))) == 300
455
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(False, {std_hash(b"2")}, uint32(0))) == 0
456
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(300))) == 151
457
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(603))) == 0
458
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"1")}, uint32(0))) == 0
459
+
460
+ # test max_items limit
461
+ for limit in [0, 1, 42, 300]:
462
+ assert (
463
+ len(
464
+ await coin_store.get_coin_states_by_puzzle_hashes(
465
+ True, {std_hash(b"2")}, uint32(0), max_items=limit
466
+ )
467
+ )
468
+ == limit
469
+ )
470
+
471
+ # if the limit is very high, we should get all of them
472
+ assert (
473
+ len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(0), max_items=10000))
474
+ == 300
475
+ )
476
+
477
+ coins = {cr.coin.name() for cr in crs}
478
+ bad_coins = {std_hash(cr.coin.name()) for cr in crs}
479
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(0))) == 600
480
+ assert len(await coin_store.get_coin_states_by_ids(False, coins, uint32(0))) == 0
481
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300))) == 302
482
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(603))) == 0
483
+ assert len(await coin_store.get_coin_states_by_ids(True, bad_coins, uint32(0))) == 0
484
+ # Test max_height
485
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(603))) == 600
486
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(602))) == 600
487
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(599))) == 598
488
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(400))) == 400
489
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(301))) == 300
490
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(300))) == 300
491
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(299))) == 298
492
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(0))) == 0
493
+ # Test min_height + max_height
494
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(603))) == 302
495
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(602))) == 302
496
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(599))) == 300
497
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(400))) == 102
498
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(301))) == 2
499
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(300))) == 2
500
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(299))) == 0
501
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(0))) == 0
502
+
503
+ # test max_items limit
504
+ for limit in [0, 1, 42, 300]:
505
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(0), max_items=limit)) == limit
506
+
507
+ # if the limit is very high, we should get all of them
508
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(0), max_items=10000)) == 600
509
+
510
+
511
+ @dataclass(frozen=True)
512
+ class RandomCoinRecords:
513
+ items: list[CoinRecord]
514
+ puzzle_hashes: list[bytes32]
515
+ hints: list[tuple[bytes32, bytes]]
516
+
517
+
518
+ @pytest.fixture(scope="session")
519
+ def random_coin_records() -> RandomCoinRecords:
520
+ coin_records: list[CoinRecord] = []
521
+ puzzle_hashes: list[bytes32] = []
522
+ hints: list[tuple[bytes32, bytes]] = []
523
+
524
+ for i in range(50000):
525
+ is_spent = i % 2 == 0
526
+ is_hinted = i % 7 == 0
527
+ created_height = uint32(i)
528
+ spent_height = uint32(created_height + 100)
529
+
530
+ puzzle_hash = std_hash(i.to_bytes(4, byteorder="big"))
531
+
532
+ coin = Coin(
533
+ std_hash(b"Parent Coin Id " + i.to_bytes(4, byteorder="big")),
534
+ puzzle_hash,
535
+ uint64(i),
536
+ )
537
+
538
+ if is_hinted:
539
+ hint = std_hash(b"Hinted " + puzzle_hash)
540
+ hints.append((coin.name(), hint))
541
+ puzzle_hashes.append(hint)
542
+ else:
543
+ puzzle_hashes.append(puzzle_hash)
544
+
545
+ coin_records.append(
546
+ CoinRecord(
547
+ coin=coin,
548
+ confirmed_block_index=created_height,
549
+ spent_block_index=spent_height if is_spent else uint32(0),
550
+ coinbase=False,
551
+ timestamp=uint64(0),
552
+ )
553
+ )
554
+
555
+ coin_records.sort(key=lambda cr: max(cr.confirmed_block_index, cr.spent_block_index))
556
+
557
+ return RandomCoinRecords(coin_records, puzzle_hashes, hints)
558
+
559
+
560
+ @pytest.mark.anyio
561
+ @pytest.mark.parametrize("include_spent", [True, False])
562
+ @pytest.mark.parametrize("include_unspent", [True, False])
563
+ @pytest.mark.parametrize("include_hinted", [True, False])
564
+ @pytest.mark.parametrize(
565
+ "min_amount", [uint64(0), uint64(30000), uint64(0xFFFF), uint64(0x7FFF), uint64(0x8000), uint64(0x8000000000000000)]
566
+ )
567
+ async def test_coin_state_batches(
568
+ db_version: int,
569
+ random_coin_records: RandomCoinRecords,
570
+ include_spent: bool,
571
+ include_unspent: bool,
572
+ include_hinted: bool,
573
+ min_amount: uint64,
574
+ ) -> None:
575
+ async with DBConnection(db_version) as db_wrapper:
576
+ # Initialize coin and hint stores.
577
+ coin_store = await CoinStore.create(db_wrapper)
578
+ hint_store = await HintStore.create(db_wrapper)
579
+
580
+ await coin_store._add_coin_records(random_coin_records.items)
581
+ await hint_store.add_hints(random_coin_records.hints)
582
+
583
+ # Make sure all of the coin states are found when batching.
584
+ ph_set = set(random_coin_records.puzzle_hashes)
585
+ expected_crs = []
586
+ for cr in random_coin_records.items:
587
+ if cr.spent_block_index == 0 and not include_unspent:
588
+ continue
589
+ if cr.spent_block_index > 0 and not include_spent:
590
+ continue
591
+ if cr.coin.puzzle_hash not in ph_set and not include_hinted:
592
+ continue
593
+ if cr.coin.amount < min_amount:
594
+ continue
595
+ expected_crs.append(cr)
596
+
597
+ height: Optional[uint32] = uint32(0)
598
+ all_coin_states: list[CoinState] = []
599
+ remaining_phs = random_coin_records.puzzle_hashes.copy()
600
+
601
+ def height_of(coin_state: CoinState) -> int:
602
+ return max(coin_state.created_height or 0, coin_state.spent_height or 0)
603
+
604
+ while len(remaining_phs) > 0:
605
+ while height is not None:
606
+ (coin_states, height) = await coin_store.batch_coin_states_by_puzzle_hashes(
607
+ remaining_phs[: CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE],
608
+ min_height=height,
609
+ include_spent=include_spent,
610
+ include_unspent=include_unspent,
611
+ include_hinted=include_hinted,
612
+ min_amount=min_amount,
613
+ max_items=7000,
614
+ )
615
+
616
+ # Ensure that all of the returned coin states are in order.
617
+ assert all(
618
+ height_of(coin_states[i]) <= height_of(coin_states[i + 1]) for i in range(len(coin_states) - 1)
619
+ )
620
+
621
+ all_coin_states += coin_states
622
+
623
+ if height is None:
624
+ remaining_phs = remaining_phs[CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE :]
625
+
626
+ if len(remaining_phs) > 0:
627
+ height = uint32(0)
628
+
629
+ assert len(all_coin_states) == len(expected_crs)
630
+
631
+ all_coin_states.sort(key=height_of)
632
+
633
+ for i in range(len(expected_crs)):
634
+ actual = all_coin_states[i]
635
+ expected = expected_crs[i]
636
+
637
+ assert actual.coin == expected.coin, i
638
+ assert uint32(actual.created_height or 0) == expected.confirmed_block_index, i
639
+ assert uint32(actual.spent_height or 0) == expected.spent_block_index, i
640
+
641
+
642
+ @pytest.mark.anyio
643
+ @pytest.mark.parametrize("cut_off_middle", [True, False])
644
+ async def test_batch_many_coin_states(db_version: int, cut_off_middle: bool) -> None:
645
+ async with DBConnection(db_version) as db_wrapper:
646
+ ph = bytes32(b"0" * 32)
647
+
648
+ # Generate coin records.
649
+ coin_records: list[CoinRecord] = []
650
+ count = 50000
651
+
652
+ for i in range(count):
653
+ # Create coin records at either height 10 or 12.
654
+ created_height = uint32((i % 2) * 2 + 10)
655
+ coin = Coin(
656
+ std_hash(b"Parent Coin Id " + i.to_bytes(4, byteorder="big")),
657
+ ph,
658
+ uint64(i),
659
+ )
660
+ coin_records.append(
661
+ CoinRecord(
662
+ coin=coin,
663
+ confirmed_block_index=created_height,
664
+ spent_block_index=uint32(0),
665
+ coinbase=False,
666
+ timestamp=uint64(0),
667
+ )
668
+ )
669
+
670
+ # Initialize coin and hint stores.
671
+ coin_store = await CoinStore.create(db_wrapper)
672
+ await HintStore.create(db_wrapper)
673
+
674
+ await coin_store._add_coin_records(coin_records)
675
+
676
+ # Make sure all of the coin states are found.
677
+ (all_coin_states, next_height) = await coin_store.batch_coin_states_by_puzzle_hashes([ph])
678
+ all_coin_states.sort(key=lambda cs: cs.coin.amount)
679
+
680
+ assert next_height is None
681
+ assert len(all_coin_states) == len(coin_records)
682
+
683
+ for i in range(min(len(coin_records), len(all_coin_states))):
684
+ assert coin_records[i].coin.name().hex() == all_coin_states[i].coin.name().hex(), i
685
+
686
+ # For the middle case, insert a coin record between the two heights 10 and 12.
687
+ await coin_store._add_coin_records(
688
+ [
689
+ CoinRecord(
690
+ coin=Coin(std_hash(b"extra coin"), ph, uint64(0)),
691
+ # Insert a coin record in the middle between heights 10 and 12.
692
+ # Or after all of the other coins if testing the batch limit.
693
+ confirmed_block_index=uint32(11 if cut_off_middle else 50),
694
+ spent_block_index=uint32(0),
695
+ coinbase=False,
696
+ timestamp=uint64(0),
697
+ )
698
+ ]
699
+ )
700
+
701
+ (all_coin_states, next_height) = await coin_store.batch_coin_states_by_puzzle_hashes([ph])
702
+
703
+ # Make sure that the extra coin records are not included in the results.
704
+ assert next_height == (12 if cut_off_middle else 50)
705
+ assert len(all_coin_states) == (25001 if cut_off_middle else 50000)
706
+
707
+
708
+ @pytest.mark.anyio
709
+ async def test_batch_no_puzzle_hashes(db_version: int) -> None:
710
+ async with DBConnection(db_version) as db_wrapper:
711
+ # Initialize coin and hint stores.
712
+ coin_store = await CoinStore.create(db_wrapper)
713
+ await HintStore.create(db_wrapper)
714
+
715
+ coin_states, height = await coin_store.batch_coin_states_by_puzzle_hashes([])
716
+ assert coin_states == []
717
+ assert height is None
718
+
719
+
720
+ @pytest.mark.anyio
721
+ async def test_duplicate_by_hint(db_version: int) -> None:
722
+ async with DBConnection(db_version) as db_wrapper:
723
+ # Initialize coin and hint stores.
724
+ coin_store = await CoinStore.create(db_wrapper)
725
+ hint_store = await HintStore.create(db_wrapper)
726
+
727
+ cr = CoinRecord(
728
+ Coin(std_hash(b"Parent Coin Id"), std_hash(b"Puzzle Hash"), uint64(100)),
729
+ uint32(10),
730
+ uint32(0),
731
+ False,
732
+ uint64(12321312),
733
+ )
734
+
735
+ await coin_store._add_coin_records([cr])
736
+ await hint_store.add_hints([(cr.coin.name(), cr.coin.puzzle_hash)])
737
+
738
+ coin_states, height = await coin_store.batch_coin_states_by_puzzle_hashes([cr.coin.puzzle_hash])
739
+
740
+ assert coin_states == [cr.coin_state]
741
+ assert height is None
742
+
743
+
744
+ @pytest.mark.anyio
745
+ async def test_unsupported_version() -> None:
746
+ with pytest.raises(RuntimeError, match="CoinStore does not support database schema v1"):
747
+ async with DBConnection(1) as db_wrapper:
748
+ await CoinStore.create(db_wrapper)
749
+
750
+
751
+ TEST_COIN_ID = b"c" * 32
752
+ TEST_PUZZLEHASH = b"p" * 32
753
+ TEST_AMOUNT = uint64(1337)
754
+ TEST_PARENT_ID = Coin(b"a" * 32, TEST_PUZZLEHASH, TEST_AMOUNT).name()
755
+ TEST_PARENT_DIFFERENT_AMOUNT = uint64(5)
756
+ TEST_PARENT_ID_DIFFERENT_AMOUNT = Coin(b"a" * 32, TEST_PUZZLEHASH, TEST_PARENT_DIFFERENT_AMOUNT).name()
757
+ TEST_PARENT_PARENT_ID = b"f" * 32
758
+
759
+
760
+ @dataclass(frozen=True)
761
+ class UnspentLineageInfoTestItem:
762
+ coin_id: bytes
763
+ puzzlehash: bytes
764
+ amount: int
765
+ parent_id: bytes
766
+ is_spent: bool = False
767
+
768
+
769
+ @dataclass
770
+ class UnspentLineageInfoCase:
771
+ id: str
772
+ items: list[UnspentLineageInfoTestItem]
773
+ expected_success: bool
774
+ parent_with_diff_amount: bool = False
775
+ marks: Marks = ()
776
+
777
+
778
+ @pytest.mark.anyio
779
+ @datacases(
780
+ UnspentLineageInfoCase(
781
+ id="Unspent with parent that has same amount but different puzzlehash",
782
+ items=[
783
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
784
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
785
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
786
+ UnspentLineageInfoTestItem(TEST_PARENT_ID, b"4" * 32, TEST_AMOUNT, TEST_PARENT_PARENT_ID, is_spent=True),
787
+ ],
788
+ expected_success=False,
789
+ ),
790
+ UnspentLineageInfoCase(
791
+ id="Unspent with parent that has same puzzlehash but different amount",
792
+ items=[
793
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID_DIFFERENT_AMOUNT),
794
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
795
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
796
+ UnspentLineageInfoTestItem(
797
+ TEST_PARENT_ID_DIFFERENT_AMOUNT,
798
+ TEST_PUZZLEHASH,
799
+ TEST_PARENT_DIFFERENT_AMOUNT,
800
+ TEST_PARENT_PARENT_ID,
801
+ is_spent=True,
802
+ ),
803
+ ],
804
+ parent_with_diff_amount=True,
805
+ expected_success=True,
806
+ ),
807
+ UnspentLineageInfoCase(
808
+ id="Unspent with parent that has same puzzlehash and amount but is also unspent",
809
+ items=[
810
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
811
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
812
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
813
+ UnspentLineageInfoTestItem(TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID),
814
+ ],
815
+ expected_success=False,
816
+ ),
817
+ UnspentLineageInfoCase(
818
+ id="More than one unspent with parent that has same puzzlehash and amount",
819
+ items=[
820
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
821
+ UnspentLineageInfoTestItem(b"2" * 32, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
822
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
823
+ UnspentLineageInfoTestItem(
824
+ TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID, is_spent=True
825
+ ),
826
+ ],
827
+ expected_success=False,
828
+ ),
829
+ UnspentLineageInfoCase(
830
+ id="Unspent with parent that has same puzzlehash and amount",
831
+ items=[
832
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
833
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
834
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
835
+ UnspentLineageInfoTestItem(
836
+ TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID, is_spent=True
837
+ ),
838
+ ],
839
+ expected_success=True,
840
+ ),
841
+ )
842
+ async def test_get_unspent_lineage_info_for_puzzle_hash(case: UnspentLineageInfoCase) -> None:
843
+ CoinRecordRawData = tuple[
844
+ bytes, # coin_name (blob)
845
+ int, # confirmed_index (bigint)
846
+ int, # spent_index (bigint)
847
+ int, # coinbase (int)
848
+ bytes, # puzzle_hash (blob)
849
+ bytes, # coin_parent (blob)
850
+ bytes, # amount (blob)
851
+ int, # timestamp (bigint)
852
+ ]
853
+
854
+ def make_test_data(test_items: list[UnspentLineageInfoTestItem]) -> list[CoinRecordRawData]:
855
+ test_data = []
856
+ for item in test_items:
857
+ test_data.append(
858
+ (
859
+ item.coin_id,
860
+ 0,
861
+ 1 if item.is_spent else 0,
862
+ 0,
863
+ item.puzzlehash,
864
+ item.parent_id,
865
+ int_to_bytes(item.amount),
866
+ 0,
867
+ )
868
+ )
869
+ return test_data
870
+
871
+ async with DBConnection(2) as db_wrapper:
872
+ # Prepare the coin store with the test case's data
873
+ coin_store = await CoinStore.create(db_wrapper)
874
+ async with db_wrapper.writer() as writer:
875
+ for item in make_test_data(case.items):
876
+ await writer.execute(
877
+ "INSERT INTO coin_record "
878
+ "(coin_name, confirmed_index, spent_index, coinbase, puzzle_hash, coin_parent, amount, timestamp) "
879
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
880
+ item,
881
+ )
882
+ # Run the test case
883
+ result = await coin_store.get_unspent_lineage_info_for_puzzle_hash(bytes32(TEST_PUZZLEHASH))
884
+ if case.expected_success:
885
+ assert result == UnspentLineageInfo(
886
+ coin_id=bytes32(TEST_COIN_ID),
887
+ coin_amount=TEST_AMOUNT,
888
+ parent_id=(
889
+ bytes32(TEST_PARENT_ID_DIFFERENT_AMOUNT)
890
+ if case.parent_with_diff_amount
891
+ else bytes32(TEST_PARENT_ID)
892
+ ),
893
+ parent_amount=TEST_PARENT_DIFFERENT_AMOUNT if case.parent_with_diff_amount else TEST_AMOUNT,
894
+ parent_parent_id=bytes32(TEST_PARENT_PARENT_ID),
895
+ )
896
+ else:
897
+ assert result is None