chia-blockchain 2.4.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1028) hide show
  1. chia/__init__.py +10 -0
  2. chia/__main__.py +5 -0
  3. chia/_tests/README.md +53 -0
  4. chia/_tests/__init__.py +0 -0
  5. chia/_tests/blockchain/__init__.py +0 -0
  6. chia/_tests/blockchain/blockchain_test_utils.py +197 -0
  7. chia/_tests/blockchain/config.py +4 -0
  8. chia/_tests/blockchain/test_augmented_chain.py +147 -0
  9. chia/_tests/blockchain/test_blockchain.py +4100 -0
  10. chia/_tests/blockchain/test_blockchain_transactions.py +1050 -0
  11. chia/_tests/blockchain/test_build_chains.py +61 -0
  12. chia/_tests/blockchain/test_get_block_generator.py +72 -0
  13. chia/_tests/blockchain/test_lookup_fork_chain.py +195 -0
  14. chia/_tests/build-init-files.py +93 -0
  15. chia/_tests/build-job-matrix.py +204 -0
  16. chia/_tests/check_pytest_monitor_output.py +34 -0
  17. chia/_tests/check_sql_statements.py +73 -0
  18. chia/_tests/chia-start-sim +42 -0
  19. chia/_tests/clvm/__init__.py +0 -0
  20. chia/_tests/clvm/benchmark_costs.py +23 -0
  21. chia/_tests/clvm/coin_store.py +147 -0
  22. chia/_tests/clvm/test_chialisp_deserialization.py +101 -0
  23. chia/_tests/clvm/test_clvm_step.py +37 -0
  24. chia/_tests/clvm/test_condition_codes.py +13 -0
  25. chia/_tests/clvm/test_curry_and_treehash.py +57 -0
  26. chia/_tests/clvm/test_program.py +150 -0
  27. chia/_tests/clvm/test_puzzle_compression.py +144 -0
  28. chia/_tests/clvm/test_puzzle_drivers.py +45 -0
  29. chia/_tests/clvm/test_puzzles.py +247 -0
  30. chia/_tests/clvm/test_singletons.py +540 -0
  31. chia/_tests/clvm/test_spend_sim.py +181 -0
  32. chia/_tests/cmds/__init__.py +0 -0
  33. chia/_tests/cmds/cmd_test_utils.py +472 -0
  34. chia/_tests/cmds/config.py +3 -0
  35. chia/_tests/cmds/conftest.py +23 -0
  36. chia/_tests/cmds/test_click_types.py +195 -0
  37. chia/_tests/cmds/test_cmd_framework.py +400 -0
  38. chia/_tests/cmds/test_cmds_util.py +97 -0
  39. chia/_tests/cmds/test_daemon.py +92 -0
  40. chia/_tests/cmds/test_farm_cmd.py +67 -0
  41. chia/_tests/cmds/test_show.py +116 -0
  42. chia/_tests/cmds/test_sim.py +207 -0
  43. chia/_tests/cmds/test_timelock_args.py +75 -0
  44. chia/_tests/cmds/test_tx_config_args.py +153 -0
  45. chia/_tests/cmds/testing_classes.py +59 -0
  46. chia/_tests/cmds/wallet/__init__.py +0 -0
  47. chia/_tests/cmds/wallet/test_coins.py +195 -0
  48. chia/_tests/cmds/wallet/test_consts.py +47 -0
  49. chia/_tests/cmds/wallet/test_dao.py +565 -0
  50. chia/_tests/cmds/wallet/test_did.py +403 -0
  51. chia/_tests/cmds/wallet/test_nft.py +470 -0
  52. chia/_tests/cmds/wallet/test_notifications.py +124 -0
  53. chia/_tests/cmds/wallet/test_offer.toffer +1 -0
  54. chia/_tests/cmds/wallet/test_tx_decorators.py +27 -0
  55. chia/_tests/cmds/wallet/test_vcs.py +376 -0
  56. chia/_tests/cmds/wallet/test_wallet.py +1126 -0
  57. chia/_tests/cmds/wallet/test_wallet_check.py +111 -0
  58. chia/_tests/conftest.py +1304 -0
  59. chia/_tests/connection_utils.py +124 -0
  60. chia/_tests/core/__init__.py +0 -0
  61. chia/_tests/core/cmds/__init__.py +0 -0
  62. chia/_tests/core/cmds/test_beta.py +382 -0
  63. chia/_tests/core/cmds/test_keys.py +1734 -0
  64. chia/_tests/core/cmds/test_wallet.py +126 -0
  65. chia/_tests/core/config.py +3 -0
  66. chia/_tests/core/consensus/__init__.py +0 -0
  67. chia/_tests/core/consensus/test_block_creation.py +56 -0
  68. chia/_tests/core/consensus/test_pot_iterations.py +117 -0
  69. chia/_tests/core/custom_types/__init__.py +0 -0
  70. chia/_tests/core/custom_types/test_coin.py +109 -0
  71. chia/_tests/core/custom_types/test_proof_of_space.py +144 -0
  72. chia/_tests/core/custom_types/test_spend_bundle.py +71 -0
  73. chia/_tests/core/daemon/__init__.py +0 -0
  74. chia/_tests/core/daemon/config.py +4 -0
  75. chia/_tests/core/daemon/test_daemon.py +2128 -0
  76. chia/_tests/core/daemon/test_daemon_register.py +109 -0
  77. chia/_tests/core/daemon/test_keychain_proxy.py +100 -0
  78. chia/_tests/core/data_layer/__init__.py +0 -0
  79. chia/_tests/core/data_layer/config.py +5 -0
  80. chia/_tests/core/data_layer/conftest.py +105 -0
  81. chia/_tests/core/data_layer/test_data_cli.py +57 -0
  82. chia/_tests/core/data_layer/test_data_layer.py +83 -0
  83. chia/_tests/core/data_layer/test_data_layer_util.py +219 -0
  84. chia/_tests/core/data_layer/test_data_rpc.py +3865 -0
  85. chia/_tests/core/data_layer/test_data_store.py +2423 -0
  86. chia/_tests/core/data_layer/test_data_store_schema.py +381 -0
  87. chia/_tests/core/data_layer/test_plugin.py +91 -0
  88. chia/_tests/core/data_layer/util.py +232 -0
  89. chia/_tests/core/farmer/__init__.py +0 -0
  90. chia/_tests/core/farmer/config.py +3 -0
  91. chia/_tests/core/farmer/test_farmer_api.py +101 -0
  92. chia/_tests/core/full_node/__init__.py +0 -0
  93. chia/_tests/core/full_node/config.py +4 -0
  94. chia/_tests/core/full_node/dos/__init__.py +0 -0
  95. chia/_tests/core/full_node/dos/config.py +3 -0
  96. chia/_tests/core/full_node/full_sync/__init__.py +0 -0
  97. chia/_tests/core/full_node/full_sync/config.py +4 -0
  98. chia/_tests/core/full_node/full_sync/test_full_sync.py +448 -0
  99. chia/_tests/core/full_node/ram_db.py +27 -0
  100. chia/_tests/core/full_node/stores/__init__.py +0 -0
  101. chia/_tests/core/full_node/stores/config.py +4 -0
  102. chia/_tests/core/full_node/stores/test_block_store.py +488 -0
  103. chia/_tests/core/full_node/stores/test_coin_store.py +888 -0
  104. chia/_tests/core/full_node/stores/test_full_node_store.py +1215 -0
  105. chia/_tests/core/full_node/stores/test_hint_store.py +230 -0
  106. chia/_tests/core/full_node/stores/test_sync_store.py +135 -0
  107. chia/_tests/core/full_node/test_address_manager.py +588 -0
  108. chia/_tests/core/full_node/test_block_height_map.py +556 -0
  109. chia/_tests/core/full_node/test_conditions.py +558 -0
  110. chia/_tests/core/full_node/test_full_node.py +2445 -0
  111. chia/_tests/core/full_node/test_generator_tools.py +82 -0
  112. chia/_tests/core/full_node/test_hint_management.py +104 -0
  113. chia/_tests/core/full_node/test_node_load.py +34 -0
  114. chia/_tests/core/full_node/test_performance.py +182 -0
  115. chia/_tests/core/full_node/test_subscriptions.py +492 -0
  116. chia/_tests/core/full_node/test_transactions.py +203 -0
  117. chia/_tests/core/full_node/test_tx_processing_queue.py +154 -0
  118. chia/_tests/core/large_block.py +2388 -0
  119. chia/_tests/core/make_block_generator.py +72 -0
  120. chia/_tests/core/mempool/__init__.py +0 -0
  121. chia/_tests/core/mempool/config.py +4 -0
  122. chia/_tests/core/mempool/test_mempool.py +3180 -0
  123. chia/_tests/core/mempool/test_mempool_fee_estimator.py +104 -0
  124. chia/_tests/core/mempool/test_mempool_fee_protocol.py +55 -0
  125. chia/_tests/core/mempool/test_mempool_item_queries.py +192 -0
  126. chia/_tests/core/mempool/test_mempool_manager.py +2054 -0
  127. chia/_tests/core/mempool/test_mempool_performance.py +65 -0
  128. chia/_tests/core/mempool/test_singleton_fast_forward.py +567 -0
  129. chia/_tests/core/node_height.py +28 -0
  130. chia/_tests/core/server/__init__.py +0 -0
  131. chia/_tests/core/server/config.py +3 -0
  132. chia/_tests/core/server/flood.py +82 -0
  133. chia/_tests/core/server/serve.py +132 -0
  134. chia/_tests/core/server/test_capabilities.py +68 -0
  135. chia/_tests/core/server/test_dos.py +320 -0
  136. chia/_tests/core/server/test_event_loop.py +109 -0
  137. chia/_tests/core/server/test_loop.py +290 -0
  138. chia/_tests/core/server/test_node_discovery.py +74 -0
  139. chia/_tests/core/server/test_rate_limits.py +370 -0
  140. chia/_tests/core/server/test_server.py +225 -0
  141. chia/_tests/core/server/test_upnp.py +8 -0
  142. chia/_tests/core/services/__init__.py +0 -0
  143. chia/_tests/core/services/config.py +3 -0
  144. chia/_tests/core/services/test_services.py +166 -0
  145. chia/_tests/core/ssl/__init__.py +0 -0
  146. chia/_tests/core/ssl/config.py +3 -0
  147. chia/_tests/core/ssl/test_ssl.py +198 -0
  148. chia/_tests/core/test_coins.py +33 -0
  149. chia/_tests/core/test_cost_calculation.py +314 -0
  150. chia/_tests/core/test_crawler.py +175 -0
  151. chia/_tests/core/test_crawler_rpc.py +53 -0
  152. chia/_tests/core/test_daemon_rpc.py +24 -0
  153. chia/_tests/core/test_db_conversion.py +129 -0
  154. chia/_tests/core/test_db_validation.py +161 -0
  155. chia/_tests/core/test_farmer_harvester_rpc.py +504 -0
  156. chia/_tests/core/test_filter.py +37 -0
  157. chia/_tests/core/test_full_node_rpc.py +794 -0
  158. chia/_tests/core/test_merkle_set.py +343 -0
  159. chia/_tests/core/test_program.py +49 -0
  160. chia/_tests/core/test_rpc_util.py +87 -0
  161. chia/_tests/core/test_seeder.py +308 -0
  162. chia/_tests/core/test_setproctitle.py +13 -0
  163. chia/_tests/core/util/__init__.py +0 -0
  164. chia/_tests/core/util/config.py +4 -0
  165. chia/_tests/core/util/test_block_cache.py +44 -0
  166. chia/_tests/core/util/test_cached_bls.py +57 -0
  167. chia/_tests/core/util/test_config.py +337 -0
  168. chia/_tests/core/util/test_file_keyring_synchronization.py +105 -0
  169. chia/_tests/core/util/test_files.py +391 -0
  170. chia/_tests/core/util/test_jsonify.py +146 -0
  171. chia/_tests/core/util/test_keychain.py +514 -0
  172. chia/_tests/core/util/test_keyring_wrapper.py +490 -0
  173. chia/_tests/core/util/test_lockfile.py +380 -0
  174. chia/_tests/core/util/test_log_exceptions.py +187 -0
  175. chia/_tests/core/util/test_lru_cache.py +56 -0
  176. chia/_tests/core/util/test_significant_bits.py +40 -0
  177. chia/_tests/core/util/test_streamable.py +883 -0
  178. chia/_tests/db/__init__.py +0 -0
  179. chia/_tests/db/test_db_wrapper.py +565 -0
  180. chia/_tests/environments/__init__.py +0 -0
  181. chia/_tests/environments/common.py +35 -0
  182. chia/_tests/environments/full_node.py +47 -0
  183. chia/_tests/environments/wallet.py +368 -0
  184. chia/_tests/ether.py +19 -0
  185. chia/_tests/farmer_harvester/__init__.py +0 -0
  186. chia/_tests/farmer_harvester/config.py +3 -0
  187. chia/_tests/farmer_harvester/test_farmer.py +1264 -0
  188. chia/_tests/farmer_harvester/test_farmer_harvester.py +292 -0
  189. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +130 -0
  190. chia/_tests/farmer_harvester/test_third_party_harvesters.py +501 -0
  191. chia/_tests/farmer_harvester/test_third_party_harvesters_data.json +29 -0
  192. chia/_tests/fee_estimation/__init__.py +0 -0
  193. chia/_tests/fee_estimation/config.py +3 -0
  194. chia/_tests/fee_estimation/test_fee_estimation_integration.py +262 -0
  195. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +287 -0
  196. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +145 -0
  197. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +146 -0
  198. chia/_tests/generator/__init__.py +0 -0
  199. chia/_tests/generator/puzzles/__init__.py +0 -0
  200. chia/_tests/generator/puzzles/test_generator_deserialize.clsp +3 -0
  201. chia/_tests/generator/puzzles/test_generator_deserialize.clsp.hex +1 -0
  202. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp +19 -0
  203. chia/_tests/generator/puzzles/test_multiple_generator_input_arguments.clsp.hex +1 -0
  204. chia/_tests/generator/test_compression.py +218 -0
  205. chia/_tests/generator/test_generator_types.py +44 -0
  206. chia/_tests/generator/test_rom.py +182 -0
  207. chia/_tests/plot_sync/__init__.py +0 -0
  208. chia/_tests/plot_sync/config.py +3 -0
  209. chia/_tests/plot_sync/test_delta.py +102 -0
  210. chia/_tests/plot_sync/test_plot_sync.py +617 -0
  211. chia/_tests/plot_sync/test_receiver.py +451 -0
  212. chia/_tests/plot_sync/test_sender.py +116 -0
  213. chia/_tests/plot_sync/test_sync_simulated.py +450 -0
  214. chia/_tests/plot_sync/util.py +67 -0
  215. chia/_tests/plotting/__init__.py +0 -0
  216. chia/_tests/plotting/config.py +3 -0
  217. chia/_tests/plotting/test_plot_manager.py +738 -0
  218. chia/_tests/plotting/util.py +13 -0
  219. chia/_tests/pools/__init__.py +0 -0
  220. chia/_tests/pools/config.py +5 -0
  221. chia/_tests/pools/test_pool_cmdline.py +23 -0
  222. chia/_tests/pools/test_pool_config.py +44 -0
  223. chia/_tests/pools/test_pool_puzzles_lifecycle.py +398 -0
  224. chia/_tests/pools/test_pool_rpc.py +1010 -0
  225. chia/_tests/pools/test_pool_wallet.py +201 -0
  226. chia/_tests/pools/test_wallet_pool_store.py +161 -0
  227. chia/_tests/process_junit.py +349 -0
  228. chia/_tests/rpc/__init__.py +0 -0
  229. chia/_tests/rpc/test_rpc_client.py +81 -0
  230. chia/_tests/simulation/__init__.py +0 -0
  231. chia/_tests/simulation/config.py +6 -0
  232. chia/_tests/simulation/test_simulation.py +501 -0
  233. chia/_tests/simulation/test_simulator.py +234 -0
  234. chia/_tests/simulation/test_start_simulator.py +106 -0
  235. chia/_tests/testconfig.py +13 -0
  236. chia/_tests/timelord/__init__.py +0 -0
  237. chia/_tests/timelord/config.py +3 -0
  238. chia/_tests/timelord/test_new_peak.py +437 -0
  239. chia/_tests/timelord/test_timelord.py +11 -0
  240. chia/_tests/tools/1315537.json +170 -0
  241. chia/_tests/tools/1315544.json +160 -0
  242. chia/_tests/tools/1315630.json +150 -0
  243. chia/_tests/tools/300000.json +105 -0
  244. chia/_tests/tools/442734.json +140 -0
  245. chia/_tests/tools/466212.json +130 -0
  246. chia/_tests/tools/__init__.py +0 -0
  247. chia/_tests/tools/config.py +5 -0
  248. chia/_tests/tools/test-blockchain-db.sqlite +0 -0
  249. chia/_tests/tools/test_full_sync.py +30 -0
  250. chia/_tests/tools/test_legacy_keyring.py +82 -0
  251. chia/_tests/tools/test_run_block.py +129 -0
  252. chia/_tests/util/__init__.py +0 -0
  253. chia/_tests/util/benchmark_cost.py +170 -0
  254. chia/_tests/util/benchmarks.py +154 -0
  255. chia/_tests/util/bip39_test_vectors.json +148 -0
  256. chia/_tests/util/blockchain.py +133 -0
  257. chia/_tests/util/blockchain_mock.py +132 -0
  258. chia/_tests/util/build_network_protocol_files.py +302 -0
  259. chia/_tests/util/clvm_generator.bin +0 -0
  260. chia/_tests/util/config.py +3 -0
  261. chia/_tests/util/constants.py +20 -0
  262. chia/_tests/util/db_connection.py +36 -0
  263. chia/_tests/util/full_sync.py +245 -0
  264. chia/_tests/util/gen_ssl_certs.py +115 -0
  265. chia/_tests/util/generator_tools_testing.py +47 -0
  266. chia/_tests/util/key_tool.py +37 -0
  267. chia/_tests/util/misc.py +722 -0
  268. chia/_tests/util/network_protocol_data.py +1074 -0
  269. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  270. chia/_tests/util/protocol_messages_json.py +2700 -0
  271. chia/_tests/util/rpc.py +23 -0
  272. chia/_tests/util/run_block.py +163 -0
  273. chia/_tests/util/setup_nodes.py +479 -0
  274. chia/_tests/util/split_managers.py +99 -0
  275. chia/_tests/util/temp_file.py +14 -0
  276. chia/_tests/util/test_action_scope.py +143 -0
  277. chia/_tests/util/test_async_pool.py +366 -0
  278. chia/_tests/util/test_build_job_matrix.py +43 -0
  279. chia/_tests/util/test_build_network_protocol_files.py +7 -0
  280. chia/_tests/util/test_chia_version.py +50 -0
  281. chia/_tests/util/test_collection.py +11 -0
  282. chia/_tests/util/test_condition_tools.py +231 -0
  283. chia/_tests/util/test_config.py +426 -0
  284. chia/_tests/util/test_dump_keyring.py +60 -0
  285. chia/_tests/util/test_errors.py +10 -0
  286. chia/_tests/util/test_full_block_utils.py +271 -0
  287. chia/_tests/util/test_installed.py +20 -0
  288. chia/_tests/util/test_limited_semaphore.py +52 -0
  289. chia/_tests/util/test_logging_filter.py +43 -0
  290. chia/_tests/util/test_misc.py +444 -0
  291. chia/_tests/util/test_network.py +74 -0
  292. chia/_tests/util/test_network_protocol_files.py +579 -0
  293. chia/_tests/util/test_network_protocol_json.py +266 -0
  294. chia/_tests/util/test_network_protocol_test.py +257 -0
  295. chia/_tests/util/test_paginator.py +72 -0
  296. chia/_tests/util/test_pprint.py +17 -0
  297. chia/_tests/util/test_priority_mutex.py +487 -0
  298. chia/_tests/util/test_recursive_replace.py +116 -0
  299. chia/_tests/util/test_replace_str_to_bytes.py +137 -0
  300. chia/_tests/util/test_service_groups.py +15 -0
  301. chia/_tests/util/test_ssl_check.py +31 -0
  302. chia/_tests/util/test_testnet_overrides.py +19 -0
  303. chia/_tests/util/test_tests_misc.py +38 -0
  304. chia/_tests/util/test_timing.py +37 -0
  305. chia/_tests/util/test_trusted_peer.py +51 -0
  306. chia/_tests/util/time_out_assert.py +154 -0
  307. chia/_tests/wallet/__init__.py +0 -0
  308. chia/_tests/wallet/cat_wallet/__init__.py +0 -0
  309. chia/_tests/wallet/cat_wallet/config.py +4 -0
  310. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +468 -0
  311. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +69 -0
  312. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +1738 -0
  313. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +291 -0
  314. chia/_tests/wallet/cat_wallet/test_trades.py +2578 -0
  315. chia/_tests/wallet/clawback/__init__.py +0 -0
  316. chia/_tests/wallet/clawback/config.py +3 -0
  317. chia/_tests/wallet/clawback/test_clawback_decorator.py +80 -0
  318. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +292 -0
  319. chia/_tests/wallet/clawback/test_clawback_metadata.py +51 -0
  320. chia/_tests/wallet/config.py +4 -0
  321. chia/_tests/wallet/conftest.py +217 -0
  322. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  323. chia/_tests/wallet/dao_wallet/config.py +3 -0
  324. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +1322 -0
  325. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +3488 -0
  326. chia/_tests/wallet/db_wallet/__init__.py +0 -0
  327. chia/_tests/wallet/db_wallet/config.py +3 -0
  328. chia/_tests/wallet/db_wallet/test_db_graftroot.py +143 -0
  329. chia/_tests/wallet/db_wallet/test_dl_offers.py +491 -0
  330. chia/_tests/wallet/db_wallet/test_dl_wallet.py +823 -0
  331. chia/_tests/wallet/did_wallet/__init__.py +0 -0
  332. chia/_tests/wallet/did_wallet/config.py +4 -0
  333. chia/_tests/wallet/did_wallet/test_did.py +1481 -0
  334. chia/_tests/wallet/nft_wallet/__init__.py +0 -0
  335. chia/_tests/wallet/nft_wallet/config.py +4 -0
  336. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1492 -0
  337. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +1014 -0
  338. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +376 -0
  339. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1209 -0
  340. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +172 -0
  341. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2558 -0
  342. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +70 -0
  343. chia/_tests/wallet/rpc/__init__.py +0 -0
  344. chia/_tests/wallet/rpc/config.py +4 -0
  345. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +287 -0
  346. chia/_tests/wallet/rpc/test_wallet_rpc.py +3106 -0
  347. chia/_tests/wallet/simple_sync/__init__.py +0 -0
  348. chia/_tests/wallet/simple_sync/config.py +3 -0
  349. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +719 -0
  350. chia/_tests/wallet/sync/__init__.py +0 -0
  351. chia/_tests/wallet/sync/config.py +4 -0
  352. chia/_tests/wallet/sync/test_wallet_sync.py +1529 -0
  353. chia/_tests/wallet/test_address_type.py +189 -0
  354. chia/_tests/wallet/test_bech32m.py +45 -0
  355. chia/_tests/wallet/test_clvm_streamable.py +244 -0
  356. chia/_tests/wallet/test_coin_selection.py +589 -0
  357. chia/_tests/wallet/test_conditions.py +388 -0
  358. chia/_tests/wallet/test_debug_spend_bundle.py +76 -0
  359. chia/_tests/wallet/test_new_wallet_protocol.py +1176 -0
  360. chia/_tests/wallet/test_nft_store.py +193 -0
  361. chia/_tests/wallet/test_notifications.py +196 -0
  362. chia/_tests/wallet/test_offer_parsing_performance.py +48 -0
  363. chia/_tests/wallet/test_puzzle_store.py +133 -0
  364. chia/_tests/wallet/test_sign_coin_spends.py +159 -0
  365. chia/_tests/wallet/test_signer_protocol.py +948 -0
  366. chia/_tests/wallet/test_singleton.py +122 -0
  367. chia/_tests/wallet/test_singleton_lifecycle_fast.py +772 -0
  368. chia/_tests/wallet/test_singleton_store.py +152 -0
  369. chia/_tests/wallet/test_taproot.py +19 -0
  370. chia/_tests/wallet/test_transaction_store.py +941 -0
  371. chia/_tests/wallet/test_util.py +181 -0
  372. chia/_tests/wallet/test_wallet.py +2139 -0
  373. chia/_tests/wallet/test_wallet_action_scope.py +85 -0
  374. chia/_tests/wallet/test_wallet_blockchain.py +113 -0
  375. chia/_tests/wallet/test_wallet_coin_store.py +1002 -0
  376. chia/_tests/wallet/test_wallet_interested_store.py +43 -0
  377. chia/_tests/wallet/test_wallet_key_val_store.py +40 -0
  378. chia/_tests/wallet/test_wallet_node.py +783 -0
  379. chia/_tests/wallet/test_wallet_retry.py +95 -0
  380. chia/_tests/wallet/test_wallet_state_manager.py +252 -0
  381. chia/_tests/wallet/test_wallet_test_framework.py +275 -0
  382. chia/_tests/wallet/test_wallet_trade_store.py +218 -0
  383. chia/_tests/wallet/test_wallet_user_store.py +34 -0
  384. chia/_tests/wallet/test_wallet_utils.py +155 -0
  385. chia/_tests/wallet/vc_wallet/__init__.py +0 -0
  386. chia/_tests/wallet/vc_wallet/config.py +3 -0
  387. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +70 -0
  388. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +883 -0
  389. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +801 -0
  390. chia/_tests/wallet/wallet_block_tools.py +327 -0
  391. chia/_tests/weight_proof/__init__.py +0 -0
  392. chia/_tests/weight_proof/config.py +3 -0
  393. chia/_tests/weight_proof/test_weight_proof.py +528 -0
  394. chia/clvm/__init__.py +0 -0
  395. chia/clvm/spend_sim.py +488 -0
  396. chia/cmds/__init__.py +0 -0
  397. chia/cmds/beta.py +183 -0
  398. chia/cmds/beta_funcs.py +133 -0
  399. chia/cmds/check_wallet_db.py +418 -0
  400. chia/cmds/chia.py +143 -0
  401. chia/cmds/cmd_classes.py +315 -0
  402. chia/cmds/cmds_util.py +498 -0
  403. chia/cmds/coin_funcs.py +260 -0
  404. chia/cmds/coins.py +220 -0
  405. chia/cmds/completion.py +49 -0
  406. chia/cmds/configure.py +331 -0
  407. chia/cmds/dao.py +1008 -0
  408. chia/cmds/dao_funcs.py +576 -0
  409. chia/cmds/data.py +707 -0
  410. chia/cmds/data_funcs.py +380 -0
  411. chia/cmds/db.py +86 -0
  412. chia/cmds/db_backup_func.py +77 -0
  413. chia/cmds/db_upgrade_func.py +452 -0
  414. chia/cmds/db_validate_func.py +184 -0
  415. chia/cmds/dev.py +16 -0
  416. chia/cmds/farm.py +87 -0
  417. chia/cmds/farm_funcs.py +207 -0
  418. chia/cmds/init.py +70 -0
  419. chia/cmds/init_funcs.py +367 -0
  420. chia/cmds/installers.py +129 -0
  421. chia/cmds/keys.py +510 -0
  422. chia/cmds/keys_funcs.py +864 -0
  423. chia/cmds/netspace.py +47 -0
  424. chia/cmds/netspace_funcs.py +53 -0
  425. chia/cmds/options.py +32 -0
  426. chia/cmds/param_types.py +228 -0
  427. chia/cmds/passphrase.py +130 -0
  428. chia/cmds/passphrase_funcs.py +346 -0
  429. chia/cmds/peer.py +50 -0
  430. chia/cmds/peer_funcs.py +129 -0
  431. chia/cmds/plotnft.py +206 -0
  432. chia/cmds/plotnft_funcs.py +374 -0
  433. chia/cmds/plots.py +222 -0
  434. chia/cmds/plotters.py +17 -0
  435. chia/cmds/rpc.py +188 -0
  436. chia/cmds/show.py +71 -0
  437. chia/cmds/show_funcs.py +214 -0
  438. chia/cmds/signer.py +304 -0
  439. chia/cmds/sim.py +217 -0
  440. chia/cmds/sim_funcs.py +509 -0
  441. chia/cmds/start.py +24 -0
  442. chia/cmds/start_funcs.py +112 -0
  443. chia/cmds/stop.py +61 -0
  444. chia/cmds/units.py +11 -0
  445. chia/cmds/wallet.py +1745 -0
  446. chia/cmds/wallet_funcs.py +1800 -0
  447. chia/consensus/__init__.py +0 -0
  448. chia/consensus/block_body_validation.py +515 -0
  449. chia/consensus/block_creation.py +525 -0
  450. chia/consensus/block_header_validation.py +1064 -0
  451. chia/consensus/block_record.py +32 -0
  452. chia/consensus/block_rewards.py +53 -0
  453. chia/consensus/block_root_validation.py +46 -0
  454. chia/consensus/blockchain.py +1100 -0
  455. chia/consensus/blockchain_interface.py +56 -0
  456. chia/consensus/coinbase.py +30 -0
  457. chia/consensus/condition_costs.py +9 -0
  458. chia/consensus/constants.py +49 -0
  459. chia/consensus/cost_calculator.py +15 -0
  460. chia/consensus/default_constants.py +90 -0
  461. chia/consensus/deficit.py +55 -0
  462. chia/consensus/difficulty_adjustment.py +412 -0
  463. chia/consensus/find_fork_point.py +111 -0
  464. chia/consensus/full_block_to_block_record.py +167 -0
  465. chia/consensus/get_block_challenge.py +106 -0
  466. chia/consensus/get_block_generator.py +26 -0
  467. chia/consensus/make_sub_epoch_summary.py +210 -0
  468. chia/consensus/multiprocess_validation.py +365 -0
  469. chia/consensus/pos_quality.py +19 -0
  470. chia/consensus/pot_iterations.py +67 -0
  471. chia/consensus/puzzles/__init__.py +0 -0
  472. chia/consensus/puzzles/chialisp_deserialisation.clsp +69 -0
  473. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +1 -0
  474. chia/consensus/puzzles/rom_bootstrap_generator.clsp +37 -0
  475. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +1 -0
  476. chia/consensus/vdf_info_computation.py +156 -0
  477. chia/daemon/__init__.py +0 -0
  478. chia/daemon/client.py +233 -0
  479. chia/daemon/keychain_proxy.py +501 -0
  480. chia/daemon/keychain_server.py +365 -0
  481. chia/daemon/server.py +1616 -0
  482. chia/daemon/windows_signal.py +56 -0
  483. chia/data_layer/__init__.py +0 -0
  484. chia/data_layer/data_layer.py +1303 -0
  485. chia/data_layer/data_layer_api.py +25 -0
  486. chia/data_layer/data_layer_errors.py +50 -0
  487. chia/data_layer/data_layer_server.py +170 -0
  488. chia/data_layer/data_layer_util.py +985 -0
  489. chia/data_layer/data_layer_wallet.py +1315 -0
  490. chia/data_layer/data_store.py +2267 -0
  491. chia/data_layer/dl_wallet_store.py +407 -0
  492. chia/data_layer/download_data.py +389 -0
  493. chia/data_layer/puzzles/__init__.py +0 -0
  494. chia/data_layer/puzzles/graftroot_dl_offers.clsp +100 -0
  495. chia/data_layer/puzzles/graftroot_dl_offers.clsp.hex +1 -0
  496. chia/data_layer/s3_plugin_config.yml +33 -0
  497. chia/data_layer/s3_plugin_service.py +468 -0
  498. chia/data_layer/util/__init__.py +0 -0
  499. chia/data_layer/util/benchmark.py +108 -0
  500. chia/data_layer/util/plugin.py +41 -0
  501. chia/farmer/__init__.py +0 -0
  502. chia/farmer/farmer.py +920 -0
  503. chia/farmer/farmer_api.py +814 -0
  504. chia/full_node/__init__.py +0 -0
  505. chia/full_node/bitcoin_fee_estimator.py +85 -0
  506. chia/full_node/block_height_map.py +271 -0
  507. chia/full_node/block_store.py +570 -0
  508. chia/full_node/bundle_tools.py +19 -0
  509. chia/full_node/coin_store.py +646 -0
  510. chia/full_node/fee_estimate.py +54 -0
  511. chia/full_node/fee_estimate_store.py +24 -0
  512. chia/full_node/fee_estimation.py +93 -0
  513. chia/full_node/fee_estimator.py +90 -0
  514. chia/full_node/fee_estimator_constants.py +38 -0
  515. chia/full_node/fee_estimator_interface.py +42 -0
  516. chia/full_node/fee_history.py +26 -0
  517. chia/full_node/fee_tracker.py +564 -0
  518. chia/full_node/full_node.py +3052 -0
  519. chia/full_node/full_node_api.py +1974 -0
  520. chia/full_node/full_node_store.py +1033 -0
  521. chia/full_node/hint_management.py +56 -0
  522. chia/full_node/hint_store.py +94 -0
  523. chia/full_node/mempool.py +583 -0
  524. chia/full_node/mempool_check_conditions.py +177 -0
  525. chia/full_node/mempool_manager.py +858 -0
  526. chia/full_node/pending_tx_cache.py +112 -0
  527. chia/full_node/puzzles/__init__.py +0 -0
  528. chia/full_node/puzzles/block_program_zero.clsp +14 -0
  529. chia/full_node/puzzles/block_program_zero.clsp.hex +1 -0
  530. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +5 -0
  531. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +1 -0
  532. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +7 -0
  533. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +1 -0
  534. chia/full_node/puzzles/decompress_puzzle.clsp +6 -0
  535. chia/full_node/puzzles/decompress_puzzle.clsp.hex +1 -0
  536. chia/full_node/signage_point.py +16 -0
  537. chia/full_node/subscriptions.py +248 -0
  538. chia/full_node/sync_store.py +145 -0
  539. chia/full_node/tx_processing_queue.py +78 -0
  540. chia/full_node/weight_proof.py +1719 -0
  541. chia/harvester/__init__.py +0 -0
  542. chia/harvester/harvester.py +271 -0
  543. chia/harvester/harvester_api.py +374 -0
  544. chia/introducer/__init__.py +0 -0
  545. chia/introducer/introducer.py +120 -0
  546. chia/introducer/introducer_api.py +64 -0
  547. chia/legacy/__init__.py +0 -0
  548. chia/legacy/keyring.py +154 -0
  549. chia/plot_sync/__init__.py +0 -0
  550. chia/plot_sync/delta.py +61 -0
  551. chia/plot_sync/exceptions.py +56 -0
  552. chia/plot_sync/receiver.py +385 -0
  553. chia/plot_sync/sender.py +337 -0
  554. chia/plot_sync/util.py +43 -0
  555. chia/plotters/__init__.py +0 -0
  556. chia/plotters/bladebit.py +388 -0
  557. chia/plotters/chiapos.py +63 -0
  558. chia/plotters/madmax.py +224 -0
  559. chia/plotters/plotters.py +577 -0
  560. chia/plotters/plotters_util.py +131 -0
  561. chia/plotting/__init__.py +0 -0
  562. chia/plotting/cache.py +212 -0
  563. chia/plotting/check_plots.py +283 -0
  564. chia/plotting/create_plots.py +278 -0
  565. chia/plotting/manager.py +436 -0
  566. chia/plotting/util.py +324 -0
  567. chia/pools/__init__.py +0 -0
  568. chia/pools/pool_config.py +110 -0
  569. chia/pools/pool_puzzles.py +459 -0
  570. chia/pools/pool_wallet.py +926 -0
  571. chia/pools/pool_wallet_info.py +118 -0
  572. chia/pools/puzzles/__init__.py +0 -0
  573. chia/pools/puzzles/pool_member_innerpuz.clsp +70 -0
  574. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +1 -0
  575. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +69 -0
  576. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +1 -0
  577. chia/protocols/__init__.py +0 -0
  578. chia/protocols/farmer_protocol.py +102 -0
  579. chia/protocols/full_node_protocol.py +219 -0
  580. chia/protocols/harvester_protocol.py +216 -0
  581. chia/protocols/introducer_protocol.py +26 -0
  582. chia/protocols/pool_protocol.py +177 -0
  583. chia/protocols/protocol_message_types.py +139 -0
  584. chia/protocols/protocol_state_machine.py +87 -0
  585. chia/protocols/protocol_timing.py +7 -0
  586. chia/protocols/shared_protocol.py +86 -0
  587. chia/protocols/timelord_protocol.py +93 -0
  588. chia/protocols/wallet_protocol.py +401 -0
  589. chia/py.typed +0 -0
  590. chia/rpc/__init__.py +0 -0
  591. chia/rpc/crawler_rpc_api.py +75 -0
  592. chia/rpc/data_layer_rpc_api.py +639 -0
  593. chia/rpc/data_layer_rpc_client.py +188 -0
  594. chia/rpc/data_layer_rpc_util.py +62 -0
  595. chia/rpc/farmer_rpc_api.py +360 -0
  596. chia/rpc/farmer_rpc_client.py +86 -0
  597. chia/rpc/full_node_rpc_api.py +954 -0
  598. chia/rpc/full_node_rpc_client.py +292 -0
  599. chia/rpc/harvester_rpc_api.py +136 -0
  600. chia/rpc/harvester_rpc_client.py +54 -0
  601. chia/rpc/rpc_client.py +144 -0
  602. chia/rpc/rpc_server.py +447 -0
  603. chia/rpc/timelord_rpc_api.py +27 -0
  604. chia/rpc/util.py +293 -0
  605. chia/rpc/wallet_request_types.py +688 -0
  606. chia/rpc/wallet_rpc_api.py +4779 -0
  607. chia/rpc/wallet_rpc_client.py +1844 -0
  608. chia/seeder/__init__.py +0 -0
  609. chia/seeder/crawl_store.py +427 -0
  610. chia/seeder/crawler.py +423 -0
  611. chia/seeder/crawler_api.py +129 -0
  612. chia/seeder/dns_server.py +544 -0
  613. chia/seeder/peer_record.py +146 -0
  614. chia/seeder/start_crawler.py +88 -0
  615. chia/server/__init__.py +0 -0
  616. chia/server/address_manager.py +658 -0
  617. chia/server/address_manager_store.py +237 -0
  618. chia/server/api_protocol.py +11 -0
  619. chia/server/capabilities.py +24 -0
  620. chia/server/chia_policy.py +345 -0
  621. chia/server/introducer_peers.py +76 -0
  622. chia/server/node_discovery.py +718 -0
  623. chia/server/outbound_message.py +33 -0
  624. chia/server/rate_limit_numbers.py +204 -0
  625. chia/server/rate_limits.py +113 -0
  626. chia/server/server.py +720 -0
  627. chia/server/signal_handlers.py +117 -0
  628. chia/server/ssl_context.py +32 -0
  629. chia/server/start_data_layer.py +137 -0
  630. chia/server/start_farmer.py +86 -0
  631. chia/server/start_full_node.py +106 -0
  632. chia/server/start_harvester.py +80 -0
  633. chia/server/start_introducer.py +69 -0
  634. chia/server/start_service.py +328 -0
  635. chia/server/start_timelord.py +82 -0
  636. chia/server/start_wallet.py +109 -0
  637. chia/server/upnp.py +117 -0
  638. chia/server/ws_connection.py +752 -0
  639. chia/simulator/__init__.py +0 -0
  640. chia/simulator/block_tools.py +2053 -0
  641. chia/simulator/full_node_simulator.py +802 -0
  642. chia/simulator/keyring.py +128 -0
  643. chia/simulator/setup_services.py +505 -0
  644. chia/simulator/simulator_constants.py +13 -0
  645. chia/simulator/simulator_full_node_rpc_api.py +101 -0
  646. chia/simulator/simulator_full_node_rpc_client.py +62 -0
  647. chia/simulator/simulator_protocol.py +29 -0
  648. chia/simulator/simulator_test_tools.py +163 -0
  649. chia/simulator/socket.py +27 -0
  650. chia/simulator/ssl_certs.py +114 -0
  651. chia/simulator/ssl_certs_1.py +699 -0
  652. chia/simulator/ssl_certs_10.py +699 -0
  653. chia/simulator/ssl_certs_2.py +699 -0
  654. chia/simulator/ssl_certs_3.py +699 -0
  655. chia/simulator/ssl_certs_4.py +699 -0
  656. chia/simulator/ssl_certs_5.py +699 -0
  657. chia/simulator/ssl_certs_6.py +699 -0
  658. chia/simulator/ssl_certs_7.py +699 -0
  659. chia/simulator/ssl_certs_8.py +699 -0
  660. chia/simulator/ssl_certs_9.py +699 -0
  661. chia/simulator/start_simulator.py +135 -0
  662. chia/simulator/wallet_tools.py +245 -0
  663. chia/ssl/__init__.py +0 -0
  664. chia/ssl/chia_ca.crt +19 -0
  665. chia/ssl/chia_ca.key +28 -0
  666. chia/ssl/create_ssl.py +249 -0
  667. chia/ssl/dst_root_ca.pem +20 -0
  668. chia/timelord/__init__.py +0 -0
  669. chia/timelord/iters_from_block.py +50 -0
  670. chia/timelord/timelord.py +1202 -0
  671. chia/timelord/timelord_api.py +132 -0
  672. chia/timelord/timelord_launcher.py +188 -0
  673. chia/timelord/timelord_state.py +244 -0
  674. chia/timelord/types.py +22 -0
  675. chia/types/__init__.py +0 -0
  676. chia/types/aliases.py +35 -0
  677. chia/types/block_protocol.py +20 -0
  678. chia/types/blockchain_format/__init__.py +0 -0
  679. chia/types/blockchain_format/classgroup.py +5 -0
  680. chia/types/blockchain_format/coin.py +28 -0
  681. chia/types/blockchain_format/foliage.py +8 -0
  682. chia/types/blockchain_format/pool_target.py +5 -0
  683. chia/types/blockchain_format/program.py +270 -0
  684. chia/types/blockchain_format/proof_of_space.py +135 -0
  685. chia/types/blockchain_format/reward_chain_block.py +6 -0
  686. chia/types/blockchain_format/serialized_program.py +5 -0
  687. chia/types/blockchain_format/sized_bytes.py +11 -0
  688. chia/types/blockchain_format/slots.py +9 -0
  689. chia/types/blockchain_format/sub_epoch_summary.py +5 -0
  690. chia/types/blockchain_format/tree_hash.py +72 -0
  691. chia/types/blockchain_format/vdf.py +86 -0
  692. chia/types/clvm_cost.py +13 -0
  693. chia/types/coin_record.py +43 -0
  694. chia/types/coin_spend.py +115 -0
  695. chia/types/condition_opcodes.py +73 -0
  696. chia/types/condition_with_args.py +17 -0
  697. chia/types/eligible_coin_spends.py +364 -0
  698. chia/types/end_of_slot_bundle.py +5 -0
  699. chia/types/fee_rate.py +38 -0
  700. chia/types/full_block.py +5 -0
  701. chia/types/generator_types.py +14 -0
  702. chia/types/header_block.py +5 -0
  703. chia/types/internal_mempool_item.py +19 -0
  704. chia/types/mempool_inclusion_status.py +9 -0
  705. chia/types/mempool_item.py +85 -0
  706. chia/types/mempool_submission_status.py +30 -0
  707. chia/types/mojos.py +7 -0
  708. chia/types/peer_info.py +64 -0
  709. chia/types/signing_mode.py +29 -0
  710. chia/types/spend_bundle.py +31 -0
  711. chia/types/spend_bundle_conditions.py +7 -0
  712. chia/types/transaction_queue_entry.py +55 -0
  713. chia/types/unfinished_block.py +5 -0
  714. chia/types/unfinished_header_block.py +37 -0
  715. chia/types/weight_proof.py +50 -0
  716. chia/util/__init__.py +0 -0
  717. chia/util/action_scope.py +168 -0
  718. chia/util/api_decorators.py +89 -0
  719. chia/util/async_pool.py +224 -0
  720. chia/util/augmented_chain.py +130 -0
  721. chia/util/batches.py +39 -0
  722. chia/util/bech32m.py +123 -0
  723. chia/util/beta_metrics.py +118 -0
  724. chia/util/block_cache.py +56 -0
  725. chia/util/byte_types.py +10 -0
  726. chia/util/check_fork_next_block.py +32 -0
  727. chia/util/chia_logging.py +124 -0
  728. chia/util/chia_version.py +33 -0
  729. chia/util/collection.py +17 -0
  730. chia/util/condition_tools.py +201 -0
  731. chia/util/config.py +366 -0
  732. chia/util/cpu.py +20 -0
  733. chia/util/db_synchronous.py +21 -0
  734. chia/util/db_version.py +30 -0
  735. chia/util/db_wrapper.py +427 -0
  736. chia/util/default_root.py +10 -0
  737. chia/util/dump_keyring.py +93 -0
  738. chia/util/english.txt +2048 -0
  739. chia/util/errors.py +351 -0
  740. chia/util/file_keyring.py +480 -0
  741. chia/util/files.py +95 -0
  742. chia/util/full_block_utils.py +321 -0
  743. chia/util/generator_tools.py +62 -0
  744. chia/util/hash.py +29 -0
  745. chia/util/initial-config.yaml +675 -0
  746. chia/util/inline_executor.py +24 -0
  747. chia/util/ints.py +19 -0
  748. chia/util/json_util.py +41 -0
  749. chia/util/keychain.py +673 -0
  750. chia/util/keyring_wrapper.py +266 -0
  751. chia/util/limited_semaphore.py +39 -0
  752. chia/util/lock.py +47 -0
  753. chia/util/log_exceptions.py +29 -0
  754. chia/util/logging.py +34 -0
  755. chia/util/lru_cache.py +29 -0
  756. chia/util/math.py +20 -0
  757. chia/util/network.py +240 -0
  758. chia/util/paginator.py +46 -0
  759. chia/util/path.py +29 -0
  760. chia/util/permissions.py +19 -0
  761. chia/util/pprint.py +40 -0
  762. chia/util/prev_transaction_block.py +23 -0
  763. chia/util/priority_mutex.py +92 -0
  764. chia/util/profiler.py +194 -0
  765. chia/util/recursive_replace.py +22 -0
  766. chia/util/safe_cancel_task.py +14 -0
  767. chia/util/service_groups.py +47 -0
  768. chia/util/setproctitle.py +20 -0
  769. chia/util/significant_bits.py +30 -0
  770. chia/util/ssl_check.py +213 -0
  771. chia/util/streamable.py +654 -0
  772. chia/util/task_timing.py +378 -0
  773. chia/util/timing.py +64 -0
  774. chia/util/vdf_prover.py +31 -0
  775. chia/util/ws_message.py +66 -0
  776. chia/wallet/__init__.py +0 -0
  777. chia/wallet/cat_wallet/__init__.py +0 -0
  778. chia/wallet/cat_wallet/cat_constants.py +75 -0
  779. chia/wallet/cat_wallet/cat_info.py +47 -0
  780. chia/wallet/cat_wallet/cat_outer_puzzle.py +120 -0
  781. chia/wallet/cat_wallet/cat_utils.py +163 -0
  782. chia/wallet/cat_wallet/cat_wallet.py +869 -0
  783. chia/wallet/cat_wallet/dao_cat_info.py +28 -0
  784. chia/wallet/cat_wallet/dao_cat_wallet.py +669 -0
  785. chia/wallet/cat_wallet/lineage_store.py +74 -0
  786. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  787. chia/wallet/cat_wallet/puzzles/cat_truths.clib +31 -0
  788. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +397 -0
  789. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +1 -0
  790. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +25 -0
  791. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +1 -0
  792. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +15 -0
  793. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +1 -0
  794. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +26 -0
  795. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +1 -0
  796. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +42 -0
  797. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +1 -0
  798. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +24 -0
  799. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +1 -0
  800. chia/wallet/coin_selection.py +188 -0
  801. chia/wallet/conditions.py +1326 -0
  802. chia/wallet/dao_wallet/__init__.py +0 -0
  803. chia/wallet/dao_wallet/dao_info.py +61 -0
  804. chia/wallet/dao_wallet/dao_utils.py +810 -0
  805. chia/wallet/dao_wallet/dao_wallet.py +2121 -0
  806. chia/wallet/db_wallet/__init__.py +0 -0
  807. chia/wallet/db_wallet/db_wallet_puzzles.py +107 -0
  808. chia/wallet/derivation_record.py +30 -0
  809. chia/wallet/derive_keys.py +146 -0
  810. chia/wallet/did_wallet/__init__.py +0 -0
  811. chia/wallet/did_wallet/did_info.py +39 -0
  812. chia/wallet/did_wallet/did_wallet.py +1485 -0
  813. chia/wallet/did_wallet/did_wallet_puzzles.py +220 -0
  814. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  815. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +135 -0
  816. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +1 -0
  817. chia/wallet/driver_protocol.py +26 -0
  818. chia/wallet/key_val_store.py +55 -0
  819. chia/wallet/lineage_proof.py +58 -0
  820. chia/wallet/nft_wallet/__init__.py +0 -0
  821. chia/wallet/nft_wallet/metadata_outer_puzzle.py +92 -0
  822. chia/wallet/nft_wallet/nft_info.py +120 -0
  823. chia/wallet/nft_wallet/nft_puzzles.py +305 -0
  824. chia/wallet/nft_wallet/nft_wallet.py +1686 -0
  825. chia/wallet/nft_wallet/ownership_outer_puzzle.py +101 -0
  826. chia/wallet/nft_wallet/puzzles/__init__.py +0 -0
  827. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp +6 -0
  828. chia/wallet/nft_wallet/puzzles/create_nft_launcher_from_did.clsp.hex +1 -0
  829. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp +6 -0
  830. chia/wallet/nft_wallet/puzzles/nft_intermediate_launcher.clsp.hex +1 -0
  831. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp +30 -0
  832. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_default.clsp.hex +1 -0
  833. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp +28 -0
  834. chia/wallet/nft_wallet/puzzles/nft_metadata_updater_updateable.clsp.hex +1 -0
  835. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp +100 -0
  836. chia/wallet/nft_wallet/puzzles/nft_ownership_layer.clsp.hex +1 -0
  837. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp +78 -0
  838. chia/wallet/nft_wallet/puzzles/nft_ownership_transfer_program_one_way_claim_with_royalties.clsp.hex +1 -0
  839. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp +74 -0
  840. chia/wallet/nft_wallet/puzzles/nft_state_layer.clsp.hex +1 -0
  841. chia/wallet/nft_wallet/singleton_outer_puzzle.py +101 -0
  842. chia/wallet/nft_wallet/transfer_program_puzzle.py +82 -0
  843. chia/wallet/nft_wallet/uncurry_nft.py +217 -0
  844. chia/wallet/notification_manager.py +117 -0
  845. chia/wallet/notification_store.py +178 -0
  846. chia/wallet/outer_puzzles.py +84 -0
  847. chia/wallet/payment.py +34 -0
  848. chia/wallet/puzzle_drivers.py +118 -0
  849. chia/wallet/puzzles/__init__.py +0 -0
  850. chia/wallet/puzzles/augmented_condition.clsp +13 -0
  851. chia/wallet/puzzles/augmented_condition.clsp.hex +1 -0
  852. chia/wallet/puzzles/clawback/__init__.py +0 -0
  853. chia/wallet/puzzles/clawback/drivers.py +188 -0
  854. chia/wallet/puzzles/clawback/metadata.py +38 -0
  855. chia/wallet/puzzles/clawback/puzzle_decorator.py +67 -0
  856. chia/wallet/puzzles/condition_codes.clib +77 -0
  857. chia/wallet/puzzles/curry-and-treehash.clib +102 -0
  858. chia/wallet/puzzles/curry.clib +135 -0
  859. chia/wallet/puzzles/curry_by_index.clib +16 -0
  860. chia/wallet/puzzles/dao_cat_eve.clsp +17 -0
  861. chia/wallet/puzzles/dao_cat_eve.clsp.hex +1 -0
  862. chia/wallet/puzzles/dao_cat_launcher.clsp +36 -0
  863. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +1 -0
  864. chia/wallet/puzzles/dao_finished_state.clsp +35 -0
  865. chia/wallet/puzzles/dao_finished_state.clsp.hex +1 -0
  866. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +1 -0
  867. chia/wallet/puzzles/dao_lockup.clsp +288 -0
  868. chia/wallet/puzzles/dao_lockup.clsp.hex +1 -0
  869. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +1 -0
  870. chia/wallet/puzzles/dao_proposal.clsp +377 -0
  871. chia/wallet/puzzles/dao_proposal.clsp.hex +1 -0
  872. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +1 -0
  873. chia/wallet/puzzles/dao_proposal_timer.clsp +78 -0
  874. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +1 -0
  875. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +1 -0
  876. chia/wallet/puzzles/dao_proposal_validator.clsp +87 -0
  877. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +1 -0
  878. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +1 -0
  879. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +240 -0
  880. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +1 -0
  881. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +1 -0
  882. chia/wallet/puzzles/dao_treasury.clsp +115 -0
  883. chia/wallet/puzzles/dao_treasury.clsp.hex +1 -0
  884. chia/wallet/puzzles/dao_update_proposal.clsp +44 -0
  885. chia/wallet/puzzles/dao_update_proposal.clsp.hex +1 -0
  886. chia/wallet/puzzles/deployed_puzzle_hashes.json +67 -0
  887. chia/wallet/puzzles/json.clib +25 -0
  888. chia/wallet/puzzles/load_clvm.py +162 -0
  889. chia/wallet/puzzles/merkle_utils.clib +18 -0
  890. chia/wallet/puzzles/notification.clsp +7 -0
  891. chia/wallet/puzzles/notification.clsp.hex +1 -0
  892. chia/wallet/puzzles/p2_1_of_n.clsp +22 -0
  893. chia/wallet/puzzles/p2_1_of_n.clsp.hex +1 -0
  894. chia/wallet/puzzles/p2_conditions.clsp +3 -0
  895. chia/wallet/puzzles/p2_conditions.clsp.hex +1 -0
  896. chia/wallet/puzzles/p2_conditions.py +27 -0
  897. chia/wallet/puzzles/p2_delegated_conditions.clsp +18 -0
  898. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +1 -0
  899. chia/wallet/puzzles/p2_delegated_conditions.py +22 -0
  900. chia/wallet/puzzles/p2_delegated_puzzle.clsp +19 -0
  901. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +1 -0
  902. chia/wallet/puzzles/p2_delegated_puzzle.py +35 -0
  903. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +91 -0
  904. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +1 -0
  905. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +161 -0
  906. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +108 -0
  907. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +1 -0
  908. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +22 -0
  909. chia/wallet/puzzles/p2_parent.clsp +19 -0
  910. chia/wallet/puzzles/p2_parent.clsp.hex +1 -0
  911. chia/wallet/puzzles/p2_puzzle_hash.clsp +18 -0
  912. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +1 -0
  913. chia/wallet/puzzles/p2_puzzle_hash.py +28 -0
  914. chia/wallet/puzzles/p2_singleton.clsp +30 -0
  915. chia/wallet/puzzles/p2_singleton.clsp.hex +1 -0
  916. chia/wallet/puzzles/p2_singleton_aggregator.clsp +81 -0
  917. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +1 -0
  918. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +50 -0
  919. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +1 -0
  920. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +47 -0
  921. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +1 -0
  922. chia/wallet/puzzles/puzzle_utils.py +34 -0
  923. chia/wallet/puzzles/settlement_payments.clsp +49 -0
  924. chia/wallet/puzzles/settlement_payments.clsp.hex +1 -0
  925. chia/wallet/puzzles/sha256tree.clib +11 -0
  926. chia/wallet/puzzles/singleton_launcher.clsp +16 -0
  927. chia/wallet/puzzles/singleton_launcher.clsp.hex +1 -0
  928. chia/wallet/puzzles/singleton_top_layer.clsp +177 -0
  929. chia/wallet/puzzles/singleton_top_layer.clsp.hex +1 -0
  930. chia/wallet/puzzles/singleton_top_layer.py +295 -0
  931. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +107 -0
  932. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +1 -0
  933. chia/wallet/puzzles/singleton_top_layer_v1_1.py +344 -0
  934. chia/wallet/puzzles/singleton_truths.clib +21 -0
  935. chia/wallet/puzzles/tails.py +344 -0
  936. chia/wallet/puzzles/utility_macros.clib +48 -0
  937. chia/wallet/signer_protocol.py +126 -0
  938. chia/wallet/singleton.py +106 -0
  939. chia/wallet/singleton_record.py +30 -0
  940. chia/wallet/trade_manager.py +1088 -0
  941. chia/wallet/trade_record.py +67 -0
  942. chia/wallet/trading/__init__.py +0 -0
  943. chia/wallet/trading/offer.py +703 -0
  944. chia/wallet/trading/trade_status.py +13 -0
  945. chia/wallet/trading/trade_store.py +526 -0
  946. chia/wallet/transaction_record.py +143 -0
  947. chia/wallet/transaction_sorting.py +14 -0
  948. chia/wallet/uncurried_puzzle.py +17 -0
  949. chia/wallet/util/__init__.py +0 -0
  950. chia/wallet/util/address_type.py +55 -0
  951. chia/wallet/util/blind_signer_tl.py +168 -0
  952. chia/wallet/util/clvm_streamable.py +203 -0
  953. chia/wallet/util/compute_hints.py +66 -0
  954. chia/wallet/util/compute_memos.py +45 -0
  955. chia/wallet/util/curry_and_treehash.py +90 -0
  956. chia/wallet/util/debug_spend_bundle.py +234 -0
  957. chia/wallet/util/merkle_tree.py +100 -0
  958. chia/wallet/util/merkle_utils.py +102 -0
  959. chia/wallet/util/new_peak_queue.py +82 -0
  960. chia/wallet/util/notifications.py +12 -0
  961. chia/wallet/util/peer_request_cache.py +174 -0
  962. chia/wallet/util/puzzle_compression.py +96 -0
  963. chia/wallet/util/puzzle_decorator.py +100 -0
  964. chia/wallet/util/puzzle_decorator_type.py +7 -0
  965. chia/wallet/util/query_filter.py +60 -0
  966. chia/wallet/util/transaction_type.py +23 -0
  967. chia/wallet/util/tx_config.py +158 -0
  968. chia/wallet/util/wallet_sync_utils.py +348 -0
  969. chia/wallet/util/wallet_types.py +65 -0
  970. chia/wallet/vc_wallet/__init__.py +0 -0
  971. chia/wallet/vc_wallet/cr_cat_drivers.py +663 -0
  972. chia/wallet/vc_wallet/cr_cat_wallet.py +875 -0
  973. chia/wallet/vc_wallet/cr_outer_puzzle.py +102 -0
  974. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  975. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +3 -0
  976. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +1 -0
  977. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +304 -0
  978. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +1 -0
  979. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +45 -0
  980. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +1 -0
  981. chia/wallet/vc_wallet/vc_drivers.py +838 -0
  982. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  983. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +30 -0
  984. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +1 -0
  985. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +75 -0
  986. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +1 -0
  987. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +32 -0
  988. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +1 -0
  989. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +80 -0
  990. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +1 -0
  991. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +163 -0
  992. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +1 -0
  993. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +16 -0
  994. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +1 -0
  995. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +74 -0
  996. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +1 -0
  997. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +23 -0
  998. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +1 -0
  999. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +64 -0
  1000. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +1 -0
  1001. chia/wallet/vc_wallet/vc_store.py +263 -0
  1002. chia/wallet/vc_wallet/vc_wallet.py +638 -0
  1003. chia/wallet/wallet.py +698 -0
  1004. chia/wallet/wallet_action_scope.py +95 -0
  1005. chia/wallet/wallet_blockchain.py +244 -0
  1006. chia/wallet/wallet_coin_record.py +72 -0
  1007. chia/wallet/wallet_coin_store.py +351 -0
  1008. chia/wallet/wallet_info.py +36 -0
  1009. chia/wallet/wallet_interested_store.py +188 -0
  1010. chia/wallet/wallet_nft_store.py +279 -0
  1011. chia/wallet/wallet_node.py +1769 -0
  1012. chia/wallet/wallet_node_api.py +201 -0
  1013. chia/wallet/wallet_pool_store.py +120 -0
  1014. chia/wallet/wallet_protocol.py +90 -0
  1015. chia/wallet/wallet_puzzle_store.py +365 -0
  1016. chia/wallet/wallet_retry_store.py +70 -0
  1017. chia/wallet/wallet_singleton_store.py +258 -0
  1018. chia/wallet/wallet_spend_bundle.py +41 -0
  1019. chia/wallet/wallet_state_manager.py +2820 -0
  1020. chia/wallet/wallet_transaction_store.py +470 -0
  1021. chia/wallet/wallet_user_store.py +110 -0
  1022. chia/wallet/wallet_weight_proof_handler.py +126 -0
  1023. chia_blockchain-2.4.4.dist-info/LICENSE +201 -0
  1024. chia_blockchain-2.4.4.dist-info/METADATA +161 -0
  1025. chia_blockchain-2.4.4.dist-info/RECORD +1028 -0
  1026. chia_blockchain-2.4.4.dist-info/WHEEL +4 -0
  1027. chia_blockchain-2.4.4.dist-info/entry_points.txt +17 -0
  1028. mozilla-ca/cacert.pem +3666 -0
@@ -0,0 +1,1176 @@
1
+ from __future__ import annotations
2
+
3
+ from asyncio import Queue
4
+ from dataclasses import dataclass
5
+ from random import Random
6
+ from typing import TYPE_CHECKING, AsyncGenerator, Dict, List, Optional, OrderedDict, Set, Tuple
7
+
8
+ import pytest
9
+ from chia_rs import AugSchemeMPL, Coin, CoinSpend, CoinState, Program
10
+
11
+ from chia._tests.connection_utils import add_dummy_connection
12
+ from chia.full_node.coin_store import CoinStore
13
+ from chia.full_node.full_node import FullNode
14
+ from chia.full_node.mempool import MempoolRemoveReason
15
+ from chia.protocols import wallet_protocol
16
+ from chia.protocols.protocol_message_types import ProtocolMessageTypes
17
+ from chia.protocols.shared_protocol import Capability
18
+ from chia.server.outbound_message import Message, NodeType
19
+ from chia.server.ws_connection import WSChiaConnection
20
+ from chia.simulator import simulator_protocol
21
+ from chia.simulator.block_tools import BlockTools
22
+ from chia.simulator.full_node_simulator import FullNodeSimulator
23
+ from chia.simulator.start_simulator import SimulatorFullNodeService
24
+ from chia.types.aliases import WalletService
25
+ from chia.types.blockchain_format.sized_bytes import bytes32
26
+ from chia.types.coin_record import CoinRecord
27
+ from chia.types.mempool_inclusion_status import MempoolInclusionStatus
28
+ from chia.types.spend_bundle import SpendBundle
29
+ from chia.util.hash import std_hash
30
+ from chia.util.ints import uint8, uint16, uint32, uint64
31
+
32
+ IDENTITY_PUZZLE = Program.to(1)
33
+ IDENTITY_PUZZLE_HASH = IDENTITY_PUZZLE.get_tree_hash()
34
+
35
+ OneNode = Tuple[List[SimulatorFullNodeService], List[WalletService], BlockTools]
36
+ # python 3.8 workaround follows - can be removed when 3.8 support is removed
37
+ if TYPE_CHECKING:
38
+ Mpu = Tuple[FullNodeSimulator, Queue[Message], WSChiaConnection]
39
+ else:
40
+ Mpu = Tuple[FullNodeSimulator, Queue, WSChiaConnection]
41
+
42
+ ALL_FILTER = wallet_protocol.CoinStateFilters(True, True, True, uint64(0))
43
+
44
+
45
+ async def connect_to_simulator(
46
+ one_node: OneNode, self_hostname: str, mempool_updates: bool = True
47
+ ) -> Tuple[FullNodeSimulator, Queue[Message], WSChiaConnection]:
48
+ [full_node_service], _, _ = one_node
49
+
50
+ full_node_api = full_node_service._api
51
+ fn_server = full_node_api.server
52
+
53
+ incoming_queue, peer_id = await add_dummy_connection(
54
+ fn_server,
55
+ self_hostname,
56
+ 41723,
57
+ NodeType.WALLET,
58
+ additional_capabilities=[(uint16(Capability.MEMPOOL_UPDATES), "1")] if mempool_updates else [],
59
+ )
60
+ peer = fn_server.all_connections[peer_id]
61
+
62
+ return full_node_api, incoming_queue, peer
63
+
64
+
65
+ @pytest.mark.anyio
66
+ async def test_puzzle_subscriptions(one_node: OneNode, self_hostname: str) -> None:
67
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
68
+ subs = simulator.full_node.subscriptions
69
+ genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
70
+
71
+ await simulator.farm_blocks_to_puzzlehash(1)
72
+
73
+ ph1 = bytes32(b"\x01" * 32)
74
+ ph2 = bytes32(b"\x02" * 32)
75
+ ph3 = bytes32(b"\x03" * 32)
76
+
77
+ # Add puzzle subscriptions, ignore duplicates
78
+ # Response can be in any order
79
+ resp = await simulator.request_puzzle_state(
80
+ wallet_protocol.RequestPuzzleState(
81
+ [ph1, ph2, ph2],
82
+ None,
83
+ genesis_challenge,
84
+ wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
85
+ True,
86
+ ),
87
+ peer,
88
+ )
89
+ assert resp is not None
90
+
91
+ add_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
92
+ assert set(add_response.puzzle_hashes) == {ph1, ph2}
93
+
94
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2}
95
+
96
+ # Add another puzzle hash and existing ones
97
+ resp = await simulator.request_puzzle_state(
98
+ wallet_protocol.RequestPuzzleState(
99
+ [ph1, ph2, ph3],
100
+ None,
101
+ genesis_challenge,
102
+ wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
103
+ True,
104
+ ),
105
+ peer,
106
+ )
107
+ assert resp is not None
108
+
109
+ add_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
110
+ assert set(add_response.puzzle_hashes) == {ph1, ph2, ph3}
111
+
112
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2, ph3}
113
+
114
+ # Remove puzzle subscriptions
115
+ # Ignore duplicates or missing subscriptions
116
+ resp = await simulator.request_remove_puzzle_subscriptions(
117
+ wallet_protocol.RequestRemovePuzzleSubscriptions([ph1, ph1, ph2]), peer
118
+ )
119
+ assert resp is not None
120
+
121
+ remove_response = wallet_protocol.RespondRemovePuzzleSubscriptions.from_bytes(resp.data)
122
+ assert set(remove_response.puzzle_hashes) == {ph1, ph2}
123
+
124
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == {ph3}
125
+
126
+ # Clear all puzzle subscriptions.
127
+ resp = await simulator.request_remove_puzzle_subscriptions(
128
+ wallet_protocol.RequestRemovePuzzleSubscriptions(None), peer
129
+ )
130
+ assert resp is not None
131
+
132
+ remove_response = wallet_protocol.RespondRemovePuzzleSubscriptions.from_bytes(resp.data)
133
+ assert set(remove_response.puzzle_hashes) == {ph3}
134
+
135
+ assert len(subs.puzzle_subscriptions(peer.peer_node_id)) == 0
136
+
137
+
138
+ @pytest.mark.anyio
139
+ async def test_coin_subscriptions(one_node: OneNode, self_hostname: str) -> None:
140
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
141
+ subs = simulator.full_node.subscriptions
142
+ genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
143
+
144
+ await simulator.farm_blocks_to_puzzlehash(1)
145
+
146
+ coin1 = bytes32(b"\x01" * 32)
147
+ coin2 = bytes32(b"\x02" * 32)
148
+ coin3 = bytes32(b"\x03" * 32)
149
+
150
+ # Add coin subscriptions, ignore duplicates
151
+ # Response can be in any order
152
+ resp = await simulator.request_coin_state(
153
+ wallet_protocol.RequestCoinState([coin1, coin2, coin2], None, genesis_challenge, True), peer
154
+ )
155
+ assert resp is not None
156
+
157
+ add_response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
158
+ assert set(add_response.coin_ids) == {coin1, coin2}
159
+
160
+ assert subs.coin_subscriptions(peer.peer_node_id) == {coin1, coin2}
161
+
162
+ # Add another puzzle hash and existing ones
163
+ resp = await simulator.request_coin_state(
164
+ wallet_protocol.RequestCoinState([coin1, coin2, coin3], None, genesis_challenge, True), peer
165
+ )
166
+ assert resp is not None
167
+
168
+ add_response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
169
+ assert set(add_response.coin_ids) == {coin1, coin2, coin3}
170
+
171
+ assert subs.coin_subscriptions(peer.peer_node_id) == {coin1, coin2, coin3}
172
+
173
+ # Remove coin subscriptions
174
+ # Ignore duplicates or missing subscriptions
175
+ resp = await simulator.request_remove_coin_subscriptions(
176
+ wallet_protocol.RequestRemoveCoinSubscriptions([coin1, coin1, coin2]), peer
177
+ )
178
+ assert resp is not None
179
+
180
+ remove_response = wallet_protocol.RespondRemoveCoinSubscriptions.from_bytes(resp.data)
181
+ assert set(remove_response.coin_ids) == {coin1, coin2}
182
+
183
+ assert subs.coin_subscriptions(peer.peer_node_id) == {coin3}
184
+
185
+ # Clear all coin subscriptions.
186
+ resp = await simulator.request_remove_coin_subscriptions(wallet_protocol.RequestRemoveCoinSubscriptions(None), peer)
187
+ assert resp is not None
188
+
189
+ remove_response = wallet_protocol.RespondRemoveCoinSubscriptions.from_bytes(resp.data)
190
+ assert set(remove_response.coin_ids) == {coin3}
191
+
192
+ assert len(subs.coin_subscriptions(peer.peer_node_id)) == 0
193
+
194
+
195
+ @pytest.mark.anyio
196
+ async def test_subscription_limits(one_node: OneNode, self_hostname: str) -> None:
197
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
198
+ subs = simulator.full_node.subscriptions
199
+ genesis_challenge = simulator.full_node.constants.GENESIS_CHALLENGE
200
+
201
+ await simulator.farm_blocks_to_puzzlehash(1)
202
+
203
+ # This is a safe limit for this test that will fit within the current maximum in `RequestPuzzleState`.
204
+ simulator.full_node.config["max_subscribe_items"] = CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE
205
+
206
+ max_subs = simulator.max_subscriptions(peer)
207
+ puzzle_hashes = [std_hash(i.to_bytes(4, byteorder="big", signed=False)) for i in range(max_subs + 100)]
208
+
209
+ # Add puzzle subscriptions to the limit
210
+ first_batch = puzzle_hashes[: CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE]
211
+ first_batch_set = set(first_batch)
212
+
213
+ resp = await simulator.request_puzzle_state(
214
+ wallet_protocol.RequestPuzzleState(
215
+ first_batch, None, genesis_challenge, wallet_protocol.CoinStateFilters(False, False, False, uint64(0)), True
216
+ ),
217
+ peer,
218
+ )
219
+ assert resp is not None
220
+
221
+ add_ph_response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
222
+ assert set(add_ph_response.puzzle_hashes) == first_batch_set
223
+
224
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == first_batch_set
225
+
226
+ # Try to add the remaining subscriptions
227
+ resp = await simulator.request_puzzle_state(
228
+ wallet_protocol.RequestPuzzleState(
229
+ puzzle_hashes[CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE :],
230
+ None,
231
+ genesis_challenge,
232
+ wallet_protocol.CoinStateFilters(False, False, False, uint64(0)),
233
+ True,
234
+ ),
235
+ peer,
236
+ )
237
+ assert resp is not None
238
+
239
+ overflow_ph_response = wallet_protocol.RejectPuzzleState.from_bytes(resp.data)
240
+ assert overflow_ph_response == wallet_protocol.RejectPuzzleState(
241
+ uint8(wallet_protocol.RejectStateReason.EXCEEDED_SUBSCRIPTION_LIMIT)
242
+ )
243
+
244
+ assert subs.puzzle_subscriptions(peer.peer_node_id) == first_batch_set
245
+
246
+ # Try to overflow with coin subscriptions
247
+ resp = await simulator.request_coin_state(
248
+ wallet_protocol.RequestCoinState([bytes32(b"coin" * 8)], None, genesis_challenge, True), peer
249
+ )
250
+ assert resp is not None
251
+
252
+ overflow_coin_response = wallet_protocol.RejectCoinState.from_bytes(resp.data)
253
+ assert overflow_coin_response == wallet_protocol.RejectCoinState(
254
+ uint8(wallet_protocol.RejectStateReason.EXCEEDED_SUBSCRIPTION_LIMIT)
255
+ )
256
+
257
+
258
+ @pytest.mark.anyio
259
+ async def test_request_coin_state(one_node: OneNode, self_hostname: str) -> None:
260
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
261
+
262
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
263
+ assert genesis is not None
264
+
265
+ # Add coin records
266
+ coin_records = [
267
+ CoinRecord(
268
+ coin=Coin(bytes32(b"\0" * 32), bytes32(b"\0" * 32), uint64(i)),
269
+ confirmed_block_index=uint32(1),
270
+ spent_block_index=uint32(1 if i % 2 == 0 else 0),
271
+ coinbase=False,
272
+ timestamp=uint64(0),
273
+ )
274
+ for i in range(50)
275
+ ]
276
+ ignored_coin = CoinRecord(
277
+ coin=Coin(bytes32(b"\1" * 32), bytes32(b"\1" * 32), uint64(1)),
278
+ confirmed_block_index=uint32(1),
279
+ spent_block_index=uint32(2),
280
+ coinbase=False,
281
+ timestamp=uint64(1),
282
+ )
283
+ await simulator.full_node.coin_store._add_coin_records(coin_records + [ignored_coin])
284
+
285
+ # Request no coin states
286
+ resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState([], None, genesis, False), peer)
287
+ assert resp is not None
288
+
289
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
290
+
291
+ assert len(response.coin_ids) == 0
292
+ assert len(response.coin_states) == 0
293
+
294
+ # Request coin state
295
+ coin_ids = [cr.coin.name() for cr in coin_records]
296
+
297
+ resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState(coin_ids, None, genesis, False), peer)
298
+ assert resp is not None
299
+
300
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
301
+
302
+ assert response.coin_ids == coin_ids
303
+ assert set(response.coin_states) == {cr.coin_state for cr in coin_records}
304
+
305
+
306
+ @pytest.mark.anyio
307
+ async def test_request_coin_state_and_subscribe(one_node: OneNode, self_hostname: str) -> None:
308
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
309
+
310
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
311
+ assert genesis is not None
312
+
313
+ c1 = bytes32(b"1" * 32)
314
+ c2 = bytes32(b"2" * 32)
315
+ c3 = bytes32(b"3" * 32)
316
+ c4 = bytes32(b"4" * 32)
317
+
318
+ # Request initial state (empty in this case) and subscribe
319
+ resp = await simulator.request_coin_state(
320
+ wallet_protocol.RequestCoinState([c1, c2, c3, c3, c4], None, genesis, True), peer
321
+ )
322
+ assert resp is not None
323
+
324
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
325
+
326
+ assert len(response.coin_ids) == 4
327
+ assert len(response.coin_states) == 0
328
+
329
+ # Make sure the subscriptions were added
330
+ assert simulator.full_node.subscriptions.coin_subscriptions(peer.peer_node_id) == {c1, c2, c3, c4}
331
+
332
+
333
+ @pytest.mark.anyio
334
+ async def test_request_coin_state_reorg(one_node: OneNode, self_hostname: str) -> None:
335
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
336
+
337
+ # Farm block
338
+ await simulator.farm_blocks_to_puzzlehash(8)
339
+
340
+ header_hash = simulator.full_node.blockchain.height_to_hash(uint32(5))
341
+ assert header_hash is not None
342
+
343
+ # Reorg
344
+ await simulator.reorg_from_index_to_new_index(
345
+ simulator_protocol.ReorgProtocol(uint32(3), uint32(10), bytes32(b"\1" * 32), bytes32(b"\0" * 32))
346
+ )
347
+
348
+ # Request coin state, should reject due to reorg
349
+ resp = await simulator.request_coin_state(wallet_protocol.RequestCoinState([], uint32(5), header_hash, False), peer)
350
+ assert resp is not None
351
+
352
+ assert wallet_protocol.RejectCoinState.from_bytes(resp.data) == wallet_protocol.RejectCoinState(
353
+ uint8(wallet_protocol.RejectStateReason.REORG)
354
+ )
355
+
356
+
357
+ @pytest.mark.anyio
358
+ async def test_request_coin_state_limit(one_node: OneNode, self_hostname: str) -> None:
359
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
360
+
361
+ # Farm blocks 0-11 and make sure the last one is farmed
362
+ await simulator.farm_blocks_to_puzzlehash(12)
363
+
364
+ h0 = simulator.full_node.blockchain.height_to_hash(uint32(0))
365
+ assert h0 is not None
366
+
367
+ h1 = simulator.full_node.blockchain.height_to_hash(uint32(1))
368
+ assert h1 is not None
369
+
370
+ # Add more than the max response coin records
371
+ coin_records: OrderedDict[bytes32, CoinRecord] = OrderedDict()
372
+ for height in range(1, 12):
373
+ for i in range(10000):
374
+ coin_record = CoinRecord(
375
+ coin=Coin(std_hash(i.to_bytes(4, "big")), std_hash(height.to_bytes(4, "big")), uint64(i)),
376
+ confirmed_block_index=uint32(height),
377
+ spent_block_index=uint32(0),
378
+ coinbase=False,
379
+ timestamp=uint64(472618),
380
+ )
381
+ coin_records[coin_record.coin.name()] = coin_record
382
+
383
+ await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
384
+
385
+ # Fetch the coin records using the wallet protocol,
386
+ # with more coin ids than the limit of 100,000, but only after height 10000.
387
+ resp = await simulator.request_coin_state(
388
+ wallet_protocol.RequestCoinState(list(coin_records.keys()), uint32(1), h1, False),
389
+ peer,
390
+ )
391
+ assert resp is not None
392
+
393
+ response = wallet_protocol.RespondCoinState.from_bytes(resp.data)
394
+
395
+ assert response.coin_ids == list(coin_records.keys())[:100000]
396
+ assert len(response.coin_states) == len(coin_records) - 20000
397
+
398
+ for coin_state in response.coin_states:
399
+ coin_record = coin_records[coin_state.coin.name()]
400
+ assert coin_record.coin_state == coin_state
401
+ assert coin_record.confirmed_block_index > 1
402
+
403
+
404
+ @pytest.mark.anyio
405
+ async def test_request_puzzle_state(one_node: OneNode, self_hostname: str) -> None:
406
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
407
+
408
+ # Farm block to a puzzle hash we aren't looking at
409
+ await simulator.farm_blocks_to_puzzlehash(3, farm_to=bytes32(b"\x0A" * 32))
410
+
411
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
412
+
413
+ peak_height = simulator.full_node.blockchain.get_peak_height()
414
+ assert peak_height is not None
415
+
416
+ peak_header_hash = simulator.full_node.blockchain.height_to_hash(peak_height)
417
+ assert peak_header_hash is not None
418
+
419
+ # Add coin records
420
+ coin_records: List[CoinRecord] = []
421
+ puzzle_hashes: List[bytes32] = []
422
+
423
+ for ph_i in range(10):
424
+ puzzle_hash = bytes32(ph_i.to_bytes(1, "big") * 32)
425
+ puzzle_hashes.append(puzzle_hash)
426
+
427
+ for i in range(5):
428
+ coin_records.append(
429
+ CoinRecord(
430
+ coin=Coin(bytes32(b"\0" * 32), puzzle_hash, uint64(i)),
431
+ confirmed_block_index=uint32(1),
432
+ spent_block_index=uint32(1 if i % 2 == 0 else 0),
433
+ coinbase=False,
434
+ timestamp=uint64(0),
435
+ )
436
+ )
437
+
438
+ ignored_coin = CoinRecord(
439
+ coin=Coin(bytes32(b"\1" * 32), bytes32(b"\1" * 31 + b"\0"), uint64(1)),
440
+ confirmed_block_index=uint32(1),
441
+ spent_block_index=uint32(2),
442
+ coinbase=False,
443
+ timestamp=uint64(1),
444
+ )
445
+
446
+ await simulator.full_node.coin_store._add_coin_records(coin_records + [ignored_coin])
447
+
448
+ # We already test permutations of CoinStateFilters in the CoinStore tests
449
+ # So it's redundant to do so here
450
+ filters = wallet_protocol.CoinStateFilters(True, True, True, uint64(0))
451
+
452
+ # Request no coin states
453
+ resp = await simulator.request_puzzle_state(
454
+ wallet_protocol.RequestPuzzleState([], None, genesis, filters, False), peer
455
+ )
456
+ assert resp is not None
457
+
458
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
459
+
460
+ # The peak height and header hash is returned when you are caught up to the peak
461
+ assert response == wallet_protocol.RespondPuzzleState([], peak_height, peak_header_hash, True, [])
462
+
463
+ # Request coin state
464
+ resp = await simulator.request_puzzle_state(
465
+ wallet_protocol.RequestPuzzleState(puzzle_hashes, None, genesis, filters, False), peer
466
+ )
467
+ assert resp is not None
468
+
469
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
470
+
471
+ assert response.puzzle_hashes == puzzle_hashes
472
+ assert set(response.coin_states) == {cr.coin_state for cr in coin_records}
473
+
474
+ assert response.height == peak_height
475
+ assert response.header_hash == peak_header_hash
476
+
477
+ assert response.is_finished
478
+
479
+
480
+ @pytest.mark.anyio
481
+ async def test_request_puzzle_state_and_subscribe(one_node: OneNode, self_hostname: str) -> None:
482
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
483
+
484
+ # You have to farm a block so there is a peak.
485
+ # Otherwise you will get an AssertionError from `request_puzzle_state`.
486
+ await simulator.farm_blocks_to_puzzlehash(1)
487
+
488
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
489
+ assert genesis is not None
490
+
491
+ ph1 = bytes32(b"1" * 32)
492
+ ph2 = bytes32(b"2" * 32)
493
+ ph3 = bytes32(b"3" * 32)
494
+ ph4 = bytes32(b"4" * 32)
495
+
496
+ # Request initial state (empty in this case) and subscribe
497
+ resp = await simulator.request_puzzle_state(
498
+ wallet_protocol.RequestPuzzleState(
499
+ [ph1, ph2, ph3, ph3, ph4],
500
+ None,
501
+ genesis,
502
+ wallet_protocol.CoinStateFilters(True, True, True, uint64(0)),
503
+ True,
504
+ ),
505
+ peer,
506
+ )
507
+ assert resp is not None
508
+
509
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
510
+
511
+ assert len(response.puzzle_hashes) == 4
512
+ assert len(response.coin_states) == 0
513
+
514
+ # Make sure the subscriptions were added
515
+ assert simulator.full_node.subscriptions.puzzle_subscriptions(peer.peer_node_id) == {ph1, ph2, ph3, ph4}
516
+
517
+
518
+ @pytest.mark.anyio
519
+ async def test_request_puzzle_state_reorg(one_node: OneNode, self_hostname: str) -> None:
520
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
521
+
522
+ # Farm block
523
+ await simulator.farm_blocks_to_puzzlehash(8)
524
+
525
+ header_hash = simulator.full_node.blockchain.height_to_hash(uint32(5))
526
+ assert header_hash is not None
527
+
528
+ # Reorg
529
+ await simulator.reorg_from_index_to_new_index(
530
+ simulator_protocol.ReorgProtocol(uint32(3), uint32(10), bytes32(b"\1" * 32), bytes32(b"\0" * 32))
531
+ )
532
+
533
+ # Request coin state, should reject due to reorg
534
+ resp = await simulator.request_puzzle_state(
535
+ wallet_protocol.RequestPuzzleState(
536
+ [], uint32(5), header_hash, wallet_protocol.CoinStateFilters(True, True, True, uint64(0)), False
537
+ ),
538
+ peer,
539
+ )
540
+ assert resp is not None
541
+
542
+ assert wallet_protocol.RejectPuzzleState.from_bytes(resp.data) == wallet_protocol.RejectPuzzleState(
543
+ uint8(wallet_protocol.RejectStateReason.REORG)
544
+ )
545
+
546
+
547
+ @pytest.mark.anyio
548
+ async def test_request_puzzle_state_limit(one_node: OneNode, self_hostname: str) -> None:
549
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
550
+
551
+ # Farm blocks 0-11 and make sure the last one is farmed
552
+ await simulator.farm_blocks_to_puzzlehash(12)
553
+
554
+ h0 = simulator.full_node.blockchain.height_to_hash(uint32(0))
555
+ assert h0 is not None
556
+
557
+ h1 = simulator.full_node.blockchain.height_to_hash(uint32(1))
558
+ assert h1 is not None
559
+
560
+ # Add more than the max response coin records
561
+ coin_records: OrderedDict[bytes32, CoinRecord] = OrderedDict()
562
+ ph = bytes32(b"\1" * 32)
563
+
564
+ for height in range(1, 12):
565
+ for i in range(10000):
566
+ coin_record = CoinRecord(
567
+ coin=Coin(std_hash(i.to_bytes(4, "big")), ph, uint64(height)),
568
+ confirmed_block_index=uint32(height),
569
+ spent_block_index=uint32(0),
570
+ coinbase=False,
571
+ timestamp=uint64(472618),
572
+ )
573
+ coin_records[coin_record.coin.name()] = coin_record
574
+
575
+ await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
576
+
577
+ # Fetch the coin records using the wallet protocol,
578
+ # only after height 10000, so that the limit of 100000 isn't exceeded
579
+ resp = await simulator.request_puzzle_state(
580
+ wallet_protocol.RequestPuzzleState(
581
+ [ph], uint32(1), h1, wallet_protocol.CoinStateFilters(True, True, True, uint64(0)), False
582
+ ),
583
+ peer,
584
+ )
585
+ assert resp is not None
586
+
587
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
588
+
589
+ assert response.puzzle_hashes == [ph]
590
+ assert len(response.coin_states) == len(coin_records) - 10000
591
+
592
+ for coin_state in response.coin_states:
593
+ coin_record = coin_records[coin_state.coin.name()]
594
+ assert coin_record.coin_state == coin_state
595
+ assert coin_record.confirmed_block_index > 1
596
+
597
+ # The expected behavior when the limit is exceeded, is to skip the rest
598
+ resp = await simulator.request_puzzle_state(
599
+ wallet_protocol.RequestPuzzleState(
600
+ [ph],
601
+ uint32(0),
602
+ h0,
603
+ wallet_protocol.CoinStateFilters(True, True, True, uint64(0)),
604
+ False,
605
+ ),
606
+ peer,
607
+ )
608
+ assert resp is not None
609
+
610
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
611
+
612
+ assert response.puzzle_hashes == [ph]
613
+ assert len(response.coin_states) == len(coin_records) - 10000
614
+
615
+ for coin_state in response.coin_states:
616
+ coin_record = coin_records[coin_state.coin.name()]
617
+ assert coin_record.coin_state == coin_state
618
+ # Unlike requesting coin state by ids, the order is enforced here so block 11 should be excluded
619
+ assert coin_record.confirmed_block_index <= 10
620
+
621
+
622
+ @dataclass(frozen=True)
623
+ class PuzzleStateData:
624
+ coin_states: List[CoinState]
625
+ end_of_batch: bool
626
+ previous_height: Optional[uint32]
627
+ header_hash: bytes32
628
+
629
+
630
+ async def sync_puzzle_hashes(
631
+ puzzle_hashes: List[bytes32],
632
+ *,
633
+ initial_previous_height: Optional[uint32],
634
+ initial_header_hash: bytes32,
635
+ filters: wallet_protocol.CoinStateFilters,
636
+ subscribe_when_finished: bool = False,
637
+ max_hashes_in_request: int = CoinStore.MAX_PUZZLE_HASH_BATCH_SIZE,
638
+ simulator: FullNodeSimulator,
639
+ peer: WSChiaConnection,
640
+ ) -> AsyncGenerator[PuzzleStateData, None]:
641
+ remaining = puzzle_hashes.copy()
642
+
643
+ while len(remaining) > 0:
644
+ previous_height = initial_previous_height
645
+ previous_header_hash = initial_header_hash
646
+ is_finished = False
647
+
648
+ while not is_finished:
649
+ resp = await simulator.request_puzzle_state(
650
+ wallet_protocol.RequestPuzzleState(
651
+ remaining[:max_hashes_in_request],
652
+ previous_height,
653
+ previous_header_hash,
654
+ filters,
655
+ subscribe_when_finished,
656
+ ),
657
+ peer,
658
+ )
659
+ assert resp is not None
660
+
661
+ response = wallet_protocol.RespondPuzzleState.from_bytes(resp.data)
662
+
663
+ consumed = len(response.puzzle_hashes)
664
+ assert set(response.puzzle_hashes) == set(remaining[:consumed])
665
+
666
+ if not response.is_finished:
667
+ previous_height = response.height
668
+ previous_header_hash = response.header_hash
669
+ yield PuzzleStateData(
670
+ coin_states=response.coin_states,
671
+ end_of_batch=False,
672
+ previous_height=previous_height,
673
+ header_hash=previous_header_hash,
674
+ )
675
+ else:
676
+ remaining = remaining[consumed:]
677
+ yield PuzzleStateData(
678
+ coin_states=response.coin_states,
679
+ end_of_batch=True,
680
+ previous_height=previous_height,
681
+ header_hash=previous_header_hash,
682
+ )
683
+ is_finished = True
684
+
685
+
686
+ @pytest.mark.anyio
687
+ @pytest.mark.parametrize("puzzle_hash_count,coins_per_block", [(0, 0), (5, 100), (3000, 3), (25000, 1)])
688
+ async def test_sync_puzzle_state(
689
+ one_node: OneNode, self_hostname: str, puzzle_hash_count: int, coins_per_block: int
690
+ ) -> None:
691
+ simulator, _, peer = await connect_to_simulator(one_node, self_hostname)
692
+
693
+ simulator.full_node.config["max_subscribe_response_items"] = 7400
694
+
695
+ # Generate coin records
696
+ puzzle_hashes: List[bytes32] = []
697
+ hints: List[Tuple[bytes32, bytes]] = []
698
+ coin_records: Dict[bytes32, CoinRecord] = dict()
699
+
700
+ rng = Random(0)
701
+
702
+ # Skip block 0 because it's skipped by `RequestPuzzleState`.
703
+ for i in range(1, puzzle_hash_count + 1):
704
+ puzzle_hash = std_hash(i.to_bytes(4, "big"))
705
+ puzzle_hashes.append(puzzle_hash)
706
+
707
+ base_amount = rng.randint(0, 1000000000)
708
+
709
+ for added_amount in range(coins_per_block):
710
+ coin_ph = puzzle_hash
711
+
712
+ # Weight toward normal puzzle hash.
713
+ if rng.choice([True, False, False, False, False]):
714
+ coin_ph = std_hash(coin_ph)
715
+
716
+ coin = Coin(bytes32(b"\0" * 32), coin_ph, uint64(base_amount + added_amount))
717
+
718
+ coin_records[coin.name()] = CoinRecord(
719
+ coin=coin,
720
+ confirmed_block_index=uint32(rng.randrange(1, 10)),
721
+ spent_block_index=uint32(rng.randrange(11, 20) if rng.choice([True, False]) else 0),
722
+ coinbase=False,
723
+ timestamp=uint64(rng.randint(1000, 100000000)),
724
+ )
725
+
726
+ if coin_ph != puzzle_hash:
727
+ hints.append((coin.name(), puzzle_hash))
728
+
729
+ await simulator.full_node.coin_store._add_coin_records(list(coin_records.values()))
730
+ await simulator.full_node.hint_store.add_hints(hints)
731
+
732
+ # Farm peak
733
+ await simulator.farm_blocks_to_puzzlehash(30)
734
+
735
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
736
+
737
+ async def run_test(include_spent: bool, include_unspent: bool, include_hinted: bool, min_amount: uint64) -> None:
738
+ # Calculate expected coin records based on filters
739
+ expected_coin_records: Dict[bytes32, CoinRecord] = dict()
740
+
741
+ for coin_id, coin_record in coin_records.items():
742
+ if not include_spent and coin_record.spent_block_index > 0:
743
+ continue
744
+ if not include_unspent and coin_record.spent_block_index == 0:
745
+ continue
746
+ if not include_hinted and coin_record.coin.puzzle_hash not in puzzle_hashes:
747
+ continue
748
+ if coin_record.coin.amount < min_amount:
749
+ continue
750
+
751
+ expected_coin_records[coin_id] = coin_record
752
+
753
+ # Sync all coin states
754
+ coin_ids: Set[bytes32] = set()
755
+ last_height = -1
756
+
757
+ async for batch in sync_puzzle_hashes(
758
+ puzzle_hashes,
759
+ initial_previous_height=None,
760
+ initial_header_hash=genesis,
761
+ filters=wallet_protocol.CoinStateFilters(include_spent, include_unspent, include_hinted, min_amount),
762
+ simulator=simulator,
763
+ peer=peer,
764
+ ):
765
+ for coin_state in batch.coin_states:
766
+ coin_id = coin_state.coin.name()
767
+ coin_ids.add(coin_id)
768
+
769
+ coin_record = expected_coin_records[coin_id]
770
+ assert coin_record.coin_state == coin_state
771
+
772
+ height = max(coin_state.created_height or 0, coin_state.spent_height or 0)
773
+
774
+ assert height > last_height
775
+ if batch.end_of_batch:
776
+ last_height = -1
777
+
778
+ assert len(coin_ids) == len(expected_coin_records)
779
+
780
+ for include_spent in [True, False]:
781
+ for include_unspent in [True, False]:
782
+ for include_hinted in [True, False]:
783
+ for min_amount in [0, 100000, 500000000]:
784
+ await run_test(include_spent, include_unspent, include_hinted, uint64(min_amount))
785
+
786
+
787
+ async def assert_mempool_added(queue: Queue[Message], transaction_ids: Set[bytes32]) -> None:
788
+ message = await queue.get()
789
+ assert message.type == ProtocolMessageTypes.mempool_items_added.value
790
+
791
+ update = wallet_protocol.MempoolItemsAdded.from_bytes(message.data)
792
+ assert set(update.transaction_ids) == transaction_ids
793
+
794
+
795
+ async def assert_mempool_removed(
796
+ queue: Queue[Message],
797
+ removed_items: Set[wallet_protocol.RemovedMempoolItem],
798
+ ) -> None:
799
+ message = await queue.get()
800
+ assert message.type == ProtocolMessageTypes.mempool_items_removed.value
801
+
802
+ update = wallet_protocol.MempoolItemsRemoved.from_bytes(message.data)
803
+ assert set(update.removed_items) == removed_items
804
+
805
+
806
+ @pytest.fixture
807
+ async def mpu_setup(one_node: OneNode, self_hostname: str) -> Mpu:
808
+ return await raw_mpu_setup(one_node, self_hostname)
809
+
810
+
811
+ @pytest.fixture
812
+ async def mpu_setup_no_capability(one_node: OneNode, self_hostname: str) -> Mpu:
813
+ return await raw_mpu_setup(one_node, self_hostname, no_capability=True)
814
+
815
+
816
+ async def raw_mpu_setup(one_node: OneNode, self_hostname: str, no_capability: bool = False) -> Mpu:
817
+ simulator, queue, peer = await connect_to_simulator(one_node, self_hostname, mempool_updates=not no_capability)
818
+ await simulator.farm_blocks_to_puzzlehash(1)
819
+ await queue.get()
820
+
821
+ new_coins: List[Tuple[Coin, bytes32]] = []
822
+
823
+ for i in range(10):
824
+ puzzle = Program.to(2)
825
+ ph = puzzle.get_tree_hash()
826
+ coin = Coin(std_hash(b"unrelated coin id" + i.to_bytes(4, "big")), ph, uint64(1))
827
+ hint = std_hash(b"unrelated hint" + i.to_bytes(4, "big"))
828
+ new_coins.append((coin, hint))
829
+
830
+ reward_1 = Coin(std_hash(b"reward 1"), std_hash(b"reward puzzle hash"), uint64(1000))
831
+ reward_2 = Coin(std_hash(b"reward 2"), std_hash(b"reward puzzle hash"), uint64(2000))
832
+ await simulator.full_node.coin_store.new_block(
833
+ uint32(2), uint64(10000), [reward_1, reward_2], [coin for coin, _ in new_coins], []
834
+ )
835
+ await simulator.full_node.hint_store.add_hints([(coin.name(), hint) for coin, hint in new_coins])
836
+
837
+ for coin, hint in new_coins:
838
+ solution = Program.to([[]])
839
+ bundle = SpendBundle([CoinSpend(coin, puzzle, solution)], AugSchemeMPL.aggregate([]))
840
+ tx_resp = await simulator.send_transaction(wallet_protocol.SendTransaction(bundle))
841
+ assert tx_resp is not None
842
+
843
+ ack = wallet_protocol.TransactionAck.from_bytes(tx_resp.data)
844
+ assert ack.error is None
845
+ assert ack.status == int(MempoolInclusionStatus.SUCCESS)
846
+
847
+ return simulator, queue, peer
848
+
849
+
850
+ async def make_coin(full_node: FullNode) -> Tuple[Coin, bytes32]:
851
+ ph = IDENTITY_PUZZLE_HASH
852
+ coin = Coin(bytes32(b"\0" * 32), ph, uint64(1000))
853
+ hint = bytes32(b"\0" * 32)
854
+
855
+ height = full_node.blockchain.get_peak_height()
856
+ assert height is not None
857
+
858
+ reward_1 = Coin(std_hash(b"reward 1"), std_hash(b"reward puzzle hash"), uint64(3000))
859
+ reward_2 = Coin(std_hash(b"reward 2"), std_hash(b"reward puzzle hash"), uint64(4000))
860
+ await full_node.coin_store.new_block(uint32(height + 1), uint64(200000), [reward_1, reward_2], [coin], [])
861
+ await full_node.hint_store.add_hints([(coin.name(), hint)])
862
+
863
+ return coin, hint
864
+
865
+
866
+ async def subscribe_coin(
867
+ simulator: FullNodeSimulator, coin_id: bytes32, peer: WSChiaConnection, *, existing_coin_states: int = 1
868
+ ) -> None:
869
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
870
+ assert genesis is not None
871
+
872
+ msg = await simulator.request_coin_state(wallet_protocol.RequestCoinState([coin_id], None, genesis, True), peer)
873
+ assert msg is not None
874
+
875
+ response = wallet_protocol.RespondCoinState.from_bytes(msg.data)
876
+ assert response.coin_ids == [coin_id]
877
+ assert len(response.coin_states) == existing_coin_states
878
+
879
+
880
+ async def subscribe_puzzle(
881
+ simulator: FullNodeSimulator, puzzle_hash: bytes32, peer: WSChiaConnection, *, existing_coin_states: int = 1
882
+ ) -> None:
883
+ genesis = simulator.full_node.blockchain.constants.GENESIS_CHALLENGE
884
+ assert genesis is not None
885
+
886
+ msg = await simulator.request_puzzle_state(
887
+ wallet_protocol.RequestPuzzleState([puzzle_hash], None, genesis, ALL_FILTER, True), peer
888
+ )
889
+ assert msg is not None
890
+
891
+ response = wallet_protocol.RespondPuzzleState.from_bytes(msg.data)
892
+ assert response.puzzle_hashes == [puzzle_hash]
893
+ assert len(response.coin_states) == existing_coin_states
894
+
895
+
896
+ async def spend_coin(simulator: FullNodeSimulator, coin: Coin, solution: Optional[Program] = None) -> bytes32:
897
+ bundle = SpendBundle(
898
+ [CoinSpend(coin, IDENTITY_PUZZLE, Program.to([]) if solution is None else solution)], AugSchemeMPL.aggregate([])
899
+ )
900
+ tx_resp = await simulator.send_transaction(wallet_protocol.SendTransaction(bundle))
901
+ assert tx_resp is not None
902
+
903
+ ack = wallet_protocol.TransactionAck.from_bytes(tx_resp.data)
904
+ assert ack.error is None
905
+ assert ack.status == int(MempoolInclusionStatus.SUCCESS)
906
+
907
+ transaction_id = bundle.name()
908
+ assert ack.txid == transaction_id
909
+
910
+ return transaction_id
911
+
912
+
913
+ @pytest.mark.anyio
914
+ async def test_spent_coin_id_mempool_update(mpu_setup: Mpu) -> None:
915
+ simulator, queue, peer = mpu_setup
916
+
917
+ # Make a coin and spend it
918
+ coin, _ = await make_coin(simulator.full_node)
919
+ await subscribe_coin(simulator, coin.name(), peer)
920
+ transaction_id = await spend_coin(simulator, coin)
921
+
922
+ # We should have gotten a mempool update for this transaction
923
+ await assert_mempool_added(queue, {transaction_id})
924
+
925
+ # Check the mempool to make sure the transaction is there
926
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
927
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
928
+
929
+ # The mempool item should now be in the initial update
930
+ await subscribe_coin(simulator, coin.name(), peer)
931
+ await assert_mempool_added(queue, {transaction_id})
932
+
933
+ # Farm a block and listen for the mempool removal event
934
+ await simulator.farm_blocks_to_puzzlehash(1)
935
+ await assert_mempool_removed(
936
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
937
+ )
938
+
939
+
940
+ @pytest.mark.anyio
941
+ async def test_spent_puzzle_hash_mempool_update(mpu_setup: Mpu) -> None:
942
+ simulator, queue, peer = mpu_setup
943
+
944
+ # Make a coin and spend it
945
+ coin, _ = await make_coin(simulator.full_node)
946
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
947
+ transaction_id = await spend_coin(simulator, coin)
948
+
949
+ # We should have gotten a mempool update for this transaction
950
+ await assert_mempool_added(queue, {transaction_id})
951
+
952
+ # Check the mempool to make sure the transaction is there
953
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
954
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
955
+
956
+ # The mempool item should now be in the initial update
957
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
958
+ await assert_mempool_added(queue, {transaction_id})
959
+
960
+ # Farm a block and listen for the mempool removal event
961
+ await simulator.farm_blocks_to_puzzlehash(1)
962
+ await assert_mempool_removed(
963
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
964
+ )
965
+
966
+
967
+ @pytest.mark.anyio
968
+ async def test_spent_hint_mempool_update(mpu_setup: Mpu) -> None:
969
+ simulator, queue, peer = mpu_setup
970
+
971
+ # Make a coin and spend it
972
+ coin, hint = await make_coin(simulator.full_node)
973
+ await subscribe_puzzle(simulator, hint, peer)
974
+ transaction_id = await spend_coin(simulator, coin)
975
+
976
+ # We should have gotten a mempool update for this transaction
977
+ await assert_mempool_added(queue, {transaction_id})
978
+
979
+ # Check the mempool to make sure the transaction is there
980
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
981
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
982
+
983
+ # The mempool item should now be in the initial update
984
+ await subscribe_puzzle(simulator, hint, peer)
985
+ await assert_mempool_added(queue, {transaction_id})
986
+
987
+ # Farm a block and listen for the mempool removal event
988
+ await simulator.farm_blocks_to_puzzlehash(1)
989
+ await assert_mempool_removed(
990
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
991
+ )
992
+
993
+
994
+ @pytest.mark.anyio
995
+ async def test_created_coin_id_mempool_update(mpu_setup: Mpu) -> None:
996
+ simulator, queue, peer = mpu_setup
997
+
998
+ # Make a coin and spend it to create a child coin
999
+ coin, _ = await make_coin(simulator.full_node)
1000
+ child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
1001
+ await subscribe_coin(simulator, child_coin.name(), peer, existing_coin_states=0)
1002
+ transaction_id = await spend_coin(
1003
+ simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount]])
1004
+ )
1005
+
1006
+ # We should have gotten a mempool update for this transaction
1007
+ await assert_mempool_added(queue, {transaction_id})
1008
+
1009
+ # Check the mempool to make sure the transaction is there
1010
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1011
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1012
+
1013
+ # The mempool item should now be in the initial update
1014
+ await subscribe_coin(simulator, child_coin.name(), peer, existing_coin_states=0)
1015
+ await assert_mempool_added(queue, {transaction_id})
1016
+
1017
+ # Farm a block and listen for the mempool removal event
1018
+ await simulator.farm_blocks_to_puzzlehash(1)
1019
+ await assert_mempool_removed(
1020
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
1021
+ )
1022
+
1023
+
1024
+ @pytest.mark.anyio
1025
+ async def test_created_puzzle_hash_mempool_update(mpu_setup: Mpu) -> None:
1026
+ simulator, queue, peer = mpu_setup
1027
+
1028
+ # Make a coin and spend it to create a child coin
1029
+ coin, _ = await make_coin(simulator.full_node)
1030
+ child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
1031
+ await subscribe_puzzle(simulator, child_coin.puzzle_hash, peer, existing_coin_states=0)
1032
+ transaction_id = await spend_coin(
1033
+ simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount]])
1034
+ )
1035
+
1036
+ # We should have gotten a mempool update for this transaction
1037
+ await assert_mempool_added(queue, {transaction_id})
1038
+
1039
+ # Check the mempool to make sure the transaction is there
1040
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1041
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1042
+
1043
+ # The mempool item should now be in the initial update
1044
+ await subscribe_puzzle(simulator, child_coin.puzzle_hash, peer, existing_coin_states=0)
1045
+ await assert_mempool_added(queue, {transaction_id})
1046
+
1047
+ # Farm a block and listen for the mempool removal event
1048
+ await simulator.farm_blocks_to_puzzlehash(1)
1049
+ await assert_mempool_removed(
1050
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
1051
+ )
1052
+
1053
+
1054
+ @pytest.mark.anyio
1055
+ async def test_created_hint_mempool_update(mpu_setup: Mpu) -> None:
1056
+ simulator, queue, peer = mpu_setup
1057
+
1058
+ # Make a coin and spend it to create a child coin
1059
+ coin, _ = await make_coin(simulator.full_node)
1060
+ child_coin = Coin(coin.name(), std_hash(b"new puzzle hash"), coin.amount)
1061
+ hint = std_hash(b"new hint")
1062
+ await subscribe_puzzle(simulator, hint, peer, existing_coin_states=0)
1063
+ transaction_id = await spend_coin(
1064
+ simulator, coin, solution=Program.to([[51, child_coin.puzzle_hash, child_coin.amount, [hint]]])
1065
+ )
1066
+
1067
+ # We should have gotten a mempool update for this transaction
1068
+ await assert_mempool_added(queue, {transaction_id})
1069
+
1070
+ # Check the mempool to make sure the transaction is there
1071
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1072
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1073
+
1074
+ # The mempool item should now be in the initial update
1075
+ await subscribe_puzzle(simulator, hint, peer, existing_coin_states=0)
1076
+ await assert_mempool_added(queue, {transaction_id})
1077
+
1078
+ # Farm a block and listen for the mempool removal event
1079
+ await simulator.farm_blocks_to_puzzlehash(1)
1080
+ await assert_mempool_removed(
1081
+ queue, {wallet_protocol.RemovedMempoolItem(transaction_id, uint8(MempoolRemoveReason.BLOCK_INCLUSION.value))}
1082
+ )
1083
+
1084
+
1085
+ @pytest.mark.anyio
1086
+ async def test_missing_capability_coin_id(mpu_setup_no_capability: Mpu) -> None:
1087
+ simulator, queue, peer = mpu_setup_no_capability
1088
+
1089
+ # Make a coin and spend it
1090
+ coin, _ = await make_coin(simulator.full_node)
1091
+ await subscribe_coin(simulator, coin.name(), peer)
1092
+ transaction_id = await spend_coin(simulator, coin)
1093
+
1094
+ # There is no mempool update for this transaction since the peer doesn't have the capability
1095
+ assert queue.empty()
1096
+
1097
+ # Check the mempool to make sure the transaction is there
1098
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1099
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1100
+
1101
+ # There is no initial mempool update since the peer doesn't have the capability
1102
+ await subscribe_coin(simulator, coin.name(), peer)
1103
+ assert queue.empty()
1104
+
1105
+ # Farm a block and there's still no mempool update
1106
+ await simulator.farm_blocks_to_puzzlehash(1)
1107
+ assert queue.empty()
1108
+
1109
+
1110
+ @pytest.mark.anyio
1111
+ async def test_missing_capability_puzzle_hash(mpu_setup_no_capability: Mpu) -> None:
1112
+ simulator, queue, peer = mpu_setup_no_capability
1113
+
1114
+ # Make a coin and spend it
1115
+ coin, _ = await make_coin(simulator.full_node)
1116
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
1117
+ transaction_id = await spend_coin(simulator, coin)
1118
+
1119
+ # There is no mempool update for this transaction since the peer doesn't have the capability
1120
+ assert queue.empty()
1121
+
1122
+ # Check the mempool to make sure the transaction is there
1123
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1124
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1125
+
1126
+ # There is no initial mempool update since the peer doesn't have the capability
1127
+ await subscribe_puzzle(simulator, coin.puzzle_hash, peer)
1128
+ assert queue.empty()
1129
+
1130
+ # Farm a block and there's still no mempool update
1131
+ await simulator.farm_blocks_to_puzzlehash(1)
1132
+ assert queue.empty()
1133
+
1134
+
1135
+ @pytest.mark.anyio
1136
+ async def test_missing_capability_hint(mpu_setup_no_capability: Mpu) -> None:
1137
+ simulator, queue, peer = mpu_setup_no_capability
1138
+
1139
+ # Make a coin and spend it
1140
+ coin, hint = await make_coin(simulator.full_node)
1141
+ await subscribe_puzzle(simulator, hint, peer)
1142
+ transaction_id = await spend_coin(simulator, coin)
1143
+
1144
+ # There is no mempool update for this transaction since the peer doesn't have the capability
1145
+ assert queue.empty()
1146
+
1147
+ # Check the mempool to make sure the transaction is there
1148
+ await simulator.wait_bundle_ids_in_mempool([transaction_id])
1149
+ assert simulator.full_node.mempool_manager.mempool.get_item_by_id(transaction_id) is not None
1150
+
1151
+ # There is no initial mempool update since the peer doesn't have the capability
1152
+ await subscribe_puzzle(simulator, hint, peer)
1153
+ assert queue.empty()
1154
+
1155
+ # Farm a block and there's still no mempool update
1156
+ await simulator.farm_blocks_to_puzzlehash(1)
1157
+ assert queue.empty()
1158
+
1159
+
1160
+ @pytest.mark.anyio
1161
+ async def test_cost_info(one_node: OneNode, self_hostname: str) -> None:
1162
+ simulator, _, _ = await connect_to_simulator(one_node, self_hostname)
1163
+
1164
+ msg = await simulator.request_cost_info(wallet_protocol.RequestCostInfo())
1165
+ assert msg is not None
1166
+
1167
+ response = wallet_protocol.RespondCostInfo.from_bytes(msg.data)
1168
+ mempool_manager = simulator.full_node.mempool_manager
1169
+ assert response == wallet_protocol.RespondCostInfo(
1170
+ max_transaction_cost=mempool_manager.max_tx_clvm_cost,
1171
+ max_block_cost=mempool_manager.max_block_clvm_cost,
1172
+ max_mempool_cost=uint64(mempool_manager.mempool_max_total_cost),
1173
+ mempool_cost=uint64(mempool_manager.mempool._total_cost),
1174
+ mempool_fee=uint64(mempool_manager.mempool._total_fee),
1175
+ bump_fee_per_cost=uint8(mempool_manager.nonzero_fee_minimum_fpc),
1176
+ )