chia-blockchain 2.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1028) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +197 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +147 -0
  9. chia/_tests/blockchain/test_blockchain.py +4100 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1050 -0
  11. chia/_tests/blockchain/test_build_chains.py +61 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +195 -0
  14. chia/_tests/build-init-files.py +93 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +73 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +147 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +57 -0
  26. chia/_tests/clvm/test_program.py +150 -0
  27. chia/_tests/clvm/test_puzzle_compression.py +144 -0
  28. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  29. chia/_tests/clvm/test_puzzles.py +247 -0
  30. chia/_tests/clvm/test_singletons.py +540 -0
  31. chia/_tests/clvm/test_spend_sim.py +181 -0
  32. chia/_tests/cmds/__init__.py +0 -0
  33. chia/_tests/cmds/cmd_test_utils.py +472 -0
  34. chia/_tests/cmds/config.py +3 -0
  35. chia/_tests/cmds/conftest.py +23 -0
  36. chia/_tests/cmds/test_click_types.py +195 -0
  37. chia/_tests/cmds/test_cmd_framework.py +400 -0
  38. chia/_tests/cmds/test_cmds_util.py +97 -0
  39. chia/_tests/cmds/test_daemon.py +92 -0
  40. chia/_tests/cmds/test_farm_cmd.py +67 -0
  41. chia/_tests/cmds/test_show.py +116 -0
  42. chia/_tests/cmds/test_sim.py +207 -0
  43. chia/_tests/cmds/test_timelock_args.py +75 -0
  44. chia/_tests/cmds/test_tx_config_args.py +153 -0
  45. chia/_tests/cmds/testing_classes.py +59 -0
  46. chia/_tests/cmds/wallet/__init__.py +0 -0
  47. chia/_tests/cmds/wallet/test_coins.py +195 -0
  48. chia/_tests/cmds/wallet/test_consts.py +47 -0
  49. chia/_tests/cmds/wallet/test_dao.py +565 -0
  50. chia/_tests/cmds/wallet/test_did.py +403 -0
  51. chia/_tests/cmds/wallet/test_nft.py +470 -0
  52. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  53. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  54. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  55. chia/_tests/cmds/wallet/test_vcs.py +376 -0
  56. chia/_tests/cmds/wallet/test_wallet.py +1126 -0
  57. chia/_tests/cmds/wallet/test_wallet_check.py +111 -0
  58. chia/_tests/conftest.py +1304 -0
  59. chia/_tests/connection_utils.py +124 -0
  60. chia/_tests/core/__init__.py +0 -0
  61. chia/_tests/core/cmds/__init__.py +0 -0
  62. chia/_tests/core/cmds/test_beta.py +382 -0
  63. chia/_tests/core/cmds/test_keys.py +1734 -0
  64. chia/_tests/core/cmds/test_wallet.py +126 -0
  65. chia/_tests/core/config.py +3 -0
  66. chia/_tests/core/consensus/__init__.py +0 -0
  67. chia/_tests/core/consensus/test_block_creation.py +56 -0
  68. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  69. chia/_tests/core/custom_types/__init__.py +0 -0
  70. chia/_tests/core/custom_types/test_coin.py +109 -0
  71. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  72. chia/_tests/core/custom_types/test_spend_bundle.py +71 -0
  73. chia/_tests/core/daemon/__init__.py +0 -0
  74. chia/_tests/core/daemon/config.py +4 -0
  75. chia/_tests/core/daemon/test_daemon.py +2128 -0
  76. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  77. chia/_tests/core/daemon/test_keychain_proxy.py +100 -0
  78. chia/_tests/core/data_layer/__init__.py +0 -0
  79. chia/_tests/core/data_layer/config.py +5 -0
  80. chia/_tests/core/data_layer/conftest.py +105 -0
  81. chia/_tests/core/data_layer/test_data_cli.py +57 -0
  82. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  83. chia/_tests/core/data_layer/test_data_layer_util.py +219 -0
  84. chia/_tests/core/data_layer/test_data_rpc.py +3865 -0
  85. chia/_tests/core/data_layer/test_data_store.py +2423 -0
  86. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  87. chia/_tests/core/data_layer/test_plugin.py +91 -0
  88. chia/_tests/core/data_layer/util.py +232 -0
  89. chia/_tests/core/farmer/__init__.py +0 -0
  90. chia/_tests/core/farmer/config.py +3 -0
  91. chia/_tests/core/farmer/test_farmer_api.py +101 -0
  92. chia/_tests/core/full_node/__init__.py +0 -0
  93. chia/_tests/core/full_node/config.py +4 -0
  94. chia/_tests/core/full_node/dos/__init__.py +0 -0
  95. chia/_tests/core/full_node/dos/config.py +3 -0
  96. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  97. chia/_tests/core/full_node/full_sync/config.py +4 -0
  98. chia/_tests/core/full_node/full_sync/test_full_sync.py +448 -0
  99. chia/_tests/core/full_node/ram_db.py +27 -0
  100. chia/_tests/core/full_node/stores/__init__.py +0 -0
  101. chia/_tests/core/full_node/stores/config.py +4 -0
  102. chia/_tests/core/full_node/stores/test_block_store.py +488 -0
  103. chia/_tests/core/full_node/stores/test_coin_store.py +888 -0
  104. chia/_tests/core/full_node/stores/test_full_node_store.py +1215 -0
  105. chia/_tests/core/full_node/stores/test_hint_store.py +230 -0
  106. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  107. chia/_tests/core/full_node/test_address_manager.py +588 -0
  108. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  109. chia/_tests/core/full_node/test_conditions.py +558 -0
  110. chia/_tests/core/full_node/test_full_node.py +2445 -0
  111. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  112. chia/_tests/core/full_node/test_hint_management.py +104 -0
  113. chia/_tests/core/full_node/test_node_load.py +34 -0
  114. chia/_tests/core/full_node/test_performance.py +182 -0
  115. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  116. chia/_tests/core/full_node/test_transactions.py +203 -0
  117. chia/_tests/core/full_node/test_tx_processing_queue.py +154 -0
  118. chia/_tests/core/large_block.py +2388 -0
  119. chia/_tests/core/make_block_generator.py +72 -0
  120. chia/_tests/core/mempool/__init__.py +0 -0
  121. chia/_tests/core/mempool/config.py +4 -0
  122. chia/_tests/core/mempool/test_mempool.py +3180 -0
  123. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  124. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  125. chia/_tests/core/mempool/test_mempool_item_queries.py +192 -0
  126. chia/_tests/core/mempool/test_mempool_manager.py +2054 -0
  127. chia/_tests/core/mempool/test_mempool_performance.py +65 -0
  128. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  129. chia/_tests/core/node_height.py +28 -0
  130. chia/_tests/core/server/__init__.py +0 -0
  131. chia/_tests/core/server/config.py +3 -0
  132. chia/_tests/core/server/flood.py +82 -0
  133. chia/_tests/core/server/serve.py +132 -0
  134. chia/_tests/core/server/test_capabilities.py +68 -0
  135. chia/_tests/core/server/test_dos.py +320 -0
  136. chia/_tests/core/server/test_event_loop.py +109 -0
  137. chia/_tests/core/server/test_loop.py +290 -0
  138. chia/_tests/core/server/test_node_discovery.py +74 -0
  139. chia/_tests/core/server/test_rate_limits.py +370 -0
  140. chia/_tests/core/server/test_server.py +225 -0
  141. chia/_tests/core/server/test_upnp.py +8 -0
  142. chia/_tests/core/services/__init__.py +0 -0
  143. chia/_tests/core/services/config.py +3 -0
  144. chia/_tests/core/services/test_services.py +166 -0
  145. chia/_tests/core/ssl/__init__.py +0 -0
  146. chia/_tests/core/ssl/config.py +3 -0
  147. chia/_tests/core/ssl/test_ssl.py +198 -0
  148. chia/_tests/core/test_coins.py +33 -0
  149. chia/_tests/core/test_cost_calculation.py +314 -0
  150. chia/_tests/core/test_crawler.py +175 -0
  151. chia/_tests/core/test_crawler_rpc.py +53 -0
  152. chia/_tests/core/test_daemon_rpc.py +24 -0
  153. chia/_tests/core/test_db_conversion.py +129 -0
  154. chia/_tests/core/test_db_validation.py +161 -0
  155. chia/_tests/core/test_farmer_harvester_rpc.py +504 -0
  156. chia/_tests/core/test_filter.py +37 -0
  157. chia/_tests/core/test_full_node_rpc.py +794 -0
  158. chia/_tests/core/test_merkle_set.py +343 -0
  159. chia/_tests/core/test_program.py +49 -0
  160. chia/_tests/core/test_rpc_util.py +87 -0
  161. chia/_tests/core/test_seeder.py +308 -0
  162. chia/_tests/core/test_setproctitle.py +13 -0
  163. chia/_tests/core/util/__init__.py +0 -0
  164. chia/_tests/core/util/config.py +4 -0
  165. chia/_tests/core/util/test_block_cache.py +44 -0
  166. chia/_tests/core/util/test_cached_bls.py +57 -0
  167. chia/_tests/core/util/test_config.py +337 -0
  168. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  169. chia/_tests/core/util/test_files.py +391 -0
  170. chia/_tests/core/util/test_jsonify.py +146 -0
  171. chia/_tests/core/util/test_keychain.py +514 -0
  172. chia/_tests/core/util/test_keyring_wrapper.py +490 -0
  173. chia/_tests/core/util/test_lockfile.py +380 -0
  174. chia/_tests/core/util/test_log_exceptions.py +187 -0
  175. chia/_tests/core/util/test_lru_cache.py +56 -0
  176. chia/_tests/core/util/test_significant_bits.py +40 -0
  177. chia/_tests/core/util/test_streamable.py +883 -0
  178. chia/_tests/db/__init__.py +0 -0
  179. chia/_tests/db/test_db_wrapper.py +565 -0
  180. chia/_tests/environments/__init__.py +0 -0
  181. chia/_tests/environments/common.py +35 -0
  182. chia/_tests/environments/full_node.py +47 -0
  183. chia/_tests/environments/wallet.py +368 -0
  184. chia/_tests/ether.py +19 -0
  185. chia/_tests/farmer_harvester/__init__.py +0 -0
  186. chia/_tests/farmer_harvester/config.py +3 -0
  187. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  188. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  189. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +130 -0
  190. chia/_tests/farmer_harvester/test_third_party_harvesters.py +501 -0
  191. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  192. chia/_tests/fee_estimation/__init__.py +0 -0
  193. chia/_tests/fee_estimation/config.py +3 -0
  194. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  195. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +145 -0
  197. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  198. chia/_tests/generator/__init__.py +0 -0
  199. chia/_tests/generator/puzzles/__init__.py +0 -0
  200. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  201. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  202. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  203. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  204. chia/_tests/generator/test_compression.py +218 -0
  205. chia/_tests/generator/test_generator_types.py +44 -0
  206. chia/_tests/generator/test_rom.py +182 -0
  207. chia/_tests/plot_sync/__init__.py +0 -0
  208. chia/_tests/plot_sync/config.py +3 -0
  209. chia/_tests/plot_sync/test_delta.py +102 -0
  210. chia/_tests/plot_sync/test_plot_sync.py +617 -0
  211. chia/_tests/plot_sync/test_receiver.py +451 -0
  212. chia/_tests/plot_sync/test_sender.py +116 -0
  213. chia/_tests/plot_sync/test_sync_simulated.py +450 -0
  214. chia/_tests/plot_sync/util.py +67 -0
  215. chia/_tests/plotting/__init__.py +0 -0
  216. chia/_tests/plotting/config.py +3 -0
  217. chia/_tests/plotting/test_plot_manager.py +738 -0
  218. chia/_tests/plotting/util.py +13 -0
  219. chia/_tests/pools/__init__.py +0 -0
  220. chia/_tests/pools/config.py +5 -0
  221. chia/_tests/pools/test_pool_cmdline.py +23 -0
  222. chia/_tests/pools/test_pool_config.py +44 -0
  223. chia/_tests/pools/test_pool_puzzles_lifecycle.py +398 -0
  224. chia/_tests/pools/test_pool_rpc.py +1010 -0
  225. chia/_tests/pools/test_pool_wallet.py +201 -0
  226. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  227. chia/_tests/process_junit.py +349 -0
  228. chia/_tests/rpc/__init__.py +0 -0
  229. chia/_tests/rpc/test_rpc_client.py +81 -0
  230. chia/_tests/simulation/__init__.py +0 -0
  231. chia/_tests/simulation/config.py +6 -0
  232. chia/_tests/simulation/test_simulation.py +501 -0
  233. chia/_tests/simulation/test_simulator.py +234 -0
  234. chia/_tests/simulation/test_start_simulator.py +106 -0
  235. chia/_tests/testconfig.py +13 -0
  236. chia/_tests/timelord/__init__.py +0 -0
  237. chia/_tests/timelord/config.py +3 -0
  238. chia/_tests/timelord/test_new_peak.py +437 -0
  239. chia/_tests/timelord/test_timelord.py +11 -0
  240. chia/_tests/tools/1315537.json +170 -0
  241. chia/_tests/tools/1315544.json +160 -0
  242. chia/_tests/tools/1315630.json +150 -0
  243. chia/_tests/tools/300000.json +105 -0
  244. chia/_tests/tools/442734.json +140 -0
  245. chia/_tests/tools/466212.json +130 -0
  246. chia/_tests/tools/__init__.py +0 -0
  247. chia/_tests/tools/config.py +5 -0
  248. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  249. chia/_tests/tools/test_full_sync.py +30 -0
  250. chia/_tests/tools/test_legacy_keyring.py +82 -0
  251. chia/_tests/tools/test_run_block.py +129 -0
  252. chia/_tests/util/__init__.py +0 -0
  253. chia/_tests/util/benchmark_cost.py +170 -0
  254. chia/_tests/util/benchmarks.py +154 -0
  255. chia/_tests/util/bip39_test_vectors.json +148 -0
  256. chia/_tests/util/blockchain.py +133 -0
  257. chia/_tests/util/blockchain_mock.py +132 -0
  258. chia/_tests/util/build_network_protocol_files.py +302 -0
  259. chia/_tests/util/clvm_generator.bin +0 -0
  260. chia/_tests/util/config.py +3 -0
  261. chia/_tests/util/constants.py +20 -0
  262. chia/_tests/util/db_connection.py +36 -0
  263. chia/_tests/util/full_sync.py +245 -0
  264. chia/_tests/util/gen_ssl_certs.py +115 -0
  265. chia/_tests/util/generator_tools_testing.py +47 -0
  266. chia/_tests/util/key_tool.py +37 -0
  267. chia/_tests/util/misc.py +722 -0
  268. chia/_tests/util/network_protocol_data.py +1074 -0
  269. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  270. chia/_tests/util/protocol_messages_json.py +2700 -0
  271. chia/_tests/util/rpc.py +23 -0
  272. chia/_tests/util/run_block.py +163 -0
  273. chia/_tests/util/setup_nodes.py +479 -0
  274. chia/_tests/util/split_managers.py +99 -0
  275. chia/_tests/util/temp_file.py +14 -0
  276. chia/_tests/util/test_action_scope.py +143 -0
  277. chia/_tests/util/test_async_pool.py +366 -0
  278. chia/_tests/util/test_build_job_matrix.py +43 -0
  279. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  280. chia/_tests/util/test_chia_version.py +50 -0
  281. chia/_tests/util/test_collection.py +11 -0
  282. chia/_tests/util/test_condition_tools.py +231 -0
  283. chia/_tests/util/test_config.py +426 -0
  284. chia/_tests/util/test_dump_keyring.py +60 -0
  285. chia/_tests/util/test_errors.py +10 -0
  286. chia/_tests/util/test_full_block_utils.py +271 -0
  287. chia/_tests/util/test_installed.py +20 -0
  288. chia/_tests/util/test_limited_semaphore.py +52 -0
  289. chia/_tests/util/test_logging_filter.py +43 -0
  290. chia/_tests/util/test_misc.py +444 -0
  291. chia/_tests/util/test_network.py +74 -0
  292. chia/_tests/util/test_network_protocol_files.py +579 -0
  293. chia/_tests/util/test_network_protocol_json.py +266 -0
  294. chia/_tests/util/test_network_protocol_test.py +257 -0
  295. chia/_tests/util/test_paginator.py +72 -0
  296. chia/_tests/util/test_pprint.py +17 -0
  297. chia/_tests/util/test_priority_mutex.py +487 -0
  298. chia/_tests/util/test_recursive_replace.py +116 -0
  299. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  300. chia/_tests/util/test_service_groups.py +15 -0
  301. chia/_tests/util/test_ssl_check.py +31 -0
  302. chia/_tests/util/test_testnet_overrides.py +19 -0
  303. chia/_tests/util/test_tests_misc.py +38 -0
  304. chia/_tests/util/test_timing.py +37 -0
  305. chia/_tests/util/test_trusted_peer.py +51 -0
  306. chia/_tests/util/time_out_assert.py +154 -0
  307. chia/_tests/wallet/__init__.py +0 -0
  308. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  309. chia/_tests/wallet/cat_wallet/config.py +4 -0
  310. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  311. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  312. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1738 -0
  313. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  314. chia/_tests/wallet/cat_wallet/test_trades.py +2578 -0
  315. chia/_tests/wallet/clawback/__init__.py +0 -0
  316. chia/_tests/wallet/clawback/config.py +3 -0
  317. chia/_tests/wallet/clawback/test_clawback_decorator.py +80 -0
  318. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  319. chia/_tests/wallet/clawback/test_clawback_metadata.py +51 -0
  320. chia/_tests/wallet/config.py +4 -0
  321. chia/_tests/wallet/conftest.py +217 -0
  322. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  323. chia/_tests/wallet/dao_wallet/config.py +3 -0
  324. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1322 -0
  325. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  326. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  327. chia/_tests/wallet/db_wallet/config.py +3 -0
  328. chia/_tests/wallet/db_wallet/test_db_graftroot.py +143 -0
  329. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  330. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  331. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  332. chia/_tests/wallet/did_wallet/config.py +4 -0
  333. chia/_tests/wallet/did_wallet/test_did.py +1481 -0
  334. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  335. chia/_tests/wallet/nft_wallet/config.py +4 -0
  336. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1492 -0
  337. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1014 -0
  338. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +376 -0
  339. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  340. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  341. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2558 -0
  342. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  343. chia/_tests/wallet/rpc/__init__.py +0 -0
  344. chia/_tests/wallet/rpc/config.py +4 -0
  345. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +287 -0
  346. chia/_tests/wallet/rpc/test_wallet_rpc.py +3106 -0
  347. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  348. chia/_tests/wallet/simple_sync/config.py +3 -0
  349. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +719 -0
  350. chia/_tests/wallet/sync/__init__.py +0 -0
  351. chia/_tests/wallet/sync/config.py +4 -0
  352. chia/_tests/wallet/sync/test_wallet_sync.py +1529 -0
  353. chia/_tests/wallet/test_address_type.py +189 -0
  354. chia/_tests/wallet/test_bech32m.py +45 -0
  355. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  356. chia/_tests/wallet/test_coin_selection.py +589 -0
  357. chia/_tests/wallet/test_conditions.py +388 -0
  358. chia/_tests/wallet/test_debug_spend_bundle.py +76 -0
  359. chia/_tests/wallet/test_new_wallet_protocol.py +1176 -0
  360. chia/_tests/wallet/test_nft_store.py +193 -0
  361. chia/_tests/wallet/test_notifications.py +196 -0
  362. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  363. chia/_tests/wallet/test_puzzle_store.py +133 -0
  364. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  365. chia/_tests/wallet/test_signer_protocol.py +948 -0
  366. chia/_tests/wallet/test_singleton.py +122 -0
  367. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  368. chia/_tests/wallet/test_singleton_store.py +152 -0
  369. chia/_tests/wallet/test_taproot.py +19 -0
  370. chia/_tests/wallet/test_transaction_store.py +941 -0
  371. chia/_tests/wallet/test_util.py +181 -0
  372. chia/_tests/wallet/test_wallet.py +2139 -0
  373. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  374. chia/_tests/wallet/test_wallet_blockchain.py +113 -0
  375. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  376. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  377. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  378. chia/_tests/wallet/test_wallet_node.py +783 -0
  379. chia/_tests/wallet/test_wallet_retry.py +95 -0
  380. chia/_tests/wallet/test_wallet_state_manager.py +252 -0
  381. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  382. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  383. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  384. chia/_tests/wallet/test_wallet_utils.py +155 -0
  385. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  386. chia/_tests/wallet/vc_wallet/config.py +3 -0
  387. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  388. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  389. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +801 -0
  390. chia/_tests/wallet/wallet_block_tools.py +327 -0
  391. chia/_tests/weight_proof/__init__.py +0 -0
  392. chia/_tests/weight_proof/config.py +3 -0
  393. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  394. chia/clvm/__init__.py +0 -0
  395. chia/clvm/spend_sim.py +488 -0
  396. chia/cmds/__init__.py +0 -0
  397. chia/cmds/beta.py +183 -0
  398. chia/cmds/beta_funcs.py +133 -0
  399. chia/cmds/check_wallet_db.py +418 -0
  400. chia/cmds/chia.py +143 -0
  401. chia/cmds/cmd_classes.py +315 -0
  402. chia/cmds/cmds_util.py +498 -0
  403. chia/cmds/coin_funcs.py +260 -0
  404. chia/cmds/coins.py +220 -0
  405. chia/cmds/completion.py +49 -0
  406. chia/cmds/configure.py +331 -0
  407. chia/cmds/dao.py +1008 -0
  408. chia/cmds/dao_funcs.py +576 -0
  409. chia/cmds/data.py +707 -0
  410. chia/cmds/data_funcs.py +380 -0
  411. chia/cmds/db.py +86 -0
  412. chia/cmds/db_backup_func.py +77 -0
  413. chia/cmds/db_upgrade_func.py +452 -0
  414. chia/cmds/db_validate_func.py +184 -0
  415. chia/cmds/dev.py +16 -0
  416. chia/cmds/farm.py +87 -0
  417. chia/cmds/farm_funcs.py +207 -0
  418. chia/cmds/init.py +70 -0
  419. chia/cmds/init_funcs.py +367 -0
  420. chia/cmds/installers.py +129 -0
  421. chia/cmds/keys.py +510 -0
  422. chia/cmds/keys_funcs.py +864 -0
  423. chia/cmds/netspace.py +47 -0
  424. chia/cmds/netspace_funcs.py +53 -0
  425. chia/cmds/options.py +32 -0
  426. chia/cmds/param_types.py +228 -0
  427. chia/cmds/passphrase.py +130 -0
  428. chia/cmds/passphrase_funcs.py +346 -0
  429. chia/cmds/peer.py +50 -0
  430. chia/cmds/peer_funcs.py +129 -0
  431. chia/cmds/plotnft.py +206 -0
  432. chia/cmds/plotnft_funcs.py +374 -0
  433. chia/cmds/plots.py +222 -0
  434. chia/cmds/plotters.py +17 -0
  435. chia/cmds/rpc.py +188 -0
  436. chia/cmds/show.py +71 -0
  437. chia/cmds/show_funcs.py +214 -0
  438. chia/cmds/signer.py +304 -0
  439. chia/cmds/sim.py +217 -0
  440. chia/cmds/sim_funcs.py +509 -0
  441. chia/cmds/start.py +24 -0
  442. chia/cmds/start_funcs.py +112 -0
  443. chia/cmds/stop.py +61 -0
  444. chia/cmds/units.py +11 -0
  445. chia/cmds/wallet.py +1745 -0
  446. chia/cmds/wallet_funcs.py +1800 -0
  447. chia/consensus/__init__.py +0 -0
  448. chia/consensus/block_body_validation.py +515 -0
  449. chia/consensus/block_creation.py +525 -0
  450. chia/consensus/block_header_validation.py +1064 -0
  451. chia/consensus/block_record.py +32 -0
  452. chia/consensus/block_rewards.py +53 -0
  453. chia/consensus/block_root_validation.py +46 -0
  454. chia/consensus/blockchain.py +1100 -0
  455. chia/consensus/blockchain_interface.py +56 -0
  456. chia/consensus/coinbase.py +30 -0
  457. chia/consensus/condition_costs.py +9 -0
  458. chia/consensus/constants.py +49 -0
  459. chia/consensus/cost_calculator.py +15 -0
  460. chia/consensus/default_constants.py +90 -0
  461. chia/consensus/deficit.py +55 -0
  462. chia/consensus/difficulty_adjustment.py +412 -0
  463. chia/consensus/find_fork_point.py +111 -0
  464. chia/consensus/full_block_to_block_record.py +167 -0
  465. chia/consensus/get_block_challenge.py +106 -0
  466. chia/consensus/get_block_generator.py +26 -0
  467. chia/consensus/make_sub_epoch_summary.py +210 -0
  468. chia/consensus/multiprocess_validation.py +365 -0
  469. chia/consensus/pos_quality.py +19 -0
  470. chia/consensus/pot_iterations.py +67 -0
  471. chia/consensus/puzzles/__init__.py +0 -0
  472. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  473. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  474. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  475. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  476. chia/consensus/vdf_info_computation.py +156 -0
  477. chia/daemon/__init__.py +0 -0
  478. chia/daemon/client.py +233 -0
  479. chia/daemon/keychain_proxy.py +501 -0
  480. chia/daemon/keychain_server.py +365 -0
  481. chia/daemon/server.py +1616 -0
  482. chia/daemon/windows_signal.py +56 -0
  483. chia/data_layer/__init__.py +0 -0
  484. chia/data_layer/data_layer.py +1303 -0
  485. chia/data_layer/data_layer_api.py +25 -0
  486. chia/data_layer/data_layer_errors.py +50 -0
  487. chia/data_layer/data_layer_server.py +170 -0
  488. chia/data_layer/data_layer_util.py +985 -0
  489. chia/data_layer/data_layer_wallet.py +1315 -0
  490. chia/data_layer/data_store.py +2267 -0
  491. chia/data_layer/dl_wallet_store.py +407 -0
  492. chia/data_layer/download_data.py +389 -0
  493. chia/data_layer/puzzles/__init__.py +0 -0
  494. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  495. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  496. chia/data_layer/s3_plugin_config.yml +33 -0
  497. chia/data_layer/s3_plugin_service.py +468 -0
  498. chia/data_layer/util/__init__.py +0 -0
  499. chia/data_layer/util/benchmark.py +108 -0
  500. chia/data_layer/util/plugin.py +41 -0
  501. chia/farmer/__init__.py +0 -0
  502. chia/farmer/farmer.py +920 -0
  503. chia/farmer/farmer_api.py +814 -0
  504. chia/full_node/__init__.py +0 -0
  505. chia/full_node/bitcoin_fee_estimator.py +85 -0
  506. chia/full_node/block_height_map.py +271 -0
  507. chia/full_node/block_store.py +570 -0
  508. chia/full_node/bundle_tools.py +19 -0
  509. chia/full_node/coin_store.py +646 -0
  510. chia/full_node/fee_estimate.py +54 -0
  511. chia/full_node/fee_estimate_store.py +24 -0
  512. chia/full_node/fee_estimation.py +93 -0
  513. chia/full_node/fee_estimator.py +90 -0
  514. chia/full_node/fee_estimator_constants.py +38 -0
  515. chia/full_node/fee_estimator_interface.py +42 -0
  516. chia/full_node/fee_history.py +26 -0
  517. chia/full_node/fee_tracker.py +564 -0
  518. chia/full_node/full_node.py +3052 -0
  519. chia/full_node/full_node_api.py +1974 -0
  520. chia/full_node/full_node_store.py +1033 -0
  521. chia/full_node/hint_management.py +56 -0
  522. chia/full_node/hint_store.py +94 -0
  523. chia/full_node/mempool.py +583 -0
  524. chia/full_node/mempool_check_conditions.py +177 -0
  525. chia/full_node/mempool_manager.py +858 -0
  526. chia/full_node/pending_tx_cache.py +112 -0
  527. chia/full_node/puzzles/__init__.py +0 -0
  528. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  529. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  530. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  531. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  532. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  533. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  534. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  535. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  536. chia/full_node/signage_point.py +16 -0
  537. chia/full_node/subscriptions.py +248 -0
  538. chia/full_node/sync_store.py +145 -0
  539. chia/full_node/tx_processing_queue.py +78 -0
  540. chia/full_node/weight_proof.py +1719 -0
  541. chia/harvester/__init__.py +0 -0
  542. chia/harvester/harvester.py +271 -0
  543. chia/harvester/harvester_api.py +374 -0
  544. chia/introducer/__init__.py +0 -0
  545. chia/introducer/introducer.py +120 -0
  546. chia/introducer/introducer_api.py +64 -0
  547. chia/legacy/__init__.py +0 -0
  548. chia/legacy/keyring.py +154 -0
  549. chia/plot_sync/__init__.py +0 -0
  550. chia/plot_sync/delta.py +61 -0
  551. chia/plot_sync/exceptions.py +56 -0
  552. chia/plot_sync/receiver.py +385 -0
  553. chia/plot_sync/sender.py +337 -0
  554. chia/plot_sync/util.py +43 -0
  555. chia/plotters/__init__.py +0 -0
  556. chia/plotters/bladebit.py +388 -0
  557. chia/plotters/chiapos.py +63 -0
  558. chia/plotters/madmax.py +224 -0
  559. chia/plotters/plotters.py +577 -0
  560. chia/plotters/plotters_util.py +131 -0
  561. chia/plotting/__init__.py +0 -0
  562. chia/plotting/cache.py +212 -0
  563. chia/plotting/check_plots.py +283 -0
  564. chia/plotting/create_plots.py +278 -0
  565. chia/plotting/manager.py +436 -0
  566. chia/plotting/util.py +324 -0
  567. chia/pools/__init__.py +0 -0
  568. chia/pools/pool_config.py +110 -0
  569. chia/pools/pool_puzzles.py +459 -0
  570. chia/pools/pool_wallet.py +926 -0
  571. chia/pools/pool_wallet_info.py +118 -0
  572. chia/pools/puzzles/__init__.py +0 -0
  573. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  574. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  575. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  576. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  577. chia/protocols/__init__.py +0 -0
  578. chia/protocols/farmer_protocol.py +102 -0
  579. chia/protocols/full_node_protocol.py +219 -0
  580. chia/protocols/harvester_protocol.py +216 -0
  581. chia/protocols/introducer_protocol.py +26 -0
  582. chia/protocols/pool_protocol.py +177 -0
  583. chia/protocols/protocol_message_types.py +139 -0
  584. chia/protocols/protocol_state_machine.py +87 -0
  585. chia/protocols/protocol_timing.py +7 -0
  586. chia/protocols/shared_protocol.py +86 -0
  587. chia/protocols/timelord_protocol.py +93 -0
  588. chia/protocols/wallet_protocol.py +401 -0
  589. chia/py.typed +0 -0
  590. chia/rpc/__init__.py +0 -0
  591. chia/rpc/crawler_rpc_api.py +75 -0
  592. chia/rpc/data_layer_rpc_api.py +639 -0
  593. chia/rpc/data_layer_rpc_client.py +188 -0
  594. chia/rpc/data_layer_rpc_util.py +62 -0
  595. chia/rpc/farmer_rpc_api.py +360 -0
  596. chia/rpc/farmer_rpc_client.py +86 -0
  597. chia/rpc/full_node_rpc_api.py +954 -0
  598. chia/rpc/full_node_rpc_client.py +292 -0
  599. chia/rpc/harvester_rpc_api.py +136 -0
  600. chia/rpc/harvester_rpc_client.py +54 -0
  601. chia/rpc/rpc_client.py +144 -0
  602. chia/rpc/rpc_server.py +447 -0
  603. chia/rpc/timelord_rpc_api.py +27 -0
  604. chia/rpc/util.py +293 -0
  605. chia/rpc/wallet_request_types.py +688 -0
  606. chia/rpc/wallet_rpc_api.py +4779 -0
  607. chia/rpc/wallet_rpc_client.py +1844 -0
  608. chia/seeder/__init__.py +0 -0
  609. chia/seeder/crawl_store.py +427 -0
  610. chia/seeder/crawler.py +423 -0
  611. chia/seeder/crawler_api.py +129 -0
  612. chia/seeder/dns_server.py +544 -0
  613. chia/seeder/peer_record.py +146 -0
  614. chia/seeder/start_crawler.py +88 -0
  615. chia/server/__init__.py +0 -0
  616. chia/server/address_manager.py +658 -0
  617. chia/server/address_manager_store.py +237 -0
  618. chia/server/api_protocol.py +11 -0
  619. chia/server/capabilities.py +24 -0
  620. chia/server/chia_policy.py +345 -0
  621. chia/server/introducer_peers.py +76 -0
  622. chia/server/node_discovery.py +718 -0
  623. chia/server/outbound_message.py +33 -0
  624. chia/server/rate_limit_numbers.py +204 -0
  625. chia/server/rate_limits.py +113 -0
  626. chia/server/server.py +720 -0
  627. chia/server/signal_handlers.py +117 -0
  628. chia/server/ssl_context.py +32 -0
  629. chia/server/start_data_layer.py +137 -0
  630. chia/server/start_farmer.py +86 -0
  631. chia/server/start_full_node.py +106 -0
  632. chia/server/start_harvester.py +80 -0
  633. chia/server/start_introducer.py +69 -0
  634. chia/server/start_service.py +328 -0
  635. chia/server/start_timelord.py +82 -0
  636. chia/server/start_wallet.py +109 -0
  637. chia/server/upnp.py +117 -0
  638. chia/server/ws_connection.py +752 -0
  639. chia/simulator/__init__.py +0 -0
  640. chia/simulator/block_tools.py +2053 -0
  641. chia/simulator/full_node_simulator.py +802 -0
  642. chia/simulator/keyring.py +128 -0
  643. chia/simulator/setup_services.py +505 -0
  644. chia/simulator/simulator_constants.py +13 -0
  645. chia/simulator/simulator_full_node_rpc_api.py +101 -0
  646. chia/simulator/simulator_full_node_rpc_client.py +62 -0
  647. chia/simulator/simulator_protocol.py +29 -0
  648. chia/simulator/simulator_test_tools.py +163 -0
  649. chia/simulator/socket.py +27 -0
  650. chia/simulator/ssl_certs.py +114 -0
  651. chia/simulator/ssl_certs_1.py +699 -0
  652. chia/simulator/ssl_certs_10.py +699 -0
  653. chia/simulator/ssl_certs_2.py +699 -0
  654. chia/simulator/ssl_certs_3.py +699 -0
  655. chia/simulator/ssl_certs_4.py +699 -0
  656. chia/simulator/ssl_certs_5.py +699 -0
  657. chia/simulator/ssl_certs_6.py +699 -0
  658. chia/simulator/ssl_certs_7.py +699 -0
  659. chia/simulator/ssl_certs_8.py +699 -0
  660. chia/simulator/ssl_certs_9.py +699 -0
  661. chia/simulator/start_simulator.py +135 -0
  662. chia/simulator/wallet_tools.py +245 -0
  663. chia/ssl/__init__.py +0 -0
  664. chia/ssl/chia_ca.crt +19 -0
  665. chia/ssl/chia_ca.key +28 -0
  666. chia/ssl/create_ssl.py +249 -0
  667. chia/ssl/dst_root_ca.pem +20 -0
  668. chia/timelord/__init__.py +0 -0
  669. chia/timelord/iters_from_block.py +50 -0
  670. chia/timelord/timelord.py +1202 -0
  671. chia/timelord/timelord_api.py +132 -0
  672. chia/timelord/timelord_launcher.py +188 -0
  673. chia/timelord/timelord_state.py +244 -0
  674. chia/timelord/types.py +22 -0
  675. chia/types/__init__.py +0 -0
  676. chia/types/aliases.py +35 -0
  677. chia/types/block_protocol.py +20 -0
  678. chia/types/blockchain_format/__init__.py +0 -0
  679. chia/types/blockchain_format/classgroup.py +5 -0
  680. chia/types/blockchain_format/coin.py +28 -0
  681. chia/types/blockchain_format/foliage.py +8 -0
  682. chia/types/blockchain_format/pool_target.py +5 -0
  683. chia/types/blockchain_format/program.py +270 -0
  684. chia/types/blockchain_format/proof_of_space.py +135 -0
  685. chia/types/blockchain_format/reward_chain_block.py +6 -0
  686. chia/types/blockchain_format/serialized_program.py +5 -0
  687. chia/types/blockchain_format/sized_bytes.py +11 -0
  688. chia/types/blockchain_format/slots.py +9 -0
  689. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  690. chia/types/blockchain_format/tree_hash.py +72 -0
  691. chia/types/blockchain_format/vdf.py +86 -0
  692. chia/types/clvm_cost.py +13 -0
  693. chia/types/coin_record.py +43 -0
  694. chia/types/coin_spend.py +115 -0
  695. chia/types/condition_opcodes.py +73 -0
  696. chia/types/condition_with_args.py +17 -0
  697. chia/types/eligible_coin_spends.py +364 -0
  698. chia/types/end_of_slot_bundle.py +5 -0
  699. chia/types/fee_rate.py +38 -0
  700. chia/types/full_block.py +5 -0
  701. chia/types/generator_types.py +14 -0
  702. chia/types/header_block.py +5 -0
  703. chia/types/internal_mempool_item.py +19 -0
  704. chia/types/mempool_inclusion_status.py +9 -0
  705. chia/types/mempool_item.py +85 -0
  706. chia/types/mempool_submission_status.py +30 -0
  707. chia/types/mojos.py +7 -0
  708. chia/types/peer_info.py +64 -0
  709. chia/types/signing_mode.py +29 -0
  710. chia/types/spend_bundle.py +31 -0
  711. chia/types/spend_bundle_conditions.py +7 -0
  712. chia/types/transaction_queue_entry.py +55 -0
  713. chia/types/unfinished_block.py +5 -0
  714. chia/types/unfinished_header_block.py +37 -0
  715. chia/types/weight_proof.py +50 -0
  716. chia/util/__init__.py +0 -0
  717. chia/util/action_scope.py +168 -0
  718. chia/util/api_decorators.py +89 -0
  719. chia/util/async_pool.py +224 -0
  720. chia/util/augmented_chain.py +130 -0
  721. chia/util/batches.py +39 -0
  722. chia/util/bech32m.py +123 -0
  723. chia/util/beta_metrics.py +118 -0
  724. chia/util/block_cache.py +56 -0
  725. chia/util/byte_types.py +10 -0
  726. chia/util/check_fork_next_block.py +32 -0
  727. chia/util/chia_logging.py +124 -0
  728. chia/util/chia_version.py +33 -0
  729. chia/util/collection.py +17 -0
  730. chia/util/condition_tools.py +201 -0
  731. chia/util/config.py +366 -0
  732. chia/util/cpu.py +20 -0
  733. chia/util/db_synchronous.py +21 -0
  734. chia/util/db_version.py +30 -0
  735. chia/util/db_wrapper.py +427 -0
  736. chia/util/default_root.py +10 -0
  737. chia/util/dump_keyring.py +93 -0
  738. chia/util/english.txt +2048 -0
  739. chia/util/errors.py +351 -0
  740. chia/util/file_keyring.py +480 -0
  741. chia/util/files.py +95 -0
  742. chia/util/full_block_utils.py +321 -0
  743. chia/util/generator_tools.py +62 -0
  744. chia/util/hash.py +29 -0
  745. chia/util/initial-config.yaml +675 -0
  746. chia/util/inline_executor.py +24 -0
  747. chia/util/ints.py +19 -0
  748. chia/util/json_util.py +41 -0
  749. chia/util/keychain.py +673 -0
  750. chia/util/keyring_wrapper.py +266 -0
  751. chia/util/limited_semaphore.py +39 -0
  752. chia/util/lock.py +47 -0
  753. chia/util/log_exceptions.py +29 -0
  754. chia/util/logging.py +34 -0
  755. chia/util/lru_cache.py +29 -0
  756. chia/util/math.py +20 -0
  757. chia/util/network.py +240 -0
  758. chia/util/paginator.py +46 -0
  759. chia/util/path.py +29 -0
  760. chia/util/permissions.py +19 -0
  761. chia/util/pprint.py +40 -0
  762. chia/util/prev_transaction_block.py +23 -0
  763. chia/util/priority_mutex.py +92 -0
  764. chia/util/profiler.py +194 -0
  765. chia/util/recursive_replace.py +22 -0
  766. chia/util/safe_cancel_task.py +14 -0
  767. chia/util/service_groups.py +47 -0
  768. chia/util/setproctitle.py +20 -0
  769. chia/util/significant_bits.py +30 -0
  770. chia/util/ssl_check.py +213 -0
  771. chia/util/streamable.py +654 -0
  772. chia/util/task_timing.py +378 -0
  773. chia/util/timing.py +64 -0
  774. chia/util/vdf_prover.py +31 -0
  775. chia/util/ws_message.py +66 -0
  776. chia/wallet/__init__.py +0 -0
  777. chia/wallet/cat_wallet/__init__.py +0 -0
  778. chia/wallet/cat_wallet/cat_constants.py +75 -0
  779. chia/wallet/cat_wallet/cat_info.py +47 -0
  780. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  781. chia/wallet/cat_wallet/cat_utils.py +163 -0
  782. chia/wallet/cat_wallet/cat_wallet.py +869 -0
  783. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  784. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  785. chia/wallet/cat_wallet/lineage_store.py +74 -0
  786. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  787. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  788. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  789. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  790. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  791. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  792. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  793. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  794. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  795. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  796. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  797. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  798. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  799. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  800. chia/wallet/coin_selection.py +188 -0
  801. chia/wallet/conditions.py +1326 -0
  802. chia/wallet/dao_wallet/__init__.py +0 -0
  803. chia/wallet/dao_wallet/dao_info.py +61 -0
  804. chia/wallet/dao_wallet/dao_utils.py +810 -0
  805. chia/wallet/dao_wallet/dao_wallet.py +2121 -0
  806. chia/wallet/db_wallet/__init__.py +0 -0
  807. chia/wallet/db_wallet/db_wallet_puzzles.py +107 -0
  808. chia/wallet/derivation_record.py +30 -0
  809. chia/wallet/derive_keys.py +146 -0
  810. chia/wallet/did_wallet/__init__.py +0 -0
  811. chia/wallet/did_wallet/did_info.py +39 -0
  812. chia/wallet/did_wallet/did_wallet.py +1485 -0
  813. chia/wallet/did_wallet/did_wallet_puzzles.py +220 -0
  814. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  815. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  816. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  817. chia/wallet/driver_protocol.py +26 -0
  818. chia/wallet/key_val_store.py +55 -0
  819. chia/wallet/lineage_proof.py +58 -0
  820. chia/wallet/nft_wallet/__init__.py +0 -0
  821. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  822. chia/wallet/nft_wallet/nft_info.py +120 -0
  823. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  824. chia/wallet/nft_wallet/nft_wallet.py +1686 -0
  825. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  826. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  827. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  828. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  829. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  830. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  831. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  832. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  833. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  834. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  835. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  836. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  837. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  838. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  839. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  840. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  841. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  842. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  843. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  844. chia/wallet/notification_manager.py +117 -0
  845. chia/wallet/notification_store.py +178 -0
  846. chia/wallet/outer_puzzles.py +84 -0
  847. chia/wallet/payment.py +34 -0
  848. chia/wallet/puzzle_drivers.py +118 -0
  849. chia/wallet/puzzles/__init__.py +0 -0
  850. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  851. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  852. chia/wallet/puzzles/clawback/__init__.py +0 -0
  853. chia/wallet/puzzles/clawback/drivers.py +188 -0
  854. chia/wallet/puzzles/clawback/metadata.py +38 -0
  855. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  856. chia/wallet/puzzles/condition_codes.clib +77 -0
  857. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  858. chia/wallet/puzzles/curry.clib +135 -0
  859. chia/wallet/puzzles/curry_by_index.clib +16 -0
  860. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  861. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  862. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  863. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  864. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  865. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  866. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  867. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  868. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  869. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  870. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  871. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  872. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  873. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  874. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  876. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  877. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  878. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  879. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  880. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  881. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  882. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  883. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  884. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  885. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  886. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  887. chia/wallet/puzzles/json.clib +25 -0
  888. chia/wallet/puzzles/load_clvm.py +162 -0
  889. chia/wallet/puzzles/merkle_utils.clib +18 -0
  890. chia/wallet/puzzles/notification.clsp +7 -0
  891. chia/wallet/puzzles/notification.clsp.hex +1 -0
  892. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  893. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  894. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  895. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  896. chia/wallet/puzzles/p2_conditions.py +27 -0
  897. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  898. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  899. chia/wallet/puzzles/p2_delegated_conditions.py +22 -0
  900. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  901. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  902. chia/wallet/puzzles/p2_delegated_puzzle.py +35 -0
  903. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  904. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +161 -0
  906. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  907. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  908. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +22 -0
  909. chia/wallet/puzzles/p2_parent.clsp +19 -0
  910. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  911. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  912. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  913. chia/wallet/puzzles/p2_puzzle_hash.py +28 -0
  914. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  915. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  916. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  917. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  919. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  920. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  921. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  922. chia/wallet/puzzles/puzzle_utils.py +34 -0
  923. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  924. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  925. chia/wallet/puzzles/sha256tree.clib +11 -0
  926. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  927. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  928. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  929. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  930. chia/wallet/puzzles/singleton_top_layer.py +295 -0
  931. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  932. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  933. chia/wallet/puzzles/singleton_top_layer_v1_1.py +344 -0
  934. chia/wallet/puzzles/singleton_truths.clib +21 -0
  935. chia/wallet/puzzles/tails.py +344 -0
  936. chia/wallet/puzzles/utility_macros.clib +48 -0
  937. chia/wallet/signer_protocol.py +126 -0
  938. chia/wallet/singleton.py +106 -0
  939. chia/wallet/singleton_record.py +30 -0
  940. chia/wallet/trade_manager.py +1088 -0
  941. chia/wallet/trade_record.py +67 -0
  942. chia/wallet/trading/__init__.py +0 -0
  943. chia/wallet/trading/offer.py +703 -0
  944. chia/wallet/trading/trade_status.py +13 -0
  945. chia/wallet/trading/trade_store.py +526 -0
  946. chia/wallet/transaction_record.py +143 -0
  947. chia/wallet/transaction_sorting.py +14 -0
  948. chia/wallet/uncurried_puzzle.py +17 -0
  949. chia/wallet/util/__init__.py +0 -0
  950. chia/wallet/util/address_type.py +55 -0
  951. chia/wallet/util/blind_signer_tl.py +168 -0
  952. chia/wallet/util/clvm_streamable.py +203 -0
  953. chia/wallet/util/compute_hints.py +66 -0
  954. chia/wallet/util/compute_memos.py +45 -0
  955. chia/wallet/util/curry_and_treehash.py +90 -0
  956. chia/wallet/util/debug_spend_bundle.py +234 -0
  957. chia/wallet/util/merkle_tree.py +100 -0
  958. chia/wallet/util/merkle_utils.py +102 -0
  959. chia/wallet/util/new_peak_queue.py +82 -0
  960. chia/wallet/util/notifications.py +12 -0
  961. chia/wallet/util/peer_request_cache.py +174 -0
  962. chia/wallet/util/puzzle_compression.py +96 -0
  963. chia/wallet/util/puzzle_decorator.py +100 -0
  964. chia/wallet/util/puzzle_decorator_type.py +7 -0
  965. chia/wallet/util/query_filter.py +60 -0
  966. chia/wallet/util/transaction_type.py +23 -0
  967. chia/wallet/util/tx_config.py +158 -0
  968. chia/wallet/util/wallet_sync_utils.py +348 -0
  969. chia/wallet/util/wallet_types.py +65 -0
  970. chia/wallet/vc_wallet/__init__.py +0 -0
  971. chia/wallet/vc_wallet/cr_cat_drivers.py +663 -0
  972. chia/wallet/vc_wallet/cr_cat_wallet.py +875 -0
  973. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  974. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  975. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  976. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  977. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  978. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  979. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  980. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  981. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  982. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  983. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  984. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  985. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  986. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  987. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  988. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  989. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  990. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  992. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  994. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  996. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  997. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  998. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_store.py +263 -0
  1002. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1003. chia/wallet/wallet.py +698 -0
  1004. chia/wallet/wallet_action_scope.py +95 -0
  1005. chia/wallet/wallet_blockchain.py +244 -0
  1006. chia/wallet/wallet_coin_record.py +72 -0
  1007. chia/wallet/wallet_coin_store.py +351 -0
  1008. chia/wallet/wallet_info.py +36 -0
  1009. chia/wallet/wallet_interested_store.py +188 -0
  1010. chia/wallet/wallet_nft_store.py +279 -0
  1011. chia/wallet/wallet_node.py +1769 -0
  1012. chia/wallet/wallet_node_api.py +201 -0
  1013. chia/wallet/wallet_pool_store.py +120 -0
  1014. chia/wallet/wallet_protocol.py +90 -0
  1015. chia/wallet/wallet_puzzle_store.py +365 -0
  1016. chia/wallet/wallet_retry_store.py +70 -0
  1017. chia/wallet/wallet_singleton_store.py +258 -0
  1018. chia/wallet/wallet_spend_bundle.py +41 -0
  1019. chia/wallet/wallet_state_manager.py +2820 -0
  1020. chia/wallet/wallet_transaction_store.py +470 -0
  1021. chia/wallet/wallet_user_store.py +110 -0
  1022. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1023. chia_blockchain-2.4.4.dist-info/LICENSE +201 -0
  1024. chia_blockchain-2.4.4.dist-info/METADATA +161 -0
  1025. chia_blockchain-2.4.4.dist-info/RECORD +1028 -0
  1026. chia_blockchain-2.4.4.dist-info/WHEEL +4 -0
  1027. chia_blockchain-2.4.4.dist-info/entry_points.txt +17 -0
  1028. mozilla-ca/cacert.pem +3666 -0
@@ -0,0 +1,888 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import List, Optional, Set, Tuple
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.misc import Marks, datacases
14
+ from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
15
+ from chia.consensus.blockchain import AddBlockResult, Blockchain
16
+ from chia.consensus.coinbase import create_farmer_coin, create_pool_coin
17
+ from chia.full_node.block_store import BlockStore
18
+ from chia.full_node.coin_store import CoinStore
19
+ from chia.full_node.hint_store import HintStore
20
+ from chia.full_node.mempool_check_conditions import get_name_puzzle_conditions
21
+ from chia.protocols.wallet_protocol import CoinState
22
+ from chia.simulator.block_tools import BlockTools, test_constants
23
+ from chia.simulator.wallet_tools import WalletTool
24
+ from chia.types.blockchain_format.coin import Coin
25
+ from chia.types.blockchain_format.sized_bytes import bytes32
26
+ from chia.types.coin_record import CoinRecord
27
+ from chia.types.eligible_coin_spends import UnspentLineageInfo
28
+ from chia.types.full_block import FullBlock
29
+ from chia.types.generator_types import BlockGenerator
30
+ from chia.util.generator_tools import tx_removals_and_additions
31
+ from chia.util.hash import std_hash
32
+ from chia.util.ints import uint32, uint64
33
+
34
+ constants = test_constants
35
+
36
+ WALLET_A = WalletTool(constants)
37
+
38
+ log = logging.getLogger(__name__)
39
+
40
+
41
+ def get_future_reward_coins(block: FullBlock) -> Tuple[Coin, Coin]:
42
+ pool_amount = calculate_pool_reward(block.height)
43
+ farmer_amount = calculate_base_farmer_reward(block.height)
44
+ if block.is_transaction_block():
45
+ assert block.transactions_info is not None
46
+ farmer_amount = uint64(farmer_amount + block.transactions_info.fees)
47
+ pool_coin: Coin = create_pool_coin(
48
+ block.height, block.foliage.foliage_block_data.pool_target.puzzle_hash, pool_amount, constants.GENESIS_CHALLENGE
49
+ )
50
+ farmer_coin: Coin = create_farmer_coin(
51
+ block.height,
52
+ block.foliage.foliage_block_data.farmer_reward_puzzle_hash,
53
+ farmer_amount,
54
+ constants.GENESIS_CHALLENGE,
55
+ )
56
+ return pool_coin, farmer_coin
57
+
58
+
59
+ @pytest.mark.limit_consensus_modes(reason="save time")
60
+ @pytest.mark.anyio
61
+ async def test_basic_coin_store(db_version: int, softfork_height: uint32, bt: BlockTools) -> None:
62
+ wallet_a = WALLET_A
63
+ reward_ph = wallet_a.get_new_puzzlehash()
64
+
65
+ # Generate some coins
66
+ blocks = bt.get_consecutive_blocks(
67
+ 10,
68
+ [],
69
+ farmer_reward_puzzle_hash=reward_ph,
70
+ pool_reward_puzzle_hash=reward_ph,
71
+ )
72
+
73
+ coins_to_spend: List[Coin] = []
74
+ for block in blocks:
75
+ if block.is_transaction_block():
76
+ for coin in block.get_included_reward_coins():
77
+ if coin.puzzle_hash == reward_ph:
78
+ coins_to_spend.append(coin)
79
+
80
+ spend_bundle = wallet_a.generate_signed_transaction(uint64(1000), wallet_a.get_new_puzzlehash(), coins_to_spend[0])
81
+
82
+ async with DBConnection(db_version) as db_wrapper:
83
+ coin_store = await CoinStore.create(db_wrapper)
84
+
85
+ blocks = bt.get_consecutive_blocks(
86
+ 10,
87
+ blocks,
88
+ farmer_reward_puzzle_hash=reward_ph,
89
+ pool_reward_puzzle_hash=reward_ph,
90
+ transaction_data=spend_bundle,
91
+ )
92
+
93
+ # Adding blocks to the coin store
94
+ should_be_included_prev: Set[Coin] = set()
95
+ should_be_included: Set[Coin] = set()
96
+ for block in blocks:
97
+ farmer_coin, pool_coin = get_future_reward_coins(block)
98
+ should_be_included.add(farmer_coin)
99
+ should_be_included.add(pool_coin)
100
+ if block.is_transaction_block():
101
+ if block.transactions_generator is not None:
102
+ block_gen: BlockGenerator = BlockGenerator(block.transactions_generator, [])
103
+ npc_result = get_name_puzzle_conditions(
104
+ block_gen,
105
+ bt.constants.MAX_BLOCK_COST_CLVM,
106
+ mempool_mode=False,
107
+ height=softfork_height,
108
+ constants=bt.constants,
109
+ )
110
+ tx_removals, tx_additions = tx_removals_and_additions(npc_result.conds)
111
+ else:
112
+ tx_removals, tx_additions = [], []
113
+
114
+ assert set(block.get_included_reward_coins()) == should_be_included_prev
115
+
116
+ if block.is_transaction_block():
117
+ assert block.foliage_transaction_block is not None
118
+ await coin_store.new_block(
119
+ block.height,
120
+ block.foliage_transaction_block.timestamp,
121
+ block.get_included_reward_coins(),
122
+ tx_additions,
123
+ tx_removals,
124
+ )
125
+
126
+ if block.height != 0:
127
+ with pytest.raises(Exception):
128
+ await coin_store.new_block(
129
+ block.height,
130
+ block.foliage_transaction_block.timestamp,
131
+ block.get_included_reward_coins(),
132
+ tx_additions,
133
+ tx_removals,
134
+ )
135
+
136
+ all_records = set()
137
+ for expected_coin in should_be_included_prev:
138
+ # Check that the coinbase rewards are added
139
+ record = await coin_store.get_coin_record(expected_coin.name())
140
+ assert record is not None
141
+ assert not record.spent
142
+ assert record.coin == expected_coin
143
+ all_records.add(record)
144
+ for coin_name in tx_removals:
145
+ # Check that the removed coins are set to spent
146
+ record = await coin_store.get_coin_record(coin_name)
147
+ assert record is not None
148
+ assert record.spent
149
+ all_records.add(record)
150
+ for coin in tx_additions:
151
+ # Check that the added coins are added
152
+ record = await coin_store.get_coin_record(coin.name())
153
+ assert record is not None
154
+ assert not record.spent
155
+ assert coin == record.coin
156
+ all_records.add(record)
157
+
158
+ db_records = await coin_store.get_coin_records(
159
+ [c.name() for c in list(should_be_included_prev) + tx_additions] + tx_removals
160
+ )
161
+ assert len(db_records) == len(should_be_included_prev) + len(tx_removals) + len(tx_additions)
162
+ assert len(db_records) == len(all_records)
163
+ for record in db_records:
164
+ assert record in all_records
165
+
166
+ should_be_included_prev = should_be_included.copy()
167
+ should_be_included = set()
168
+
169
+
170
+ @pytest.mark.limit_consensus_modes(reason="save time")
171
+ @pytest.mark.anyio
172
+ async def test_set_spent(db_version: int, bt: BlockTools) -> None:
173
+ blocks = bt.get_consecutive_blocks(9, [])
174
+
175
+ async with DBConnection(db_version) as db_wrapper:
176
+ coin_store = await CoinStore.create(db_wrapper)
177
+
178
+ # Save/get block
179
+ for block in blocks:
180
+ if block.is_transaction_block():
181
+ removals: List[bytes32] = []
182
+ additions: List[Coin] = []
183
+ async with db_wrapper.writer():
184
+ if block.is_transaction_block():
185
+ assert block.foliage_transaction_block is not None
186
+ await coin_store.new_block(
187
+ block.height,
188
+ block.foliage_transaction_block.timestamp,
189
+ block.get_included_reward_coins(),
190
+ additions,
191
+ removals,
192
+ )
193
+
194
+ coins = block.get_included_reward_coins()
195
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
196
+
197
+ await coin_store._set_spent([r.name for r in records if r is not None], block.height)
198
+
199
+ if len(records) > 0:
200
+ for r in records:
201
+ assert r is not None
202
+ assert (await coin_store.get_coin_record(r.name)) is not None
203
+
204
+ # Check that we can't spend a coin twice in DB
205
+ with pytest.raises(ValueError, match="Invalid operation to set spent"):
206
+ await coin_store._set_spent([r.name for r in records if r is not None], block.height)
207
+
208
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
209
+ for record in records:
210
+ assert record is not None
211
+ assert record.spent
212
+ assert record.spent_block_index == block.height
213
+
214
+
215
+ @pytest.mark.limit_consensus_modes(reason="save time")
216
+ @pytest.mark.anyio
217
+ async def test_num_unspent(bt: BlockTools, db_version: int) -> None:
218
+ blocks = bt.get_consecutive_blocks(37, [])
219
+
220
+ expect_unspent = 0
221
+ test_excercised = False
222
+
223
+ async with DBConnection(db_version) as db_wrapper:
224
+ coin_store = await CoinStore.create(db_wrapper)
225
+
226
+ for block in blocks:
227
+ if not block.is_transaction_block():
228
+ continue
229
+
230
+ if block.is_transaction_block():
231
+ assert block.foliage_transaction_block is not None
232
+ removals: List[bytes32] = []
233
+ additions: List[Coin] = []
234
+ await coin_store.new_block(
235
+ block.height,
236
+ block.foliage_transaction_block.timestamp,
237
+ block.get_included_reward_coins(),
238
+ additions,
239
+ removals,
240
+ )
241
+
242
+ expect_unspent += len(block.get_included_reward_coins())
243
+ assert await coin_store.num_unspent() == expect_unspent
244
+ test_excercised = expect_unspent > 0
245
+
246
+ assert test_excercised
247
+
248
+
249
+ @pytest.mark.limit_consensus_modes(reason="save time")
250
+ @pytest.mark.anyio
251
+ async def test_rollback(db_version: int, bt: BlockTools) -> None:
252
+ blocks = bt.get_consecutive_blocks(20)
253
+
254
+ async with DBConnection(db_version) as db_wrapper:
255
+ coin_store = await CoinStore.create(db_wrapper)
256
+
257
+ selected_coin: Optional[CoinRecord] = None
258
+ all_coins: List[Coin] = []
259
+
260
+ for block in blocks:
261
+ all_coins += list(block.get_included_reward_coins())
262
+ if block.is_transaction_block():
263
+ removals: List[bytes32] = []
264
+ additions: List[Coin] = []
265
+ assert block.foliage_transaction_block is not None
266
+ await coin_store.new_block(
267
+ block.height,
268
+ block.foliage_transaction_block.timestamp,
269
+ block.get_included_reward_coins(),
270
+ additions,
271
+ removals,
272
+ )
273
+ coins = block.get_included_reward_coins()
274
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
275
+
276
+ spend_selected_coin = selected_coin is not None
277
+ if block.height != 0 and selected_coin is None:
278
+ # Select the first CoinRecord which will be spent at the next transaction block.
279
+ selected_coin = records[0]
280
+ await coin_store._set_spent([r.name for r in records[1:] if r is not None], block.height)
281
+ else:
282
+ await coin_store._set_spent([r.name for r in records if r is not None], block.height)
283
+
284
+ if spend_selected_coin:
285
+ assert selected_coin is not None
286
+ await coin_store._set_spent([selected_coin.name], block.height)
287
+
288
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins] # update coin records
289
+ for record in records:
290
+ assert record is not None
291
+ if (
292
+ selected_coin is not None
293
+ and selected_coin.name == record.name
294
+ and not selected_coin.confirmed_block_index < block.height
295
+ ):
296
+ assert not record.spent
297
+ else:
298
+ assert record.spent
299
+ assert record.spent_block_index == block.height
300
+
301
+ if spend_selected_coin:
302
+ break
303
+
304
+ assert selected_coin is not None
305
+ reorg_index = selected_coin.confirmed_block_index
306
+
307
+ # Get all CoinRecords.
308
+ all_records = [await coin_store.get_coin_record(coin.name()) for coin in all_coins]
309
+
310
+ # The reorg will revert the creation and spend of many coins. It will also revert the spend (but not the
311
+ # creation) of the selected coin.
312
+ changed_records = await coin_store.rollback_to_block(reorg_index)
313
+ changed_coin_records = [cr.coin for cr in changed_records]
314
+ assert selected_coin in changed_records
315
+ for coin_record in all_records:
316
+ assert coin_record is not None
317
+ if coin_record.confirmed_block_index > reorg_index:
318
+ assert coin_record.coin in changed_coin_records
319
+ if coin_record.spent_block_index > reorg_index:
320
+ assert coin_record.coin in changed_coin_records
321
+
322
+ for block in blocks:
323
+ if block.is_transaction_block():
324
+ coins = block.get_included_reward_coins()
325
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
326
+
327
+ if block.height <= reorg_index:
328
+ for record in records:
329
+ assert record is not None
330
+ assert record.spent == (record.name != selected_coin.name)
331
+ else:
332
+ for record in records:
333
+ assert record is None
334
+
335
+
336
+ @pytest.mark.anyio
337
+ async def test_basic_reorg(tmp_dir: Path, db_version: int, bt: BlockTools) -> None:
338
+ async with DBConnection(db_version) as db_wrapper:
339
+ initial_block_count = 30
340
+ reorg_length = 15
341
+ blocks = bt.get_consecutive_blocks(initial_block_count)
342
+ coin_store = await CoinStore.create(db_wrapper)
343
+ store = await BlockStore.create(db_wrapper)
344
+ b: Blockchain = await Blockchain.create(coin_store, store, bt.constants, tmp_dir, 2)
345
+ try:
346
+ records: List[Optional[CoinRecord]] = []
347
+
348
+ for block in blocks:
349
+ await _validate_and_add_block(b, block)
350
+ peak = b.get_peak()
351
+ assert peak is not None
352
+ assert peak.height == initial_block_count - 1
353
+
354
+ for c, block in enumerate(blocks):
355
+ if block.is_transaction_block():
356
+ coins = block.get_included_reward_coins()
357
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
358
+ for record in records:
359
+ assert record is not None
360
+ assert not record.spent
361
+ assert record.confirmed_block_index == block.height
362
+ assert record.spent_block_index == 0
363
+
364
+ blocks_reorg_chain = bt.get_consecutive_blocks(reorg_length, blocks[: initial_block_count - 10], seed=b"2")
365
+
366
+ for reorg_block in blocks_reorg_chain:
367
+ if reorg_block.height < initial_block_count - 10:
368
+ await _validate_and_add_block(b, reorg_block, expected_result=AddBlockResult.ALREADY_HAVE_BLOCK)
369
+ elif reorg_block.height < initial_block_count:
370
+ await _validate_and_add_block(b, reorg_block, expected_result=AddBlockResult.ADDED_AS_ORPHAN)
371
+ elif reorg_block.height >= initial_block_count:
372
+ await _validate_and_add_block(b, reorg_block, expected_result=AddBlockResult.NEW_PEAK)
373
+ if reorg_block.is_transaction_block():
374
+ coins = reorg_block.get_included_reward_coins()
375
+ records = [await coin_store.get_coin_record(coin.name()) for coin in coins]
376
+ for record in records:
377
+ assert record is not None
378
+ assert not record.spent
379
+ assert record.confirmed_block_index == reorg_block.height
380
+ assert record.spent_block_index == 0
381
+ peak = b.get_peak()
382
+ assert peak is not None
383
+ assert peak.height == initial_block_count - 10 + reorg_length - 1
384
+ finally:
385
+ b.shut_down()
386
+
387
+
388
+ @pytest.mark.limit_consensus_modes(reason="save time")
389
+ @pytest.mark.anyio
390
+ async def test_get_puzzle_hash(tmp_dir: Path, db_version: int, bt: BlockTools) -> None:
391
+ async with DBConnection(db_version) as db_wrapper:
392
+ num_blocks = 20
393
+ farmer_ph = bytes32(32 * b"0")
394
+ pool_ph = bytes32(32 * b"1")
395
+ blocks = bt.get_consecutive_blocks(
396
+ num_blocks,
397
+ farmer_reward_puzzle_hash=farmer_ph,
398
+ pool_reward_puzzle_hash=pool_ph,
399
+ guarantee_transaction_block=True,
400
+ )
401
+ coin_store = await CoinStore.create(db_wrapper)
402
+ store = await BlockStore.create(db_wrapper)
403
+ b: Blockchain = await Blockchain.create(coin_store, store, bt.constants, tmp_dir, 2)
404
+ for block in blocks:
405
+ await _validate_and_add_block(b, block)
406
+ peak = b.get_peak()
407
+ assert peak is not None
408
+ assert peak.height == num_blocks - 1
409
+
410
+ coins_farmer = await coin_store.get_coin_records_by_puzzle_hash(True, pool_ph)
411
+ coins_pool = await coin_store.get_coin_records_by_puzzle_hash(True, farmer_ph)
412
+
413
+ assert len(coins_farmer) == num_blocks - 2
414
+ assert len(coins_pool) == num_blocks - 2
415
+
416
+ b.shut_down()
417
+
418
+
419
+ @pytest.mark.anyio
420
+ async def test_get_coin_states(db_version: int) -> None:
421
+ async with DBConnection(db_version) as db_wrapper:
422
+ crs = [
423
+ CoinRecord(
424
+ Coin(std_hash(i.to_bytes(4, byteorder="big")), std_hash(b"2"), uint64(100)),
425
+ uint32(i),
426
+ uint32(2 * i),
427
+ False,
428
+ uint64(12321312),
429
+ )
430
+ for i in range(1, 301)
431
+ ]
432
+ crs += [
433
+ CoinRecord(
434
+ Coin(std_hash(b"X" + i.to_bytes(4, byteorder="big")), std_hash(b"3"), uint64(100)),
435
+ uint32(i),
436
+ uint32(2 * i),
437
+ False,
438
+ uint64(12321312),
439
+ )
440
+ for i in range(1, 301)
441
+ ]
442
+ coin_store = await CoinStore.create(db_wrapper)
443
+ await coin_store._add_coin_records(crs)
444
+
445
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(0))) == 300
446
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(False, {std_hash(b"2")}, uint32(0))) == 0
447
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(300))) == 151
448
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(603))) == 0
449
+ assert len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"1")}, uint32(0))) == 0
450
+
451
+ # test max_items limit
452
+ for limit in [0, 1, 42, 300]:
453
+ assert (
454
+ len(
455
+ await coin_store.get_coin_states_by_puzzle_hashes(
456
+ True, {std_hash(b"2")}, uint32(0), max_items=limit
457
+ )
458
+ )
459
+ == limit
460
+ )
461
+
462
+ # if the limit is very high, we should get all of them
463
+ assert (
464
+ len(await coin_store.get_coin_states_by_puzzle_hashes(True, {std_hash(b"2")}, uint32(0), max_items=10000))
465
+ == 300
466
+ )
467
+
468
+ coins = {cr.coin.name() for cr in crs}
469
+ bad_coins = {std_hash(cr.coin.name()) for cr in crs}
470
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(0))) == 600
471
+ assert len(await coin_store.get_coin_states_by_ids(False, coins, uint32(0))) == 0
472
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300))) == 302
473
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(603))) == 0
474
+ assert len(await coin_store.get_coin_states_by_ids(True, bad_coins, uint32(0))) == 0
475
+ # Test max_height
476
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(603))) == 600
477
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(602))) == 600
478
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(599))) == 598
479
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(400))) == 400
480
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(301))) == 300
481
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(300))) == 300
482
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(299))) == 298
483
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, max_height=uint32(0))) == 0
484
+ # Test min_height + max_height
485
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(603))) == 302
486
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(602))) == 302
487
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(599))) == 300
488
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(400))) == 102
489
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(301))) == 2
490
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(300))) == 2
491
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(299))) == 0
492
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(300), max_height=uint32(0))) == 0
493
+
494
+ # test max_items limit
495
+ for limit in [0, 1, 42, 300]:
496
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(0), max_items=limit)) == limit
497
+
498
+ # if the limit is very high, we should get all of them
499
+ assert len(await coin_store.get_coin_states_by_ids(True, coins, uint32(0), max_items=10000)) == 600
500
+
501
+
502
+ @dataclass(frozen=True)
503
+ class RandomCoinRecords:
504
+ items: List[CoinRecord]
505
+ puzzle_hashes: List[bytes32]
506
+ hints: List[Tuple[bytes32, bytes]]
507
+
508
+
509
+ @pytest.fixture(scope="session")
510
+ def random_coin_records() -> RandomCoinRecords:
511
+ coin_records: List[CoinRecord] = []
512
+ puzzle_hashes: List[bytes32] = []
513
+ hints: List[Tuple[bytes32, bytes]] = []
514
+
515
+ for i in range(50000):
516
+ is_spent = i % 2 == 0
517
+ is_hinted = i % 7 == 0
518
+ created_height = uint32(i)
519
+ spent_height = uint32(created_height + 100)
520
+
521
+ puzzle_hash = std_hash(i.to_bytes(4, byteorder="big"))
522
+
523
+ coin = Coin(
524
+ std_hash(b"Parent Coin Id " + i.to_bytes(4, byteorder="big")),
525
+ puzzle_hash,
526
+ uint64(i),
527
+ )
528
+
529
+ if is_hinted:
530
+ hint = std_hash(b"Hinted " + puzzle_hash)
531
+ hints.append((coin.name(), hint))
532
+ puzzle_hashes.append(hint)
533
+ else:
534
+ puzzle_hashes.append(puzzle_hash)
535
+
536
+ coin_records.append(
537
+ CoinRecord(
538
+ coin=coin,
539
+ confirmed_block_index=created_height,
540
+ spent_block_index=spent_height if is_spent else uint32(0),
541
+ coinbase=False,
542
+ timestamp=uint64(0),
543
+ )
544
+ )
545
+
546
+ coin_records.sort(key=lambda cr: max(cr.confirmed_block_index, cr.spent_block_index))
547
+
548
+ return RandomCoinRecords(coin_records, puzzle_hashes, hints)
549
+
550
+
551
+ @pytest.mark.anyio
552
+ @pytest.mark.parametrize("include_spent", [True, False])
553
+ @pytest.mark.parametrize("include_unspent", [True, False])
554
+ @pytest.mark.parametrize("include_hinted", [True, False])
555
+ @pytest.mark.parametrize(
556
+ "min_amount", [uint64(0), uint64(30000), uint64(0xFFFF), uint64(0x7FFF), uint64(0x8000), uint64(0x8000000000000000)]
557
+ )
558
+ async def test_coin_state_batches(
559
+ db_version: int,
560
+ random_coin_records: RandomCoinRecords,
561
+ include_spent: bool,
562
+ include_unspent: bool,
563
+ include_hinted: bool,
564
+ min_amount: uint64,
565
+ ) -> None:
566
+ async with DBConnection(db_version) as db_wrapper:
567
+ # Initialize coin and hint stores.
568
+ coin_store = await CoinStore.create(db_wrapper)
569
+ hint_store = await HintStore.create(db_wrapper)
570
+
571
+ await coin_store._add_coin_records(random_coin_records.items)
572
+ await hint_store.add_hints(random_coin_records.hints)
573
+
574
+ # Make sure all of the coin states are found when batching.
575
+ ph_set = set(random_coin_records.puzzle_hashes)
576
+ expected_crs = []
577
+ for cr in random_coin_records.items:
578
+ if cr.spent_block_index == 0 and not include_unspent:
579
+ continue
580
+ if cr.spent_block_index > 0 and not include_spent:
581
+ continue
582
+ if cr.coin.puzzle_hash not in ph_set and not include_hinted:
583
+ continue
584
+ if cr.coin.amount < min_amount:
585
+ continue
586
+ expected_crs.append(cr)
587
+
588
+ height: Optional[uint32] = uint32(0)
589
+ all_coin_states: List[CoinState] = []
590
+ remaining_phs = random_coin_records.puzzle_hashes.copy()
591
+
592
+ def height_of(coin_state: CoinState) -> int:
593
+ return max(coin_state.created_height or 0, coin_state.spent_height or 0)
594
+
595
+ while len(remaining_phs) > 0:
596
+ while height is not None:
597
+ (coin_states, height) = await coin_store.batch_coin_states_by_puzzle_hashes(
598
+ remaining_phs[: CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE],
599
+ min_height=height,
600
+ include_spent=include_spent,
601
+ include_unspent=include_unspent,
602
+ include_hinted=include_hinted,
603
+ min_amount=min_amount,
604
+ max_items=7000,
605
+ )
606
+
607
+ # Ensure that all of the returned coin states are in order.
608
+ assert all(
609
+ height_of(coin_states[i]) <= height_of(coin_states[i + 1]) for i in range(len(coin_states) - 1)
610
+ )
611
+
612
+ all_coin_states += coin_states
613
+
614
+ if height is None:
615
+ remaining_phs = remaining_phs[CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE :]
616
+
617
+ if len(remaining_phs) > 0:
618
+ height = uint32(0)
619
+
620
+ assert len(all_coin_states) == len(expected_crs)
621
+
622
+ all_coin_states.sort(key=height_of)
623
+
624
+ for i in range(len(expected_crs)):
625
+ actual = all_coin_states[i]
626
+ expected = expected_crs[i]
627
+
628
+ assert actual.coin == expected.coin, i
629
+ assert uint32(actual.created_height or 0) == expected.confirmed_block_index, i
630
+ assert uint32(actual.spent_height or 0) == expected.spent_block_index, i
631
+
632
+
633
+ @pytest.mark.anyio
634
+ @pytest.mark.parametrize("cut_off_middle", [True, False])
635
+ async def test_batch_many_coin_states(db_version: int, cut_off_middle: bool) -> None:
636
+ async with DBConnection(db_version) as db_wrapper:
637
+ ph = bytes32(b"0" * 32)
638
+
639
+ # Generate coin records.
640
+ coin_records: List[CoinRecord] = []
641
+ count = 50000
642
+
643
+ for i in range(count):
644
+ # Create coin records at either height 10 or 12.
645
+ created_height = uint32((i % 2) * 2 + 10)
646
+ coin = Coin(
647
+ std_hash(b"Parent Coin Id " + i.to_bytes(4, byteorder="big")),
648
+ ph,
649
+ uint64(i),
650
+ )
651
+ coin_records.append(
652
+ CoinRecord(
653
+ coin=coin,
654
+ confirmed_block_index=created_height,
655
+ spent_block_index=uint32(0),
656
+ coinbase=False,
657
+ timestamp=uint64(0),
658
+ )
659
+ )
660
+
661
+ # Initialize coin and hint stores.
662
+ coin_store = await CoinStore.create(db_wrapper)
663
+ await HintStore.create(db_wrapper)
664
+
665
+ await coin_store._add_coin_records(coin_records)
666
+
667
+ # Make sure all of the coin states are found.
668
+ (all_coin_states, next_height) = await coin_store.batch_coin_states_by_puzzle_hashes([ph])
669
+ all_coin_states.sort(key=lambda cs: cs.coin.amount)
670
+
671
+ assert next_height is None
672
+ assert len(all_coin_states) == len(coin_records)
673
+
674
+ for i in range(min(len(coin_records), len(all_coin_states))):
675
+ assert coin_records[i].coin.name().hex() == all_coin_states[i].coin.name().hex(), i
676
+
677
+ # For the middle case, insert a coin record between the two heights 10 and 12.
678
+ await coin_store._add_coin_records(
679
+ [
680
+ CoinRecord(
681
+ coin=Coin(std_hash(b"extra coin"), ph, uint64(0)),
682
+ # Insert a coin record in the middle between heights 10 and 12.
683
+ # Or after all of the other coins if testing the batch limit.
684
+ confirmed_block_index=uint32(11 if cut_off_middle else 50),
685
+ spent_block_index=uint32(0),
686
+ coinbase=False,
687
+ timestamp=uint64(0),
688
+ )
689
+ ]
690
+ )
691
+
692
+ (all_coin_states, next_height) = await coin_store.batch_coin_states_by_puzzle_hashes([ph])
693
+
694
+ # Make sure that the extra coin records are not included in the results.
695
+ assert next_height == (12 if cut_off_middle else 50)
696
+ assert len(all_coin_states) == (25001 if cut_off_middle else 50000)
697
+
698
+
699
+ @pytest.mark.anyio
700
+ async def test_batch_no_puzzle_hashes(db_version: int) -> None:
701
+ async with DBConnection(db_version) as db_wrapper:
702
+ # Initialize coin and hint stores.
703
+ coin_store = await CoinStore.create(db_wrapper)
704
+ await HintStore.create(db_wrapper)
705
+
706
+ coin_states, height = await coin_store.batch_coin_states_by_puzzle_hashes([])
707
+ assert coin_states == []
708
+ assert height is None
709
+
710
+
711
+ @pytest.mark.anyio
712
+ async def test_duplicate_by_hint(db_version: int) -> None:
713
+ async with DBConnection(db_version) as db_wrapper:
714
+ # Initialize coin and hint stores.
715
+ coin_store = await CoinStore.create(db_wrapper)
716
+ hint_store = await HintStore.create(db_wrapper)
717
+
718
+ cr = CoinRecord(
719
+ Coin(std_hash(b"Parent Coin Id"), std_hash(b"Puzzle Hash"), uint64(100)),
720
+ uint32(10),
721
+ uint32(0),
722
+ False,
723
+ uint64(12321312),
724
+ )
725
+
726
+ await coin_store._add_coin_records([cr])
727
+ await hint_store.add_hints([(cr.coin.name(), cr.coin.puzzle_hash)])
728
+
729
+ coin_states, height = await coin_store.batch_coin_states_by_puzzle_hashes([cr.coin.puzzle_hash])
730
+
731
+ assert coin_states == [cr.coin_state]
732
+ assert height is None
733
+
734
+
735
+ @pytest.mark.anyio
736
+ async def test_unsupported_version() -> None:
737
+ with pytest.raises(RuntimeError, match="CoinStore does not support database schema v1"):
738
+ async with DBConnection(1) as db_wrapper:
739
+ await CoinStore.create(db_wrapper)
740
+
741
+
742
+ TEST_COIN_ID = b"c" * 32
743
+ TEST_PUZZLEHASH = b"p" * 32
744
+ TEST_AMOUNT = uint64(1337)
745
+ TEST_PARENT_ID = Coin(b"a" * 32, TEST_PUZZLEHASH, TEST_AMOUNT).name()
746
+ TEST_PARENT_DIFFERENT_AMOUNT = uint64(5)
747
+ TEST_PARENT_ID_DIFFERENT_AMOUNT = Coin(b"a" * 32, TEST_PUZZLEHASH, TEST_PARENT_DIFFERENT_AMOUNT).name()
748
+ TEST_PARENT_PARENT_ID = b"f" * 32
749
+
750
+
751
+ @dataclass(frozen=True)
752
+ class UnspentLineageInfoTestItem:
753
+ coin_id: bytes
754
+ puzzlehash: bytes
755
+ amount: int
756
+ parent_id: bytes
757
+ is_spent: bool = False
758
+
759
+
760
+ @dataclass
761
+ class UnspentLineageInfoCase:
762
+ id: str
763
+ items: List[UnspentLineageInfoTestItem]
764
+ expected_success: bool
765
+ parent_with_diff_amount: bool = False
766
+ marks: Marks = ()
767
+
768
+
769
+ @pytest.mark.anyio
770
+ @datacases(
771
+ UnspentLineageInfoCase(
772
+ id="Unspent with parent that has same amount but different puzzlehash",
773
+ items=[
774
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
775
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
776
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
777
+ UnspentLineageInfoTestItem(TEST_PARENT_ID, b"4" * 32, TEST_AMOUNT, TEST_PARENT_PARENT_ID, is_spent=True),
778
+ ],
779
+ expected_success=False,
780
+ ),
781
+ UnspentLineageInfoCase(
782
+ id="Unspent with parent that has same puzzlehash but different amount",
783
+ items=[
784
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID_DIFFERENT_AMOUNT),
785
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
786
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
787
+ UnspentLineageInfoTestItem(
788
+ TEST_PARENT_ID_DIFFERENT_AMOUNT,
789
+ TEST_PUZZLEHASH,
790
+ TEST_PARENT_DIFFERENT_AMOUNT,
791
+ TEST_PARENT_PARENT_ID,
792
+ is_spent=True,
793
+ ),
794
+ ],
795
+ parent_with_diff_amount=True,
796
+ expected_success=True,
797
+ ),
798
+ UnspentLineageInfoCase(
799
+ id="Unspent with parent that has same puzzlehash and amount but is also unspent",
800
+ items=[
801
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
802
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
803
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
804
+ UnspentLineageInfoTestItem(TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID),
805
+ ],
806
+ expected_success=False,
807
+ ),
808
+ UnspentLineageInfoCase(
809
+ id="More than one unspent with parent that has same puzzlehash and amount",
810
+ items=[
811
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
812
+ UnspentLineageInfoTestItem(b"2" * 32, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
813
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
814
+ UnspentLineageInfoTestItem(
815
+ TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID, is_spent=True
816
+ ),
817
+ ],
818
+ expected_success=False,
819
+ ),
820
+ UnspentLineageInfoCase(
821
+ id="Unspent with parent that has same puzzlehash and amount",
822
+ items=[
823
+ UnspentLineageInfoTestItem(TEST_COIN_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_ID),
824
+ UnspentLineageInfoTestItem(b"2" * 32, b"2" * 32, 2, b"1" * 32),
825
+ UnspentLineageInfoTestItem(b"3" * 32, b"3" * 32, 3, b"2" * 32),
826
+ UnspentLineageInfoTestItem(
827
+ TEST_PARENT_ID, TEST_PUZZLEHASH, TEST_AMOUNT, TEST_PARENT_PARENT_ID, is_spent=True
828
+ ),
829
+ ],
830
+ expected_success=True,
831
+ ),
832
+ )
833
+ async def test_get_unspent_lineage_info_for_puzzle_hash(case: UnspentLineageInfoCase) -> None:
834
+ CoinRecordRawData = Tuple[
835
+ bytes, # coin_name (blob)
836
+ int, # confirmed_index (bigint)
837
+ int, # spent_index (bigint)
838
+ int, # coinbase (int)
839
+ bytes, # puzzle_hash (blob)
840
+ bytes, # coin_parent (blob)
841
+ bytes, # amount (blob)
842
+ int, # timestamp (bigint)
843
+ ]
844
+
845
+ def make_test_data(test_items: List[UnspentLineageInfoTestItem]) -> List[CoinRecordRawData]:
846
+ test_data = []
847
+ for item in test_items:
848
+ test_data.append(
849
+ (
850
+ item.coin_id,
851
+ 0,
852
+ 1 if item.is_spent else 0,
853
+ 0,
854
+ item.puzzlehash,
855
+ item.parent_id,
856
+ int_to_bytes(item.amount),
857
+ 0,
858
+ )
859
+ )
860
+ return test_data
861
+
862
+ async with DBConnection(2) as db_wrapper:
863
+ # Prepare the coin store with the test case's data
864
+ coin_store = await CoinStore.create(db_wrapper)
865
+ async with db_wrapper.writer() as writer:
866
+ for item in make_test_data(case.items):
867
+ await writer.execute(
868
+ "INSERT INTO coin_record "
869
+ "(coin_name, confirmed_index, spent_index, coinbase, puzzle_hash, coin_parent, amount, timestamp) "
870
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
871
+ item,
872
+ )
873
+ # Run the test case
874
+ result = await coin_store.get_unspent_lineage_info_for_puzzle_hash(bytes32(TEST_PUZZLEHASH))
875
+ if case.expected_success:
876
+ assert result == UnspentLineageInfo(
877
+ coin_id=bytes32(TEST_COIN_ID),
878
+ coin_amount=TEST_AMOUNT,
879
+ parent_id=(
880
+ bytes32(TEST_PARENT_ID_DIFFERENT_AMOUNT)
881
+ if case.parent_with_diff_amount
882
+ else bytes32(TEST_PARENT_ID)
883
+ ),
884
+ parent_amount=TEST_PARENT_DIFFERENT_AMOUNT if case.parent_with_diff_amount else TEST_AMOUNT,
885
+ parent_parent_id=bytes32(TEST_PARENT_PARENT_ID),
886
+ )
887
+ else:
888
+ assert result is None