chia-blockchain 2.5.4rc1__py3-none-any.whl → 2.5.5__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 (453) hide show
  1. chia/_tests/blockchain/blockchain_test_utils.py +2 -3
  2. chia/_tests/blockchain/test_augmented_chain.py +2 -3
  3. chia/_tests/blockchain/test_blockchain.py +261 -44
  4. chia/_tests/blockchain/test_blockchain_transactions.py +4 -3
  5. chia/_tests/blockchain/test_build_chains.py +197 -1
  6. chia/_tests/blockchain/test_get_block_generator.py +1 -1
  7. chia/_tests/blockchain/test_lookup_fork_chain.py +1 -1
  8. chia/_tests/clvm/benchmark_costs.py +1 -1
  9. chia/_tests/clvm/coin_store.py +3 -4
  10. chia/_tests/clvm/test_message_conditions.py +2 -2
  11. chia/_tests/clvm/test_puzzle_compression.py +2 -3
  12. chia/_tests/clvm/test_puzzles.py +1 -2
  13. chia/_tests/clvm/test_singletons.py +2 -3
  14. chia/_tests/clvm/test_spend_sim.py +7 -7
  15. chia/_tests/cmds/cmd_test_utils.py +30 -25
  16. chia/_tests/cmds/test_dev_gh.py +1 -1
  17. chia/_tests/cmds/test_farm_cmd.py +1 -1
  18. chia/_tests/cmds/test_show.py +1 -2
  19. chia/_tests/cmds/wallet/test_did.py +101 -56
  20. chia/_tests/cmds/wallet/test_nft.py +109 -84
  21. chia/_tests/cmds/wallet/test_notifications.py +1 -1
  22. chia/_tests/cmds/wallet/test_offer.toffer +1 -1
  23. chia/_tests/cmds/wallet/test_vcs.py +8 -8
  24. chia/_tests/cmds/wallet/test_wallet.py +100 -46
  25. chia/_tests/conftest.py +31 -20
  26. chia/_tests/connection_utils.py +1 -1
  27. chia/_tests/core/consensus/stores/__init__.py +0 -0
  28. chia/_tests/core/consensus/stores/test_coin_store_protocol.py +40 -0
  29. chia/_tests/core/consensus/test_block_creation.py +2 -31
  30. chia/_tests/core/consensus/test_pot_iterations.py +38 -3
  31. chia/_tests/core/custom_types/test_proof_of_space.py +154 -26
  32. chia/_tests/core/custom_types/test_spend_bundle.py +2 -3
  33. chia/_tests/core/daemon/test_daemon.py +80 -0
  34. chia/_tests/core/data_layer/test_data_layer.py +1 -1
  35. chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
  36. chia/_tests/core/data_layer/test_data_rpc.py +14 -10
  37. chia/_tests/core/data_layer/test_data_store.py +5 -5
  38. chia/_tests/core/farmer/test_farmer_api.py +2 -2
  39. chia/_tests/core/full_node/full_sync/test_full_sync.py +446 -406
  40. chia/_tests/core/full_node/ram_db.py +3 -1
  41. chia/_tests/core/full_node/stores/test_block_store.py +28 -16
  42. chia/_tests/core/full_node/stores/test_coin_store.py +277 -185
  43. chia/_tests/core/full_node/stores/test_full_node_store.py +11 -4
  44. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  45. chia/_tests/core/full_node/test_address_manager.py +200 -27
  46. chia/_tests/core/full_node/test_block_height_map.py +2 -2
  47. chia/_tests/core/full_node/test_conditions.py +7 -6
  48. chia/_tests/core/full_node/test_full_node.py +456 -40
  49. chia/_tests/core/full_node/test_generator_tools.py +32 -2
  50. chia/_tests/core/full_node/test_hint_management.py +1 -1
  51. chia/_tests/core/full_node/test_node_load.py +20 -21
  52. chia/_tests/core/full_node/test_performance.py +3 -4
  53. chia/_tests/core/full_node/test_prev_tx_block.py +43 -0
  54. chia/_tests/core/full_node/test_subscriptions.py +1 -2
  55. chia/_tests/core/full_node/test_transactions.py +9 -5
  56. chia/_tests/core/full_node/test_tx_processing_queue.py +1 -2
  57. chia/_tests/core/large_block.py +1 -2
  58. chia/_tests/core/make_block_generator.py +3 -4
  59. chia/_tests/core/mempool/test_mempool.py +36 -86
  60. chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
  61. chia/_tests/core/mempool/test_mempool_item_queries.py +1 -3
  62. chia/_tests/core/mempool/test_mempool_manager.py +529 -69
  63. chia/_tests/core/mempool/test_mempool_performance.py +3 -2
  64. chia/_tests/core/mempool/test_singleton_fast_forward.py +61 -132
  65. chia/_tests/core/server/flood.py +1 -1
  66. chia/_tests/core/server/test_dos.py +1 -1
  67. chia/_tests/core/server/test_node_discovery.py +41 -27
  68. chia/_tests/core/server/test_rate_limits.py +1 -1
  69. chia/_tests/core/server/test_server.py +1 -1
  70. chia/_tests/core/services/test_services.py +5 -5
  71. chia/_tests/core/ssl/test_ssl.py +1 -1
  72. chia/_tests/core/test_cost_calculation.py +6 -6
  73. chia/_tests/core/test_crawler.py +2 -2
  74. chia/_tests/core/test_crawler_rpc.py +1 -1
  75. chia/_tests/core/test_db_conversion.py +3 -1
  76. chia/_tests/core/test_db_validation.py +5 -3
  77. chia/_tests/core/test_farmer_harvester_rpc.py +15 -15
  78. chia/_tests/core/test_filter.py +4 -1
  79. chia/_tests/core/test_full_node_rpc.py +99 -82
  80. chia/_tests/core/test_program.py +2 -2
  81. chia/_tests/core/util/test_block_cache.py +1 -1
  82. chia/_tests/core/util/test_keychain.py +2 -2
  83. chia/_tests/core/util/test_lockfile.py +1 -1
  84. chia/_tests/core/util/test_log_exceptions.py +5 -5
  85. chia/_tests/core/util/test_streamable.py +81 -22
  86. chia/_tests/db/test_db_wrapper.py +1 -3
  87. chia/_tests/environments/wallet.py +5 -5
  88. chia/_tests/farmer_harvester/test_farmer.py +9 -7
  89. chia/_tests/farmer_harvester/test_farmer_harvester.py +11 -4
  90. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +6 -5
  91. chia/_tests/farmer_harvester/test_third_party_harvesters.py +15 -9
  92. chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -2
  93. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +7 -5
  94. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
  95. chia/_tests/generator/test_compression.py +1 -2
  96. chia/_tests/generator/test_rom.py +8 -4
  97. chia/_tests/plot_sync/test_plot_sync.py +3 -3
  98. chia/_tests/plot_sync/test_receiver.py +3 -3
  99. chia/_tests/plot_sync/test_sender.py +1 -1
  100. chia/_tests/plot_sync/test_sync_simulated.py +3 -3
  101. chia/_tests/plot_sync/util.py +2 -2
  102. chia/_tests/pools/test_pool_cmdline.py +48 -21
  103. chia/_tests/pools/test_pool_puzzles_lifecycle.py +2 -3
  104. chia/_tests/pools/test_pool_rpc.py +237 -105
  105. chia/_tests/pools/test_pool_wallet.py +11 -2
  106. chia/_tests/pools/test_wallet_pool_store.py +5 -4
  107. chia/_tests/rpc/test_rpc_client.py +1 -1
  108. chia/_tests/simulation/test_simulation.py +13 -8
  109. chia/_tests/simulation/test_simulator.py +2 -2
  110. chia/_tests/timelord/test_new_peak.py +191 -47
  111. chia/_tests/timelord/test_timelord.py +1 -1
  112. chia/_tests/tools/test_full_sync.py +0 -2
  113. chia/_tests/tools/test_run_block.py +3 -1
  114. chia/_tests/util/benchmark_cost.py +3 -3
  115. chia/_tests/util/benchmarks.py +2 -2
  116. chia/_tests/util/blockchain.py +11 -5
  117. chia/_tests/util/blockchain_mock.py +1 -4
  118. chia/_tests/util/coin_store.py +29 -0
  119. chia/_tests/util/constants.py +2 -18
  120. chia/_tests/util/full_sync.py +3 -3
  121. chia/_tests/util/generator_tools_testing.py +2 -3
  122. chia/_tests/util/key_tool.py +2 -3
  123. chia/_tests/util/misc.py +33 -31
  124. chia/_tests/util/network_protocol_data.py +19 -17
  125. chia/_tests/util/protocol_messages_bytes-v1.0 +0 -0
  126. chia/_tests/util/protocol_messages_json.py +3 -1
  127. chia/_tests/util/run_block.py +2 -2
  128. chia/_tests/util/setup_nodes.py +7 -7
  129. chia/_tests/util/spend_sim.py +47 -55
  130. chia/_tests/util/test_condition_tools.py +5 -4
  131. chia/_tests/util/test_config.py +2 -2
  132. chia/_tests/util/test_dump_keyring.py +1 -1
  133. chia/_tests/util/test_full_block_utils.py +12 -14
  134. chia/_tests/util/test_misc.py +2 -2
  135. chia/_tests/util/test_paginator.py +4 -4
  136. chia/_tests/util/test_priority_mutex.py +2 -2
  137. chia/_tests/util/test_replace_str_to_bytes.py +15 -5
  138. chia/_tests/util/test_ssl_check.py +1 -1
  139. chia/_tests/util/test_testnet_overrides.py +13 -3
  140. chia/_tests/util/time_out_assert.py +4 -2
  141. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
  142. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +1 -2
  143. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +352 -432
  144. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +3 -6
  145. chia/_tests/wallet/cat_wallet/test_trades.py +53 -77
  146. chia/_tests/wallet/clawback/test_clawback_decorator.py +3 -1
  147. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +3 -3
  148. chia/_tests/wallet/clawback/test_clawback_metadata.py +4 -2
  149. chia/_tests/wallet/conftest.py +11 -12
  150. chia/_tests/wallet/db_wallet/test_db_graftroot.py +11 -4
  151. chia/_tests/wallet/db_wallet/test_dl_offers.py +433 -130
  152. chia/_tests/wallet/db_wallet/test_dl_wallet.py +3 -3
  153. chia/_tests/wallet/did_wallet/test_did.py +2132 -2000
  154. chia/_tests/wallet/nft_wallet/config.py +1 -1
  155. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +1610 -742
  156. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +486 -907
  157. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +4 -4
  158. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +517 -294
  159. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +133 -62
  160. chia/_tests/wallet/rpc/test_wallet_rpc.py +495 -265
  161. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +10 -6
  162. chia/_tests/wallet/sync/test_wallet_sync.py +89 -60
  163. chia/_tests/wallet/test_clvm_casts.py +88 -0
  164. chia/_tests/wallet/test_coin_management.py +1 -1
  165. chia/_tests/wallet/test_coin_selection.py +1 -1
  166. chia/_tests/wallet/test_conditions.py +1 -1
  167. chia/_tests/wallet/test_new_wallet_protocol.py +13 -11
  168. chia/_tests/wallet/test_notifications.py +5 -3
  169. chia/_tests/wallet/test_sign_coin_spends.py +6 -6
  170. chia/_tests/wallet/test_signer_protocol.py +13 -12
  171. chia/_tests/wallet/test_singleton.py +1 -1
  172. chia/_tests/wallet/test_singleton_lifecycle_fast.py +5 -7
  173. chia/_tests/wallet/test_util.py +2 -2
  174. chia/_tests/wallet/test_wallet.py +108 -29
  175. chia/_tests/wallet/test_wallet_action_scope.py +9 -2
  176. chia/_tests/wallet/test_wallet_blockchain.py +2 -3
  177. chia/_tests/wallet/test_wallet_key_val_store.py +1 -2
  178. chia/_tests/wallet/test_wallet_node.py +2 -4
  179. chia/_tests/wallet/test_wallet_retry.py +4 -2
  180. chia/_tests/wallet/test_wallet_state_manager.py +191 -5
  181. chia/_tests/wallet/test_wallet_test_framework.py +1 -1
  182. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +8 -8
  183. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +29 -12
  184. chia/_tests/wallet/wallet_block_tools.py +6 -6
  185. chia/_tests/weight_proof/test_weight_proof.py +10 -48
  186. chia/apis.py +1 -1
  187. chia/cmds/beta.py +1 -1
  188. chia/cmds/chia.py +9 -9
  189. chia/cmds/cmd_classes.py +12 -11
  190. chia/cmds/cmd_helpers.py +1 -1
  191. chia/cmds/cmds_util.py +12 -9
  192. chia/cmds/coin_funcs.py +2 -2
  193. chia/cmds/configure.py +2 -2
  194. chia/cmds/data.py +0 -2
  195. chia/cmds/data_funcs.py +1 -1
  196. chia/cmds/db_validate_func.py +1 -2
  197. chia/cmds/dev/__init__.py +0 -0
  198. chia/cmds/dev/data.py +273 -0
  199. chia/cmds/{gh.py → dev/gh.py} +5 -5
  200. chia/cmds/dev/main.py +22 -0
  201. chia/cmds/dev/mempool.py +78 -0
  202. chia/cmds/dev/mempool_funcs.py +63 -0
  203. chia/cmds/farm_funcs.py +5 -4
  204. chia/cmds/init_funcs.py +11 -11
  205. chia/cmds/keys.py +2 -2
  206. chia/cmds/keys_funcs.py +4 -4
  207. chia/cmds/netspace_funcs.py +1 -1
  208. chia/cmds/peer_funcs.py +2 -2
  209. chia/cmds/plotnft_funcs.py +72 -26
  210. chia/cmds/rpc.py +1 -1
  211. chia/cmds/show_funcs.py +5 -5
  212. chia/cmds/signer.py +8 -7
  213. chia/cmds/sim_funcs.py +8 -9
  214. chia/cmds/wallet.py +2 -2
  215. chia/cmds/wallet_funcs.py +165 -131
  216. chia/{util → consensus}/augmented_chain.py +1 -2
  217. chia/consensus/block_body_validation.py +54 -40
  218. chia/consensus/block_creation.py +42 -76
  219. chia/consensus/block_header_validation.py +32 -26
  220. chia/consensus/block_record.py +0 -3
  221. chia/consensus/blockchain.py +23 -32
  222. chia/consensus/blockchain_interface.py +1 -5
  223. chia/consensus/check_time_locks.py +57 -0
  224. chia/consensus/coin_store_protocol.py +151 -0
  225. chia/consensus/coinbase.py +0 -6
  226. chia/consensus/condition_costs.py +4 -0
  227. chia/{util → consensus}/condition_tools.py +4 -5
  228. chia/consensus/cost_calculator.py +1 -1
  229. chia/consensus/default_constants.py +32 -9
  230. chia/consensus/deficit.py +1 -3
  231. chia/consensus/difficulty_adjustment.py +1 -2
  232. chia/consensus/find_fork_point.py +1 -3
  233. chia/consensus/full_block_to_block_record.py +1 -6
  234. chia/{util → consensus}/generator_tools.py +1 -3
  235. chia/consensus/get_block_challenge.py +30 -7
  236. chia/consensus/make_sub_epoch_summary.py +1 -5
  237. chia/consensus/multiprocess_validation.py +21 -20
  238. chia/consensus/pot_iterations.py +74 -13
  239. chia/{util → consensus}/prev_transaction_block.py +1 -1
  240. chia/consensus/vdf_info_computation.py +1 -3
  241. chia/daemon/keychain_proxy.py +5 -5
  242. chia/daemon/server.py +22 -5
  243. chia/data_layer/data_layer.py +92 -51
  244. chia/{rpc → data_layer}/data_layer_rpc_api.py +1 -1
  245. chia/{rpc → data_layer}/data_layer_rpc_util.py +3 -6
  246. chia/data_layer/data_layer_util.py +4 -6
  247. chia/data_layer/data_layer_wallet.py +42 -69
  248. chia/data_layer/dl_wallet_store.py +12 -6
  249. chia/data_layer/download_data.py +3 -3
  250. chia/data_layer/s3_plugin_service.py +0 -1
  251. chia/farmer/farmer.py +3 -4
  252. chia/farmer/farmer_api.py +11 -7
  253. chia/{rpc → farmer}/farmer_rpc_client.py +1 -1
  254. chia/full_node/block_height_map.py +7 -6
  255. chia/full_node/block_store.py +5 -7
  256. chia/full_node/bundle_tools.py +1 -2
  257. chia/full_node/coin_store.py +153 -124
  258. chia/{types → full_node}/eligible_coin_spends.py +39 -70
  259. chia/full_node/fee_estimator.py +1 -1
  260. chia/full_node/fee_estimator_interface.py +0 -8
  261. chia/full_node/fee_tracker.py +25 -25
  262. chia/full_node/full_node.py +70 -53
  263. chia/full_node/full_node_api.py +57 -40
  264. chia/{rpc → full_node}/full_node_rpc_api.py +87 -8
  265. chia/{rpc → full_node}/full_node_rpc_client.py +7 -6
  266. chia/full_node/full_node_store.py +23 -8
  267. chia/full_node/mempool.py +206 -53
  268. chia/full_node/mempool_check_conditions.py +20 -63
  269. chia/full_node/mempool_manager.py +53 -47
  270. chia/full_node/subscriptions.py +1 -3
  271. chia/full_node/tx_processing_queue.py +50 -3
  272. chia/full_node/weight_proof.py +46 -37
  273. chia/harvester/harvester.py +1 -1
  274. chia/harvester/harvester_api.py +22 -7
  275. chia/introducer/introducer.py +1 -1
  276. chia/introducer/introducer_api.py +1 -1
  277. chia/plot_sync/exceptions.py +1 -1
  278. chia/plot_sync/receiver.py +1 -1
  279. chia/plot_sync/sender.py +2 -2
  280. chia/pools/pool_puzzles.py +13 -18
  281. chia/pools/pool_wallet.py +23 -46
  282. chia/protocols/farmer_protocol.py +11 -3
  283. chia/protocols/full_node_protocol.py +1 -4
  284. chia/protocols/harvester_protocol.py +3 -3
  285. chia/protocols/pool_protocol.py +1 -2
  286. chia/protocols/shared_protocol.py +3 -3
  287. chia/protocols/timelord_protocol.py +1 -3
  288. chia/protocols/wallet_protocol.py +3 -3
  289. chia/rpc/rpc_client.py +7 -8
  290. chia/rpc/rpc_server.py +3 -3
  291. chia/rpc/util.py +3 -1
  292. chia/seeder/crawler.py +1 -1
  293. chia/seeder/crawler_api.py +1 -1
  294. chia/seeder/dns_server.py +2 -0
  295. chia/seeder/start_crawler.py +3 -3
  296. chia/server/address_manager.py +286 -38
  297. chia/server/address_manager_store.py +0 -215
  298. chia/{types → server}/aliases.py +7 -7
  299. chia/server/api_protocol.py +1 -1
  300. chia/server/chia_policy.py +1 -1
  301. chia/server/node_discovery.py +76 -113
  302. chia/server/rate_limits.py +1 -1
  303. chia/server/resolve_peer_info.py +43 -0
  304. chia/server/server.py +5 -5
  305. chia/server/start_data_layer.py +4 -4
  306. chia/server/start_farmer.py +5 -4
  307. chia/server/start_full_node.py +5 -4
  308. chia/server/start_harvester.py +7 -5
  309. chia/server/start_introducer.py +2 -2
  310. chia/server/start_service.py +1 -1
  311. chia/server/start_timelord.py +7 -5
  312. chia/server/start_wallet.py +7 -5
  313. chia/server/ws_connection.py +1 -1
  314. chia/simulator/add_blocks_in_batches.py +2 -2
  315. chia/simulator/block_tools.py +245 -201
  316. chia/simulator/full_node_simulator.py +38 -10
  317. chia/simulator/setup_services.py +12 -12
  318. chia/simulator/simulator_full_node_rpc_api.py +2 -2
  319. chia/simulator/simulator_full_node_rpc_client.py +2 -2
  320. chia/simulator/simulator_test_tools.py +2 -2
  321. chia/simulator/start_simulator.py +1 -1
  322. chia/simulator/wallet_tools.py +10 -18
  323. chia/ssl/create_ssl.py +1 -1
  324. chia/timelord/iters_from_block.py +14 -14
  325. chia/timelord/timelord.py +15 -11
  326. chia/timelord/timelord_api.py +14 -2
  327. chia/timelord/timelord_state.py +20 -14
  328. chia/types/blockchain_format/program.py +53 -10
  329. chia/types/blockchain_format/proof_of_space.py +73 -19
  330. chia/types/coin_spend.py +3 -56
  331. chia/types/generator_types.py +28 -0
  332. chia/types/internal_mempool_item.py +1 -2
  333. chia/types/mempool_item.py +12 -7
  334. chia/types/unfinished_header_block.py +1 -2
  335. chia/types/validation_state.py +1 -2
  336. chia/types/weight_proof.py +1 -3
  337. chia/util/action_scope.py +3 -3
  338. chia/util/block_cache.py +1 -2
  339. chia/util/byte_types.py +1 -1
  340. chia/util/casts.py +21 -0
  341. chia/util/config.py +0 -37
  342. chia/util/db_wrapper.py +8 -1
  343. chia/util/errors.py +3 -2
  344. chia/util/initial-config.yaml +21 -5
  345. chia/util/keychain.py +6 -7
  346. chia/util/keyring_wrapper.py +5 -5
  347. chia/util/limited_semaphore.py +1 -1
  348. chia/util/priority_mutex.py +1 -1
  349. chia/util/streamable.py +63 -5
  350. chia/util/task_timing.py +1 -1
  351. chia/util/virtual_project_analysis.py +1 -1
  352. chia/wallet/cat_wallet/cat_info.py +7 -3
  353. chia/wallet/cat_wallet/cat_outer_puzzle.py +9 -5
  354. chia/wallet/cat_wallet/cat_utils.py +1 -1
  355. chia/wallet/cat_wallet/cat_wallet.py +44 -36
  356. chia/wallet/cat_wallet/lineage_store.py +7 -0
  357. chia/wallet/cat_wallet/r_cat_wallet.py +274 -0
  358. chia/wallet/conditions.py +5 -10
  359. chia/wallet/db_wallet/db_wallet_puzzles.py +4 -4
  360. chia/wallet/derivation_record.py +33 -0
  361. chia/wallet/derive_keys.py +3 -3
  362. chia/wallet/did_wallet/did_info.py +12 -3
  363. chia/wallet/did_wallet/did_wallet.py +132 -101
  364. chia/wallet/did_wallet/did_wallet_puzzles.py +9 -9
  365. chia/wallet/driver_protocol.py +3 -1
  366. chia/{types/spend_bundle.py → wallet/estimate_fees.py} +2 -7
  367. chia/wallet/nft_wallet/metadata_outer_puzzle.py +5 -3
  368. chia/wallet/nft_wallet/nft_puzzle_utils.py +1 -1
  369. chia/wallet/nft_wallet/nft_wallet.py +69 -112
  370. chia/wallet/nft_wallet/ownership_outer_puzzle.py +5 -3
  371. chia/wallet/nft_wallet/singleton_outer_puzzle.py +6 -4
  372. chia/wallet/nft_wallet/transfer_program_puzzle.py +4 -2
  373. chia/wallet/nft_wallet/uncurry_nft.py +4 -6
  374. chia/wallet/notification_manager.py +2 -3
  375. chia/wallet/outer_puzzles.py +7 -2
  376. chia/wallet/puzzle_drivers.py +1 -1
  377. chia/wallet/puzzles/clawback/drivers.py +5 -4
  378. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +1 -1
  379. chia/wallet/puzzles/singleton_top_layer.py +2 -1
  380. chia/wallet/puzzles/singleton_top_layer_v1_1.py +2 -1
  381. chia/wallet/puzzles/tails.py +1 -3
  382. chia/wallet/signer_protocol.py +5 -6
  383. chia/wallet/singleton.py +5 -4
  384. chia/wallet/singleton_record.py +1 -1
  385. chia/wallet/trade_manager.py +18 -20
  386. chia/wallet/trade_record.py +3 -6
  387. chia/wallet/trading/offer.py +12 -13
  388. chia/wallet/uncurried_puzzle.py +2 -2
  389. chia/wallet/util/compute_additions.py +58 -0
  390. chia/wallet/util/compute_hints.py +3 -3
  391. chia/wallet/util/compute_memos.py +4 -4
  392. chia/wallet/util/curry_and_treehash.py +2 -1
  393. chia/wallet/util/debug_spend_bundle.py +1 -1
  394. chia/wallet/util/merkle_tree.py +1 -1
  395. chia/wallet/util/peer_request_cache.py +1 -2
  396. chia/wallet/util/tx_config.py +3 -8
  397. chia/wallet/util/wallet_sync_utils.py +10 -5
  398. chia/wallet/util/wallet_types.py +1 -0
  399. chia/wallet/vc_wallet/cr_cat_drivers.py +17 -18
  400. chia/wallet/vc_wallet/cr_cat_wallet.py +30 -28
  401. chia/wallet/vc_wallet/cr_outer_puzzle.py +5 -3
  402. chia/wallet/vc_wallet/vc_drivers.py +50 -8
  403. chia/wallet/vc_wallet/vc_store.py +3 -5
  404. chia/wallet/vc_wallet/vc_wallet.py +15 -22
  405. chia/wallet/wallet.py +36 -46
  406. chia/wallet/wallet_action_scope.py +73 -4
  407. chia/wallet/wallet_blockchain.py +1 -3
  408. chia/wallet/wallet_interested_store.py +1 -1
  409. chia/wallet/wallet_nft_store.py +3 -3
  410. chia/wallet/wallet_node.py +17 -16
  411. chia/wallet/wallet_node_api.py +4 -5
  412. chia/wallet/wallet_pool_store.py +1 -1
  413. chia/wallet/wallet_protocol.py +2 -0
  414. chia/wallet/wallet_puzzle_store.py +1 -1
  415. chia/{rpc → wallet}/wallet_request_types.py +670 -81
  416. chia/{rpc → wallet}/wallet_rpc_api.py +735 -766
  417. chia/{rpc → wallet}/wallet_rpc_client.py +268 -420
  418. chia/wallet/wallet_singleton_store.py +8 -7
  419. chia/wallet/wallet_spend_bundle.py +4 -3
  420. chia/wallet/wallet_state_manager.py +320 -191
  421. chia/wallet/wallet_weight_proof_handler.py +1 -2
  422. chia/wallet/wsm_apis.py +98 -0
  423. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/METADATA +7 -7
  424. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/RECORD +443 -436
  425. mozilla-ca/cacert.pem +3 -165
  426. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +0 -145
  427. chia/cmds/dev.py +0 -18
  428. chia/types/blockchain_format/slots.py +0 -9
  429. chia/types/blockchain_format/sub_epoch_summary.py +0 -5
  430. chia/types/end_of_slot_bundle.py +0 -5
  431. chia/types/full_block.py +0 -5
  432. chia/types/header_block.py +0 -5
  433. chia/types/spend_bundle_conditions.py +0 -7
  434. chia/types/transaction_queue_entry.py +0 -56
  435. chia/types/unfinished_block.py +0 -5
  436. /chia/cmds/{installers.py → dev/installers.py} +0 -0
  437. /chia/cmds/{sim.py → dev/sim.py} +0 -0
  438. /chia/{util → cmds}/dump_keyring.py +0 -0
  439. /chia/{full_node → consensus}/signage_point.py +0 -0
  440. /chia/{rpc → data_layer}/data_layer_rpc_client.py +0 -0
  441. /chia/{rpc → farmer}/farmer_rpc_api.py +0 -0
  442. /chia/{util → full_node}/full_block_utils.py +0 -0
  443. /chia/{rpc → harvester}/harvester_rpc_api.py +0 -0
  444. /chia/{rpc → harvester}/harvester_rpc_client.py +0 -0
  445. /chia/{full_node → protocols}/fee_estimate.py +0 -0
  446. /chia/{server → protocols}/outbound_message.py +0 -0
  447. /chia/{rpc → seeder}/crawler_rpc_api.py +0 -0
  448. /chia/{util → simulator}/vdf_prover.py +0 -0
  449. /chia/{util → ssl}/ssl_check.py +0 -0
  450. /chia/{rpc → timelord}/timelord_rpc_api.py +0 -0
  451. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/LICENSE +0 -0
  452. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/WHEEL +0 -0
  453. {chia_blockchain-2.5.4rc1.dist-info → chia_blockchain-2.5.5.dist-info}/entry_points.txt +0 -0
@@ -2,8 +2,10 @@ from __future__ import annotations
2
2
 
3
3
  import tempfile
4
4
  from pathlib import Path
5
+ from typing import Any, TypeVar
5
6
 
6
7
  import pytest
8
+ from chia_rs import CoinState
7
9
  from chia_rs.sized_bytes import bytes32
8
10
  from chia_rs.sized_ints import uint32, uint64
9
11
 
@@ -15,27 +17,34 @@ from chia._tests.environments.wallet import (
15
17
  WalletTestFramework,
16
18
  )
17
19
  from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_not_none
18
- from chia.protocols.wallet_protocol import CoinState
19
- from chia.rpc.wallet_request_types import GetTransactionMemo, PushTX
20
20
  from chia.simulator.simulator_protocol import ReorgProtocol
21
21
  from chia.types.blockchain_format.coin import Coin, coin_as_list
22
- from chia.types.blockchain_format.program import Program
22
+ from chia.types.blockchain_format.program import NIL, Program
23
23
  from chia.types.coin_spend import make_spend
24
24
  from chia.util.bech32m import encode_puzzle_hash
25
25
  from chia.util.db_wrapper import DBWrapper2
26
26
  from chia.wallet.cat_wallet.cat_constants import DEFAULT_CATS
27
27
  from chia.wallet.cat_wallet.cat_info import LegacyCATInfo
28
- from chia.wallet.cat_wallet.cat_utils import CAT_MOD, construct_cat_puzzle
28
+ from chia.wallet.cat_wallet.cat_utils import (
29
+ CAT_MOD,
30
+ SpendableCAT,
31
+ construct_cat_puzzle,
32
+ unsigned_spend_bundle_for_spendable_cats,
33
+ )
29
34
  from chia.wallet.cat_wallet.cat_wallet import CATWallet
35
+ from chia.wallet.cat_wallet.r_cat_wallet import RCATWallet
36
+ from chia.wallet.conditions import CreateCoin, UnknownCondition
30
37
  from chia.wallet.derivation_record import DerivationRecord
31
38
  from chia.wallet.derive_keys import master_pk_to_wallet_pk_unhardened
32
39
  from chia.wallet.lineage_proof import LineageProof
33
40
  from chia.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_hash_for_pk
34
41
  from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
35
42
  from chia.wallet.util.wallet_types import WalletType
43
+ from chia.wallet.vc_wallet.vc_drivers import create_revocation_layer
36
44
  from chia.wallet.wallet_info import WalletInfo
37
45
  from chia.wallet.wallet_interested_store import WalletInterestedStore
38
46
  from chia.wallet.wallet_node import WalletNode
47
+ from chia.wallet.wallet_request_types import GetTransactionMemo, PushTX
39
48
  from chia.wallet.wallet_state_manager import WalletStateManager
40
49
 
41
50
 
@@ -43,149 +52,220 @@ def check_wallets(node: WalletNode) -> int:
43
52
  return len(node.wallet_state_manager.wallets.keys())
44
53
 
45
54
 
46
- @pytest.mark.parametrize(
47
- "wallet_environments",
48
- [
49
- {
50
- "num_environments": 1,
51
- "blocks_needed": [1],
52
- }
53
- ],
54
- indirect=True,
55
- )
56
- @pytest.mark.limit_consensus_modes([ConsensusMode.PLAIN], reason="irrelevant")
57
- @pytest.mark.anyio
58
- async def test_cat_creation(wallet_environments: WalletTestFramework) -> None:
59
- full_node_api = wallet_environments.full_node
60
- wsm = wallet_environments.environments[0].wallet_state_manager
61
- wallet = wallet_environments.environments[0].xch_wallet
62
- wallet_node = wallet_environments.environments[0].node
63
- wallet_environments.environments[0].wallet_aliases = {
64
- "xch": 1,
65
- "cat": 2,
66
- }
67
- test_amount = 100
68
- test_fee = 10
69
- async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
70
- cat_wallet = await CATWallet.create_new_cat_wallet(
71
- wsm,
72
- wallet,
73
- {"identifier": "genesis_by_id"},
74
- uint64(test_amount),
75
- action_scope,
76
- fee=uint64(test_fee),
55
+ _T_CATWallet = TypeVar("_T_CATWallet", bound=CATWallet)
56
+
57
+
58
+ async def mint_cat(
59
+ wallet_environments: WalletTestFramework,
60
+ environment: WalletEnvironment,
61
+ xch_alias: str,
62
+ cat_alias: str,
63
+ amount: uint64,
64
+ wallet_type: type[_T_CATWallet],
65
+ tail_nonce: str,
66
+ ) -> _T_CATWallet:
67
+ # (f (q . (() . tail_nonce)))
68
+ tail = Program.to([5, (1, (None, tail_nonce))])
69
+ tail_hash = tail.get_tree_hash()
70
+ async with environment.wallet_state_manager.new_action_scope(
71
+ wallet_environments.tx_config, push=True
72
+ ) as action_scope:
73
+ inner_puzzle_hash = await action_scope.get_puzzle_hash(environment.wallet_state_manager)
74
+ if wallet_type is RCATWallet:
75
+ wrapped_inner_puzzle_hash = create_revocation_layer(bytes32.zeros, inner_puzzle_hash).get_tree_hash()
76
+ extra_args: Any = (bytes32.zeros,)
77
+ else:
78
+ wrapped_inner_puzzle_hash = inner_puzzle_hash
79
+ extra_args = tuple()
80
+ eve_inner_puzzle = Program.to(
81
+ (
82
+ 1,
83
+ [
84
+ CreateCoin(wrapped_inner_puzzle_hash, amount, memos=[inner_puzzle_hash]).to_program(),
85
+ UnknownCondition(opcode=Program.to(51), args=[NIL, Program.to(-113), tail, NIL]).to_program(),
86
+ ],
87
+ )
77
88
  )
78
- # The next 2 lines are basically a noop, it just adds test coverage
79
- cat_wallet = await CATWallet.create(wsm, wallet, cat_wallet.wallet_info)
80
- await wsm.add_new_wallet(cat_wallet)
89
+ eve_cat_puzzle = construct_cat_puzzle(
90
+ CAT_MOD,
91
+ tail_hash,
92
+ eve_inner_puzzle,
93
+ )
94
+ eve_cat_puzzle_hash = eve_cat_puzzle.get_tree_hash()
95
+ await environment.xch_wallet.generate_signed_transaction(
96
+ amounts=[amount],
97
+ puzzle_hashes=[eve_cat_puzzle_hash],
98
+ action_scope=action_scope,
99
+ )
100
+ async with action_scope.use() as interface:
101
+ cat_addition = next(
102
+ addition
103
+ for tx in interface.side_effects.transactions
104
+ for addition in tx.additions
105
+ if addition.puzzle_hash == eve_cat_puzzle_hash
106
+ )
107
+ interface.side_effects.extra_spends.append(
108
+ unsigned_spend_bundle_for_spendable_cats(
109
+ CAT_MOD,
110
+ [
111
+ SpendableCAT(
112
+ cat_addition,
113
+ tail_hash,
114
+ eve_inner_puzzle,
115
+ NIL,
116
+ )
117
+ ],
118
+ )
119
+ )
120
+
121
+ cat_wallet = await wallet_type.get_or_create_wallet_for_cat(
122
+ environment.wallet_state_manager, environment.xch_wallet, tail_hash.hex(), *extra_args
123
+ )
81
124
 
82
125
  await wallet_environments.process_pending_states(
83
126
  [
84
- WalletStateTransition(
127
+ WalletStateTransition()
128
+ if env != environment
129
+ else WalletStateTransition(
85
130
  pre_block_balance_updates={
86
- "xch": {
131
+ xch_alias: {
87
132
  "confirmed_wallet_balance": 0,
88
- "unconfirmed_wallet_balance": -test_amount + -test_fee,
89
- "<=#spendable_balance": -test_amount + -test_fee,
90
- "<=#max_send_amount": -test_amount + -test_fee,
133
+ "unconfirmed_wallet_balance": -amount,
134
+ "<=#spendable_balance": -amount,
135
+ "<=#max_send_amount": -amount,
91
136
  ">=#pending_change": 1, # any amount increase
92
137
  "pending_coin_removal_count": 1,
93
138
  },
94
- "cat": {
139
+ cat_alias: {
95
140
  "init": True,
96
- "confirmed_wallet_balance": 0,
97
- "unconfirmed_wallet_balance": test_amount,
98
- "spendable_balance": 0,
99
- "max_send_amount": 0,
100
- "pending_change": test_amount,
101
- "pending_coin_removal_count": 1,
102
141
  },
103
142
  },
104
143
  post_block_balance_updates={
105
- "xch": {
106
- "confirmed_wallet_balance": -test_amount + -test_fee,
144
+ xch_alias: {
145
+ "confirmed_wallet_balance": -amount,
107
146
  "unconfirmed_wallet_balance": 0,
108
147
  ">=#spendable_balance": 0,
109
148
  ">=#max_send_amount": 0,
110
149
  "<=#pending_change": 1, # any amount decrease
111
150
  "pending_coin_removal_count": -1,
112
151
  },
113
- "cat": {
114
- "confirmed_wallet_balance": test_amount,
115
- "unconfirmed_wallet_balance": 0,
116
- "spendable_balance": test_amount,
117
- "max_send_amount": test_amount,
118
- "pending_change": -test_amount,
119
- "pending_coin_removal_count": -1,
152
+ cat_alias: {
153
+ "confirmed_wallet_balance": amount,
154
+ "unconfirmed_wallet_balance": amount,
155
+ "spendable_balance": amount,
156
+ "max_send_amount": amount,
120
157
  "unspent_coin_count": 1,
121
158
  },
122
159
  },
123
160
  )
161
+ for env in wallet_environments.environments
124
162
  ]
125
163
  )
126
164
 
127
- # Test migration
128
- all_lineage = await cat_wallet.lineage_store.get_all_lineage_proofs()
129
- current_info = cat_wallet.wallet_info
130
- data_str = bytes(
131
- LegacyCATInfo(
132
- cat_wallet.cat_info.limitations_program_hash, cat_wallet.cat_info.my_tail, list(all_lineage.items())
133
- )
134
- ).hex()
135
- wallet_info = WalletInfo(current_info.id, current_info.name, current_info.type, data_str)
136
- new_cat_wallet = await CATWallet.create(wsm, wallet, wallet_info)
137
- assert new_cat_wallet.cat_info.limitations_program_hash == cat_wallet.cat_info.limitations_program_hash
138
- assert new_cat_wallet.cat_info.my_tail == cat_wallet.cat_info.my_tail
139
- assert await cat_wallet.lineage_store.get_all_lineage_proofs() == all_lineage
165
+ return cat_wallet
140
166
 
141
- height = full_node_api.full_node.blockchain.get_peak_height()
142
- assert height is not None
143
- await full_node_api.reorg_from_index_to_new_index(
144
- ReorgProtocol(uint32(height - 1), uint32(height + 1), bytes32(32 * b"1"), None)
167
+
168
+ @pytest.mark.parametrize(
169
+ "wallet_environments",
170
+ [
171
+ {
172
+ "num_environments": 1,
173
+ "blocks_needed": [1],
174
+ }
175
+ ],
176
+ indirect=True,
177
+ )
178
+ @pytest.mark.limit_consensus_modes([ConsensusMode.PLAIN], reason="irrelevant")
179
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
180
+ @pytest.mark.anyio
181
+ async def test_cat_creation(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
182
+ full_node_api = wallet_environments.full_node
183
+ wsm = wallet_environments.environments[0].wallet_state_manager
184
+ wallet = wallet_environments.environments[0].xch_wallet
185
+ wallet_node = wallet_environments.environments[0].node
186
+ wallet_environments.environments[0].wallet_aliases = {
187
+ "xch": 1,
188
+ "cat": 2,
189
+ }
190
+ test_amount = uint64(100)
191
+
192
+ cat_wallet = await mint_cat(
193
+ wallet_environments,
194
+ wallet_environments.environments[0],
195
+ "xch",
196
+ "cat",
197
+ test_amount,
198
+ wallet_type,
199
+ "cat wallet",
145
200
  )
146
- await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, peak_height=uint32(height + 1))
147
- # The "set_remainder" sections here are due to a peculiarity with how the creation method creates an incoming TX
148
- # The creation method is for testing purposes only so we're not going to bother fixing it for any real reason
149
- await wallet_environments.process_pending_states(
150
- [
151
- WalletStateTransition(
152
- pre_block_balance_updates={
153
- "xch": {
154
- "confirmed_wallet_balance": test_amount + test_fee,
155
- "unconfirmed_wallet_balance": 0,
156
- "<=#spendable_balance": 1,
157
- "<=#max_send_amount": 1,
158
- ">=#pending_change": 1, # any amount increase
159
- "pending_coin_removal_count": 1,
160
- },
161
- "cat": {
162
- "confirmed_wallet_balance": -test_amount,
163
- "spendable_balance": -test_amount,
164
- "max_send_amount": -test_amount,
165
- "unspent_coin_count": -1,
166
- "set_remainder": True,
167
- },
168
- },
169
- post_block_balance_updates={
170
- "xch": {
171
- "confirmed_wallet_balance": -test_amount + -test_fee,
172
- "unconfirmed_wallet_balance": 0,
173
- ">=#spendable_balance": 0,
174
- ">=#max_send_amount": 0,
175
- "<=#pending_change": 1, # any amount decrease
176
- "pending_coin_removal_count": -1,
201
+
202
+ # The next 2 lines are basically a noop, it just adds test coverage
203
+ cat_wallet = await wallet_type.create(wsm, wallet, cat_wallet.wallet_info)
204
+ await wsm.add_new_wallet(cat_wallet)
205
+
206
+ if wallet_type is CATWallet:
207
+ # Test migration
208
+ all_lineage = await cat_wallet.lineage_store.get_all_lineage_proofs()
209
+ current_info = cat_wallet.wallet_info
210
+ data_str = bytes(
211
+ LegacyCATInfo(
212
+ cat_wallet.cat_info.limitations_program_hash, cat_wallet.cat_info.my_tail, list(all_lineage.items())
213
+ )
214
+ ).hex()
215
+ wallet_info = WalletInfo(current_info.id, current_info.name, current_info.type, data_str)
216
+ new_cat_wallet = await wallet_type.create(wsm, wallet, wallet_info)
217
+ assert new_cat_wallet.cat_info.limitations_program_hash == cat_wallet.cat_info.limitations_program_hash
218
+ assert new_cat_wallet.cat_info.my_tail == cat_wallet.cat_info.my_tail
219
+ assert await cat_wallet.lineage_store.get_all_lineage_proofs() == all_lineage
220
+
221
+ height = full_node_api.full_node.blockchain.get_peak_height()
222
+ assert height is not None
223
+ await full_node_api.reorg_from_index_to_new_index(
224
+ ReorgProtocol(uint32(height - 1), uint32(height + 1), bytes32(32 * b"1"), None)
225
+ )
226
+ await full_node_api.wait_for_wallet_synced(wallet_node=wallet_node, peak_height=uint32(height + 1))
227
+ # The "set_remainder" sections here are due to a peculiarity with how the creation method creates an incoming TX
228
+ # The creation method is for testing purposes only so we're not going to bother fixing it for any real reason
229
+ await wallet_environments.process_pending_states(
230
+ [
231
+ WalletStateTransition(
232
+ pre_block_balance_updates={
233
+ "xch": {
234
+ "confirmed_wallet_balance": test_amount,
235
+ "unconfirmed_wallet_balance": 0,
236
+ "<=#spendable_balance": 1,
237
+ "<=#max_send_amount": 1,
238
+ ">=#pending_change": 1, # any amount increase
239
+ "pending_coin_removal_count": 1,
240
+ },
241
+ "cat": {
242
+ "confirmed_wallet_balance": -test_amount,
243
+ "spendable_balance": -test_amount,
244
+ "max_send_amount": -test_amount,
245
+ "unspent_coin_count": -1,
246
+ "set_remainder": True,
247
+ },
177
248
  },
178
- "cat": {
179
- "confirmed_wallet_balance": test_amount,
180
- "spendable_balance": test_amount,
181
- "max_send_amount": test_amount,
182
- "unspent_coin_count": 1,
183
- "set_remainder": True,
249
+ post_block_balance_updates={
250
+ "xch": {
251
+ "confirmed_wallet_balance": -test_amount,
252
+ "unconfirmed_wallet_balance": 0,
253
+ ">=#spendable_balance": 0,
254
+ ">=#max_send_amount": 0,
255
+ "<=#pending_change": 1, # any amount decrease
256
+ "pending_coin_removal_count": -1,
257
+ },
258
+ "cat": {
259
+ "confirmed_wallet_balance": test_amount,
260
+ "spendable_balance": test_amount,
261
+ "max_send_amount": test_amount,
262
+ "unspent_coin_count": 1,
263
+ "set_remainder": True,
264
+ },
184
265
  },
185
- },
186
- ),
187
- ]
188
- )
266
+ ),
267
+ ]
268
+ )
189
269
 
190
270
 
191
271
  @pytest.mark.parametrize(
@@ -201,27 +281,35 @@ async def test_cat_creation(wallet_environments: WalletTestFramework) -> None:
201
281
  indirect=True,
202
282
  )
203
283
  @pytest.mark.limit_consensus_modes([ConsensusMode.PLAIN], reason="irrelevant")
284
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
204
285
  @pytest.mark.anyio
205
- async def test_cat_creation_unique_lineage_store(wallet_environments: WalletTestFramework) -> None:
206
- wsm = wallet_environments.environments[0].wallet_state_manager
207
- wallet = wallet_environments.environments[0].xch_wallet
286
+ async def test_cat_creation_unique_lineage_store(
287
+ wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]
288
+ ) -> None:
289
+ wallet_environments.environments[0].wallet_aliases = {
290
+ "xch": 1,
291
+ "cat1": 2,
292
+ "cat2": 3,
293
+ }
208
294
 
209
- async with wsm.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
210
- cat_wallet_1 = await CATWallet.create_new_cat_wallet(
211
- wsm,
212
- wallet,
213
- {"identifier": "genesis_by_id"},
214
- uint64(100),
215
- action_scope,
216
- )
217
- async with wsm.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
218
- cat_wallet_2 = await CATWallet.create_new_cat_wallet(
219
- wsm,
220
- wallet,
221
- {"identifier": "genesis_by_id"},
222
- uint64(200),
223
- action_scope,
224
- )
295
+ cat_wallet_1 = await mint_cat(
296
+ wallet_environments,
297
+ wallet_environments.environments[0],
298
+ "xch",
299
+ "cat1",
300
+ uint64(100),
301
+ wallet_type,
302
+ "cat wallet 1",
303
+ )
304
+ cat_wallet_2 = await mint_cat(
305
+ wallet_environments,
306
+ wallet_environments.environments[0],
307
+ "xch",
308
+ "cat2",
309
+ uint64(200),
310
+ wallet_type,
311
+ "cat wallet 2",
312
+ )
225
313
 
226
314
  proofs_1 = await cat_wallet_1.lineage_store.get_all_lineage_proofs()
227
315
  proofs_2 = await cat_wallet_2.lineage_store.get_all_lineage_proofs()
@@ -241,14 +329,14 @@ async def test_cat_creation_unique_lineage_store(wallet_environments: WalletTest
241
329
  ],
242
330
  indirect=True,
243
331
  )
332
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
244
333
  @pytest.mark.anyio
245
- async def test_cat_spend(wallet_environments: WalletTestFramework) -> None:
334
+ async def test_cat_spend(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
246
335
  # Setup
247
336
  env_1: WalletEnvironment = wallet_environments.environments[0]
248
337
  env_2: WalletEnvironment = wallet_environments.environments[1]
249
338
  wallet_node = env_1.node
250
339
  wallet_node_2 = env_2.node
251
- wallet = env_1.xch_wallet
252
340
  wallet2 = env_2.xch_wallet
253
341
  full_node_api = wallet_environments.full_node
254
342
 
@@ -261,69 +349,25 @@ async def test_cat_spend(wallet_environments: WalletTestFramework) -> None:
261
349
  "cat": 2,
262
350
  }
263
351
 
264
- async with wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
265
- cat_wallet = await CATWallet.create_new_cat_wallet(
266
- wallet_node.wallet_state_manager,
267
- wallet,
268
- {"identifier": "genesis_by_id"},
269
- uint64(100),
270
- action_scope,
271
- )
272
-
273
- await wallet_environments.process_pending_states(
274
- [
275
- WalletStateTransition(
276
- pre_block_balance_updates={
277
- "xch": {
278
- "unconfirmed_wallet_balance": -100,
279
- "<=#spendable_balance": -100,
280
- "<=#max_send_amount": -100,
281
- ">=#pending_change": 1, # any amount increase
282
- "unspent_coin_count": 0,
283
- "pending_coin_removal_count": 1,
284
- },
285
- "cat": {
286
- "init": True,
287
- "confirmed_wallet_balance": 0,
288
- "unconfirmed_wallet_balance": 100,
289
- "spendable_balance": 0,
290
- "pending_change": 100, # A little weird but technically correct
291
- "max_send_amount": 0,
292
- "unspent_coin_count": 0,
293
- "pending_coin_removal_count": 1, # The ephemeral eve spend
294
- },
295
- },
296
- post_block_balance_updates={
297
- "xch": {
298
- "confirmed_wallet_balance": -100,
299
- ">=#spendable_balance": 1, # any amount increase
300
- ">=#max_send_amount": 1, # any amount increase
301
- "<=#pending_change": -1, # any amount decrease
302
- "unspent_coin_count": 0,
303
- "pending_coin_removal_count": -1,
304
- },
305
- "cat": {
306
- "confirmed_wallet_balance": 100,
307
- "spendable_balance": 100,
308
- "pending_change": -100,
309
- "max_send_amount": 100,
310
- "unspent_coin_count": 1,
311
- "pending_coin_removal_count": -1,
312
- },
313
- },
314
- ),
315
- WalletStateTransition(),
316
- ]
317
- )
352
+ cat_wallet = await mint_cat(wallet_environments, env_1, "xch", "cat", uint64(100), wallet_type, "cat wallet")
318
353
 
319
354
  assert cat_wallet.cat_info.limitations_program_hash is not None
320
355
  asset_id = cat_wallet.get_asset_id()
321
356
 
322
- cat_wallet_2 = await CATWallet.get_or_create_wallet_for_cat(wallet_node_2.wallet_state_manager, wallet2, asset_id)
357
+ if wallet_type is RCATWallet:
358
+ extra_args: Any = (bytes32.zeros,)
359
+ else:
360
+ extra_args = tuple()
361
+ cat_wallet_2 = await wallet_type.get_or_create_wallet_for_cat(
362
+ wallet_node_2.wallet_state_manager, wallet2, asset_id, *extra_args
363
+ )
323
364
 
324
365
  assert cat_wallet.cat_info.limitations_program_hash == cat_wallet_2.cat_info.limitations_program_hash
325
366
 
326
- cat_2_hash = await cat_wallet_2.standard_wallet.get_puzzle_hash(new=False)
367
+ async with cat_wallet_2.wallet_state_manager.new_action_scope(
368
+ wallet_environments.tx_config, push=True
369
+ ) as action_scope:
370
+ cat_2_hash = await action_scope.get_puzzle_hash(cat_wallet_2.wallet_state_manager)
327
371
  async with cat_wallet.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
328
372
  await cat_wallet.generate_signed_transaction([uint64(60)], [cat_2_hash], action_scope, fee=uint64(1))
329
373
  tx_id = None
@@ -335,7 +379,7 @@ async def test_cat_spend(wallet_environments: WalletTestFramework) -> None:
335
379
  assert tx_id is not None
336
380
  memos = await env_1.rpc_client.get_transaction_memo(GetTransactionMemo(transaction_id=tx_id))
337
381
  assert len(memos.coins_with_memos) == 2
338
- assert memos.coins_with_memos[1].memos[0] == cat_2_hash
382
+ assert cat_2_hash in {coin_w_memos.memos[0] for coin_w_memos in memos.coins_with_memos}
339
383
 
340
384
  await wallet_environments.process_pending_states(
341
385
  [
@@ -412,8 +456,11 @@ async def test_cat_spend(wallet_environments: WalletTestFramework) -> None:
412
456
  tx_id = coin.name()
413
457
  memos = await env_2.rpc_client.get_transaction_memo(GetTransactionMemo(transaction_id=tx_id))
414
458
  assert len(memos.coins_with_memos) == 2
415
- assert memos.coins_with_memos[1].memos[0] == cat_2_hash
416
- cat_hash = await cat_wallet.standard_wallet.get_puzzle_hash(new=False)
459
+ assert cat_2_hash in {coin_w_memos.memos[0] for coin_w_memos in memos.coins_with_memos}
460
+ async with cat_wallet.wallet_state_manager.new_action_scope(
461
+ wallet_environments.tx_config, push=True
462
+ ) as action_scope:
463
+ cat_hash = await action_scope.get_puzzle_hash(cat_wallet.wallet_state_manager)
417
464
  async with cat_wallet_2.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
418
465
  await cat_wallet_2.generate_signed_transaction([uint64(15)], [cat_hash], action_scope)
419
466
 
@@ -493,8 +540,9 @@ async def test_cat_spend(wallet_environments: WalletTestFramework) -> None:
493
540
  ],
494
541
  indirect=True,
495
542
  )
543
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
496
544
  @pytest.mark.anyio
497
- async def test_get_wallet_for_asset_id(wallet_environments: WalletTestFramework) -> None:
545
+ async def test_get_wallet_for_asset_id(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
498
546
  wsm = wallet_environments.environments[0].wallet_state_manager
499
547
  wallet = wallet_environments.environments[0].xch_wallet
500
548
 
@@ -503,14 +551,9 @@ async def test_get_wallet_for_asset_id(wallet_environments: WalletTestFramework)
503
551
  "cat": 2,
504
552
  }
505
553
 
506
- async with wsm.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
507
- cat_wallet = await CATWallet.create_new_cat_wallet(
508
- wsm,
509
- wallet,
510
- {"identifier": "genesis_by_id"},
511
- uint64(100),
512
- action_scope,
513
- )
554
+ cat_wallet = await mint_cat(
555
+ wallet_environments, wallet_environments.environments[0], "xch", "cat", uint64(100), wallet_type, "cat wallet"
556
+ )
514
557
 
515
558
  await wallet_environments.process_pending_states(
516
559
  [
@@ -528,14 +571,16 @@ async def test_get_wallet_for_asset_id(wallet_environments: WalletTestFramework)
528
571
  )
529
572
 
530
573
  asset_id = cat_wallet.get_asset_id()
531
- assert cat_wallet.cat_info.my_tail is not None
532
- await cat_wallet.set_tail_program(bytes(cat_wallet.cat_info.my_tail).hex())
533
574
  assert await wsm.get_wallet_for_asset_id(asset_id) == cat_wallet
534
575
 
535
576
  # Test that the a default CAT will initialize correctly
536
577
  asset = DEFAULT_CATS[next(iter(DEFAULT_CATS))]
537
578
  asset_id = asset["asset_id"]
538
- cat_wallet_2 = await CATWallet.get_or_create_wallet_for_cat(wsm, wallet, asset_id)
579
+ if wallet_type is RCATWallet:
580
+ extra_args: Any = (bytes32.zeros,)
581
+ else:
582
+ extra_args = tuple()
583
+ cat_wallet_2 = await wallet_type.get_or_create_wallet_for_cat(wsm, wallet, asset_id, *extra_args)
539
584
  assert cat_wallet_2.get_name() == asset["name"]
540
585
  await cat_wallet_2.set_name("Test Name")
541
586
  assert cat_wallet_2.get_name() == "Test Name"
@@ -553,12 +598,12 @@ async def test_get_wallet_for_asset_id(wallet_environments: WalletTestFramework)
553
598
  ],
554
599
  indirect=True,
555
600
  )
601
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
556
602
  @pytest.mark.anyio
557
- async def test_cat_doesnt_see_eve(wallet_environments: WalletTestFramework) -> None:
603
+ async def test_cat_doesnt_see_eve(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
558
604
  # Setup
559
605
  env_1: WalletEnvironment = wallet_environments.environments[0]
560
606
  env_2: WalletEnvironment = wallet_environments.environments[1]
561
- wallet_node = env_1.node
562
607
  wallet_node_2 = env_2.node
563
608
  wallet = env_1.xch_wallet
564
609
  wallet2 = env_2.xch_wallet
@@ -572,50 +617,25 @@ async def test_cat_doesnt_see_eve(wallet_environments: WalletTestFramework) -> N
572
617
  "cat": 2,
573
618
  }
574
619
 
575
- async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
576
- cat_wallet = await CATWallet.create_new_cat_wallet(
577
- wallet_node.wallet_state_manager,
578
- wallet,
579
- {"identifier": "genesis_by_id"},
580
- uint64(100),
581
- action_scope,
582
- )
583
-
584
- await wallet_environments.process_pending_states(
585
- [
586
- WalletStateTransition(
587
- pre_block_balance_updates={
588
- "xch": {"set_remainder": True},
589
- "cat": {"init": True, "set_remainder": True},
590
- },
591
- post_block_balance_updates={
592
- "xch": {"set_remainder": True},
593
- "cat": {
594
- "confirmed_wallet_balance": 100,
595
- "unconfirmed_wallet_balance": 0,
596
- "spendable_balance": 100,
597
- "max_send_amount": 100,
598
- "pending_change": -100,
599
- "pending_coin_removal_count": -1,
600
- "unspent_coin_count": 1,
601
- },
602
- },
603
- ),
604
- WalletStateTransition(
605
- pre_block_balance_updates={},
606
- post_block_balance_updates={},
607
- ),
608
- ]
609
- )
620
+ cat_wallet = await mint_cat(wallet_environments, env_1, "xch", "cat", uint64(100), wallet_type, "cat wallet")
610
621
 
611
622
  assert cat_wallet.cat_info.limitations_program_hash is not None
612
623
  asset_id = cat_wallet.get_asset_id()
613
624
 
614
- cat_wallet_2 = await CATWallet.get_or_create_wallet_for_cat(wallet_node_2.wallet_state_manager, wallet2, asset_id)
625
+ if wallet_type is RCATWallet:
626
+ extra_args: Any = (bytes32.zeros,)
627
+ else:
628
+ extra_args = tuple()
629
+ cat_wallet_2 = await wallet_type.get_or_create_wallet_for_cat(
630
+ wallet_node_2.wallet_state_manager, wallet2, asset_id, *extra_args
631
+ )
615
632
 
616
633
  assert cat_wallet.cat_info.limitations_program_hash == cat_wallet_2.cat_info.limitations_program_hash
617
634
 
618
- cat_2_hash = await cat_wallet_2.standard_wallet.get_puzzle_hash(new=False)
635
+ async with cat_wallet_2.wallet_state_manager.new_action_scope(
636
+ wallet_environments.tx_config, push=True
637
+ ) as action_scope:
638
+ cat_2_hash = await action_scope.get_puzzle_hash(cat_wallet_2.wallet_state_manager)
619
639
  async with cat_wallet.wallet_state_manager.new_action_scope(
620
640
  wallet_environments.tx_config, push=True
621
641
  ) as action_scope:
@@ -746,16 +766,15 @@ async def test_cat_doesnt_see_eve(wallet_environments: WalletTestFramework) -> N
746
766
  ],
747
767
  indirect=True,
748
768
  )
769
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
749
770
  @pytest.mark.anyio
750
- async def test_cat_spend_multiple(wallet_environments: WalletTestFramework) -> None:
771
+ async def test_cat_spend_multiple(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
751
772
  # Setup
752
773
  env_0: WalletEnvironment = wallet_environments.environments[0]
753
774
  env_1: WalletEnvironment = wallet_environments.environments[1]
754
775
  env_2: WalletEnvironment = wallet_environments.environments[2]
755
- wallet_node_0 = env_0.node
756
776
  wallet_node_1 = env_1.node
757
777
  wallet_node_2 = env_2.node
758
- wallet_0 = env_0.xch_wallet
759
778
  wallet_1 = env_1.xch_wallet
760
779
  wallet_2 = env_2.xch_wallet
761
780
 
@@ -772,59 +791,35 @@ async def test_cat_spend_multiple(wallet_environments: WalletTestFramework) -> N
772
791
  "cat": 2,
773
792
  }
774
793
 
775
- async with wallet_0.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
776
- cat_wallet_0 = await CATWallet.create_new_cat_wallet(
777
- wallet_node_0.wallet_state_manager,
778
- wallet_0,
779
- {"identifier": "genesis_by_id"},
780
- uint64(100),
781
- action_scope,
782
- )
783
-
784
- await wallet_environments.process_pending_states(
785
- [
786
- WalletStateTransition(
787
- pre_block_balance_updates={
788
- "xch": {"set_remainder": True},
789
- "cat": {"init": True, "set_remainder": True},
790
- },
791
- post_block_balance_updates={
792
- "xch": {"set_remainder": True},
793
- "cat": {
794
- "confirmed_wallet_balance": 100,
795
- "unconfirmed_wallet_balance": 0,
796
- "spendable_balance": 100,
797
- "max_send_amount": 100,
798
- "pending_change": -100,
799
- "pending_coin_removal_count": -1,
800
- "unspent_coin_count": 1,
801
- },
802
- },
803
- ),
804
- WalletStateTransition(
805
- pre_block_balance_updates={},
806
- post_block_balance_updates={},
807
- ),
808
- WalletStateTransition(
809
- pre_block_balance_updates={},
810
- post_block_balance_updates={},
811
- ),
812
- ]
813
- )
794
+ cat_wallet_0 = await mint_cat(wallet_environments, env_0, "xch", "cat", uint64(100), wallet_type, "cat wallet")
814
795
 
815
796
  assert cat_wallet_0.cat_info.limitations_program_hash is not None
816
797
  asset_id = cat_wallet_0.get_asset_id()
817
798
 
818
- cat_wallet_1 = await CATWallet.get_or_create_wallet_for_cat(wallet_node_1.wallet_state_manager, wallet_1, asset_id)
799
+ if wallet_type is RCATWallet:
800
+ extra_args: Any = (bytes32.zeros,)
801
+ else:
802
+ extra_args = tuple()
803
+
804
+ cat_wallet_1 = await wallet_type.get_or_create_wallet_for_cat(
805
+ wallet_node_1.wallet_state_manager, wallet_1, asset_id, *extra_args
806
+ )
819
807
 
820
- cat_wallet_2 = await CATWallet.get_or_create_wallet_for_cat(wallet_node_2.wallet_state_manager, wallet_2, asset_id)
808
+ cat_wallet_2 = await wallet_type.get_or_create_wallet_for_cat(
809
+ wallet_node_2.wallet_state_manager, wallet_2, asset_id, *extra_args
810
+ )
821
811
 
822
812
  assert cat_wallet_0.cat_info.limitations_program_hash == cat_wallet_1.cat_info.limitations_program_hash
823
813
  assert cat_wallet_0.cat_info.limitations_program_hash == cat_wallet_2.cat_info.limitations_program_hash
824
814
 
825
- cat_1_hash = await cat_wallet_1.standard_wallet.get_puzzle_hash(new=False)
826
- cat_2_hash = await cat_wallet_2.standard_wallet.get_puzzle_hash(new=False)
827
-
815
+ async with cat_wallet_1.wallet_state_manager.new_action_scope(
816
+ wallet_environments.tx_config, push=True
817
+ ) as action_scope:
818
+ cat_1_hash = await action_scope.get_puzzle_hash(cat_wallet_1.wallet_state_manager)
819
+ async with cat_wallet_2.wallet_state_manager.new_action_scope(
820
+ wallet_environments.tx_config, push=True
821
+ ) as action_scope:
822
+ cat_2_hash = await action_scope.get_puzzle_hash(cat_wallet_2.wallet_state_manager)
828
823
  async with cat_wallet_0.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
829
824
  await cat_wallet_0.generate_signed_transaction([uint64(60), uint64(20)], [cat_1_hash, cat_2_hash], action_scope)
830
825
 
@@ -905,8 +900,10 @@ async def test_cat_spend_multiple(wallet_environments: WalletTestFramework) -> N
905
900
  ]
906
901
  )
907
902
 
908
- cat_hash = await cat_wallet_0.standard_wallet.get_puzzle_hash(new=False)
909
-
903
+ async with cat_wallet_0.wallet_state_manager.new_action_scope(
904
+ wallet_environments.tx_config, push=True
905
+ ) as action_scope:
906
+ cat_hash = await action_scope.get_puzzle_hash(cat_wallet_0.wallet_state_manager)
910
907
  async with cat_wallet_1.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
911
908
  await cat_wallet_1.generate_signed_transaction([uint64(15)], [cat_hash], action_scope)
912
909
 
@@ -1066,63 +1063,32 @@ async def test_cat_spend_multiple(wallet_environments: WalletTestFramework) -> N
1066
1063
  ],
1067
1064
  indirect=True,
1068
1065
  )
1066
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
1069
1067
  @pytest.mark.anyio
1070
- async def test_cat_max_amount_send(wallet_environments: WalletTestFramework) -> None:
1068
+ async def test_cat_max_amount_send(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
1071
1069
  # Setup
1072
1070
  env: WalletEnvironment = wallet_environments.environments[0]
1073
- wallet_node = env.node
1074
- wallet = env.xch_wallet
1075
1071
 
1076
1072
  env.wallet_aliases = {
1077
1073
  "xch": 1,
1078
1074
  "cat": 2,
1079
1075
  }
1080
1076
 
1081
- async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1082
- cat_wallet = await CATWallet.create_new_cat_wallet(
1083
- wallet_node.wallet_state_manager,
1084
- wallet,
1085
- {"identifier": "genesis_by_id"},
1086
- uint64(100000),
1087
- action_scope,
1088
- )
1089
-
1090
- await wallet_environments.process_pending_states(
1091
- [
1092
- WalletStateTransition(
1093
- pre_block_balance_updates={
1094
- "xch": {"set_remainder": True},
1095
- "cat": {"init": True, "set_remainder": True},
1096
- },
1097
- post_block_balance_updates={
1098
- "xch": {"set_remainder": True},
1099
- "cat": {
1100
- "confirmed_wallet_balance": 100000,
1101
- "unconfirmed_wallet_balance": 0,
1102
- "spendable_balance": 100000,
1103
- "max_send_amount": 100000,
1104
- "pending_change": -100000,
1105
- "pending_coin_removal_count": -1,
1106
- "unspent_coin_count": 1,
1107
- },
1108
- },
1109
- )
1110
- ]
1111
- )
1077
+ cat_wallet = await mint_cat(wallet_environments, env, "xch", "cat", uint64(100000), wallet_type, "cat wallet")
1112
1078
 
1113
1079
  assert cat_wallet.cat_info.limitations_program_hash is not None
1114
1080
 
1115
- cat_2 = await cat_wallet.standard_wallet.get_puzzle(new=False)
1116
- cat_2_hash = cat_2.get_tree_hash()
1117
- amounts = []
1118
- puzzle_hashes = []
1119
- for i in range(1, 50):
1120
- amounts.append(uint64(i))
1121
- puzzle_hashes.append(cat_2_hash)
1122
- spent_coin = (await cat_wallet.get_cat_spendable_coins())[0].coin
1123
1081
  async with cat_wallet.wallet_state_manager.new_action_scope(
1124
1082
  wallet_environments.tx_config, push=True
1125
1083
  ) as action_scope:
1084
+ cat_2 = await action_scope.get_puzzle(cat_wallet.wallet_state_manager)
1085
+ cat_2_hash = cat_2.get_tree_hash()
1086
+ amounts = []
1087
+ puzzle_hashes = []
1088
+ for i in range(1, 50):
1089
+ amounts.append(uint64(i))
1090
+ puzzle_hashes.append(cat_2_hash)
1091
+ spent_coin = (await cat_wallet.get_cat_spendable_coins())[0].coin
1126
1092
  await cat_wallet.generate_signed_transaction(amounts, puzzle_hashes, action_scope, coins={spent_coin})
1127
1093
 
1128
1094
  await wallet_environments.process_pending_states(
@@ -1157,7 +1123,13 @@ async def test_cat_max_amount_send(wallet_environments: WalletTestFramework) ->
1157
1123
  spendable_name_set = set()
1158
1124
  for record in spendable:
1159
1125
  spendable_name_set.add(record.coin.name())
1160
- puzzle_hash = construct_cat_puzzle(CAT_MOD, cat_wallet.cat_info.limitations_program_hash, cat_2).get_tree_hash()
1126
+ if wallet_type is RCATWallet:
1127
+ inner_puzzle = create_revocation_layer(bytes32.zeros, cat_2_hash)
1128
+ else:
1129
+ inner_puzzle = cat_2
1130
+ puzzle_hash = construct_cat_puzzle(
1131
+ CAT_MOD, cat_wallet.cat_info.limitations_program_hash, inner_puzzle
1132
+ ).get_tree_hash()
1161
1133
  for i in range(1, 50):
1162
1134
  coin = Coin(spent_coin.name(), puzzle_hash, uint64(i))
1163
1135
  if coin.name() not in spendable_name_set:
@@ -1206,8 +1178,9 @@ async def test_cat_max_amount_send(wallet_environments: WalletTestFramework) ->
1206
1178
  ],
1207
1179
  indirect=True,
1208
1180
  )
1181
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
1209
1182
  @pytest.mark.anyio
1210
- async def test_cat_hint(wallet_environments: WalletTestFramework) -> None:
1183
+ async def test_cat_hint(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
1211
1184
  # Setup
1212
1185
  env_1: WalletEnvironment = wallet_environments.environments[0]
1213
1186
  env_2: WalletEnvironment = wallet_environments.environments[1]
@@ -1227,45 +1200,12 @@ async def test_cat_hint(wallet_environments: WalletTestFramework) -> None:
1227
1200
 
1228
1201
  autodiscovery = wallet_node_1.config["automatically_add_unknown_cats"]
1229
1202
 
1230
- async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1231
- cat_wallet = await CATWallet.create_new_cat_wallet(
1232
- wallet_node_1.wallet_state_manager,
1233
- wallet_1,
1234
- {"identifier": "genesis_by_id"},
1235
- uint64(100),
1236
- action_scope,
1237
- )
1238
-
1239
- await wallet_environments.process_pending_states(
1240
- [
1241
- WalletStateTransition(
1242
- pre_block_balance_updates={
1243
- "xch": {"set_remainder": True},
1244
- "cat": {"init": True, "set_remainder": True},
1245
- },
1246
- post_block_balance_updates={
1247
- "xch": {"set_remainder": True},
1248
- "cat": {
1249
- "confirmed_wallet_balance": 100,
1250
- "unconfirmed_wallet_balance": 0,
1251
- "spendable_balance": 100,
1252
- "max_send_amount": 100,
1253
- "pending_change": -100,
1254
- "pending_coin_removal_count": -1,
1255
- "unspent_coin_count": 1,
1256
- },
1257
- },
1258
- ),
1259
- WalletStateTransition(
1260
- pre_block_balance_updates={},
1261
- post_block_balance_updates={},
1262
- ),
1263
- ]
1264
- )
1203
+ cat_wallet = await mint_cat(wallet_environments, env_1, "xch", "cat", uint64(100), wallet_type, "cat wallet")
1265
1204
 
1266
1205
  assert cat_wallet.cat_info.limitations_program_hash is not None
1267
1206
 
1268
- cat_2_hash = await wallet_2.get_new_puzzlehash()
1207
+ async with wallet_2.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1208
+ cat_2_hash = await action_scope.get_puzzle_hash(wallet_2.wallet_state_manager)
1269
1209
  async with wallet_1.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1270
1210
  await cat_wallet.generate_signed_transaction([uint64(60)], [cat_2_hash], action_scope, memos=[[cat_2_hash]])
1271
1211
 
@@ -1387,7 +1327,10 @@ async def test_cat_hint(wallet_environments: WalletTestFramework) -> None:
1387
1327
  cat_wallet_2 = wallet_node_2.wallet_state_manager.wallets[uint32(2)]
1388
1328
  assert isinstance(cat_wallet_2, CATWallet)
1389
1329
 
1390
- cat_hash = await cat_wallet.standard_wallet.get_puzzle_hash(new=False)
1330
+ async with cat_wallet.wallet_state_manager.new_action_scope(
1331
+ wallet_environments.tx_config, push=True
1332
+ ) as action_scope:
1333
+ cat_hash = await action_scope.get_puzzle_hash(cat_wallet.wallet_state_manager)
1391
1334
  async with cat_wallet_2.wallet_state_manager.new_action_scope(
1392
1335
  wallet_environments.tx_config, push=True
1393
1336
  ) as action_scope:
@@ -1449,8 +1392,9 @@ async def test_cat_hint(wallet_environments: WalletTestFramework) -> None:
1449
1392
  ],
1450
1393
  indirect=True,
1451
1394
  )
1395
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
1452
1396
  @pytest.mark.anyio
1453
- async def test_cat_change_detection(wallet_environments: WalletTestFramework) -> None:
1397
+ async def test_cat_change_detection(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
1454
1398
  full_node_api = wallet_environments.full_node
1455
1399
  env = wallet_environments.environments[0]
1456
1400
  wsm = env.wallet_state_manager
@@ -1465,6 +1409,8 @@ async def test_cat_change_detection(wallet_environments: WalletTestFramework) ->
1465
1409
  # We should pick up this coin as balance even though it is unhinted because it is "change"
1466
1410
  pubkey_unhardened = master_pk_to_wallet_pk_unhardened(wsm.root_pubkey, uint32(100000000))
1467
1411
  inner_puzhash = puzzle_hash_for_pk(pubkey_unhardened)
1412
+ if wallet_type is RCATWallet:
1413
+ inner_puzhash = create_revocation_layer(bytes32.zeros, inner_puzhash).get_tree_hash()
1468
1414
  puzzlehash_unhardened = construct_cat_puzzle(
1469
1415
  CAT_MOD, Program.to(None).get_tree_hash(), inner_puzhash
1470
1416
  ).get_tree_hash_precalc(inner_puzhash)
@@ -1473,7 +1419,8 @@ async def test_cat_change_detection(wallet_environments: WalletTestFramework) ->
1473
1419
  )
1474
1420
  # Insert the derivation record before the wallet exists so that it is not subscribed to
1475
1421
  await wsm.puzzle_store.add_derivation_paths([change_derivation])
1476
- our_puzzle = await wallet.get_new_puzzle()
1422
+ async with wallet.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1423
+ our_puzzle = await action_scope.get_puzzle(wallet.wallet_state_manager)
1477
1424
  cat_puzzle = construct_cat_puzzle(
1478
1425
  CAT_MOD,
1479
1426
  Program.to(None).get_tree_hash(),
@@ -1626,7 +1573,6 @@ async def test_cat_melt_balance(wallet_environments: WalletTestFramework) -> Non
1626
1573
  env = wallet_environments.environments[0]
1627
1574
  wallet = env.xch_wallet
1628
1575
  simulator = wallet_environments.full_node
1629
- wallet_ph = await wallet.get_puzzle_hash(new=False)
1630
1576
 
1631
1577
  env.wallet_aliases = {
1632
1578
  "xch": 1,
@@ -1653,18 +1599,22 @@ async def test_cat_melt_balance(wallet_environments: WalletTestFramework) -> Non
1653
1599
 
1654
1600
  tx_amount = 10
1655
1601
 
1656
- spend_to_wallet = unsigned_spend_bundle_for_spendable_cats(
1657
- CAT_MOD,
1658
- [
1659
- SpendableCAT(
1660
- coin=cat_coin,
1661
- limitations_program_hash=ACS_TAIL_HASH,
1662
- inner_puzzle=ACS,
1663
- inner_solution=Program.to([[51, wallet_ph, tx_amount, [wallet_ph]], [51, None, -113, ACS_TAIL, None]]),
1664
- extra_delta=tx_amount - cat_coin.amount,
1665
- )
1666
- ],
1667
- )
1602
+ async with env.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1603
+ wallet_ph = await action_scope.get_puzzle_hash(env.wallet_state_manager)
1604
+ spend_to_wallet = unsigned_spend_bundle_for_spendable_cats(
1605
+ CAT_MOD,
1606
+ [
1607
+ SpendableCAT(
1608
+ coin=cat_coin,
1609
+ limitations_program_hash=ACS_TAIL_HASH,
1610
+ inner_puzzle=ACS,
1611
+ inner_solution=Program.to(
1612
+ [[51, wallet_ph, tx_amount, [wallet_ph]], [51, None, -113, ACS_TAIL, None]]
1613
+ ),
1614
+ extra_delta=tx_amount - cat_coin.amount,
1615
+ )
1616
+ ],
1617
+ )
1668
1618
  await env.rpc_client.push_tx(PushTX(spend_to_wallet))
1669
1619
  await time_out_assert(10, simulator.tx_id_in_mempool, True, spend_to_wallet.name())
1670
1620
 
@@ -1691,7 +1641,7 @@ async def test_cat_melt_balance(wallet_environments: WalletTestFramework) -> Non
1691
1641
  assert isinstance(cat_wallet, CATWallet)
1692
1642
 
1693
1643
  # Let's test that continuing to melt this CAT results in the correct balance changes
1694
- for _ in range(0, 5):
1644
+ for _ in range(5):
1695
1645
  tx_amount -= 1
1696
1646
  new_coin = (await cat_wallet.get_cat_spendable_coins())[0].coin
1697
1647
  new_spend = unsigned_spend_bundle_for_spendable_cats(
@@ -1748,54 +1698,26 @@ async def test_cat_melt_balance(wallet_environments: WalletTestFramework) -> Non
1748
1698
  ],
1749
1699
  indirect=True,
1750
1700
  )
1701
+ @pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet])
1751
1702
  @pytest.mark.limit_consensus_modes([ConsensusMode.PLAIN], reason="irrelevant")
1752
1703
  @pytest.mark.anyio
1753
- async def test_cat_puzzle_hashes(wallet_environments: WalletTestFramework) -> None:
1704
+ async def test_cat_puzzle_hashes(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None:
1754
1705
  env = wallet_environments.environments[0]
1755
- wallet = env.xch_wallet
1756
1706
 
1757
1707
  env.wallet_aliases = {
1758
1708
  "xch": 1,
1759
1709
  "cat": 2,
1760
1710
  }
1761
1711
 
1762
- async with env.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1763
- cat_wallet = await CATWallet.create_new_cat_wallet(
1764
- env.node.wallet_state_manager,
1765
- wallet,
1766
- {"identifier": "genesis_by_id"},
1767
- uint64(100),
1768
- action_scope,
1769
- )
1770
-
1771
- await wallet_environments.process_pending_states(
1772
- [
1773
- WalletStateTransition(
1774
- pre_block_balance_updates={
1775
- "xch": {"set_remainder": True},
1776
- "cat": {"init": True, "set_remainder": True},
1777
- },
1778
- post_block_balance_updates={
1779
- "xch": {"set_remainder": True},
1780
- "cat": {
1781
- "confirmed_wallet_balance": 100,
1782
- "unconfirmed_wallet_balance": 0,
1783
- "spendable_balance": 100,
1784
- "max_send_amount": 100,
1785
- "pending_change": -100,
1786
- "pending_coin_removal_count": -1,
1787
- "unspent_coin_count": 1,
1788
- },
1789
- },
1790
- ),
1791
- ]
1792
- )
1712
+ cat_wallet = await mint_cat(wallet_environments, env, "xch", "cat", uint64(100), wallet_type, "cat wallet")
1793
1713
 
1794
1714
  # Test that we attempt a new puzzle hash here even though everything says we shouldn't
1795
1715
  with pytest.raises(NewPuzzleHashError):
1796
1716
  async with env.wallet_state_manager.new_action_scope(wallet_environments.tx_config, push=True) as action_scope:
1797
1717
  await cat_wallet.generate_signed_transaction(
1798
- [uint64(50)], [await cat_wallet.standard_wallet.get_puzzle_hash(new=False)], action_scope
1718
+ [uint64(50)],
1719
+ [await action_scope.get_puzzle_hash(cat_wallet.wallet_state_manager)],
1720
+ action_scope,
1799
1721
  )
1800
1722
 
1801
1723
  # Test new puzzle hash getting
@@ -1818,8 +1740,6 @@ async def test_cat_puzzle_hashes(wallet_environments: WalletTestFramework) -> No
1818
1740
  await env.wallet_state_manager.puzzle_store.add_derivation_paths([dr])
1819
1741
 
1820
1742
  # Then we make sure that even though we asked for a used puzzle hash, it still gives us an unused one
1821
- unused_count = await env.wallet_state_manager.puzzle_store.get_unused_count(uint32(env.wallet_aliases["cat"]))
1743
+ unused_count = await env.wallet_state_manager.puzzle_store.get_used_count(uint32(env.wallet_aliases["cat"]))
1822
1744
  await cat_wallet.get_cat_puzzle_hash(new=False)
1823
- assert unused_count < await env.wallet_state_manager.puzzle_store.get_unused_count(
1824
- uint32(env.wallet_aliases["cat"])
1825
- )
1745
+ assert unused_count < await env.wallet_state_manager.puzzle_store.get_used_count(uint32(env.wallet_aliases["cat"]))