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,1174 @@
1
+ from __future__ import annotations
2
+
3
+ from asyncio import Queue
4
+ from collections import OrderedDict
5
+ from collections.abc import AsyncGenerator
6
+ from dataclasses import dataclass
7
+ from random import Random
8
+ from typing import Optional
9
+
10
+ import pytest
11
+ from chia_rs import AugSchemeMPL, Coin, CoinSpend, CoinState, Program
12
+
13
+ from chia._tests.connection_utils import add_dummy_connection
14
+ from chia.full_node.coin_store import CoinStore
15
+ from chia.full_node.full_node import FullNode
16
+ from chia.full_node.mempool import MempoolRemoveReason
17
+ from chia.protocols import wallet_protocol
18
+ from chia.protocols.protocol_message_types import ProtocolMessageTypes
19
+ from chia.protocols.shared_protocol import Capability
20
+ from chia.server.outbound_message import Message, NodeType
21
+ from chia.server.ws_connection import WSChiaConnection
22
+ from chia.simulator import simulator_protocol
23
+ from chia.simulator.block_tools import BlockTools
24
+ from chia.simulator.full_node_simulator import FullNodeSimulator
25
+ from chia.simulator.start_simulator import SimulatorFullNodeService
26
+ from chia.types.aliases import WalletService
27
+ from chia.types.blockchain_format.sized_bytes import bytes32
28
+ from chia.types.coin_record import CoinRecord
29
+ from chia.types.mempool_inclusion_status import MempoolInclusionStatus
30
+ from chia.types.spend_bundle import SpendBundle
31
+ from chia.util.hash import std_hash
32
+ from chia.util.ints import uint8, uint16, uint32, uint64
33
+
34
+ IDENTITY_PUZZLE = Program.to(1)
35
+ IDENTITY_PUZZLE_HASH = IDENTITY_PUZZLE.get_tree_hash()
36
+
37
+ OneNode = tuple[list[SimulatorFullNodeService], list[WalletService], BlockTools]
38
+ Mpu = tuple[FullNodeSimulator, Queue[Message], WSChiaConnection]
39
+
40
+ ALL_FILTER = wallet_protocol.CoinStateFilters(True, True, True, uint64(0))
41
+
42
+
43
+ async def connect_to_simulator(
44
+ one_node: OneNode, self_hostname: str, mempool_updates: bool = True
45
+ ) -> tuple[FullNodeSimulator, Queue[Message], WSChiaConnection]:
46
+ [full_node_service], _, _ = one_node
47
+
48
+ full_node_api = full_node_service._api
49
+ fn_server = full_node_api.server
50
+
51
+ incoming_queue, peer_id = await add_dummy_connection(
52
+ fn_server,
53
+ self_hostname,
54
+ 41723,
55
+ NodeType.WALLET,
56
+ additional_capabilities=[(uint16(Capability.MEMPOOL_UPDATES), "1")] if mempool_updates else [],
57
+ )
58
+ peer = fn_server.all_connections[peer_id]
59
+
60
+ return full_node_api, incoming_queue, peer
61
+
62
+
63
+ @pytest.mark.anyio
64
+ async def test_puzzle_subscriptions(one_node: OneNode, self_hostname: str) -> None:
65
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
66
+ subs = simulator.full_node.subscriptions
67
+ genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
68
+
69
+ await simulator.farm_blocks_to_puzzlehash(1)
70
+
71
+ ph1 = bytes32(b"\x01" * 32)
72
+ ph2 = bytes32(b"\x02" * 32)
73
+ ph3 = bytes32(b"\x03" * 32)
74
+
75
+ # Add puzzle subscriptions, ignore duplicates
76
+ # Response can be in any order
77
+ resp = await simulator.request_puzzle_state(
78
+ wallet_protocol.RequestPuzzleState(
79
+ [ph1, ph2, ph2],
80
+ None,
81
+ genesis_challenge,
82
+ wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
83
+ True,
84
+ ),
85
+ peer,
86
+ )
87
+ assert resp is not None
88
+
89
+ add_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
90
+ assert set(add_response.puzzle_hashes) == {ph1, ph2}
91
+
92
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2}
93
+
94
+ # Add another puzzle hash and existing ones
95
+ resp = await simulator.request_puzzle_state(
96
+ wallet_protocol.RequestPuzzleState(
97
+ [ph1, ph2, ph3],
98
+ None,
99
+ genesis_challenge,
100
+ wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
101
+ True,
102
+ ),
103
+ peer,
104
+ )
105
+ assert resp is not None
106
+
107
+ add_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
108
+ assert set(add_response.puzzle_hashes) == {ph1, ph2, ph3}
109
+
110
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2, ph3}
111
+
112
+ # Remove puzzle subscriptions
113
+ # Ignore duplicates or missing subscriptions
114
+ resp = await simulator.request_remove_puzzle_subscriptions(
115
+ wallet_protocol.RequestRemovePuzzleSubscriptions([ph1, ph1, ph2]), peer
116
+ )
117
+ assert resp is not None
118
+
119
+ remove_response = wallet_protocol.RespondRemovePuzzleSubscriptions.from_bytes(resp.data)
120
+ assert set(remove_response.puzzle_hashes) == {ph1, ph2}
121
+
122
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph3}
123
+
124
+ # Clear all puzzle subscriptions.
125
+ resp = await simulator.request_remove_puzzle_subscriptions(
126
+ wallet_protocol.RequestRemovePuzzleSubscriptions(None), peer
127
+ )
128
+ assert resp is not None
129
+
130
+ remove_response = wallet_protocol.RespondRemovePuzzleSubscriptions.from_bytes(resp.data)
131
+ assert set(remove_response.puzzle_hashes) == {ph3}
132
+
133
+ assert len(subs.puzzle_subscriptions(peer.peer_node_id)) == 0
134
+
135
+
136
+ @pytest.mark.anyio
137
+ async def test_coin_subscriptions(one_node: OneNode, self_hostname: str) -> None:
138
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
139
+ subs = simulator.full_node.subscriptions
140
+ genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
141
+
142
+ await simulator.farm_blocks_to_puzzlehash(1)
143
+
144
+ coin1 = bytes32(b"\x01" * 32)
145
+ coin2 = bytes32(b"\x02" * 32)
146
+ coin3 = bytes32(b"\x03" * 32)
147
+
148
+ # Add coin subscriptions, ignore duplicates
149
+ # Response can be in any order
150
+ resp = await simulator.request_coin_state(
151
+ wallet_protocol.RequestCoinState([coin1, coin2, coin2], None, genesis_challenge, True), peer
152
+ )
153
+ assert resp is not None
154
+
155
+ add_response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
156
+ assert set(add_response.coin_ids) == {coin1, coin2}
157
+
158
+ assert subs.coin_subscriptions(peer.peer_node_id) == {coin1, coin2}
159
+
160
+ # Add another puzzle hash and existing ones
161
+ resp = await simulator.request_coin_state(
162
+ wallet_protocol.RequestCoinState([coin1, coin2, coin3], None, genesis_challenge, True), peer
163
+ )
164
+ assert resp is not None
165
+
166
+ add_response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
167
+ assert set(add_response.coin_ids) == {coin1, coin2, coin3}
168
+
169
+ assert subs.coin_subscriptions(peer.peer_node_id) == {coin1, coin2, coin3}
170
+
171
+ # Remove coin subscriptions
172
+ # Ignore duplicates or missing subscriptions
173
+ resp = await simulator.request_remove_coin_subscriptions(
174
+ wallet_protocol.RequestRemoveCoinSubscriptions([coin1, coin1, coin2]), peer
175
+ )
176
+ assert resp is not None
177
+
178
+ remove_response = wallet_protocol.RespondRemoveCoinSubscriptions.from_bytes(resp.data)
179
+ assert set(remove_response.coin_ids) == {coin1, coin2}
180
+
181
+ assert subs.coin_subscriptions(peer.peer_node_id) == {coin3}
182
+
183
+ # Clear all coin subscriptions.
184
+ resp = await simulator.request_remove_coin_subscriptions(wallet_protocol.RequestRemoveCoinSubscriptions(None), peer)
185
+ assert resp is not None
186
+
187
+ remove_response = wallet_protocol.RespondRemoveCoinSubscriptions.from_bytes(resp.data)
188
+ assert set(remove_response.coin_ids) == {coin3}
189
+
190
+ assert len(subs.coin_subscriptions(peer.peer_node_id)) == 0
191
+
192
+
193
+ @pytest.mark.anyio
194
+ async def test_subscription_limits(one_node: OneNode, self_hostname: str) -> None:
195
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
196
+ subs = simulator.full_node.subscriptions
197
+ genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
198
+
199
+ await simulator.farm_blocks_to_puzzlehash(1)
200
+
201
+ # This is a safe limit for this test that will fit within the current maximum in `RequestPuzzleState`.
202
+ simulator.full_node.config["max_subscribe_items"] = CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE
203
+
204
+ max_subs = simulator.max_subscriptions(peer)
205
+ puzzle_hashes = [std_hash(i.to_bytes(4, byteorder="big", signed=False)) for i in range(max_subs + 100)]
206
+
207
+ # Add puzzle subscriptions to the limit
208
+ first_batch = puzzle_hashes[: CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE]
209
+ first_batch_set = set(first_batch)
210
+
211
+ resp = await simulator.request_puzzle_state(
212
+ wallet_protocol.RequestPuzzleState(
213
+ first_batch, None, genesis_challenge, wallet_protocol.CoinStateFilters(False, False, False, uint64(0)), True
214
+ ),
215
+ peer,
216
+ )
217
+ assert resp is not None
218
+
219
+ add_ph_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
220
+ assert set(add_ph_response.puzzle_hashes) == first_batch_set
221
+
222
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == first_batch_set
223
+
224
+ # Try to add the remaining subscriptions
225
+ resp = await simulator.request_puzzle_state(
226
+ wallet_protocol.RequestPuzzleState(
227
+ puzzle_hashes[CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE :],
228
+ None,
229
+ genesis_challenge,
230
+ wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
231
+ True,
232
+ ),
233
+ peer,
234
+ )
235
+ assert resp is not None
236
+
237
+ overflow_ph_response = wallet_protocol.RejectPuzzleState.from_bytes(resp.data)
238
+ assert overflow_ph_response == wallet_protocol.RejectPuzzleState(
239
+ uint8(wallet_protocol.RejectStateReason.EXCEEDED_SUBSCRIPTION_LIMIT)
240
+ )
241
+
242
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == first_batch_set
243
+
244
+ # Try to overflow with coin subscriptions
245
+ resp = await simulator.request_coin_state(
246
+ wallet_protocol.RequestCoinState([bytes32(b"coin" * 8)], None, genesis_challenge, True), peer
247
+ )
248
+ assert resp is not None
249
+
250
+ overflow_coin_response = wallet_protocol.RejectCoinState.from_bytes(resp.data)
251
+ assert overflow_coin_response == wallet_protocol.RejectCoinState(
252
+ uint8(wallet_protocol.RejectStateReason.EXCEEDED_SUBSCRIPTION_LIMIT)
253
+ )
254
+
255
+
256
+ @pytest.mark.anyio
257
+ async def test_request_coin_state(one_node: OneNode, self_hostname: str) -> None:
258
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
259
+
260
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
261
+ assert genesis is not None
262
+
263
+ # Add coin records
264
+ coin_records = [
265
+ CoinRecord(
266
+ coin=Coin(bytes32.zeros, bytes32.zeros, uint64(i)),
267
+ confirmed_block_index=uint32(1),
268
+ spent_block_index=uint32(1 if i % 2 == 0 else 0),
269
+ coinbase=False,
270
+ timestamp=uint64(0),
271
+ )
272
+ for i in range(50)
273
+ ]
274
+ ignored_coin = CoinRecord(
275
+ coin=Coin(bytes32(b"\1" * 32), bytes32(b"\1" * 32), uint64(1)),
276
+ confirmed_block_index=uint32(1),
277
+ spent_block_index=uint32(2),
278
+ coinbase=False,
279
+ timestamp=uint64(1),
280
+ )
281
+ await simulator.full_node.coin_store._add_coin_records([*coin_records, ignored_coin])
282
+
283
+ # Request no coin states
284
+ resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState([], None, genesis, False), peer)
285
+ assert resp is not None
286
+
287
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
288
+
289
+ assert len(response.coin_ids) == 0
290
+ assert len(response.coin_states) == 0
291
+
292
+ # Request coin state
293
+ coin_ids = [cr.coin.name() for cr in coin_records]
294
+
295
+ resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState(coin_ids, None, genesis, False), peer)
296
+ assert resp is not None
297
+
298
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
299
+
300
+ assert response.coin_ids == coin_ids
301
+ assert set(response.coin_states) == {cr.coin_state for cr in coin_records}
302
+
303
+
304
+ @pytest.mark.anyio
305
+ async def test_request_coin_state_and_subscribe(one_node: OneNode, self_hostname: str) -> None:
306
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
307
+
308
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
309
+ assert genesis is not None
310
+
311
+ c1 = bytes32(b"1" * 32)
312
+ c2 = bytes32(b"2" * 32)
313
+ c3 = bytes32(b"3" * 32)
314
+ c4 = bytes32(b"4" * 32)
315
+
316
+ # Request initial state (empty in this case) and subscribe
317
+ resp = await simulator.request_coin_state(
318
+ wallet_protocol.RequestCoinState([c1, c2, c3, c3, c4], None, genesis, True), peer
319
+ )
320
+ assert resp is not None
321
+
322
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
323
+
324
+ assert len(response.coin_ids) == 4
325
+ assert len(response.coin_states) == 0
326
+
327
+ # Make sure the subscriptions were added
328
+ assert simulator.full_node.subscriptions.coin_subscriptions(peer.peer_node_id) == {c1, c2, c3, c4}
329
+
330
+
331
+ @pytest.mark.anyio
332
+ async def test_request_coin_state_reorg(one_node: OneNode, self_hostname: str) -> None:
333
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
334
+
335
+ # Farm block
336
+ await simulator.farm_blocks_to_puzzlehash(8)
337
+
338
+ header_hash = simulator.full_node.blockchain.height_to_hash(uint32(5))
339
+ assert header_hash is not None
340
+
341
+ # Reorg
342
+ await simulator.reorg_from_index_to_new_index(
343
+ simulator_protocol.ReorgProtocol(uint32(3), uint32(10), bytes32(b"\1" * 32), bytes32.zeros)
344
+ )
345
+
346
+ # Request coin state, should reject due to reorg
347
+ resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState([], uint32(5), header_hash, False), peer)
348
+ assert resp is not None
349
+
350
+ assert wallet_protocol.RejectCoinState.from_bytes(resp.data) == wallet_protocol.RejectCoinState(
351
+ uint8(wallet_protocol.RejectStateReason.REORG)
352
+ )
353
+
354
+
355
+ @pytest.mark.anyio
356
+ async def test_request_coin_state_limit(one_node: OneNode, self_hostname: str) -> None:
357
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
358
+
359
+ # Farm blocks 0-11 and make sure the last one is farmed
360
+ await simulator.farm_blocks_to_puzzlehash(12)
361
+
362
+ h0 = simulator.full_node.blockchain.height_to_hash(uint32(0))
363
+ assert h0 is not None
364
+
365
+ h1 = simulator.full_node.blockchain.height_to_hash(uint32(1))
366
+ assert h1 is not None
367
+
368
+ # Add more than the max response coin records
369
+ coin_records: OrderedDict[bytes32, CoinRecord] = OrderedDict()
370
+ for height in range(1, 12):
371
+ for i in range(10000):
372
+ coin_record = CoinRecord(
373
+ coin=Coin(std_hash(i.to_bytes(4, "big")), std_hash(height.to_bytes(4, "big")), uint64(i)),
374
+ confirmed_block_index=uint32(height),
375
+ spent_block_index=uint32(0),
376
+ coinbase=False,
377
+ timestamp=uint64(472618),
378
+ )
379
+ coin_records[coin_record.coin.name()] = coin_record
380
+
381
+ await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
382
+
383
+ # Fetch the coin records using the wallet protocol,
384
+ # with more coin ids than the limit of 100,000, but only after height 10000.
385
+ resp = await simulator.request_coin_state(
386
+ wallet_protocol.RequestCoinState(list(coin_records.keys()), uint32(1), h1, False),
387
+ peer,
388
+ )
389
+ assert resp is not None
390
+
391
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
392
+
393
+ assert response.coin_ids == list(coin_records.keys())[:100000]
394
+ assert len(response.coin_states) == len(coin_records) - 20000
395
+
396
+ for coin_state in response.coin_states:
397
+ coin_record = coin_records[coin_state.coin.name()]
398
+ assert coin_record.coin_state == coin_state
399
+ assert coin_record.confirmed_block_index > 1
400
+
401
+
402
+ @pytest.mark.anyio
403
+ async def test_request_puzzle_state(one_node: OneNode, self_hostname: str) -> None:
404
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
405
+
406
+ # Farm block to a puzzle hash we aren't looking at
407
+ await simulator.farm_blocks_to_puzzlehash(3, farm_to=bytes32(b"\x0a" * 32))
408
+
409
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
410
+
411
+ peak_height = simulator.full_node.blockchain.get_peak_height()
412
+ assert peak_height is not None
413
+
414
+ peak_header_hash = simulator.full_node.blockchain.height_to_hash(peak_height)
415
+ assert peak_header_hash is not None
416
+
417
+ # Add coin records
418
+ coin_records: list[CoinRecord] = []
419
+ puzzle_hashes: list[bytes32] = []
420
+
421
+ for ph_i in range(10):
422
+ puzzle_hash = bytes32(ph_i.to_bytes(1, "big") * 32)
423
+ puzzle_hashes.append(puzzle_hash)
424
+
425
+ for i in range(5):
426
+ coin_records.append(
427
+ CoinRecord(
428
+ coin=Coin(bytes32.zeros, puzzle_hash, uint64(i)),
429
+ confirmed_block_index=uint32(1),
430
+ spent_block_index=uint32(1 if i % 2 == 0 else 0),
431
+ coinbase=False,
432
+ timestamp=uint64(0),
433
+ )
434
+ )
435
+
436
+ ignored_coin = CoinRecord(
437
+ coin=Coin(bytes32(b"\1" * 32), bytes32(b"\1" * 31 + b"\0"), uint64(1)),
438
+ confirmed_block_index=uint32(1),
439
+ spent_block_index=uint32(2),
440
+ coinbase=False,
441
+ timestamp=uint64(1),
442
+ )
443
+
444
+ await simulator.full_node.coin_store._add_coin_records([*coin_records, ignored_coin])
445
+
446
+ # We already test permutations of CoinStateFilters in the CoinStore tests
447
+ # So it's redundant to do so here
448
+ filters = wallet_protocol.CoinStateFilters(True, True, True, uint64(0))
449
+
450
+ # Request no coin states
451
+ resp = await simulator.request_puzzle_state(
452
+ wallet_protocol.RequestPuzzleState([], None, genesis, filters, False), peer
453
+ )
454
+ assert resp is not None
455
+
456
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
457
+
458
+ # The peak height and header hash is returned when you are caught up to the peak
459
+ assert response == wallet_protocol.RespondPuzzleState([], peak_height, peak_header_hash, True, [])
460
+
461
+ # Request coin state
462
+ resp = await simulator.request_puzzle_state(
463
+ wallet_protocol.RequestPuzzleState(puzzle_hashes, None, genesis, filters, False), peer
464
+ )
465
+ assert resp is not None
466
+
467
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
468
+
469
+ assert response.puzzle_hashes == puzzle_hashes
470
+ assert set(response.coin_states) == {cr.coin_state for cr in coin_records}
471
+
472
+ assert response.height == peak_height
473
+ assert response.header_hash == peak_header_hash
474
+
475
+ assert response.is_finished
476
+
477
+
478
+ @pytest.mark.anyio
479
+ async def test_request_puzzle_state_and_subscribe(one_node: OneNode, self_hostname: str) -> None:
480
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
481
+
482
+ # You have to farm a block so there is a peak.
483
+ # Otherwise you will get an AssertionError from `request_puzzle_state`.
484
+ await simulator.farm_blocks_to_puzzlehash(1)
485
+
486
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
487
+ assert genesis is not None
488
+
489
+ ph1 = bytes32(b"1" * 32)
490
+ ph2 = bytes32(b"2" * 32)
491
+ ph3 = bytes32(b"3" * 32)
492
+ ph4 = bytes32(b"4" * 32)
493
+
494
+ # Request initial state (empty in this case) and subscribe
495
+ resp = await simulator.request_puzzle_state(
496
+ wallet_protocol.RequestPuzzleState(
497
+ [ph1, ph2, ph3, ph3, ph4],
498
+ None,
499
+ genesis,
500
+ wallet_protocol.CoinStateFilters(True, True, True, uint64(0)),
501
+ True,
502
+ ),
503
+ peer,
504
+ )
505
+ assert resp is not None
506
+
507
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
508
+
509
+ assert len(response.puzzle_hashes) == 4
510
+ assert len(response.coin_states) == 0
511
+
512
+ # Make sure the subscriptions were added
513
+ assert simulator.full_node.subscriptions.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2, ph3, ph4}
514
+
515
+
516
+ @pytest.mark.anyio
517
+ async def test_request_puzzle_state_reorg(one_node: OneNode, self_hostname: str) -> None:
518
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
519
+
520
+ # Farm block
521
+ await simulator.farm_blocks_to_puzzlehash(8)
522
+
523
+ header_hash = simulator.full_node.blockchain.height_to_hash(uint32(5))
524
+ assert header_hash is not None
525
+
526
+ # Reorg
527
+ await simulator.reorg_from_index_to_new_index(
528
+ simulator_protocol.ReorgProtocol(uint32(3), uint32(10), bytes32(b"\1" * 32), bytes32.zeros)
529
+ )
530
+
531
+ # Request coin state, should reject due to reorg
532
+ resp = await simulator.request_puzzle_state(
533
+ wallet_protocol.RequestPuzzleState(
534
+ [], uint32(5), header_hash, wallet_protocol.CoinStateFilters(True, True, True, uint64(0)), False
535
+ ),
536
+ peer,
537
+ )
538
+ assert resp is not None
539
+
540
+ assert wallet_protocol.RejectPuzzleState.from_bytes(resp.data) == wallet_protocol.RejectPuzzleState(
541
+ uint8(wallet_protocol.RejectStateReason.REORG)
542
+ )
543
+
544
+
545
+ @pytest.mark.anyio
546
+ async def test_request_puzzle_state_limit(one_node: OneNode, self_hostname: str) -> None:
547
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
548
+
549
+ # Farm blocks 0-11 and make sure the last one is farmed
550
+ await simulator.farm_blocks_to_puzzlehash(12)
551
+
552
+ h0 = simulator.full_node.blockchain.height_to_hash(uint32(0))
553
+ assert h0 is not None
554
+
555
+ h1 = simulator.full_node.blockchain.height_to_hash(uint32(1))
556
+ assert h1 is not None
557
+
558
+ # Add more than the max response coin records
559
+ coin_records: OrderedDict[bytes32, CoinRecord] = OrderedDict()
560
+ ph = bytes32(b"\1" * 32)
561
+
562
+ for height in range(1, 12):
563
+ for i in range(10000):
564
+ coin_record = CoinRecord(
565
+ coin=Coin(std_hash(i.to_bytes(4, "big")), ph, uint64(height)),
566
+ confirmed_block_index=uint32(height),
567
+ spent_block_index=uint32(0),
568
+ coinbase=False,
569
+ timestamp=uint64(472618),
570
+ )
571
+ coin_records[coin_record.coin.name()] = coin_record
572
+
573
+ await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
574
+
575
+ # Fetch the coin records using the wallet protocol,
576
+ # only after height 10000, so that the limit of 100000 isn't exceeded
577
+ resp = await simulator.request_puzzle_state(
578
+ wallet_protocol.RequestPuzzleState(
579
+ [ph], uint32(1), h1, wallet_protocol.CoinStateFilters(True, True, True, uint64(0)), False
580
+ ),
581
+ peer,
582
+ )
583
+ assert resp is not None
584
+
585
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
586
+
587
+ assert response.puzzle_hashes == [ph]
588
+ assert len(response.coin_states) == len(coin_records) - 10000
589
+
590
+ for coin_state in response.coin_states:
591
+ coin_record = coin_records[coin_state.coin.name()]
592
+ assert coin_record.coin_state == coin_state
593
+ assert coin_record.confirmed_block_index > 1
594
+
595
+ # The expected behavior when the limit is exceeded, is to skip the rest
596
+ resp = await simulator.request_puzzle_state(
597
+ wallet_protocol.RequestPuzzleState(
598
+ [ph],
599
+ uint32(0),
600
+ h0,
601
+ wallet_protocol.CoinStateFilters(True, True, True, uint64(0)),
602
+ False,
603
+ ),
604
+ peer,
605
+ )
606
+ assert resp is not None
607
+
608
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
609
+
610
+ assert response.puzzle_hashes == [ph]
611
+ assert len(response.coin_states) == len(coin_records) - 10000
612
+
613
+ for coin_state in response.coin_states:
614
+ coin_record = coin_records[coin_state.coin.name()]
615
+ assert coin_record.coin_state == coin_state
616
+ # Unlike requesting coin state by ids, the order is enforced here so block 11 should be excluded
617
+ assert coin_record.confirmed_block_index <= 10
618
+
619
+
620
+ @dataclass(frozen=True)
621
+ class PuzzleStateData:
622
+ coin_states: list[CoinState]
623
+ end_of_batch: bool
624
+ previous_height: Optional[uint32]
625
+ header_hash: bytes32
626
+
627
+
628
+ async def sync_puzzle_hashes(
629
+ puzzle_hashes: list[bytes32],
630
+ *,
631
+ initial_previous_height: Optional[uint32],
632
+ initial_header_hash: bytes32,
633
+ filters: wallet_protocol.CoinStateFilters,
634
+ subscribe_when_finished: bool = False,
635
+ max_hashes_in_request: int = CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE,
636
+ simulator: FullNodeSimulator,
637
+ peer: WSChiaConnection,
638
+ ) -> AsyncGenerator[PuzzleStateData, None]:
639
+ remaining = puzzle_hashes.copy()
640
+
641
+ while len(remaining) > 0:
642
+ previous_height = initial_previous_height
643
+ previous_header_hash = initial_header_hash
644
+ is_finished = False
645
+
646
+ while not is_finished:
647
+ resp = await simulator.request_puzzle_state(
648
+ wallet_protocol.RequestPuzzleState(
649
+ remaining[:max_hashes_in_request],
650
+ previous_height,
651
+ previous_header_hash,
652
+ filters,
653
+ subscribe_when_finished,
654
+ ),
655
+ peer,
656
+ )
657
+ assert resp is not None
658
+
659
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
660
+
661
+ consumed = len(response.puzzle_hashes)
662
+ assert set(response.puzzle_hashes) == set(remaining[:consumed])
663
+
664
+ if not response.is_finished:
665
+ previous_height = response.height
666
+ previous_header_hash = response.header_hash
667
+ yield PuzzleStateData(
668
+ coin_states=response.coin_states,
669
+ end_of_batch=False,
670
+ previous_height=previous_height,
671
+ header_hash=previous_header_hash,
672
+ )
673
+ else:
674
+ remaining = remaining[consumed:]
675
+ yield PuzzleStateData(
676
+ coin_states=response.coin_states,
677
+ end_of_batch=True,
678
+ previous_height=previous_height,
679
+ header_hash=previous_header_hash,
680
+ )
681
+ is_finished = True
682
+
683
+
684
+ @pytest.mark.anyio
685
+ @pytest.mark.parametrize("puzzle_hash_count,coins_per_block", [(0, 0), (5, 100), (3000, 3), (25000, 1)])
686
+ async def test_sync_puzzle_state(
687
+ one_node: OneNode, self_hostname: str, puzzle_hash_count: int, coins_per_block: int
688
+ ) -> None:
689
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
690
+
691
+ simulator.full_node.config["max_subscribe_response_items"] = 7400
692
+
693
+ # Generate coin records
694
+ puzzle_hashes: list[bytes32] = []
695
+ hints: list[tuple[bytes32, bytes]] = []
696
+ coin_records: dict[bytes32, CoinRecord] = dict()
697
+
698
+ rng = Random(0)
699
+
700
+ # Skip block 0 because it's skipped by `RequestPuzzleState`.
701
+ for i in range(1, puzzle_hash_count + 1):
702
+ puzzle_hash = std_hash(i.to_bytes(4, "big"))
703
+ puzzle_hashes.append(puzzle_hash)
704
+
705
+ base_amount = rng.randint(0, 1000000000)
706
+
707
+ for added_amount in range(coins_per_block):
708
+ coin_ph = puzzle_hash
709
+
710
+ # Weight toward normal puzzle hash.
711
+ if rng.choice([True, False, False, False, False]):
712
+ coin_ph = std_hash(coin_ph)
713
+
714
+ coin = Coin(bytes32.zeros, coin_ph, uint64(base_amount + added_amount))
715
+
716
+ coin_records[coin.name()] = CoinRecord(
717
+ coin=coin,
718
+ confirmed_block_index=uint32(rng.randrange(1, 10)),
719
+ spent_block_index=uint32(rng.randrange(11, 20) if rng.choice([True, False]) else 0),
720
+ coinbase=False,
721
+ timestamp=uint64(rng.randint(1000, 100000000)),
722
+ )
723
+
724
+ if coin_ph != puzzle_hash:
725
+ hints.append((coin.name(), puzzle_hash))
726
+
727
+ await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
728
+ await simulator.full_node.hint_store.add_hints(hints)
729
+
730
+ # Farm peak
731
+ await simulator.farm_blocks_to_puzzlehash(30)
732
+
733
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
734
+
735
+ async def run_test(include_spent: bool, include_unspent: bool, include_hinted: bool, min_amount: uint64) -> None:
736
+ # Calculate expected coin records based on filters
737
+ expected_coin_records: dict[bytes32, CoinRecord] = dict()
738
+
739
+ for coin_id, coin_record in coin_records.items():
740
+ if not include_spent and coin_record.spent_block_index > 0:
741
+ continue
742
+ if not include_unspent and coin_record.spent_block_index == 0:
743
+ continue
744
+ if not include_hinted and coin_record.coin.puzzle_hash not in puzzle_hashes:
745
+ continue
746
+ if coin_record.coin.amount < min_amount:
747
+ continue
748
+
749
+ expected_coin_records[coin_id] = coin_record
750
+
751
+ # Sync all coin states
752
+ coin_ids: set[bytes32] = set()
753
+ last_height = -1
754
+
755
+ async for batch in sync_puzzle_hashes(
756
+ puzzle_hashes,
757
+ initial_previous_height=None,
758
+ initial_header_hash=genesis,
759
+ filters=wallet_protocol.CoinStateFilters(include_spent, include_unspent, include_hinted, min_amount),
760
+ simulator=simulator,
761
+ peer=peer,
762
+ ):
763
+ for coin_state in batch.coin_states:
764
+ coin_id = coin_state.coin.name()
765
+ coin_ids.add(coin_id)
766
+
767
+ coin_record = expected_coin_records[coin_id]
768
+ assert coin_record.coin_state == coin_state
769
+
770
+ height = max(coin_state.created_height or 0, coin_state.spent_height or 0)
771
+
772
+ assert height > last_height
773
+ if batch.end_of_batch:
774
+ last_height = -1
775
+
776
+ assert len(coin_ids) == len(expected_coin_records)
777
+
778
+ for include_spent in [True, False]:
779
+ for include_unspent in [True, False]:
780
+ for include_hinted in [True, False]:
781
+ for min_amount in [0, 100000, 500000000]:
782
+ await run_test(include_spent, include_unspent, include_hinted, uint64(min_amount))
783
+
784
+
785
+ async def assert_mempool_added(queue: Queue[Message], transaction_ids: set[bytes32]) -> None:
786
+ message = await queue.get()
787
+ assert message.type == ProtocolMessageTypes.mempool_items_added.value
788
+
789
+ update = wallet_protocol.MempoolItemsAdded.from_bytes(message.data)
790
+ assert set(update.transaction_ids) == transaction_ids
791
+
792
+
793
+ async def assert_mempool_removed(
794
+ queue: Queue[Message],
795
+ removed_items: set[wallet_protocol.RemovedMempoolItem],
796
+ ) -> None:
797
+ message = await queue.get()
798
+ assert message.type == ProtocolMessageTypes.mempool_items_removed.value
799
+
800
+ update = wallet_protocol.MempoolItemsRemoved.from_bytes(message.data)
801
+ assert set(update.removed_items) == removed_items
802
+
803
+
804
+ @pytest.fixture
805
+ async def mpu_setup(one_node: OneNode, self_hostname: str) -> Mpu:
806
+ return await raw_mpu_setup(one_node, self_hostname)
807
+
808
+
809
+ @pytest.fixture
810
+ async def mpu_setup_no_capability(one_node: OneNode, self_hostname: str) -> Mpu:
811
+ return await raw_mpu_setup(one_node, self_hostname, no_capability=True)
812
+
813
+
814
+ async def raw_mpu_setup(one_node: OneNode, self_hostname: str, no_capability: bool = False) -> Mpu:
815
+ simulator, queue, peer = await connect_to_simulator(one_node, self_hostname, mempool_updates=not no_capability)
816
+ await simulator.farm_blocks_to_puzzlehash(1)
817
+ await queue.get()
818
+
819
+ new_coins: list[tuple[Coin, bytes32]] = []
820
+
821
+ for i in range(10):
822
+ puzzle = Program.to(2)
823
+ ph = puzzle.get_tree_hash()
824
+ coin = Coin(std_hash(b"unrelated coin id" + i.to_bytes(4, "big")), ph, uint64(1))
825
+ hint = std_hash(b"unrelated hint" + i.to_bytes(4, "big"))
826
+ new_coins.append((coin, hint))
827
+
828
+ reward_1 = Coin(std_hash(b"reward 1"), std_hash(b"reward puzzle hash"), uint64(1000))
829
+ reward_2 = Coin(std_hash(b"reward 2"), std_hash(b"reward puzzle hash"), uint64(2000))
830
+ await simulator.full_node.coin_store.new_block(
831
+ uint32(2), uint64(10000), [reward_1, reward_2], [coin for coin, _ in new_coins], []
832
+ )
833
+ await simulator.full_node.hint_store.add_hints([(coin.name(), hint) for coin, hint in new_coins])
834
+
835
+ for coin, hint in new_coins:
836
+ solution = Program.to([[]])
837
+ bundle = SpendBundle([CoinSpend(coin, puzzle, solution)], AugSchemeMPL.aggregate([]))
838
+ tx_resp = await simulator.send_transaction(wallet_protocol.SendTransaction(bundle))
839
+ assert tx_resp is not None
840
+
841
+ ack = wallet_protocol.TransactionAck.from_bytes(tx_resp.data)
842
+ assert ack.error is None
843
+ assert ack.status == int(MempoolInclusionStatus.SUCCESS)
844
+
845
+ return simulator, queue, peer
846
+
847
+
848
+ async def make_coin(full_node: FullNode) -> tuple[Coin, bytes32]:
849
+ ph = IDENTITY_PUZZLE_HASH
850
+ coin = Coin(bytes32.zeros, ph, uint64(1000))
851
+ hint = bytes32.zeros
852
+
853
+ height = full_node.blockchain.get_peak_height()
854
+ assert height is not None
855
+
856
+ reward_1 = Coin(std_hash(b"reward 1"), std_hash(b"reward puzzle hash"), uint64(3000))
857
+ reward_2 = Coin(std_hash(b"reward 2"), std_hash(b"reward puzzle hash"), uint64(4000))
858
+ await full_node.coin_store.new_block(uint32(height + 1), uint64(200000), [reward_1, reward_2], [coin], [])
859
+ await full_node.hint_store.add_hints([(coin.name(), hint)])
860
+
861
+ return coin, hint
862
+
863
+
864
+ async def subscribe_coin(
865
+ simulator: FullNodeSimulator, coin_id: bytes32, peer: WSChiaConnection, *, existing_coin_states: int = 1
866
+ ) -> None:
867
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
868
+ assert genesis is not None
869
+
870
+ msg = await simulator.request_coin_state(wallet_protocol.RequestCoinState([coin_id], None, genesis, True), peer)
871
+ assert msg is not None
872
+
873
+ response = wallet_protocol.RespondCoinState.from_bytes(msg.data)
874
+ assert response.coin_ids == [coin_id]
875
+ assert len(response.coin_states) == existing_coin_states
876
+
877
+
878
+ async def subscribe_puzzle(
879
+ simulator: FullNodeSimulator, puzzle_hash: bytes32, peer: WSChiaConnection, *, existing_coin_states: int = 1
880
+ ) -> None:
881
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
882
+ assert genesis is not None
883
+
884
+ msg = await simulator.request_puzzle_state(
885
+ wallet_protocol.RequestPuzzleState([puzzle_hash], None, genesis, ALL_FILTER, True), peer
886
+ )
887
+ assert msg is not None
888
+
889
+ response = wallet_protocol.RespondPuzzleState.from_bytes(msg.data)
890
+ assert response.puzzle_hashes == [puzzle_hash]
891
+ assert len(response.coin_states) == existing_coin_states
892
+
893
+
894
+ async def spend_coin(simulator: FullNodeSimulator, coin: Coin, solution: Optional[Program] = None) -> bytes32:
895
+ bundle = SpendBundle(
896
+ [CoinSpend(coin, IDENTITY_PUZZLE, Program.to([]) if solution is None else solution)], AugSchemeMPL.aggregate([])
897
+ )
898
+ tx_resp = await simulator.send_transaction(wallet_protocol.SendTransaction(bundle))
899
+ assert tx_resp is not None
900
+
901
+ ack = wallet_protocol.TransactionAck.from_bytes(tx_resp.data)
902
+ assert ack.error is None
903
+ assert ack.status == int(MempoolInclusionStatus.SUCCESS)
904
+
905
+ transaction_id = bundle.name()
906
+ assert ack.txid == transaction_id
907
+
908
+ return transaction_id
909
+
910
+
911
+ @pytest.mark.anyio
912
+ async def test_spent_coin_id_mempool_update(mpu_setup: Mpu) -> None:
913
+ simulator, queue, peer = mpu_setup
914
+
915
+ # Make a coin and spend it
916
+ coin, _ = await make_coin(simulator.full_node)
917
+ await subscribe_coin(simulator, coin.name(), peer)
918
+ transaction_id = await spend_coin(simulator, coin)
919
+
920
+ # We should have gotten a mempool update for this transaction
921
+ await assert_mempool_added(queue, {transaction_id})
922
+
923
+ # Check the mempool to make sure the transaction is there
924
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
925
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
926
+
927
+ # The mempool item should now be in the initial update
928
+ await subscribe_coin(simulator, coin.name(), peer)
929
+ await assert_mempool_added(queue, {transaction_id})
930
+
931
+ # Farm a block and listen for the mempool removal event
932
+ await simulator.farm_blocks_to_puzzlehash(1)
933
+ await assert_mempool_removed(
934
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
935
+ )
936
+
937
+
938
+ @pytest.mark.anyio
939
+ async def test_spent_puzzle_hash_mempool_update(mpu_setup: Mpu) -> None:
940
+ simulator, queue, peer = mpu_setup
941
+
942
+ # Make a coin and spend it
943
+ coin, _ = await make_coin(simulator.full_node)
944
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
945
+ transaction_id = await spend_coin(simulator, coin)
946
+
947
+ # We should have gotten a mempool update for this transaction
948
+ await assert_mempool_added(queue, {transaction_id})
949
+
950
+ # Check the mempool to make sure the transaction is there
951
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
952
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
953
+
954
+ # The mempool item should now be in the initial update
955
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
956
+ await assert_mempool_added(queue, {transaction_id})
957
+
958
+ # Farm a block and listen for the mempool removal event
959
+ await simulator.farm_blocks_to_puzzlehash(1)
960
+ await assert_mempool_removed(
961
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
962
+ )
963
+
964
+
965
+ @pytest.mark.anyio
966
+ async def test_spent_hint_mempool_update(mpu_setup: Mpu) -> None:
967
+ simulator, queue, peer = mpu_setup
968
+
969
+ # Make a coin and spend it
970
+ coin, hint = await make_coin(simulator.full_node)
971
+ await subscribe_puzzle(simulator, hint, peer)
972
+ transaction_id = await spend_coin(simulator, coin)
973
+
974
+ # We should have gotten a mempool update for this transaction
975
+ await assert_mempool_added(queue, {transaction_id})
976
+
977
+ # Check the mempool to make sure the transaction is there
978
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
979
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
980
+
981
+ # The mempool item should now be in the initial update
982
+ await subscribe_puzzle(simulator, hint, peer)
983
+ await assert_mempool_added(queue, {transaction_id})
984
+
985
+ # Farm a block and listen for the mempool removal event
986
+ await simulator.farm_blocks_to_puzzlehash(1)
987
+ await assert_mempool_removed(
988
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
989
+ )
990
+
991
+
992
+ @pytest.mark.anyio
993
+ async def test_created_coin_id_mempool_update(mpu_setup: Mpu) -> None:
994
+ simulator, queue, peer = mpu_setup
995
+
996
+ # Make a coin and spend it to create a child coin
997
+ coin, _ = await make_coin(simulator.full_node)
998
+ child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
999
+ await subscribe_coin(simulator, child_coin.name(), peer, existing_coin_states=0)
1000
+ transaction_id = await spend_coin(
1001
+ simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount]])
1002
+ )
1003
+
1004
+ # We should have gotten a mempool update for this transaction
1005
+ await assert_mempool_added(queue, {transaction_id})
1006
+
1007
+ # Check the mempool to make sure the transaction is there
1008
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1009
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1010
+
1011
+ # The mempool item should now be in the initial update
1012
+ await subscribe_coin(simulator, child_coin.name(), peer, existing_coin_states=0)
1013
+ await assert_mempool_added(queue, {transaction_id})
1014
+
1015
+ # Farm a block and listen for the mempool removal event
1016
+ await simulator.farm_blocks_to_puzzlehash(1)
1017
+ await assert_mempool_removed(
1018
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
1019
+ )
1020
+
1021
+
1022
+ @pytest.mark.anyio
1023
+ async def test_created_puzzle_hash_mempool_update(mpu_setup: Mpu) -> None:
1024
+ simulator, queue, peer = mpu_setup
1025
+
1026
+ # Make a coin and spend it to create a child coin
1027
+ coin, _ = await make_coin(simulator.full_node)
1028
+ child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
1029
+ await subscribe_puzzle(simulator, child_coin.puzzle_hash, peer, existing_coin_states=0)
1030
+ transaction_id = await spend_coin(
1031
+ simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount]])
1032
+ )
1033
+
1034
+ # We should have gotten a mempool update for this transaction
1035
+ await assert_mempool_added(queue, {transaction_id})
1036
+
1037
+ # Check the mempool to make sure the transaction is there
1038
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1039
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1040
+
1041
+ # The mempool item should now be in the initial update
1042
+ await subscribe_puzzle(simulator, child_coin.puzzle_hash, peer, existing_coin_states=0)
1043
+ await assert_mempool_added(queue, {transaction_id})
1044
+
1045
+ # Farm a block and listen for the mempool removal event
1046
+ await simulator.farm_blocks_to_puzzlehash(1)
1047
+ await assert_mempool_removed(
1048
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
1049
+ )
1050
+
1051
+
1052
+ @pytest.mark.anyio
1053
+ async def test_created_hint_mempool_update(mpu_setup: Mpu) -> None:
1054
+ simulator, queue, peer = mpu_setup
1055
+
1056
+ # Make a coin and spend it to create a child coin
1057
+ coin, _ = await make_coin(simulator.full_node)
1058
+ child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
1059
+ hint = std_hash(b"new hint")
1060
+ await subscribe_puzzle(simulator, hint, peer, existing_coin_states=0)
1061
+ transaction_id = await spend_coin(
1062
+ simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount, [hint]]])
1063
+ )
1064
+
1065
+ # We should have gotten a mempool update for this transaction
1066
+ await assert_mempool_added(queue, {transaction_id})
1067
+
1068
+ # Check the mempool to make sure the transaction is there
1069
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1070
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1071
+
1072
+ # The mempool item should now be in the initial update
1073
+ await subscribe_puzzle(simulator, hint, peer, existing_coin_states=0)
1074
+ await assert_mempool_added(queue, {transaction_id})
1075
+
1076
+ # Farm a block and listen for the mempool removal event
1077
+ await simulator.farm_blocks_to_puzzlehash(1)
1078
+ await assert_mempool_removed(
1079
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
1080
+ )
1081
+
1082
+
1083
+ @pytest.mark.anyio
1084
+ async def test_missing_capability_coin_id(mpu_setup_no_capability: Mpu) -> None:
1085
+ simulator, queue, peer = mpu_setup_no_capability
1086
+
1087
+ # Make a coin and spend it
1088
+ coin, _ = await make_coin(simulator.full_node)
1089
+ await subscribe_coin(simulator, coin.name(), peer)
1090
+ transaction_id = await spend_coin(simulator, coin)
1091
+
1092
+ # There is no mempool update for this transaction since the peer doesn't have the capability
1093
+ assert queue.empty()
1094
+
1095
+ # Check the mempool to make sure the transaction is there
1096
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1097
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1098
+
1099
+ # There is no initial mempool update since the peer doesn't have the capability
1100
+ await subscribe_coin(simulator, coin.name(), peer)
1101
+ assert queue.empty()
1102
+
1103
+ # Farm a block and there's still no mempool update
1104
+ await simulator.farm_blocks_to_puzzlehash(1)
1105
+ assert queue.empty()
1106
+
1107
+
1108
+ @pytest.mark.anyio
1109
+ async def test_missing_capability_puzzle_hash(mpu_setup_no_capability: Mpu) -> None:
1110
+ simulator, queue, peer = mpu_setup_no_capability
1111
+
1112
+ # Make a coin and spend it
1113
+ coin, _ = await make_coin(simulator.full_node)
1114
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
1115
+ transaction_id = await spend_coin(simulator, coin)
1116
+
1117
+ # There is no mempool update for this transaction since the peer doesn't have the capability
1118
+ assert queue.empty()
1119
+
1120
+ # Check the mempool to make sure the transaction is there
1121
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1122
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1123
+
1124
+ # There is no initial mempool update since the peer doesn't have the capability
1125
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
1126
+ assert queue.empty()
1127
+
1128
+ # Farm a block and there's still no mempool update
1129
+ await simulator.farm_blocks_to_puzzlehash(1)
1130
+ assert queue.empty()
1131
+
1132
+
1133
+ @pytest.mark.anyio
1134
+ async def test_missing_capability_hint(mpu_setup_no_capability: Mpu) -> None:
1135
+ simulator, queue, peer = mpu_setup_no_capability
1136
+
1137
+ # Make a coin and spend it
1138
+ coin, hint = await make_coin(simulator.full_node)
1139
+ await subscribe_puzzle(simulator, hint, peer)
1140
+ transaction_id = await spend_coin(simulator, coin)
1141
+
1142
+ # There is no mempool update for this transaction since the peer doesn't have the capability
1143
+ assert queue.empty()
1144
+
1145
+ # Check the mempool to make sure the transaction is there
1146
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1147
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1148
+
1149
+ # There is no initial mempool update since the peer doesn't have the capability
1150
+ await subscribe_puzzle(simulator, hint, peer)
1151
+ assert queue.empty()
1152
+
1153
+ # Farm a block and there's still no mempool update
1154
+ await simulator.farm_blocks_to_puzzlehash(1)
1155
+ assert queue.empty()
1156
+
1157
+
1158
+ @pytest.mark.anyio
1159
+ async def test_cost_info(one_node: OneNode, self_hostname: str) -> None:
1160
+ simulator, _, _ = await connect_to_simulator(one_node, self_hostname)
1161
+
1162
+ msg = await simulator.request_cost_info(wallet_protocol.RequestCostInfo())
1163
+ assert msg is not None
1164
+
1165
+ response = wallet_protocol.RespondCostInfo.from_bytes(msg.data)
1166
+ mempool_manager = simulator.full_node.mempool_manager
1167
+ assert response == wallet_protocol.RespondCostInfo(
1168
+ max_transaction_cost=mempool_manager.max_tx_clvm_cost,
1169
+ max_block_cost=mempool_manager.max_block_clvm_cost,
1170
+ max_mempool_cost=uint64(mempool_manager.mempool_max_total_cost),
1171
+ mempool_cost=uint64(mempool_manager.mempool._total_cost),
1172
+ mempool_fee=uint64(mempool_manager.mempool._total_fee),
1173
+ bump_fee_per_cost=uint8(mempool_manager.nonzero_fee_minimum_fpc),
1174
+ )