chia-blockchain 2.5.2rc1__py3-none-any.whl → 2.5.3rc1__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 (640) hide show
  1. chia/__init__.py +7 -0
  2. chia/_tests/blockchain/blockchain_test_utils.py +1 -1
  3. chia/_tests/blockchain/test_augmented_chain.py +54 -5
  4. chia/_tests/blockchain/test_blockchain.py +5 -12
  5. chia/_tests/blockchain/test_blockchain_transactions.py +3 -5
  6. chia/_tests/blockchain/test_get_block_generator.py +2 -2
  7. chia/_tests/blockchain/test_lookup_fork_chain.py +2 -2
  8. chia/_tests/clvm/benchmark_costs.py +2 -1
  9. chia/_tests/clvm/coin_store.py +4 -3
  10. chia/_tests/clvm/test_chialisp_deserialization.py +2 -2
  11. chia/_tests/clvm/test_curry_and_treehash.py +1 -1
  12. chia/_tests/clvm/test_puzzle_compression.py +2 -2
  13. chia/_tests/clvm/test_puzzles.py +2 -2
  14. chia/_tests/clvm/test_singletons.py +2 -2
  15. chia/_tests/clvm/test_spend_sim.py +1 -1
  16. chia/_tests/cmds/cmd_test_utils.py +2 -2
  17. chia/_tests/cmds/test_click_types.py +2 -2
  18. chia/_tests/cmds/test_cmd_framework.py +6 -6
  19. chia/_tests/cmds/test_show.py +4 -3
  20. chia/_tests/cmds/test_tx_config_args.py +1 -1
  21. chia/_tests/cmds/testing_classes.py +2 -2
  22. chia/_tests/cmds/wallet/test_consts.py +2 -2
  23. chia/_tests/cmds/wallet/test_did.py +2 -2
  24. chia/_tests/cmds/wallet/test_nft.py +2 -2
  25. chia/_tests/cmds/wallet/test_notifications.py +3 -2
  26. chia/_tests/cmds/wallet/test_vcs.py +2 -2
  27. chia/_tests/cmds/wallet/test_wallet.py +4 -8
  28. chia/_tests/conftest.py +4 -3
  29. chia/_tests/connection_utils.py +2 -2
  30. chia/_tests/core/cmds/test_keys.py +1 -2
  31. chia/_tests/core/cmds/test_wallet.py +2 -2
  32. chia/_tests/core/consensus/test_block_creation.py +2 -2
  33. chia/_tests/core/consensus/test_pot_iterations.py +1 -1
  34. chia/_tests/core/custom_types/test_coin.py +2 -2
  35. chia/_tests/core/custom_types/test_proof_of_space.py +2 -2
  36. chia/_tests/core/custom_types/test_spend_bundle.py +2 -2
  37. chia/_tests/core/data_layer/conftest.py +1 -1
  38. chia/_tests/core/data_layer/test_data_layer.py +1 -1
  39. chia/_tests/core/data_layer/test_data_layer_util.py +1 -1
  40. chia/_tests/core/data_layer/test_data_rpc.py +2 -2
  41. chia/_tests/core/data_layer/test_data_store.py +1 -1
  42. chia/_tests/core/data_layer/test_data_store_schema.py +1 -1
  43. chia/_tests/core/data_layer/util.py +2 -1
  44. chia/_tests/core/farmer/test_farmer_api.py +1 -1
  45. chia/_tests/core/full_node/full_sync/test_full_sync.py +1 -7
  46. chia/_tests/core/full_node/ram_db.py +2 -1
  47. chia/_tests/core/full_node/stores/test_block_store.py +2 -2
  48. chia/_tests/core/full_node/stores/test_coin_store.py +2 -2
  49. chia/_tests/core/full_node/stores/test_full_node_store.py +3 -3
  50. chia/_tests/core/full_node/stores/test_hint_store.py +2 -2
  51. chia/_tests/core/full_node/stores/test_sync_store.py +1 -1
  52. chia/_tests/core/full_node/test_address_manager.py +1 -1
  53. chia/_tests/core/full_node/test_block_height_map.py +2 -2
  54. chia/_tests/core/full_node/test_conditions.py +1 -1
  55. chia/_tests/core/full_node/test_full_node.py +346 -164
  56. chia/_tests/core/full_node/test_generator_tools.py +3 -2
  57. chia/_tests/core/full_node/test_hint_management.py +2 -2
  58. chia/_tests/core/full_node/test_performance.py +2 -15
  59. chia/_tests/core/full_node/test_subscriptions.py +1 -1
  60. chia/_tests/core/full_node/test_transactions.py +186 -185
  61. chia/_tests/core/full_node/test_tx_processing_queue.py +1 -1
  62. chia/_tests/core/make_block_generator.py +2 -2
  63. chia/_tests/core/mempool/test_mempool.py +165 -22
  64. chia/_tests/core/mempool/test_mempool_fee_estimator.py +1 -1
  65. chia/_tests/core/mempool/test_mempool_fee_protocol.py +1 -1
  66. chia/_tests/core/mempool/test_mempool_manager.py +476 -66
  67. chia/_tests/core/mempool/test_mempool_performance.py +2 -2
  68. chia/_tests/core/mempool/test_singleton_fast_forward.py +19 -25
  69. chia/_tests/core/node_height.py +2 -1
  70. chia/_tests/core/server/test_capabilities.py +1 -1
  71. chia/_tests/core/server/test_dos.py +36 -28
  72. chia/_tests/core/server/test_loop.py +3 -3
  73. chia/_tests/core/server/test_rate_limits.py +1 -1
  74. chia/_tests/core/server/test_server.py +2 -2
  75. chia/_tests/core/services/test_services.py +1 -1
  76. chia/_tests/core/ssl/test_ssl.py +1 -1
  77. chia/_tests/core/test_coins.py +2 -1
  78. chia/_tests/core/test_cost_calculation.py +2 -2
  79. chia/_tests/core/test_crawler.py +2 -2
  80. chia/_tests/core/test_db_conversion.py +2 -2
  81. chia/_tests/core/test_db_validation.py +26 -13
  82. chia/_tests/core/test_farmer_harvester_rpc.py +2 -2
  83. chia/_tests/core/test_full_node_rpc.py +2 -2
  84. chia/_tests/core/test_merkle_set.py +2 -2
  85. chia/_tests/core/test_program.py +2 -2
  86. chia/_tests/core/test_rpc_util.py +1 -1
  87. chia/_tests/core/test_seeder.py +1 -1
  88. chia/_tests/core/util/test_block_cache.py +3 -3
  89. chia/_tests/core/util/test_jsonify.py +3 -2
  90. chia/_tests/core/util/test_keychain.py +3 -3
  91. chia/_tests/core/util/test_streamable.py +3 -4
  92. chia/_tests/environments/wallet.py +3 -2
  93. chia/_tests/farmer_harvester/test_farmer.py +3 -4
  94. chia/_tests/farmer_harvester/test_farmer_harvester.py +2 -2
  95. chia/_tests/farmer_harvester/test_filter_prefix_bits.py +2 -2
  96. chia/_tests/farmer_harvester/test_third_party_harvesters.py +3 -4
  97. chia/_tests/fee_estimation/test_fee_estimation_integration.py +1 -1
  98. chia/_tests/fee_estimation/test_fee_estimation_rpc.py +2 -2
  99. chia/_tests/fee_estimation/test_fee_estimation_unit_tests.py +1 -1
  100. chia/_tests/fee_estimation/test_mempoolitem_height_added.py +3 -4
  101. chia/_tests/generator/test_compression.py +20 -10
  102. chia/_tests/generator/test_rom.py +7 -9
  103. chia/_tests/plot_sync/test_delta.py +2 -2
  104. chia/_tests/plot_sync/test_plot_sync.py +2 -2
  105. chia/_tests/plot_sync/test_receiver.py +2 -2
  106. chia/_tests/plot_sync/test_sender.py +2 -2
  107. chia/_tests/plot_sync/test_sync_simulated.py +2 -2
  108. chia/_tests/plot_sync/util.py +3 -2
  109. chia/_tests/plotting/test_plot_manager.py +1 -1
  110. chia/_tests/pools/test_pool_cli_parsing.py +3 -2
  111. chia/_tests/pools/test_pool_cmdline.py +2 -2
  112. chia/_tests/pools/test_pool_puzzles_lifecycle.py +3 -3
  113. chia/_tests/pools/test_pool_rpc.py +4 -5
  114. chia/_tests/pools/test_pool_wallet.py +1 -1
  115. chia/_tests/pools/test_wallet_pool_store.py +2 -2
  116. chia/_tests/rpc/test_rpc_client.py +1 -1
  117. chia/_tests/rpc/test_rpc_server.py +1 -1
  118. chia/_tests/simulation/test_simulation.py +36 -8
  119. chia/_tests/simulation/test_simulator.py +5 -5
  120. chia/_tests/simulation/test_start_simulator.py +2 -2
  121. chia/_tests/timelord/test_new_peak.py +2 -2
  122. chia/_tests/tools/test_run_block.py +3 -2
  123. chia/_tests/util/benchmark_cost.py +2 -2
  124. chia/_tests/util/benchmarks.py +17 -6
  125. chia/_tests/util/blockchain.py +2 -1
  126. chia/_tests/util/blockchain_mock.py +9 -5
  127. chia/_tests/util/build_network_protocol_files.py +2 -1
  128. chia/_tests/util/constants.py +2 -1
  129. chia/_tests/util/full_sync.py +6 -3
  130. chia/_tests/util/gen_ssl_certs.py +2 -2
  131. chia/_tests/util/generator_tools_testing.py +4 -3
  132. chia/_tests/util/get_name_puzzle_conditions.py +2 -2
  133. chia/_tests/util/misc.py +16 -2
  134. chia/_tests/util/network_protocol_data.py +17 -7
  135. chia/_tests/util/run_block.py +6 -8
  136. chia/_tests/util/setup_nodes.py +4 -3
  137. chia/_tests/util/spend_sim.py +9 -5
  138. chia/_tests/util/test_condition_tools.py +2 -2
  139. chia/_tests/util/test_config.py +2 -1
  140. chia/_tests/util/test_errors.py +2 -1
  141. chia/_tests/util/test_full_block_utils.py +17 -7
  142. chia/_tests/util/test_misc.py +1 -1
  143. chia/_tests/util/test_network_protocol_test.py +24 -24
  144. chia/_tests/util/test_replace_str_to_bytes.py +2 -2
  145. chia/_tests/util/test_trusted_peer.py +1 -1
  146. chia/_tests/util/time_out_assert.py +20 -7
  147. chia/_tests/wallet/cat_wallet/test_cat_lifecycle.py +1 -1
  148. chia/_tests/wallet/cat_wallet/test_cat_outer_puzzle.py +2 -2
  149. chia/_tests/wallet/cat_wallet/test_cat_wallet.py +5 -6
  150. chia/_tests/wallet/cat_wallet/test_offer_lifecycle.py +17 -15
  151. chia/_tests/wallet/cat_wallet/test_trades.py +2 -2
  152. chia/_tests/wallet/clawback/test_clawback_lifecycle.py +2 -2
  153. chia/_tests/wallet/clawback/test_clawback_metadata.py +2 -2
  154. chia/_tests/wallet/conftest.py +3 -3
  155. chia/_tests/wallet/db_wallet/test_db_graftroot.py +3 -5
  156. chia/_tests/wallet/db_wallet/test_dl_offers.py +2 -2
  157. chia/_tests/wallet/db_wallet/test_dl_wallet.py +433 -384
  158. chia/_tests/wallet/did_wallet/test_did.py +3 -3
  159. chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +2 -2
  160. chia/_tests/wallet/nft_wallet/test_nft_bulk_mint.py +2 -2
  161. chia/_tests/wallet/nft_wallet/test_nft_lifecycle.py +3 -4
  162. chia/_tests/wallet/nft_wallet/test_nft_offers.py +1293 -703
  163. chia/_tests/wallet/nft_wallet/test_nft_puzzles.py +28 -30
  164. chia/_tests/wallet/nft_wallet/test_nft_wallet.py +2 -2
  165. chia/_tests/wallet/nft_wallet/test_ownership_outer_puzzle.py +2 -2
  166. chia/_tests/wallet/rpc/config.py +1 -1
  167. chia/_tests/wallet/rpc/test_dl_wallet_rpc.py +2 -2
  168. chia/_tests/wallet/rpc/test_wallet_rpc.py +20 -77
  169. chia/_tests/wallet/simple_sync/test_simple_sync_protocol.py +9 -7
  170. chia/_tests/wallet/sync/test_wallet_sync.py +79 -31
  171. chia/_tests/wallet/test_clvm_streamable.py +2 -2
  172. chia/_tests/wallet/test_coin_management.py +7 -7
  173. chia/_tests/wallet/test_coin_selection.py +20 -2
  174. chia/_tests/wallet/test_conditions.py +2 -2
  175. chia/_tests/wallet/test_debug_spend_bundle.py +2 -2
  176. chia/_tests/wallet/test_new_wallet_protocol.py +2 -2
  177. chia/_tests/wallet/test_nft_store.py +2 -2
  178. chia/_tests/wallet/test_notifications.py +2 -2
  179. chia/_tests/wallet/test_puzzle_store.py +2 -2
  180. chia/_tests/wallet/test_sign_coin_spends.py +2 -2
  181. chia/_tests/wallet/test_signer_protocol.py +3 -3
  182. chia/_tests/wallet/test_singleton.py +3 -11
  183. chia/_tests/wallet/test_singleton_lifecycle_fast.py +12 -13
  184. chia/_tests/wallet/test_singleton_store.py +2 -4
  185. chia/_tests/wallet/test_transaction_store.py +2 -2
  186. chia/_tests/wallet/test_util.py +2 -2
  187. chia/_tests/wallet/test_wallet.py +53 -49
  188. chia/_tests/wallet/test_wallet_action_scope.py +24 -6
  189. chia/_tests/wallet/test_wallet_blockchain.py +1 -1
  190. chia/_tests/wallet/test_wallet_coin_store.py +2 -2
  191. chia/_tests/wallet/test_wallet_interested_store.py +2 -2
  192. chia/_tests/wallet/test_wallet_node.py +3 -3
  193. chia/_tests/wallet/test_wallet_retry.py +3 -3
  194. chia/_tests/wallet/test_wallet_state_manager.py +8 -8
  195. chia/_tests/wallet/test_wallet_test_framework.py +1 -1
  196. chia/_tests/wallet/test_wallet_trade_store.py +2 -2
  197. chia/_tests/wallet/test_wallet_utils.py +2 -2
  198. chia/_tests/wallet/vc_wallet/test_cr_outer_puzzle.py +3 -2
  199. chia/_tests/wallet/vc_wallet/test_vc_lifecycle.py +15 -15
  200. chia/_tests/wallet/vc_wallet/test_vc_wallet.py +5 -3
  201. chia/_tests/wallet/wallet_block_tools.py +15 -7
  202. chia/_tests/weight_proof/test_weight_proof.py +3 -3
  203. chia/cmds/chia.py +0 -2
  204. chia/cmds/cmd_classes.py +3 -3
  205. chia/cmds/cmd_helpers.py +4 -4
  206. chia/cmds/cmds_util.py +2 -2
  207. chia/cmds/coin_funcs.py +3 -2
  208. chia/cmds/coins.py +1 -1
  209. chia/cmds/data.py +2 -2
  210. chia/cmds/data_funcs.py +3 -2
  211. chia/cmds/db_upgrade_func.py +2 -2
  212. chia/cmds/db_validate_func.py +15 -8
  213. chia/cmds/farm.py +2 -4
  214. chia/cmds/keys.py +0 -2
  215. chia/cmds/keys_funcs.py +1 -1
  216. chia/cmds/netspace_funcs.py +2 -1
  217. chia/cmds/param_types.py +2 -2
  218. chia/cmds/plotnft.py +2 -2
  219. chia/cmds/plotnft_funcs.py +2 -2
  220. chia/cmds/rpc.py +1 -1
  221. chia/cmds/show.py +1 -2
  222. chia/cmds/show_funcs.py +6 -3
  223. chia/cmds/signer.py +1 -2
  224. chia/cmds/sim.py +1 -2
  225. chia/cmds/sim_funcs.py +2 -2
  226. chia/cmds/wallet.py +2 -2
  227. chia/cmds/wallet_funcs.py +4 -11
  228. chia/consensus/block_body_validation.py +3 -4
  229. chia/consensus/block_creation.py +10 -6
  230. chia/consensus/block_header_validation.py +3 -4
  231. chia/consensus/block_record.py +2 -3
  232. chia/consensus/block_rewards.py +1 -1
  233. chia/consensus/blockchain.py +20 -17
  234. chia/consensus/blockchain_interface.py +5 -4
  235. chia/consensus/coinbase.py +2 -2
  236. chia/consensus/constants.py +1 -1
  237. chia/consensus/cost_calculator.py +2 -1
  238. chia/consensus/default_constants.py +4 -3
  239. chia/consensus/deficit.py +3 -2
  240. chia/consensus/difficulty_adjustment.py +8 -9
  241. chia/consensus/find_fork_point.py +4 -3
  242. chia/consensus/full_block_to_block_record.py +4 -3
  243. chia/consensus/get_block_challenge.py +4 -3
  244. chia/consensus/get_block_generator.py +3 -2
  245. chia/consensus/make_sub_epoch_summary.py +3 -2
  246. chia/consensus/multiprocess_validation.py +9 -4
  247. chia/consensus/pos_quality.py +1 -1
  248. chia/consensus/pot_iterations.py +4 -3
  249. chia/consensus/vdf_info_computation.py +4 -3
  250. chia/daemon/client.py +1 -1
  251. chia/daemon/keychain_server.py +1 -1
  252. chia/daemon/server.py +1 -1
  253. chia/daemon/windows_signal.py +1 -1
  254. chia/data_layer/data_layer.py +4 -3
  255. chia/data_layer/data_layer_errors.py +1 -1
  256. chia/data_layer/data_layer_util.py +2 -2
  257. chia/data_layer/data_layer_wallet.py +47 -69
  258. chia/data_layer/data_store.py +1 -1
  259. chia/data_layer/dl_wallet_store.py +5 -6
  260. chia/data_layer/download_data.py +1 -1
  261. chia/data_layer/s3_plugin_service.py +4 -4
  262. chia/data_layer/singleton_record.py +23 -0
  263. chia/data_layer/util/benchmark.py +2 -1
  264. chia/farmer/farmer.py +4 -6
  265. chia/farmer/farmer_api.py +4 -6
  266. chia/full_node/bitcoin_fee_estimator.py +2 -1
  267. chia/full_node/block_height_map.py +2 -2
  268. chia/full_node/block_store.py +8 -9
  269. chia/{util → full_node}/check_fork_next_block.py +2 -1
  270. chia/full_node/coin_store.py +10 -10
  271. chia/full_node/fee_estimate.py +2 -1
  272. chia/full_node/fee_estimation.py +2 -1
  273. chia/full_node/fee_estimator.py +2 -1
  274. chia/full_node/fee_estimator_interface.py +1 -1
  275. chia/full_node/fee_history.py +2 -1
  276. chia/full_node/fee_tracker.py +2 -1
  277. chia/full_node/full_node.py +25 -15
  278. chia/full_node/full_node_api.py +12 -32
  279. chia/full_node/full_node_store.py +4 -3
  280. chia/full_node/hint_management.py +2 -1
  281. chia/full_node/hint_store.py +3 -3
  282. chia/full_node/mempool.py +79 -12
  283. chia/full_node/mempool_check_conditions.py +6 -7
  284. chia/full_node/mempool_manager.py +168 -21
  285. chia/full_node/pending_tx_cache.py +2 -2
  286. chia/full_node/subscriptions.py +2 -2
  287. chia/full_node/sync_store.py +2 -3
  288. chia/full_node/tx_processing_queue.py +2 -1
  289. chia/full_node/weight_proof.py +5 -8
  290. chia/harvester/harvester.py +5 -3
  291. chia/harvester/harvester_api.py +2 -2
  292. chia/introducer/introducer.py +30 -2
  293. chia/introducer/introducer_api.py +9 -1
  294. chia/legacy/keyring.py +1 -2
  295. chia/plot_sync/exceptions.py +2 -1
  296. chia/plot_sync/receiver.py +2 -2
  297. chia/plot_sync/sender.py +1 -1
  298. chia/plotting/cache.py +2 -2
  299. chia/plotting/check_plots.py +4 -2
  300. chia/plotting/create_plots.py +1 -1
  301. chia/plotting/manager.py +3 -3
  302. chia/plotting/util.py +2 -2
  303. chia/pools/pool_config.py +1 -1
  304. chia/pools/pool_puzzles.py +23 -17
  305. chia/pools/pool_wallet.py +22 -9
  306. chia/pools/pool_wallet_info.py +2 -2
  307. chia/protocols/farmer_protocol.py +3 -6
  308. chia/protocols/full_node_protocol.py +3 -2
  309. chia/protocols/harvester_protocol.py +3 -4
  310. chia/protocols/pool_protocol.py +2 -2
  311. chia/protocols/shared_protocol.py +2 -1
  312. chia/protocols/timelord_protocol.py +4 -4
  313. chia/protocols/wallet_protocol.py +2 -2
  314. chia/rpc/data_layer_rpc_api.py +3 -4
  315. chia/rpc/data_layer_rpc_client.py +3 -2
  316. chia/rpc/farmer_rpc_api.py +2 -2
  317. chia/rpc/farmer_rpc_client.py +2 -1
  318. chia/rpc/full_node_rpc_api.py +3 -2
  319. chia/rpc/full_node_rpc_client.py +3 -2
  320. chia/rpc/harvester_rpc_api.py +2 -1
  321. chia/rpc/rpc_client.py +2 -2
  322. chia/rpc/rpc_server.py +1 -1
  323. chia/rpc/wallet_request_types.py +2 -62
  324. chia/rpc/wallet_rpc_api.py +98 -628
  325. chia/rpc/wallet_rpc_client.py +5 -253
  326. chia/seeder/crawl_store.py +1 -1
  327. chia/seeder/crawler.py +2 -2
  328. chia/seeder/peer_record.py +2 -1
  329. chia/seeder/start_crawler.py +3 -1
  330. chia/server/address_manager.py +2 -1
  331. chia/server/address_manager_store.py +1 -1
  332. chia/server/capabilities.py +2 -1
  333. chia/server/introducer_peers.py +2 -1
  334. chia/server/node_discovery.py +1 -1
  335. chia/server/outbound_message.py +2 -1
  336. chia/server/server.py +2 -2
  337. chia/server/start_data_layer.py +2 -1
  338. chia/server/start_farmer.py +3 -1
  339. chia/server/start_full_node.py +4 -2
  340. chia/server/start_harvester.py +3 -1
  341. chia/server/start_introducer.py +12 -1
  342. chia/server/start_service.py +2 -1
  343. chia/server/start_timelord.py +3 -1
  344. chia/server/start_wallet.py +3 -1
  345. chia/server/upnp.py +1 -2
  346. chia/server/ws_connection.py +3 -4
  347. chia/simulator/add_blocks_in_batches.py +5 -3
  348. chia/simulator/block_tools.py +16 -12
  349. chia/simulator/full_node_simulator.py +9 -14
  350. chia/simulator/setup_services.py +5 -3
  351. chia/simulator/simulator_full_node_rpc_api.py +3 -2
  352. chia/simulator/simulator_full_node_rpc_client.py +3 -2
  353. chia/simulator/simulator_protocol.py +3 -2
  354. chia/simulator/simulator_test_tools.py +2 -2
  355. chia/simulator/start_simulator.py +3 -2
  356. chia/simulator/wallet_tools.py +3 -4
  357. chia/timelord/iters_from_block.py +4 -4
  358. chia/timelord/timelord.py +7 -12
  359. chia/timelord/timelord_api.py +3 -3
  360. chia/timelord/timelord_state.py +4 -3
  361. chia/types/block_protocol.py +2 -2
  362. chia/types/blockchain_format/coin.py +2 -2
  363. chia/types/blockchain_format/program.py +1 -1
  364. chia/types/blockchain_format/proof_of_space.py +3 -4
  365. chia/types/blockchain_format/tree_hash.py +1 -1
  366. chia/types/blockchain_format/vdf.py +3 -4
  367. chia/types/clvm_cost.py +1 -1
  368. chia/types/coin_record.py +4 -3
  369. chia/types/coin_spend.py +1 -1
  370. chia/types/eligible_coin_spends.py +9 -5
  371. chia/types/fee_rate.py +1 -1
  372. chia/types/generator_types.py +3 -3
  373. chia/types/internal_mempool_item.py +3 -2
  374. chia/types/mempool_item.py +10 -3
  375. chia/types/mempool_submission_status.py +2 -1
  376. chia/types/mojos.py +1 -1
  377. chia/types/peer_info.py +2 -1
  378. chia/types/transaction_queue_entry.py +2 -1
  379. chia/types/unfinished_header_block.py +4 -4
  380. chia/types/validation_state.py +2 -1
  381. chia/types/weight_proof.py +1 -9
  382. chia/util/augmented_chain.py +20 -9
  383. chia/util/block_cache.py +8 -4
  384. chia/util/condition_tools.py +2 -2
  385. chia/util/full_block_utils.py +3 -4
  386. chia/util/generator_tools.py +2 -2
  387. chia/util/initial-config.yaml +2 -11
  388. chia/util/network.py +2 -2
  389. chia/util/prev_transaction_block.py +2 -1
  390. chia/util/task_timing.py +1 -1
  391. chia/util/vdf_prover.py +3 -3
  392. chia/util/ws_message.py +1 -1
  393. chia/wallet/cat_wallet/cat_info.py +3 -2
  394. chia/wallet/cat_wallet/cat_outer_puzzle.py +3 -2
  395. chia/wallet/cat_wallet/cat_utils.py +6 -4
  396. chia/wallet/cat_wallet/cat_wallet.py +16 -18
  397. chia/wallet/cat_wallet/lineage_store.py +2 -1
  398. chia/wallet/coin_selection.py +5 -5
  399. chia/wallet/conditions.py +22 -16
  400. chia/wallet/db_wallet/db_wallet_puzzles.py +15 -15
  401. chia/wallet/derivation_record.py +2 -2
  402. chia/wallet/derive_keys.py +2 -2
  403. chia/wallet/did_wallet/did_info.py +3 -2
  404. chia/wallet/did_wallet/did_wallet.py +41 -19
  405. chia/wallet/did_wallet/did_wallet_puzzles.py +18 -12
  406. chia/wallet/driver_protocol.py +1 -1
  407. chia/wallet/lineage_proof.py +3 -2
  408. chia/wallet/nft_wallet/metadata_outer_puzzle.py +6 -7
  409. chia/wallet/nft_wallet/nft_info.py +5 -5
  410. chia/wallet/nft_wallet/nft_puzzle_utils.py +293 -0
  411. chia/wallet/nft_wallet/nft_puzzles.py +21 -298
  412. chia/wallet/nft_wallet/nft_wallet.py +47 -62
  413. chia/wallet/nft_wallet/ownership_outer_puzzle.py +4 -8
  414. chia/wallet/nft_wallet/singleton_outer_puzzle.py +3 -2
  415. chia/wallet/nft_wallet/transfer_program_puzzle.py +6 -10
  416. chia/wallet/nft_wallet/uncurry_nft.py +6 -8
  417. chia/wallet/notification_manager.py +5 -5
  418. chia/wallet/notification_store.py +3 -2
  419. chia/wallet/outer_puzzles.py +2 -1
  420. chia/wallet/puzzles/clawback/drivers.py +21 -8
  421. chia/wallet/puzzles/clawback/metadata.py +3 -2
  422. chia/wallet/puzzles/clawback/puzzle_decorator.py +5 -4
  423. chia/wallet/puzzles/deployed_puzzle_hashes.json +0 -10
  424. chia/wallet/puzzles/p2_conditions.py +3 -2
  425. chia/wallet/puzzles/p2_delegated_conditions.py +3 -2
  426. chia/wallet/puzzles/p2_delegated_puzzle.py +3 -2
  427. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.py +3 -3
  428. chia/wallet/puzzles/p2_m_of_n_delegate_direct.py +3 -2
  429. chia/wallet/puzzles/p2_puzzle_hash.py +4 -3
  430. chia/wallet/puzzles/puzzle_utils.py +3 -2
  431. chia/wallet/puzzles/singleton_top_layer.py +26 -10
  432. chia/wallet/puzzles/singleton_top_layer_v1_1.py +21 -9
  433. chia/wallet/puzzles/tails.py +21 -129
  434. chia/wallet/signer_protocol.py +3 -2
  435. chia/wallet/singleton.py +12 -6
  436. chia/wallet/singleton_record.py +3 -2
  437. chia/wallet/trade_manager.py +31 -55
  438. chia/wallet/trade_record.py +3 -2
  439. chia/wallet/trading/offer.py +14 -13
  440. chia/wallet/trading/trade_store.py +3 -4
  441. chia/wallet/transaction_record.py +2 -2
  442. chia/wallet/util/blind_signer_tl.py +3 -2
  443. chia/wallet/util/compute_hints.py +3 -2
  444. chia/wallet/util/compute_memos.py +2 -2
  445. chia/wallet/util/curry_and_treehash.py +1 -2
  446. chia/wallet/util/merkle_tree.py +1 -1
  447. chia/wallet/util/merkle_utils.py +1 -1
  448. chia/wallet/util/new_peak_queue.py +2 -1
  449. chia/wallet/util/notifications.py +5 -4
  450. chia/wallet/util/peer_request_cache.py +3 -2
  451. chia/wallet/util/puzzle_compression.py +6 -4
  452. chia/wallet/util/puzzle_decorator.py +6 -4
  453. chia/wallet/util/query_filter.py +3 -2
  454. chia/wallet/util/tx_config.py +3 -3
  455. chia/wallet/util/wallet_sync_utils.py +2 -2
  456. chia/wallet/util/wallet_types.py +2 -3
  457. chia/wallet/vc_wallet/cr_cat_drivers.py +18 -22
  458. chia/wallet/vc_wallet/cr_cat_wallet.py +14 -10
  459. chia/wallet/vc_wallet/cr_outer_puzzle.py +2 -2
  460. chia/wallet/vc_wallet/vc_drivers.py +50 -68
  461. chia/wallet/vc_wallet/vc_store.py +2 -2
  462. chia/wallet/vc_wallet/vc_wallet.py +47 -15
  463. chia/wallet/wallet.py +51 -46
  464. chia/wallet/wallet_action_scope.py +4 -0
  465. chia/wallet/wallet_blockchain.py +12 -7
  466. chia/wallet/wallet_coin_record.py +3 -2
  467. chia/wallet/wallet_coin_store.py +3 -2
  468. chia/wallet/wallet_info.py +2 -1
  469. chia/wallet/wallet_interested_store.py +3 -2
  470. chia/wallet/wallet_nft_store.py +4 -4
  471. chia/wallet/wallet_node.py +3 -4
  472. chia/wallet/wallet_pool_store.py +3 -4
  473. chia/wallet/wallet_protocol.py +19 -5
  474. chia/wallet/wallet_puzzle_store.py +2 -2
  475. chia/wallet/wallet_retry_store.py +3 -6
  476. chia/wallet/wallet_singleton_store.py +2 -2
  477. chia/wallet/wallet_state_manager.py +20 -197
  478. chia/wallet/wallet_transaction_store.py +2 -2
  479. chia/wallet/wallet_user_store.py +2 -1
  480. chia/wallet/wallet_weight_proof_handler.py +3 -2
  481. {chia_blockchain-2.5.2rc1.dist-info → chia_blockchain-2.5.3rc1.dist-info}/METADATA +3 -2
  482. chia_blockchain-2.5.3rc1.dist-info/RECORD +891 -0
  483. mozilla-ca/cacert.pem +64 -33
  484. chia/_tests/clvm/test_condition_codes.py +0 -13
  485. chia/_tests/cmds/wallet/test_dao.py +0 -565
  486. chia/_tests/wallet/dao_wallet/__init__.py +0 -0
  487. chia/_tests/wallet/dao_wallet/config.py +0 -3
  488. chia/_tests/wallet/dao_wallet/test_dao_clvm.py +0 -1330
  489. chia/_tests/wallet/dao_wallet/test_dao_wallets.py +0 -3488
  490. chia/cmds/dao.py +0 -1064
  491. chia/cmds/dao_funcs.py +0 -598
  492. chia/consensus/puzzles/__init__.py +0 -0
  493. chia/consensus/puzzles/chialisp_deserialisation.clsp +0 -69
  494. chia/consensus/puzzles/chialisp_deserialisation.clsp.hex +0 -1
  495. chia/consensus/puzzles/rom_bootstrap_generator.clsp +0 -37
  496. chia/consensus/puzzles/rom_bootstrap_generator.clsp.hex +0 -1
  497. chia/full_node/puzzles/__init__.py +0 -0
  498. chia/full_node/puzzles/block_program_zero.clsp +0 -14
  499. chia/full_node/puzzles/block_program_zero.clsp.hex +0 -1
  500. chia/full_node/puzzles/decompress_coin_spend_entry.clsp +0 -5
  501. chia/full_node/puzzles/decompress_coin_spend_entry.clsp.hex +0 -1
  502. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp +0 -7
  503. chia/full_node/puzzles/decompress_coin_spend_entry_with_prefix.clsp.hex +0 -1
  504. chia/full_node/puzzles/decompress_puzzle.clsp +0 -6
  505. chia/full_node/puzzles/decompress_puzzle.clsp.hex +0 -1
  506. chia/pools/puzzles/__init__.py +0 -0
  507. chia/pools/puzzles/pool_member_innerpuz.clsp +0 -70
  508. chia/pools/puzzles/pool_member_innerpuz.clsp.hex +0 -1
  509. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp +0 -69
  510. chia/pools/puzzles/pool_waitingroom_innerpuz.clsp.hex +0 -1
  511. chia/simulator/simulator_constants.py +0 -13
  512. chia/types/blockchain_format/foliage.py +0 -8
  513. chia/types/blockchain_format/pool_target.py +0 -5
  514. chia/types/blockchain_format/reward_chain_block.py +0 -6
  515. chia/types/blockchain_format/sized_bytes.py +0 -11
  516. chia/util/ints.py +0 -19
  517. chia/wallet/cat_wallet/dao_cat_info.py +0 -28
  518. chia/wallet/cat_wallet/dao_cat_wallet.py +0 -669
  519. chia/wallet/cat_wallet/puzzles/__init__.py +0 -0
  520. chia/wallet/cat_wallet/puzzles/cat_truths.clib +0 -31
  521. chia/wallet/cat_wallet/puzzles/cat_v2.clsp +0 -397
  522. chia/wallet/cat_wallet/puzzles/cat_v2.clsp.hex +0 -1
  523. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp +0 -25
  524. chia/wallet/cat_wallet/puzzles/delegated_tail.clsp.hex +0 -1
  525. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp +0 -15
  526. chia/wallet/cat_wallet/puzzles/everything_with_signature.clsp.hex +0 -1
  527. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp +0 -26
  528. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id.clsp.hex +0 -1
  529. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp +0 -42
  530. chia/wallet/cat_wallet/puzzles/genesis_by_coin_id_or_singleton.clsp.hex +0 -1
  531. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp +0 -24
  532. chia/wallet/cat_wallet/puzzles/genesis_by_puzzle_hash.clsp.hex +0 -1
  533. chia/wallet/dao_wallet/__init__.py +0 -0
  534. chia/wallet/dao_wallet/dao_info.py +0 -61
  535. chia/wallet/dao_wallet/dao_utils.py +0 -811
  536. chia/wallet/dao_wallet/dao_wallet.py +0 -2119
  537. chia/wallet/did_wallet/puzzles/__init__.py +0 -0
  538. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp +0 -135
  539. chia/wallet/did_wallet/puzzles/did_innerpuz.clsp.hex +0 -1
  540. chia/wallet/payment.py +0 -33
  541. chia/wallet/puzzles/augmented_condition.clsp +0 -13
  542. chia/wallet/puzzles/augmented_condition.clsp.hex +0 -1
  543. chia/wallet/puzzles/condition_codes.clib +0 -77
  544. chia/wallet/puzzles/curry-and-treehash.clib +0 -102
  545. chia/wallet/puzzles/curry.clib +0 -135
  546. chia/wallet/puzzles/curry_by_index.clib +0 -16
  547. chia/wallet/puzzles/dao_cat_eve.clsp +0 -17
  548. chia/wallet/puzzles/dao_cat_eve.clsp.hex +0 -1
  549. chia/wallet/puzzles/dao_cat_launcher.clsp +0 -36
  550. chia/wallet/puzzles/dao_cat_launcher.clsp.hex +0 -1
  551. chia/wallet/puzzles/dao_finished_state.clsp +0 -35
  552. chia/wallet/puzzles/dao_finished_state.clsp.hex +0 -1
  553. chia/wallet/puzzles/dao_finished_state.clsp.hex.sha256tree +0 -1
  554. chia/wallet/puzzles/dao_lockup.clsp +0 -288
  555. chia/wallet/puzzles/dao_lockup.clsp.hex +0 -1
  556. chia/wallet/puzzles/dao_lockup.clsp.hex.sha256tree +0 -1
  557. chia/wallet/puzzles/dao_proposal.clsp +0 -377
  558. chia/wallet/puzzles/dao_proposal.clsp.hex +0 -1
  559. chia/wallet/puzzles/dao_proposal.clsp.hex.sha256tree +0 -1
  560. chia/wallet/puzzles/dao_proposal_timer.clsp +0 -78
  561. chia/wallet/puzzles/dao_proposal_timer.clsp.hex +0 -1
  562. chia/wallet/puzzles/dao_proposal_timer.clsp.hex.sha256tree +0 -1
  563. chia/wallet/puzzles/dao_proposal_validator.clsp +0 -87
  564. chia/wallet/puzzles/dao_proposal_validator.clsp.hex +0 -1
  565. chia/wallet/puzzles/dao_proposal_validator.clsp.hex.sha256tree +0 -1
  566. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp +0 -240
  567. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex +0 -1
  568. chia/wallet/puzzles/dao_spend_p2_singleton_v2.clsp.hex.sha256tree +0 -1
  569. chia/wallet/puzzles/dao_treasury.clsp +0 -115
  570. chia/wallet/puzzles/dao_treasury.clsp.hex +0 -1
  571. chia/wallet/puzzles/dao_update_proposal.clsp +0 -44
  572. chia/wallet/puzzles/dao_update_proposal.clsp.hex +0 -1
  573. chia/wallet/puzzles/json.clib +0 -25
  574. chia/wallet/puzzles/merkle_utils.clib +0 -18
  575. chia/wallet/puzzles/notification.clsp +0 -7
  576. chia/wallet/puzzles/notification.clsp.hex +0 -1
  577. chia/wallet/puzzles/p2_1_of_n.clsp +0 -22
  578. chia/wallet/puzzles/p2_1_of_n.clsp.hex +0 -1
  579. chia/wallet/puzzles/p2_conditions.clsp +0 -3
  580. chia/wallet/puzzles/p2_conditions.clsp.hex +0 -1
  581. chia/wallet/puzzles/p2_delegated_conditions.clsp +0 -18
  582. chia/wallet/puzzles/p2_delegated_conditions.clsp.hex +0 -1
  583. chia/wallet/puzzles/p2_delegated_puzzle.clsp +0 -19
  584. chia/wallet/puzzles/p2_delegated_puzzle.clsp.hex +0 -1
  585. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp +0 -91
  586. chia/wallet/puzzles/p2_delegated_puzzle_or_hidden_puzzle.clsp.hex +0 -1
  587. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp +0 -108
  588. chia/wallet/puzzles/p2_m_of_n_delegate_direct.clsp.hex +0 -1
  589. chia/wallet/puzzles/p2_parent.clsp +0 -19
  590. chia/wallet/puzzles/p2_parent.clsp.hex +0 -1
  591. chia/wallet/puzzles/p2_puzzle_hash.clsp +0 -18
  592. chia/wallet/puzzles/p2_puzzle_hash.clsp.hex +0 -1
  593. chia/wallet/puzzles/p2_singleton.clsp +0 -30
  594. chia/wallet/puzzles/p2_singleton.clsp.hex +0 -1
  595. chia/wallet/puzzles/p2_singleton_aggregator.clsp +0 -81
  596. chia/wallet/puzzles/p2_singleton_aggregator.clsp.hex +0 -1
  597. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp +0 -50
  598. chia/wallet/puzzles/p2_singleton_or_delayed_puzhash.clsp.hex +0 -1
  599. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp +0 -47
  600. chia/wallet/puzzles/p2_singleton_via_delegated_puzzle.clsp.hex +0 -1
  601. chia/wallet/puzzles/settlement_payments.clsp +0 -49
  602. chia/wallet/puzzles/settlement_payments.clsp.hex +0 -1
  603. chia/wallet/puzzles/sha256tree.clib +0 -11
  604. chia/wallet/puzzles/singleton_launcher.clsp +0 -16
  605. chia/wallet/puzzles/singleton_launcher.clsp.hex +0 -1
  606. chia/wallet/puzzles/singleton_top_layer.clsp +0 -177
  607. chia/wallet/puzzles/singleton_top_layer.clsp.hex +0 -1
  608. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp +0 -107
  609. chia/wallet/puzzles/singleton_top_layer_v1_1.clsp.hex +0 -1
  610. chia/wallet/puzzles/singleton_truths.clib +0 -21
  611. chia/wallet/vc_wallet/cr_puzzles/__init__.py +0 -0
  612. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp +0 -3
  613. chia/wallet/vc_wallet/cr_puzzles/conditions_w_fee_announce.clsp.hex +0 -1
  614. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp +0 -304
  615. chia/wallet/vc_wallet/cr_puzzles/credential_restriction.clsp.hex +0 -1
  616. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp +0 -45
  617. chia/wallet/vc_wallet/cr_puzzles/flag_proofs_checker.clsp.hex +0 -1
  618. chia/wallet/vc_wallet/vc_puzzles/__init__.py +0 -0
  619. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp +0 -30
  620. chia/wallet/vc_wallet/vc_puzzles/covenant_layer.clsp.hex +0 -1
  621. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp +0 -75
  622. chia/wallet/vc_wallet/vc_puzzles/eml_covenant_morpher.clsp.hex +0 -1
  623. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp +0 -32
  624. chia/wallet/vc_wallet/vc_puzzles/eml_transfer_program_covenant_adapter.clsp.hex +0 -1
  625. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp +0 -80
  626. chia/wallet/vc_wallet/vc_puzzles/eml_update_metadata_with_DID.clsp.hex +0 -1
  627. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp +0 -163
  628. chia/wallet/vc_wallet/vc_puzzles/exigent_metadata_layer.clsp.hex +0 -1
  629. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp +0 -16
  630. chia/wallet/vc_wallet/vc_puzzles/p2_announced_delegated_puzzle.clsp.hex +0 -1
  631. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp +0 -74
  632. chia/wallet/vc_wallet/vc_puzzles/standard_vc_backdoor_puzzle.clsp.hex +0 -1
  633. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp +0 -23
  634. chia/wallet/vc_wallet/vc_puzzles/std_parent_morpher.clsp.hex +0 -1
  635. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp +0 -64
  636. chia/wallet/vc_wallet/vc_puzzles/viral_backdoor.clsp.hex +0 -1
  637. chia_blockchain-2.5.2rc1.dist-info/RECORD +0 -1042
  638. {chia_blockchain-2.5.2rc1.dist-info → chia_blockchain-2.5.3rc1.dist-info}/LICENSE +0 -0
  639. {chia_blockchain-2.5.2rc1.dist-info → chia_blockchain-2.5.3rc1.dist-info}/WHEEL +0 -0
  640. {chia_blockchain-2.5.2rc1.dist-info → chia_blockchain-2.5.3rc1.dist-info}/entry_points.txt +0 -0
@@ -1,20 +1,14 @@
1
1
  from __future__ import annotations
2
2
 
3
- import random
4
- from typing import Any, Optional
3
+ from typing import Optional, Union
5
4
 
6
5
  import pytest
6
+ from chia_rs.sized_bytes import bytes32
7
+ from chia_rs.sized_ints import uint64
7
8
 
8
- from chia._tests.conftest import ConsensusMode
9
- from chia._tests.util.time_out_assert import time_out_assert, time_out_assert_not_none
10
- from chia._tests.wallet.nft_wallet.test_nft_1_offers import mempool_not_empty
11
- from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward
12
- from chia.simulator.full_node_simulator import FullNodeSimulator
13
- from chia.simulator.simulator_protocol import FarmNewBlockProtocol
9
+ from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework
10
+ from chia._tests.util.time_out_assert import time_out_assert
14
11
  from chia.types.blockchain_format.program import Program
15
- from chia.types.blockchain_format.sized_bytes import bytes32
16
- from chia.types.peer_info import PeerInfo
17
- from chia.util.ints import uint32, uint64
18
12
  from chia.wallet.cat_wallet.cat_wallet import CATWallet
19
13
  from chia.wallet.nft_wallet.nft_wallet import NFTWallet
20
14
  from chia.wallet.outer_puzzles import create_asset_id, match_puzzle
@@ -23,7 +17,6 @@ from chia.wallet.trading.offer import Offer
23
17
  from chia.wallet.trading.trade_status import TradeStatus
24
18
  from chia.wallet.uncurried_puzzle import uncurry_puzzle
25
19
  from chia.wallet.util.debug_spend_bundle import disassemble
26
- from chia.wallet.util.tx_config import DEFAULT_TX_CONFIG
27
20
 
28
21
 
29
22
  async def get_trade_and_status(trade_manager, trade) -> TradeStatus: # type: ignore
@@ -31,70 +24,33 @@ async def get_trade_and_status(trade_manager, trade) -> TradeStatus: # type: ig
31
24
  return TradeStatus(trade_rec.status)
32
25
 
33
26
 
34
- @pytest.mark.parametrize(
35
- "trusted",
36
- [False],
37
- )
38
- @pytest.mark.parametrize(
39
- "reuse_puzhash",
40
- [True, False],
41
- )
27
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
28
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
42
29
  @pytest.mark.anyio
43
- async def test_nft_offer_with_fee(
44
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, reuse_puzhash: bool, seeded_random: random.Random
45
- ) -> None:
46
- full_nodes, wallets, _ = two_wallet_nodes
47
- full_node_api: FullNodeSimulator = full_nodes[0]
48
- full_node_server = full_node_api.server
49
- wallet_node_0, server_0 = wallets[0]
50
- wallet_node_1, server_1 = wallets[1]
51
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
52
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
53
-
54
- tx_config = DEFAULT_TX_CONFIG.override(reuse_puzhash=reuse_puzhash)
55
-
56
- maker_ph = await wallet_maker.get_new_puzzlehash()
57
- taker_ph = await wallet_taker.get_new_puzzlehash()
58
- token_ph = bytes32.random(seeded_random)
59
-
60
- if trusted:
61
- wallet_node_0.config["trusted_peers"] = {
62
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
63
- }
64
- wallet_node_1.config["trusted_peers"] = {
65
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
66
- }
67
- else:
68
- wallet_node_0.config["trusted_peers"] = {}
69
- wallet_node_1.config["trusted_peers"] = {}
70
-
71
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
72
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
73
-
74
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(maker_ph))
75
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(taker_ph))
76
-
77
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
78
-
79
- funds = sum(calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, 2))
80
-
81
- await time_out_assert(20, wallet_maker.get_unconfirmed_balance, funds)
82
- await time_out_assert(20, wallet_maker.get_confirmed_balance, funds)
83
-
84
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
85
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
30
+ async def test_nft_offer_with_fee(wallet_environments: WalletTestFramework) -> None:
31
+ env_0 = wallet_environments.environments[0]
32
+ env_1 = wallet_environments.environments[1]
33
+ wallet_maker = env_0.xch_wallet
34
+ wallet_taker = env_1.xch_wallet
35
+ trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
36
+ trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
37
+ env_0.wallet_aliases = {
38
+ "xch": 1,
39
+ "nft": 2,
40
+ }
41
+ env_1.wallet_aliases = {
42
+ "xch": 1,
43
+ "nft": 2,
44
+ }
86
45
 
87
46
  nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
88
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
47
+ env_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
89
48
  )
90
49
 
91
50
  nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
92
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
51
+ env_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
93
52
  )
94
53
 
95
- trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
96
- trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
97
-
98
54
  metadata = Program.to(
99
55
  [
100
56
  ("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
@@ -102,40 +58,74 @@ async def test_nft_offer_with_fee(
102
58
  ]
103
59
  )
104
60
 
105
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
61
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
62
+ wallet_environments.tx_config, push=True
63
+ ) as action_scope:
106
64
  await nft_wallet_maker.generate_new_nft(metadata, action_scope)
107
- for tx in action_scope.side_effects.transactions:
108
- if tx.spend_bundle is not None:
109
- await time_out_assert_not_none(
110
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, tx.spend_bundle.name()
111
- )
112
-
113
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
114
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
65
+
66
+ await wallet_environments.process_pending_states(
67
+ [
68
+ WalletStateTransition(
69
+ pre_block_balance_updates={
70
+ "xch": {
71
+ "confirmed_wallet_balance": 0,
72
+ "unconfirmed_wallet_balance": -1,
73
+ "<=#spendable_balance": -1,
74
+ "<=#max_send_amount": -1,
75
+ "pending_coin_removal_count": 1,
76
+ ">=#pending_change": 1, # any amount increase
77
+ "unspent_coin_count": 0,
78
+ },
79
+ "nft": {
80
+ "init": True,
81
+ "confirmed_wallet_balance": 0,
82
+ "unconfirmed_wallet_balance": 0,
83
+ "spendable_balance": 0,
84
+ "max_send_amount": 0,
85
+ "pending_coin_removal_count": 1, # a bit weird but correct?
86
+ "pending_change": 0,
87
+ "unspent_coin_count": 0,
88
+ },
89
+ },
90
+ post_block_balance_updates={
91
+ "xch": {
92
+ "confirmed_wallet_balance": -1,
93
+ "unconfirmed_wallet_balance": 0,
94
+ ">=#spendable_balance": 1, # any amount increase
95
+ ">=#max_send_amount": 1, # any amount increase
96
+ "pending_coin_removal_count": -1,
97
+ "<=#pending_change": -1, # any amount decrease
98
+ "unspent_coin_count": 0,
99
+ },
100
+ "nft": {
101
+ "pending_coin_removal_count": -1,
102
+ "unspent_coin_count": 1,
103
+ },
104
+ },
105
+ ),
106
+ WalletStateTransition(pre_block_balance_updates={"nft": {"init": True}}),
107
+ ]
108
+ )
115
109
  coins_maker = await nft_wallet_maker.get_current_nfts()
116
110
  assert len(coins_maker) == 1
117
111
 
118
112
  assert await nft_wallet_taker.get_nft_count() == 0
119
113
  # MAKE FIRST TRADE: 1 NFT for 100 xch
120
- maker_balance_pre = await wallet_maker.get_confirmed_balance()
121
- taker_balance_pre = await wallet_taker.get_confirmed_balance()
122
114
 
123
115
  nft_to_offer = coins_maker[0]
124
116
  nft_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_offer.full_puzzle))
125
- nft_asset_id: bytes32 = create_asset_id(nft_info) # type: ignore
126
- driver_dict: dict[bytes32, Optional[PuzzleInfo]] = {nft_asset_id: nft_info}
117
+ assert nft_info is not None
118
+ nft_asset_id = create_asset_id(nft_info)
119
+ assert nft_asset_id is not None
120
+ driver_dict: dict[bytes32, PuzzleInfo] = {nft_asset_id: nft_info}
127
121
 
128
122
  xch_request = 100
129
123
  maker_fee = uint64(10)
130
- offer_nft_for_xch = {wallet_maker.id(): xch_request, nft_asset_id: -1}
131
- maker_unused_index = (
132
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
133
- ).index
134
- taker_unused_index = (
135
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
136
- ).index
137
-
138
- async with trade_manager_maker.wallet_state_manager.new_action_scope(tx_config, push=False) as action_scope:
124
+ offer_nft_for_xch: dict[Union[int, bytes32], int] = {wallet_maker.id(): xch_request, nft_asset_id: -1}
125
+
126
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
127
+ wallet_environments.tx_config, push=False
128
+ ) as action_scope:
139
129
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
140
130
  offer_nft_for_xch, action_scope, driver_dict, fee=maker_fee
141
131
  )
@@ -145,12 +135,12 @@ async def test_nft_offer_with_fee(
145
135
 
146
136
  taker_fee = uint64(1)
147
137
 
148
- [_maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
138
+ [_maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers(
149
139
  [Offer.from_bytes(trade_make.offer)]
150
140
  )
151
- peer = wallet_node_1.get_full_node_peer()
141
+ peer = env_1.node.get_full_node_peer()
152
142
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
153
- tx_config, push=True, additional_signing_responses=signing_response
143
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
154
144
  ) as action_scope:
155
145
  trade_take = await trade_manager_taker.respond_to_offer(
156
146
  Offer.from_bytes(trade_make.offer),
@@ -159,59 +149,82 @@ async def test_nft_offer_with_fee(
159
149
  fee=taker_fee,
160
150
  )
161
151
 
162
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
163
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
152
+ await wallet_environments.process_pending_states(
153
+ [
154
+ WalletStateTransition(
155
+ pre_block_balance_updates={
156
+ "xch": {
157
+ "<=#spendable_balance": -maker_fee,
158
+ "<=#max_send_amount": -maker_fee,
159
+ "pending_coin_removal_count": 1,
160
+ },
161
+ "nft": {
162
+ "pending_coin_removal_count": 1,
163
+ },
164
+ },
165
+ post_block_balance_updates={
166
+ "xch": {
167
+ "unconfirmed_wallet_balance": -maker_fee + xch_request,
168
+ "confirmed_wallet_balance": -maker_fee + xch_request,
169
+ ">=#spendable_balance": 1,
170
+ ">=#max_send_amount": 1,
171
+ "pending_coin_removal_count": -1,
172
+ "unspent_coin_count": 1,
173
+ },
174
+ "nft": {
175
+ "pending_coin_removal_count": -1,
176
+ "unspent_coin_count": -1,
177
+ },
178
+ },
179
+ ),
180
+ WalletStateTransition(
181
+ pre_block_balance_updates={
182
+ "xch": {
183
+ "unconfirmed_wallet_balance": -(xch_request + taker_fee),
184
+ "<=#spendable_balance": -taker_fee,
185
+ "<=#max_send_amount": -taker_fee,
186
+ ">=#pending_change": 1,
187
+ "pending_coin_removal_count": 1,
188
+ },
189
+ "nft": {},
190
+ },
191
+ post_block_balance_updates={
192
+ "xch": {
193
+ "confirmed_wallet_balance": -(xch_request + taker_fee),
194
+ ">=#spendable_balance": 1,
195
+ ">=#max_send_amount": 1,
196
+ "<=#pending_change": -1,
197
+ "pending_coin_removal_count": -1,
198
+ },
199
+ "nft": {
200
+ "unspent_coin_count": 1,
201
+ },
202
+ },
203
+ ),
204
+ ]
205
+ )
164
206
 
165
207
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
166
208
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
167
- await time_out_assert(20, wallet_maker.get_confirmed_balance, maker_balance_pre + xch_request - maker_fee)
168
- await time_out_assert(20, wallet_taker.get_confirmed_balance, taker_balance_pre - xch_request - taker_fee)
169
209
  coins_taker = await nft_wallet_taker.get_current_nfts()
170
210
  assert len(coins_taker) == 1
171
-
172
211
  assert await nft_wallet_maker.get_nft_count() == 0
173
- if reuse_puzhash:
174
- # Check if unused index changed
175
- assert (
176
- maker_unused_index
177
- == (
178
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
179
- ).index
180
- )
181
- assert (
182
- taker_unused_index
183
- == (
184
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
185
- ).index
186
- )
187
- else:
188
- assert (
189
- maker_unused_index
190
- < (
191
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
192
- ).index
193
- )
194
- assert (
195
- taker_unused_index
196
- < (
197
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
198
- ).index
199
- )
200
212
  # MAKE SECOND TRADE: 100 xch for 1 NFT
201
213
 
202
- maker_balance_pre = await wallet_maker.get_confirmed_balance()
203
- taker_balance_pre = await wallet_taker.get_confirmed_balance()
204
-
205
214
  nft_to_buy = coins_taker[0]
206
215
  nft_to_buy_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_buy.full_puzzle))
207
- nft_to_buy_asset_id: bytes32 = create_asset_id(nft_to_buy_info) # type: ignore
208
- driver_dict_to_buy: dict[bytes32, Optional[PuzzleInfo]] = {nft_to_buy_asset_id: nft_to_buy_info}
216
+ assert nft_to_buy_info is not None
217
+ nft_to_buy_asset_id = create_asset_id(nft_to_buy_info)
218
+ assert nft_to_buy_asset_id is not None
219
+ driver_dict_to_buy: dict[bytes32, PuzzleInfo] = {nft_to_buy_asset_id: nft_to_buy_info}
209
220
 
210
221
  xch_offered = 1000
211
222
  maker_fee = uint64(10)
212
- offer_xch_for_nft = {wallet_maker.id(): -xch_offered, nft_to_buy_asset_id: 1}
223
+ offer_xch_for_nft: dict[Union[int, bytes32], int] = {wallet_maker.id(): -xch_offered, nft_to_buy_asset_id: 1}
213
224
 
214
- async with trade_manager_maker.wallet_state_manager.new_action_scope(tx_config, push=False) as action_scope:
225
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
226
+ wallet_environments.tx_config, push=False
227
+ ) as action_scope:
215
228
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
216
229
  offer_xch_for_nft, action_scope, driver_dict_to_buy, fee=maker_fee
217
230
  )
@@ -221,85 +234,94 @@ async def test_nft_offer_with_fee(
221
234
 
222
235
  taker_fee = uint64(1)
223
236
 
224
- [_maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
237
+ [_maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers(
225
238
  [Offer.from_bytes(trade_make.offer)]
226
239
  )
227
240
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
228
- tx_config, push=True, additional_signing_responses=signing_response
241
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
229
242
  ) as action_scope:
230
243
  trade_take = await trade_manager_taker.respond_to_offer(
231
244
  Offer.from_bytes(trade_make.offer), peer, action_scope, fee=taker_fee
232
245
  )
233
246
 
234
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
235
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
247
+ await wallet_environments.process_pending_states(
248
+ [
249
+ WalletStateTransition(
250
+ pre_block_balance_updates={
251
+ "xch": {
252
+ "<=#spendable_balance": -(xch_offered + maker_fee),
253
+ "<=#max_send_amount": -(xch_offered + maker_fee),
254
+ "pending_coin_removal_count": 1,
255
+ },
256
+ "nft": {},
257
+ },
258
+ post_block_balance_updates={
259
+ "xch": {
260
+ "unconfirmed_wallet_balance": -(xch_offered + maker_fee),
261
+ "confirmed_wallet_balance": -(xch_offered + maker_fee),
262
+ ">=#spendable_balance": 1,
263
+ ">=#max_send_amount": 1,
264
+ "pending_coin_removal_count": -1,
265
+ },
266
+ "nft": {
267
+ "unspent_coin_count": 1,
268
+ },
269
+ },
270
+ ),
271
+ WalletStateTransition(
272
+ pre_block_balance_updates={
273
+ "xch": {
274
+ "unconfirmed_wallet_balance": -taker_fee + xch_offered,
275
+ "<=#spendable_balance": -(xch_offered + maker_fee),
276
+ "<=#max_send_amount": -(xch_offered + maker_fee),
277
+ ">=#pending_change": 1,
278
+ "pending_coin_removal_count": 1,
279
+ },
280
+ "nft": {
281
+ "pending_coin_removal_count": 1,
282
+ },
283
+ },
284
+ post_block_balance_updates={
285
+ "xch": {
286
+ "confirmed_wallet_balance": -taker_fee + xch_offered,
287
+ ">=#spendable_balance": 1,
288
+ ">=#max_send_amount": 1,
289
+ "<=#pending_change": -1,
290
+ "pending_coin_removal_count": -1,
291
+ "unspent_coin_count": 1,
292
+ },
293
+ "nft": {
294
+ "pending_coin_removal_count": -1,
295
+ "unspent_coin_count": -1,
296
+ },
297
+ },
298
+ ),
299
+ ]
300
+ )
236
301
 
237
302
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
238
303
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
239
- await time_out_assert(20, wallet_maker.get_confirmed_balance, maker_balance_pre - xch_offered - maker_fee)
240
- await time_out_assert(20, wallet_taker.get_confirmed_balance, taker_balance_pre + xch_offered - taker_fee)
241
304
 
242
305
  assert await nft_wallet_maker.get_nft_count() == 1
243
306
  assert await nft_wallet_taker.get_nft_count() == 0
244
307
 
245
308
 
246
- @pytest.mark.parametrize(
247
- "trusted",
248
- [False],
249
- )
309
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
310
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 1, "blocks_needed": [1]}], indirect=True)
250
311
  @pytest.mark.anyio
251
- async def test_nft_offer_cancellations(
252
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
253
- ) -> None:
254
- full_nodes, wallets, _ = two_wallet_nodes
255
- full_node_api: FullNodeSimulator = full_nodes[0]
256
- full_node_server = full_node_api.server
257
- wallet_node_0, server_0 = wallets[0]
258
- wallet_node_1, server_1 = wallets[1]
259
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
260
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
261
-
262
- maker_ph = await wallet_maker.get_new_puzzlehash()
263
- taker_ph = await wallet_taker.get_new_puzzlehash()
264
- token_ph = bytes32.random(seeded_random)
265
-
266
- if trusted:
267
- wallet_node_0.config["trusted_peers"] = {
268
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
269
- }
270
- wallet_node_1.config["trusted_peers"] = {
271
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
272
- }
273
- else:
274
- wallet_node_0.config["trusted_peers"] = {}
275
- wallet_node_1.config["trusted_peers"] = {}
276
-
277
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
278
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
279
-
280
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(maker_ph))
281
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(taker_ph))
282
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
283
-
284
- funds = sum(calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, 2))
285
-
286
- await time_out_assert(20, wallet_maker.get_unconfirmed_balance, funds)
287
- await time_out_assert(20, wallet_maker.get_confirmed_balance, funds)
288
-
289
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
290
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
312
+ async def test_nft_offer_cancellations(wallet_environments: WalletTestFramework) -> None:
313
+ env_0 = wallet_environments.environments[0]
314
+ wallet_maker = env_0.xch_wallet
315
+ trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
316
+ env_0.wallet_aliases = {
317
+ "xch": 1,
318
+ "nft": 2,
319
+ }
291
320
 
292
321
  nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
293
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
294
- )
295
-
296
- nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
297
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
322
+ env_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
298
323
  )
299
324
 
300
- trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
301
- # trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
302
-
303
325
  metadata = Program.to(
304
326
  [
305
327
  ("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
@@ -307,33 +329,72 @@ async def test_nft_offer_cancellations(
307
329
  ]
308
330
  )
309
331
 
310
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
332
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
333
+ wallet_environments.tx_config, push=True
334
+ ) as action_scope:
311
335
  await nft_wallet_maker.generate_new_nft(metadata, action_scope)
312
- for tx in action_scope.side_effects.transactions:
313
- if tx.spend_bundle is not None:
314
- await time_out_assert_not_none(
315
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, tx.spend_bundle.name()
316
- )
317
-
318
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
319
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
336
+
337
+ await wallet_environments.process_pending_states(
338
+ [
339
+ WalletStateTransition(
340
+ pre_block_balance_updates={
341
+ "xch": {
342
+ "confirmed_wallet_balance": 0,
343
+ "unconfirmed_wallet_balance": -1,
344
+ "<=#spendable_balance": -1,
345
+ "<=#max_send_amount": -1,
346
+ "pending_coin_removal_count": 1,
347
+ ">=#pending_change": 1, # any amount increase
348
+ "unspent_coin_count": 0,
349
+ },
350
+ "nft": {
351
+ "init": True,
352
+ "confirmed_wallet_balance": 0,
353
+ "unconfirmed_wallet_balance": 0,
354
+ "spendable_balance": 0,
355
+ "max_send_amount": 0,
356
+ "pending_coin_removal_count": 1, # a bit weird but correct?
357
+ "pending_change": 0,
358
+ "unspent_coin_count": 0,
359
+ },
360
+ },
361
+ post_block_balance_updates={
362
+ "xch": {
363
+ "confirmed_wallet_balance": -1,
364
+ "unconfirmed_wallet_balance": 0,
365
+ ">=#spendable_balance": 1, # any amount increase
366
+ ">=#max_send_amount": 1, # any amount increase
367
+ "pending_coin_removal_count": -1,
368
+ "<=#pending_change": -1, # any amount decrease
369
+ "unspent_coin_count": 0,
370
+ },
371
+ "nft": {
372
+ "pending_coin_removal_count": -1,
373
+ "unspent_coin_count": 1,
374
+ },
375
+ },
376
+ ),
377
+ WalletStateTransition(pre_block_balance_updates={"nft": {"init": True}}),
378
+ ]
379
+ )
320
380
  coins_maker = await nft_wallet_maker.get_current_nfts()
321
381
  assert len(coins_maker) == 1
322
- assert await nft_wallet_taker.get_nft_count() == 0
323
- # maker creates offer and cancels
324
- maker_balance_pre = await wallet_maker.get_confirmed_balance()
325
- # taker_balance_pre = await wallet_taker.get_confirmed_balance()
326
382
 
383
+ # maker creates offer and cancels
327
384
  nft_to_offer = coins_maker[0]
328
385
  nft_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_offer.full_puzzle))
329
- nft_asset_id: bytes32 = create_asset_id(nft_info) # type: ignore
330
- driver_dict: dict[bytes32, Optional[PuzzleInfo]] = {nft_asset_id: nft_info}
386
+ assert nft_info is not None
387
+ nft_asset_id = create_asset_id(nft_info)
388
+ assert nft_asset_id is not None
389
+ driver_dict: dict[bytes32, PuzzleInfo] = {nft_asset_id: nft_info}
331
390
 
332
391
  xch_request = 100
333
392
  maker_fee = uint64(10)
334
- offer_nft_for_xch = {wallet_maker.id(): xch_request, nft_asset_id: -1}
393
+ offer_nft_for_xch: dict[Union[bytes32, int], int] = {wallet_maker.id(): xch_request, nft_asset_id: -1}
335
394
 
336
- async with trade_manager_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
395
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
396
+ wallet_environments.tx_config, push=False
397
+ ) as action_scope:
337
398
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
338
399
  offer_nft_for_xch, action_scope, driver_dict, fee=maker_fee
339
400
  )
@@ -341,88 +402,92 @@ async def test_nft_offer_cancellations(
341
402
  assert error is None
342
403
  assert trade_make is not None
343
404
 
344
- # await trade_manager_maker.cancel_pending_offers([trade_make.trade_id], secure=False)
345
- # await time_out_assert(20, get_trade_and_status, TradeStatus.CANCELLED, trade_manager_maker, trade_make)
405
+ await env_0.change_balances(
406
+ {
407
+ "xch": {
408
+ "<=#spendable_balance": -maker_fee,
409
+ "<=#max_send_amount": -maker_fee,
410
+ "pending_coin_removal_count": 1,
411
+ }
412
+ }
413
+ )
346
414
 
347
415
  cancel_fee = uint64(10)
348
416
 
349
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
417
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
418
+ wallet_environments.tx_config, push=True
419
+ ) as action_scope:
350
420
  await trade_manager_maker.cancel_pending_offers(
351
421
  [trade_make.trade_id], action_scope, fee=cancel_fee, secure=True
352
422
  )
353
423
 
354
424
  await time_out_assert(20, get_trade_and_status, TradeStatus.PENDING_CANCEL, trade_manager_maker, trade_make)
355
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
356
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
357
425
 
358
- await time_out_assert(20, get_trade_and_status, TradeStatus.CANCELLED, trade_manager_maker, trade_make)
426
+ await wallet_environments.process_pending_states(
427
+ [
428
+ WalletStateTransition(
429
+ pre_block_balance_updates={
430
+ "xch": {
431
+ "unconfirmed_wallet_balance": -cancel_fee,
432
+ "<=#spendable_balance": -cancel_fee,
433
+ "<=#max_send_amount": -cancel_fee,
434
+ ">=#pending_change": 1,
435
+ "pending_coin_removal_count": 1,
436
+ },
437
+ "nft": {
438
+ "pending_coin_removal_count": 1,
439
+ },
440
+ },
441
+ post_block_balance_updates={
442
+ "xch": {
443
+ "confirmed_wallet_balance": -cancel_fee,
444
+ ">=#spendable_balance": 1,
445
+ ">=#max_send_amount": 1,
446
+ "<=#pending_change": -1,
447
+ "pending_coin_removal_count": -2, # 1 from make, 1 from cancel
448
+ },
449
+ "nft": {
450
+ "pending_coin_removal_count": -1,
451
+ },
452
+ },
453
+ ),
454
+ WalletStateTransition(),
455
+ ]
456
+ )
359
457
 
360
- maker_balance = await wallet_maker.get_confirmed_balance()
361
- assert maker_balance == maker_balance_pre - cancel_fee
458
+ await time_out_assert(20, get_trade_and_status, TradeStatus.CANCELLED, trade_manager_maker, trade_make)
362
459
  assert await nft_wallet_maker.get_nft_count() == 1
363
460
 
364
461
 
365
- @pytest.mark.parametrize(
366
- "trusted",
367
- [False],
368
- )
462
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
463
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
369
464
  @pytest.mark.anyio
370
- async def test_nft_offer_with_metadata_update(
371
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
372
- ) -> None:
373
- full_nodes, wallets, _ = two_wallet_nodes
374
- full_node_api: FullNodeSimulator = full_nodes[0]
375
- full_node_server = full_node_api.server
376
- wallet_node_0, server_0 = wallets[0]
377
- wallet_node_1, server_1 = wallets[1]
378
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
379
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
380
-
381
- maker_ph = await wallet_maker.get_new_puzzlehash()
382
- taker_ph = await wallet_taker.get_new_puzzlehash()
383
- token_ph = bytes32.random(seeded_random)
384
-
385
- if trusted:
386
- wallet_node_0.config["trusted_peers"] = {
387
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
388
- }
389
- wallet_node_1.config["trusted_peers"] = {
390
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
391
- }
392
- else:
393
- wallet_node_0.config["trusted_peers"] = {}
394
- wallet_node_1.config["trusted_peers"] = {}
395
-
396
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
397
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
398
-
399
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(maker_ph))
400
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(taker_ph))
401
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
402
-
403
- funds = sum(calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, 2))
404
-
405
- await time_out_assert(20, wallet_maker.get_unconfirmed_balance, funds)
406
- await time_out_assert(20, wallet_maker.get_confirmed_balance, funds)
407
-
408
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
409
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
465
+ async def test_nft_offer_with_metadata_update(wallet_environments: WalletTestFramework) -> None:
466
+ env_0 = wallet_environments.environments[0]
467
+ env_1 = wallet_environments.environments[1]
468
+ wallet_maker = env_0.xch_wallet
469
+ wallet_taker = env_1.xch_wallet
470
+ trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
471
+ trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
472
+ env_0.wallet_aliases = {
473
+ "xch": 1,
474
+ "nft": 2,
475
+ }
476
+ env_1.wallet_aliases = {
477
+ "xch": 1,
478
+ "nft": 2,
479
+ }
410
480
 
411
481
  nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
412
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
482
+ env_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
413
483
  )
414
484
 
415
485
  nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
416
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
486
+ env_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
417
487
  )
418
488
 
419
- trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
420
- trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
421
-
422
489
  metadata = Program.to(
423
490
  [
424
- ("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
425
- ("h", "0xD4584AD463139FA8C0D9F68F4B59F185"),
426
491
  ("mu", []),
427
492
  ("lu", []),
428
493
  ("sn", uint64(1)),
@@ -430,16 +495,54 @@ async def test_nft_offer_with_metadata_update(
430
495
  ]
431
496
  )
432
497
 
433
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
498
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
499
+ wallet_environments.tx_config, push=True
500
+ ) as action_scope:
434
501
  await nft_wallet_maker.generate_new_nft(metadata, action_scope)
435
- for tx in action_scope.side_effects.transactions:
436
- if tx.spend_bundle is not None:
437
- await time_out_assert_not_none(
438
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, tx.spend_bundle.name()
439
- )
440
-
441
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
442
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
502
+
503
+ await wallet_environments.process_pending_states(
504
+ [
505
+ WalletStateTransition(
506
+ pre_block_balance_updates={
507
+ "xch": {
508
+ "confirmed_wallet_balance": 0,
509
+ "unconfirmed_wallet_balance": -1,
510
+ "<=#spendable_balance": -1,
511
+ "<=#max_send_amount": -1,
512
+ "pending_coin_removal_count": 1,
513
+ ">=#pending_change": 1, # any amount increase
514
+ "unspent_coin_count": 0,
515
+ },
516
+ "nft": {
517
+ "init": True,
518
+ "confirmed_wallet_balance": 0,
519
+ "unconfirmed_wallet_balance": 0,
520
+ "spendable_balance": 0,
521
+ "max_send_amount": 0,
522
+ "pending_coin_removal_count": 1, # a bit weird but correct?
523
+ "pending_change": 0,
524
+ "unspent_coin_count": 0,
525
+ },
526
+ },
527
+ post_block_balance_updates={
528
+ "xch": {
529
+ "confirmed_wallet_balance": -1,
530
+ "unconfirmed_wallet_balance": 0,
531
+ ">=#spendable_balance": 1, # any amount increase
532
+ ">=#max_send_amount": 1, # any amount increase
533
+ "pending_coin_removal_count": -1,
534
+ "<=#pending_change": -1, # any amount decrease
535
+ "unspent_coin_count": 0,
536
+ },
537
+ "nft": {
538
+ "pending_coin_removal_count": -1,
539
+ "unspent_coin_count": 1,
540
+ },
541
+ },
542
+ ),
543
+ WalletStateTransition(pre_block_balance_updates={"nft": {"init": True}}),
544
+ ]
545
+ )
443
546
  coins_maker = await nft_wallet_maker.get_current_nfts()
444
547
  assert len(coins_maker) == 1
445
548
  assert await nft_wallet_taker.get_nft_count() == 0
@@ -449,36 +552,66 @@ async def test_nft_offer_with_metadata_update(
449
552
  url_to_add = "https://new_url.com"
450
553
  key = "mu"
451
554
  fee_for_update = uint64(10)
452
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
555
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
556
+ wallet_environments.tx_config, push=True
557
+ ) as action_scope:
453
558
  await nft_wallet_maker.update_metadata(nft_to_update, key, url_to_add, action_scope, fee=fee_for_update)
454
- mempool_mgr = full_node_api.full_node.mempool_manager
455
- for tx in action_scope.side_effects.transactions:
456
- if tx.spend_bundle is not None:
457
- await time_out_assert_not_none(20, mempool_mgr.get_spendbundle, tx.spend_bundle.name())
458
559
 
459
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
460
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
560
+ await wallet_environments.process_pending_states(
561
+ [
562
+ WalletStateTransition(
563
+ pre_block_balance_updates={
564
+ "xch": {
565
+ "unconfirmed_wallet_balance": -fee_for_update,
566
+ "<=#spendable_balance": -fee_for_update,
567
+ "<=#max_send_amount": -fee_for_update,
568
+ "pending_coin_removal_count": 1,
569
+ ">=#pending_change": 1, # any amount increase
570
+ },
571
+ "nft": {
572
+ "pending_coin_removal_count": 1, # a bit weird but correct?
573
+ },
574
+ },
575
+ post_block_balance_updates={
576
+ "xch": {
577
+ "confirmed_wallet_balance": -fee_for_update,
578
+ ">=#spendable_balance": 1, # any amount increase
579
+ ">=#max_send_amount": 1, # any amount increase
580
+ "pending_coin_removal_count": -1,
581
+ "<=#pending_change": -1, # any amount decrease
582
+ },
583
+ "nft": {
584
+ "pending_coin_removal_count": -1,
585
+ },
586
+ },
587
+ ),
588
+ WalletStateTransition(),
589
+ ]
590
+ )
461
591
 
462
592
  coins_maker = await nft_wallet_maker.get_current_nfts()
463
593
  updated_nft = coins_maker[0]
464
594
  updated_nft_info = match_puzzle(uncurry_puzzle(updated_nft.full_puzzle))
465
-
466
- assert url_to_add in disassemble(updated_nft_info.also().info["metadata"]) # type: ignore
595
+ assert updated_nft_info is not None
596
+ state_layer_info = updated_nft_info.also()
597
+ assert state_layer_info is not None
598
+ assert url_to_add in disassemble(state_layer_info.info["metadata"])
467
599
 
468
600
  # MAKE FIRST TRADE: 1 NFT for 100 xch
469
- maker_balance_pre = await wallet_maker.get_confirmed_balance()
470
- taker_balance_pre = await wallet_taker.get_confirmed_balance()
471
-
472
601
  nft_to_offer = coins_maker[0]
473
602
  nft_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_offer.full_puzzle))
474
- nft_asset_id: bytes32 = create_asset_id(nft_info) # type: ignore
475
- driver_dict: dict[bytes32, Optional[PuzzleInfo]] = {nft_asset_id: nft_info}
603
+ assert nft_info is not None
604
+ nft_asset_id = create_asset_id(nft_info)
605
+ assert nft_asset_id is not None
606
+ driver_dict: dict[bytes32, PuzzleInfo] = {nft_asset_id: nft_info}
476
607
 
477
608
  xch_request = 100
478
609
  maker_fee = uint64(10)
479
- offer_nft_for_xch = {wallet_maker.id(): xch_request, nft_asset_id: -1}
610
+ offer_nft_for_xch: dict[Union[bytes32, int], int] = {wallet_maker.id(): xch_request, nft_asset_id: -1}
480
611
 
481
- async with trade_manager_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
612
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
613
+ wallet_environments.tx_config, push=False
614
+ ) as action_scope:
482
615
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
483
616
  offer_nft_for_xch, action_scope, driver_dict, fee=maker_fee
484
617
  )
@@ -488,90 +621,110 @@ async def test_nft_offer_with_metadata_update(
488
621
 
489
622
  taker_fee = uint64(1)
490
623
 
491
- [_maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
624
+ [_maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers(
492
625
  [Offer.from_bytes(trade_make.offer)]
493
626
  )
494
- peer = wallet_node_1.get_full_node_peer()
627
+ peer = env_1.node.get_full_node_peer()
495
628
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
496
- DEFAULT_TX_CONFIG, push=True, additional_signing_responses=signing_response
629
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
497
630
  ) as action_scope:
498
631
  trade_take = await trade_manager_taker.respond_to_offer(
499
632
  Offer.from_bytes(trade_make.offer), peer, action_scope, fee=taker_fee
500
633
  )
501
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
502
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
634
+
635
+ await wallet_environments.process_pending_states(
636
+ [
637
+ WalletStateTransition(
638
+ pre_block_balance_updates={
639
+ "xch": {
640
+ "<=#spendable_balance": -maker_fee,
641
+ "<=#max_send_amount": -maker_fee,
642
+ "pending_coin_removal_count": 1,
643
+ },
644
+ "nft": {
645
+ "pending_coin_removal_count": 1,
646
+ },
647
+ },
648
+ post_block_balance_updates={
649
+ "xch": {
650
+ "unconfirmed_wallet_balance": -maker_fee + xch_request,
651
+ "confirmed_wallet_balance": -maker_fee + xch_request,
652
+ ">=#spendable_balance": 1,
653
+ ">=#max_send_amount": 1,
654
+ "pending_coin_removal_count": -1,
655
+ "unspent_coin_count": 1,
656
+ },
657
+ "nft": {
658
+ "pending_coin_removal_count": -1,
659
+ "unspent_coin_count": -1,
660
+ },
661
+ },
662
+ ),
663
+ WalletStateTransition(
664
+ pre_block_balance_updates={
665
+ "xch": {
666
+ "unconfirmed_wallet_balance": -(xch_request + taker_fee),
667
+ "<=#spendable_balance": -taker_fee,
668
+ "<=#max_send_amount": -taker_fee,
669
+ ">=#pending_change": 1,
670
+ "pending_coin_removal_count": 1,
671
+ },
672
+ "nft": {},
673
+ },
674
+ post_block_balance_updates={
675
+ "xch": {
676
+ "confirmed_wallet_balance": -(xch_request + taker_fee),
677
+ ">=#spendable_balance": 1,
678
+ ">=#max_send_amount": 1,
679
+ "<=#pending_change": -1,
680
+ "pending_coin_removal_count": -1,
681
+ },
682
+ "nft": {
683
+ "unspent_coin_count": 1,
684
+ },
685
+ },
686
+ ),
687
+ ]
688
+ )
503
689
 
504
690
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
505
691
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
506
- await time_out_assert(20, wallet_maker.get_confirmed_balance, maker_balance_pre + xch_request - maker_fee)
507
- await time_out_assert(20, wallet_taker.get_confirmed_balance, taker_balance_pre - xch_request - taker_fee)
508
692
 
509
693
  assert await nft_wallet_maker.get_nft_count() == 0
510
694
  assert await nft_wallet_taker.get_nft_count() == 1
511
695
 
512
696
 
513
- @pytest.mark.parametrize("trusted", [False])
514
- @pytest.mark.parametrize("reuse_puzhash", [True, False])
697
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
698
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
515
699
  @pytest.mark.anyio
516
- async def test_nft_offer_nft_for_cat(
517
- self_hostname: str,
518
- two_wallet_nodes: Any,
519
- trusted: Any,
520
- reuse_puzhash: bool,
521
- seeded_random: random.Random,
522
- ) -> None:
523
- full_nodes, wallets, _ = two_wallet_nodes
524
- full_node_api: FullNodeSimulator = full_nodes[0]
525
- full_node_server = full_node_api.server
526
- wallet_node_0, server_0 = wallets[0]
527
- wallet_node_1, server_1 = wallets[1]
528
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
529
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
530
-
531
- maker_ph = await wallet_maker.get_new_puzzlehash()
532
- taker_ph = await wallet_taker.get_new_puzzlehash()
533
- token_ph = bytes32.random(seeded_random)
534
-
535
- if trusted:
536
- wallet_node_0.config["trusted_peers"] = {
537
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
538
- }
539
- wallet_node_1.config["trusted_peers"] = {
540
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
541
- }
542
- else:
543
- wallet_node_0.config["trusted_peers"] = {}
544
- wallet_node_1.config["trusted_peers"] = {}
545
-
546
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
547
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
548
-
549
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(maker_ph))
550
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(taker_ph))
551
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
552
-
553
- funds = sum(calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, 2))
554
-
555
- await time_out_assert(20, wallet_maker.get_unconfirmed_balance, funds)
556
- await time_out_assert(20, wallet_maker.get_confirmed_balance, funds)
557
-
558
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
559
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
560
-
561
- tx_config = DEFAULT_TX_CONFIG.override(reuse_puzhash=reuse_puzhash)
700
+ async def test_nft_offer_nft_for_cat(wallet_environments: WalletTestFramework) -> None:
701
+ env_0 = wallet_environments.environments[0]
702
+ env_1 = wallet_environments.environments[1]
703
+ wallet_maker = env_0.xch_wallet
704
+ wallet_taker = env_1.xch_wallet
705
+ trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
706
+ trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
707
+ env_0.wallet_aliases = {
708
+ "xch": 1,
709
+ "nft": 2,
710
+ "maker cat": 3,
711
+ "taker cat": 4,
712
+ }
713
+ env_1.wallet_aliases = {
714
+ "xch": 1,
715
+ "nft": 2,
716
+ "taker cat": 3,
717
+ "maker cat": 4,
718
+ }
562
719
 
563
- # Create NFT wallets and nfts for maker and taker
564
720
  nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
565
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
721
+ env_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
566
722
  )
567
723
 
568
724
  nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
569
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
725
+ env_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
570
726
  )
571
727
 
572
- trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
573
- trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
574
-
575
728
  metadata = Program.to(
576
729
  [
577
730
  ("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
@@ -579,83 +732,144 @@ async def test_nft_offer_nft_for_cat(
579
732
  ]
580
733
  )
581
734
 
582
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
735
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
736
+ wallet_environments.tx_config, push=True
737
+ ) as action_scope:
583
738
  await nft_wallet_maker.generate_new_nft(metadata, action_scope)
584
- for tx in action_scope.side_effects.transactions:
585
- if tx.spend_bundle is not None:
586
- await time_out_assert_not_none(
587
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, tx.spend_bundle.name()
588
- )
589
-
590
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
591
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
592
739
 
740
+ await wallet_environments.process_pending_states(
741
+ [
742
+ WalletStateTransition(
743
+ pre_block_balance_updates={
744
+ "xch": {
745
+ "confirmed_wallet_balance": 0,
746
+ "unconfirmed_wallet_balance": -1,
747
+ "<=#spendable_balance": -1,
748
+ "<=#max_send_amount": -1,
749
+ "pending_coin_removal_count": 1,
750
+ ">=#pending_change": 1, # any amount increase
751
+ "unspent_coin_count": 0,
752
+ },
753
+ "nft": {
754
+ "init": True,
755
+ "confirmed_wallet_balance": 0,
756
+ "unconfirmed_wallet_balance": 0,
757
+ "spendable_balance": 0,
758
+ "max_send_amount": 0,
759
+ "pending_coin_removal_count": 1, # a bit weird but correct?
760
+ "pending_change": 0,
761
+ "unspent_coin_count": 0,
762
+ },
763
+ },
764
+ post_block_balance_updates={
765
+ "xch": {
766
+ "confirmed_wallet_balance": -1,
767
+ "unconfirmed_wallet_balance": 0,
768
+ ">=#spendable_balance": 1, # any amount increase
769
+ ">=#max_send_amount": 1, # any amount increase
770
+ "pending_coin_removal_count": -1,
771
+ "<=#pending_change": -1, # any amount decrease
772
+ "unspent_coin_count": 0,
773
+ },
774
+ "nft": {
775
+ "pending_coin_removal_count": -1,
776
+ "unspent_coin_count": 1,
777
+ },
778
+ },
779
+ ),
780
+ WalletStateTransition(pre_block_balance_updates={"nft": {"init": True}}),
781
+ ]
782
+ )
593
783
  coins_maker = await nft_wallet_maker.get_current_nfts()
594
784
  assert len(coins_maker) == 1
595
785
  assert await nft_wallet_taker.get_nft_count() == 0
786
+
596
787
  # Create two new CATs and wallets for maker and taker
597
788
  cats_to_mint = 10000
598
- async with wallet_maker.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
789
+ async with wallet_maker.wallet_state_manager.new_action_scope(
790
+ wallet_environments.tx_config, push=True
791
+ ) as action_scope:
599
792
  cat_wallet_maker = await CATWallet.create_new_cat_wallet(
600
- wallet_node_0.wallet_state_manager,
793
+ env_0.wallet_state_manager,
601
794
  wallet_maker,
602
795
  {"identifier": "genesis_by_id"},
603
796
  uint64(cats_to_mint),
604
797
  action_scope,
605
798
  )
606
- await time_out_assert(20, mempool_not_empty, True, full_node_api)
607
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
608
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
609
799
 
610
- async with wallet_taker.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
800
+ async with wallet_taker.wallet_state_manager.new_action_scope(
801
+ wallet_environments.tx_config, push=True
802
+ ) as action_scope:
611
803
  cat_wallet_taker = await CATWallet.create_new_cat_wallet(
612
- wallet_node_1.wallet_state_manager,
804
+ env_1.wallet_state_manager,
613
805
  wallet_taker,
614
806
  {"identifier": "genesis_by_id"},
615
807
  uint64(cats_to_mint),
616
808
  action_scope,
617
809
  )
618
- await time_out_assert(20, mempool_not_empty, True, full_node_api)
619
810
 
620
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
621
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
622
-
623
- await time_out_assert(20, cat_wallet_maker.get_confirmed_balance, cats_to_mint)
624
- await time_out_assert(20, cat_wallet_maker.get_unconfirmed_balance, cats_to_mint)
625
- await time_out_assert(20, cat_wallet_taker.get_confirmed_balance, cats_to_mint)
626
- await time_out_assert(20, cat_wallet_taker.get_unconfirmed_balance, cats_to_mint)
811
+ # mostly set_remainder here as minting CATs is tested elsewhere
812
+ await wallet_environments.process_pending_states(
813
+ [
814
+ WalletStateTransition(
815
+ pre_block_balance_updates={
816
+ "xch": {"set_remainder": True},
817
+ "maker cat": {
818
+ "init": True,
819
+ "set_remainder": True,
820
+ },
821
+ },
822
+ post_block_balance_updates={
823
+ "xch": {"set_remainder": True},
824
+ "maker cat": {
825
+ "set_remainder": True,
826
+ },
827
+ },
828
+ ),
829
+ WalletStateTransition(
830
+ pre_block_balance_updates={
831
+ "xch": {"set_remainder": True},
832
+ "taker cat": {
833
+ "init": True,
834
+ "set_remainder": True,
835
+ },
836
+ },
837
+ post_block_balance_updates={
838
+ "xch": {"set_remainder": True},
839
+ "taker cat": {
840
+ "set_remainder": True,
841
+ },
842
+ },
843
+ ),
844
+ ]
845
+ )
627
846
 
628
847
  wallet_maker_for_taker_cat: CATWallet = await CATWallet.get_or_create_wallet_for_cat(
629
- wallet_node_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id()
848
+ env_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id()
630
849
  )
631
850
 
632
- wallet_taker_for_maker_cat: CATWallet = await CATWallet.get_or_create_wallet_for_cat(
633
- wallet_node_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id()
851
+ await CATWallet.get_or_create_wallet_for_cat(
852
+ env_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id()
634
853
  )
635
854
 
636
- assert wallet_taker_for_maker_cat
637
855
  # MAKE FIRST TRADE: 1 NFT for 10 taker cats
638
- maker_balance_pre = await wallet_maker.get_confirmed_balance()
639
- taker_balance_pre = await wallet_taker.get_confirmed_balance()
640
- taker_cat_maker_balance_pre = await wallet_maker_for_taker_cat.get_confirmed_balance()
641
- taker_cat_taker_balance_pre = await cat_wallet_taker.get_confirmed_balance()
642
-
643
856
  nft_to_offer = coins_maker[0]
644
857
  nft_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_offer.full_puzzle))
645
- nft_asset_id: bytes32 = create_asset_id(nft_info) # type: ignore
646
- driver_dict: dict[bytes32, Optional[PuzzleInfo]] = {nft_asset_id: nft_info}
858
+ assert nft_info is not None
859
+ nft_asset_id = create_asset_id(nft_info)
860
+ assert nft_asset_id is not None
861
+ driver_dict: dict[bytes32, PuzzleInfo] = {nft_asset_id: nft_info}
647
862
 
648
863
  maker_fee = uint64(10)
649
864
  taker_cat_offered = 2500
650
- offer_nft_for_cat = {nft_asset_id: -1, wallet_maker_for_taker_cat.id(): taker_cat_offered}
651
- maker_unused_index = (
652
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
653
- ).index
654
- taker_unused_index = (
655
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
656
- ).index
657
-
658
- async with trade_manager_maker.wallet_state_manager.new_action_scope(tx_config, push=False) as action_scope:
865
+ offer_nft_for_cat: dict[Union[bytes32, int], int] = {
866
+ nft_asset_id: -1,
867
+ wallet_maker_for_taker_cat.id(): taker_cat_offered,
868
+ }
869
+
870
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
871
+ wallet_environments.tx_config, push=False
872
+ ) as action_scope:
659
873
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
660
874
  offer_nft_for_cat, action_scope, driver_dict, fee=maker_fee
661
875
  )
@@ -665,12 +879,12 @@ async def test_nft_offer_nft_for_cat(
665
879
 
666
880
  taker_fee = uint64(1)
667
881
 
668
- [_maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
882
+ [_maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers(
669
883
  [Offer.from_bytes(trade_make.offer)]
670
884
  )
671
- peer = wallet_node_1.get_full_node_peer()
885
+ peer = env_1.node.get_full_node_peer()
672
886
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
673
- tx_config, push=True, additional_signing_responses=signing_response
887
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
674
888
  ) as action_scope:
675
889
  trade_take = await trade_manager_taker.respond_to_offer(
676
890
  Offer.from_bytes(trade_make.offer),
@@ -679,71 +893,117 @@ async def test_nft_offer_nft_for_cat(
679
893
  fee=taker_fee,
680
894
  )
681
895
 
682
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
683
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
896
+ await wallet_environments.process_pending_states(
897
+ [
898
+ WalletStateTransition(
899
+ pre_block_balance_updates={
900
+ "xch": {
901
+ "<=#spendable_balance": -maker_fee,
902
+ "<=#max_send_amount": -maker_fee,
903
+ "pending_coin_removal_count": 1,
904
+ },
905
+ "taker cat": {
906
+ "init": True,
907
+ },
908
+ "nft": {
909
+ "pending_coin_removal_count": 1,
910
+ },
911
+ },
912
+ post_block_balance_updates={
913
+ "xch": {
914
+ "unconfirmed_wallet_balance": -maker_fee,
915
+ "confirmed_wallet_balance": -maker_fee,
916
+ ">=#spendable_balance": 1,
917
+ ">=#max_send_amount": 1,
918
+ "pending_coin_removal_count": -1,
919
+ },
920
+ "taker cat": {
921
+ "init": True,
922
+ "unconfirmed_wallet_balance": taker_cat_offered,
923
+ "confirmed_wallet_balance": taker_cat_offered,
924
+ "spendable_balance": taker_cat_offered,
925
+ "max_send_amount": taker_cat_offered,
926
+ "unspent_coin_count": 1,
927
+ },
928
+ "nft": {
929
+ "pending_coin_removal_count": -1,
930
+ "unspent_coin_count": -1,
931
+ },
932
+ },
933
+ ),
934
+ WalletStateTransition(
935
+ pre_block_balance_updates={
936
+ "xch": {
937
+ "unconfirmed_wallet_balance": -taker_fee,
938
+ "<=#spendable_balance": -taker_fee,
939
+ "<=#max_send_amount": -taker_fee,
940
+ ">=#pending_change": 1,
941
+ "pending_coin_removal_count": 1,
942
+ },
943
+ "maker cat": {
944
+ "init": True,
945
+ },
946
+ "taker cat": {
947
+ "unconfirmed_wallet_balance": -taker_cat_offered,
948
+ "<=#spendable_balance": -taker_cat_offered,
949
+ "<=#max_send_amount": -taker_cat_offered,
950
+ ">=#pending_change": 1,
951
+ "pending_coin_removal_count": 1,
952
+ },
953
+ "nft": {},
954
+ },
955
+ post_block_balance_updates={
956
+ "xch": {
957
+ "confirmed_wallet_balance": -taker_fee,
958
+ ">=#spendable_balance": 1,
959
+ ">=#max_send_amount": 1,
960
+ "<=#pending_change": -1,
961
+ "pending_coin_removal_count": -1,
962
+ },
963
+ "taker cat": {
964
+ "confirmed_wallet_balance": -taker_cat_offered,
965
+ ">=#spendable_balance": 1,
966
+ ">=#max_send_amount": 1,
967
+ "<=#pending_change": -1,
968
+ "pending_coin_removal_count": -1,
969
+ },
970
+ "nft": {
971
+ "unspent_coin_count": 1,
972
+ },
973
+ },
974
+ ),
975
+ ]
976
+ )
684
977
 
685
978
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
686
979
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
687
-
688
- taker_cat_maker_balance_post = await wallet_maker_for_taker_cat.get_confirmed_balance()
689
- taker_cat_taker_balance_post = await cat_wallet_taker.get_confirmed_balance()
690
- assert taker_cat_maker_balance_post == taker_cat_maker_balance_pre + taker_cat_offered
691
- assert taker_cat_taker_balance_post == taker_cat_taker_balance_pre - taker_cat_offered
692
- maker_balance_post = await wallet_maker.get_confirmed_balance()
693
- taker_balance_post = await wallet_taker.get_confirmed_balance()
694
- assert maker_balance_post == maker_balance_pre - maker_fee
695
- assert taker_balance_post == taker_balance_pre - taker_fee
696
980
  coins_taker = await nft_wallet_taker.get_current_nfts()
697
981
  assert len(coins_taker) == 1
698
-
699
982
  assert await nft_wallet_maker.get_nft_count() == 0
700
- if reuse_puzhash:
701
- # Check if unused index changed
702
- assert (
703
- maker_unused_index
704
- == (
705
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
706
- ).index
707
- )
708
- assert (
709
- taker_unused_index
710
- == (
711
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
712
- ).index
713
- )
714
- else:
715
- assert (
716
- maker_unused_index
717
- < (
718
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
719
- ).index
720
- )
721
- assert (
722
- taker_unused_index
723
- < (
724
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
725
- ).index
726
- )
983
+
727
984
  # Make an offer for taker NFT for multiple cats
728
985
  maker_cat_amount = 400
729
986
  taker_cat_amount = 500
730
987
 
731
988
  nft_to_buy = coins_taker[0]
732
989
  nft_to_buy_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_buy.full_puzzle))
733
- nft_to_buy_asset_id: bytes32 = create_asset_id(nft_to_buy_info) # type: ignore
734
-
735
- driver_dict_to_buy: dict[bytes32, Optional[PuzzleInfo]] = {
990
+ assert nft_to_buy_info is not None
991
+ nft_to_buy_asset_id = create_asset_id(nft_to_buy_info)
992
+ assert nft_to_buy_asset_id is not None
993
+ driver_dict_to_buy: dict[bytes32, PuzzleInfo] = {
736
994
  nft_to_buy_asset_id: nft_to_buy_info,
737
995
  }
738
996
 
739
997
  maker_fee = uint64(10)
740
- offer_multi_cats_for_nft = {
998
+ offer_multi_cats_for_nft: dict[Union[bytes32, int], int] = {
741
999
  nft_to_buy_asset_id: 1,
742
1000
  wallet_maker_for_taker_cat.id(): -taker_cat_amount,
743
1001
  cat_wallet_maker.id(): -maker_cat_amount,
744
1002
  }
745
1003
 
746
- async with trade_manager_maker.wallet_state_manager.new_action_scope(tx_config, push=False) as action_scope:
1004
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
1005
+ wallet_environments.tx_config, push=False
1006
+ ) as action_scope:
747
1007
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
748
1008
  offer_multi_cats_for_nft, action_scope, driver_dict_to_buy, fee=maker_fee
749
1009
  )
@@ -753,93 +1013,145 @@ async def test_nft_offer_nft_for_cat(
753
1013
 
754
1014
  taker_fee = uint64(1)
755
1015
 
756
- [_maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
1016
+ [_maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers(
757
1017
  [Offer.from_bytes(trade_make.offer)]
758
1018
  )
759
1019
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
760
- tx_config, push=True, additional_signing_responses=signing_response
1020
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
761
1021
  ) as action_scope:
762
1022
  trade_take = await trade_manager_taker.respond_to_offer(
763
1023
  Offer.from_bytes(trade_make.offer), peer, action_scope, fee=taker_fee
764
1024
  )
765
1025
 
766
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
767
- # check balances: taker wallet down an NFT, up cats
768
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1026
+ await wallet_environments.process_pending_states(
1027
+ [
1028
+ WalletStateTransition(
1029
+ pre_block_balance_updates={
1030
+ "xch": {
1031
+ "<=#spendable_balance": -maker_fee,
1032
+ "<=#max_send_amount": -maker_fee,
1033
+ "pending_coin_removal_count": 1,
1034
+ },
1035
+ "taker cat": {
1036
+ "<=#spendable_balance": -taker_cat_amount,
1037
+ "<=#max_send_amount": -taker_cat_amount,
1038
+ "pending_coin_removal_count": 1,
1039
+ },
1040
+ "maker cat": {
1041
+ "<=#spendable_balance": -maker_cat_amount,
1042
+ "<=#max_send_amount": -maker_cat_amount,
1043
+ "pending_coin_removal_count": 1,
1044
+ },
1045
+ "nft": {},
1046
+ },
1047
+ post_block_balance_updates={
1048
+ "xch": {
1049
+ "unconfirmed_wallet_balance": -maker_fee,
1050
+ "confirmed_wallet_balance": -maker_fee,
1051
+ ">=#spendable_balance": 1,
1052
+ ">=#max_send_amount": 1,
1053
+ "pending_coin_removal_count": -1,
1054
+ },
1055
+ "taker cat": {
1056
+ "unconfirmed_wallet_balance": -taker_cat_amount,
1057
+ "confirmed_wallet_balance": -taker_cat_amount,
1058
+ ">=#spendable_balance": 1,
1059
+ ">=#max_send_amount": 1,
1060
+ "pending_coin_removal_count": -1,
1061
+ },
1062
+ "maker cat": {
1063
+ "unconfirmed_wallet_balance": -maker_cat_amount,
1064
+ "confirmed_wallet_balance": -maker_cat_amount,
1065
+ ">=#spendable_balance": 1,
1066
+ ">=#max_send_amount": 1,
1067
+ "pending_coin_removal_count": -1,
1068
+ },
1069
+ "nft": {
1070
+ "unspent_coin_count": 1,
1071
+ },
1072
+ },
1073
+ ),
1074
+ WalletStateTransition(
1075
+ pre_block_balance_updates={
1076
+ "xch": {
1077
+ "unconfirmed_wallet_balance": -taker_fee,
1078
+ "<=#spendable_balance": -taker_fee,
1079
+ "<=#max_send_amount": -taker_fee,
1080
+ ">=#pending_change": 1,
1081
+ "pending_coin_removal_count": 1,
1082
+ },
1083
+ "maker cat": {
1084
+ "unconfirmed_wallet_balance": maker_cat_amount,
1085
+ },
1086
+ "taker cat": {
1087
+ "unconfirmed_wallet_balance": taker_cat_amount,
1088
+ },
1089
+ "nft": {
1090
+ "pending_coin_removal_count": 1,
1091
+ },
1092
+ },
1093
+ post_block_balance_updates={
1094
+ "xch": {
1095
+ "confirmed_wallet_balance": -taker_fee,
1096
+ ">=#spendable_balance": 1,
1097
+ ">=#max_send_amount": 1,
1098
+ "<=#pending_change": -1,
1099
+ "pending_coin_removal_count": -1,
1100
+ },
1101
+ "maker cat": {
1102
+ "confirmed_wallet_balance": maker_cat_amount,
1103
+ "spendable_balance": maker_cat_amount,
1104
+ "max_send_amount": maker_cat_amount,
1105
+ "unspent_coin_count": 1,
1106
+ },
1107
+ "taker cat": {
1108
+ "confirmed_wallet_balance": taker_cat_amount,
1109
+ "spendable_balance": taker_cat_amount,
1110
+ "max_send_amount": taker_cat_amount,
1111
+ "unspent_coin_count": 1,
1112
+ },
1113
+ "nft": {
1114
+ "pending_coin_removal_count": -1,
1115
+ "unspent_coin_count": -1,
1116
+ },
1117
+ },
1118
+ ),
1119
+ ]
1120
+ )
769
1121
 
770
1122
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
771
1123
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
772
-
773
- taker_cat_maker_balance_post_2 = await wallet_maker_for_taker_cat.get_confirmed_balance()
774
- taker_cat_taker_balance_post_2 = await cat_wallet_taker.get_confirmed_balance()
775
- assert taker_cat_maker_balance_post_2 == taker_cat_maker_balance_post - taker_cat_amount
776
- assert taker_cat_taker_balance_post_2 == taker_cat_taker_balance_post + taker_cat_amount
777
- maker_balance_post_2 = await wallet_maker.get_confirmed_balance()
778
- taker_balance_post_2 = await wallet_taker.get_confirmed_balance()
779
- assert maker_balance_post_2 == maker_balance_post - maker_fee
780
- assert taker_balance_post_2 == taker_balance_post - taker_fee
781
1124
  assert await nft_wallet_maker.get_nft_count() == 1
782
1125
  assert await nft_wallet_taker.get_nft_count() == 0
783
1126
 
784
1127
 
785
- @pytest.mark.parametrize(
786
- "trusted",
787
- [False],
788
- )
1128
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
1129
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
789
1130
  @pytest.mark.anyio
790
- async def test_nft_offer_nft_for_nft(
791
- self_hostname: str, two_wallet_nodes: Any, trusted: Any, seeded_random: random.Random
792
- ) -> None:
793
- full_nodes, wallets, _ = two_wallet_nodes
794
- full_node_api: FullNodeSimulator = full_nodes[0]
795
- full_node_server = full_node_api.server
796
- wallet_node_0, server_0 = wallets[0]
797
- wallet_node_1, server_1 = wallets[1]
798
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
799
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
800
-
801
- maker_ph = await wallet_maker.get_new_puzzlehash()
802
- taker_ph = await wallet_taker.get_new_puzzlehash()
803
- token_ph = bytes32.random(seeded_random)
804
-
805
- if trusted:
806
- wallet_node_0.config["trusted_peers"] = {
807
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
808
- }
809
- wallet_node_1.config["trusted_peers"] = {
810
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
811
- }
812
- else:
813
- wallet_node_0.config["trusted_peers"] = {}
814
- wallet_node_1.config["trusted_peers"] = {}
815
-
816
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
817
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
818
-
819
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(maker_ph))
820
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(taker_ph))
821
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
822
-
823
- funds = sum(calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, 2))
824
-
825
- await time_out_assert(20, wallet_maker.get_unconfirmed_balance, funds)
826
- await time_out_assert(20, wallet_maker.get_confirmed_balance, funds)
827
-
828
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
829
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1131
+ async def test_nft_offer_nft_for_nft(wallet_environments: WalletTestFramework) -> None:
1132
+ env_0 = wallet_environments.environments[0]
1133
+ env_1 = wallet_environments.environments[1]
1134
+ wallet_maker = env_0.xch_wallet
1135
+ wallet_taker = env_1.xch_wallet
1136
+ trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
1137
+ trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
1138
+ env_0.wallet_aliases = {
1139
+ "xch": 1,
1140
+ "nft": 2,
1141
+ }
1142
+ env_1.wallet_aliases = {
1143
+ "xch": 1,
1144
+ "nft": 2,
1145
+ }
830
1146
 
831
- # Create NFT wallets and nfts for maker and taker
832
1147
  nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
833
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
1148
+ env_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
834
1149
  )
835
1150
 
836
1151
  nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
837
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
1152
+ env_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
838
1153
  )
839
1154
 
840
- trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
841
- trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
842
-
843
1155
  metadata = Program.to(
844
1156
  [
845
1157
  ("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
@@ -847,14 +1159,6 @@ async def test_nft_offer_nft_for_nft(
847
1159
  ]
848
1160
  )
849
1161
 
850
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
851
- await nft_wallet_maker.generate_new_nft(metadata, action_scope)
852
- for tx in action_scope.side_effects.transactions:
853
- if tx.spend_bundle is not None:
854
- await time_out_assert_not_none(
855
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, tx.spend_bundle.name()
856
- )
857
-
858
1162
  metadata_2 = Program.to(
859
1163
  [
860
1164
  ("u", ["https://www.chia.net/image2.html"]),
@@ -862,42 +1166,123 @@ async def test_nft_offer_nft_for_nft(
862
1166
  ]
863
1167
  )
864
1168
 
865
- async with nft_wallet_taker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=True) as action_scope:
1169
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
1170
+ wallet_environments.tx_config, push=True
1171
+ ) as action_scope:
1172
+ await nft_wallet_maker.generate_new_nft(metadata, action_scope)
1173
+ async with nft_wallet_taker.wallet_state_manager.new_action_scope(
1174
+ wallet_environments.tx_config, push=True
1175
+ ) as action_scope:
866
1176
  await nft_wallet_taker.generate_new_nft(metadata_2, action_scope)
867
- for tx in action_scope.side_effects.transactions:
868
- if tx.spend_bundle is not None:
869
- await time_out_assert_not_none(
870
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, tx.spend_bundle.name()
871
- )
872
-
873
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
874
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
875
1177
 
1178
+ await wallet_environments.process_pending_states(
1179
+ [
1180
+ WalletStateTransition(
1181
+ pre_block_balance_updates={
1182
+ "xch": {
1183
+ "confirmed_wallet_balance": 0,
1184
+ "unconfirmed_wallet_balance": -1,
1185
+ "<=#spendable_balance": -1,
1186
+ "<=#max_send_amount": -1,
1187
+ "pending_coin_removal_count": 1,
1188
+ ">=#pending_change": 1, # any amount increase
1189
+ "unspent_coin_count": 0,
1190
+ },
1191
+ "nft": {
1192
+ "init": True,
1193
+ "confirmed_wallet_balance": 0,
1194
+ "unconfirmed_wallet_balance": 0,
1195
+ "spendable_balance": 0,
1196
+ "max_send_amount": 0,
1197
+ "pending_coin_removal_count": 1, # a bit weird but correct?
1198
+ "pending_change": 0,
1199
+ "unspent_coin_count": 0,
1200
+ },
1201
+ },
1202
+ post_block_balance_updates={
1203
+ "xch": {
1204
+ "confirmed_wallet_balance": -1,
1205
+ "unconfirmed_wallet_balance": 0,
1206
+ ">=#spendable_balance": 1, # any amount increase
1207
+ ">=#max_send_amount": 1, # any amount increase
1208
+ "pending_coin_removal_count": -1,
1209
+ "<=#pending_change": -1, # any amount decrease
1210
+ "unspent_coin_count": 0,
1211
+ },
1212
+ "nft": {
1213
+ "pending_coin_removal_count": -1,
1214
+ "unspent_coin_count": 1,
1215
+ },
1216
+ },
1217
+ ),
1218
+ WalletStateTransition(
1219
+ pre_block_balance_updates={
1220
+ "xch": {
1221
+ "confirmed_wallet_balance": 0,
1222
+ "unconfirmed_wallet_balance": -1,
1223
+ "<=#spendable_balance": -1,
1224
+ "<=#max_send_amount": -1,
1225
+ "pending_coin_removal_count": 1,
1226
+ ">=#pending_change": 1, # any amount increase
1227
+ "unspent_coin_count": 0,
1228
+ },
1229
+ "nft": {
1230
+ "init": True,
1231
+ "confirmed_wallet_balance": 0,
1232
+ "unconfirmed_wallet_balance": 0,
1233
+ "spendable_balance": 0,
1234
+ "max_send_amount": 0,
1235
+ "pending_coin_removal_count": 1, # a bit weird but correct?
1236
+ "pending_change": 0,
1237
+ "unspent_coin_count": 0,
1238
+ },
1239
+ },
1240
+ post_block_balance_updates={
1241
+ "xch": {
1242
+ "confirmed_wallet_balance": -1,
1243
+ "unconfirmed_wallet_balance": 0,
1244
+ ">=#spendable_balance": 1, # any amount increase
1245
+ ">=#max_send_amount": 1, # any amount increase
1246
+ "pending_coin_removal_count": -1,
1247
+ "<=#pending_change": -1, # any amount decrease
1248
+ "unspent_coin_count": 0,
1249
+ },
1250
+ "nft": {
1251
+ "pending_coin_removal_count": -1,
1252
+ "unspent_coin_count": 1,
1253
+ },
1254
+ },
1255
+ ),
1256
+ ]
1257
+ )
876
1258
  coins_maker = await nft_wallet_maker.get_current_nfts()
877
1259
  assert len(coins_maker) == 1
878
1260
  coins_taker = await nft_wallet_taker.get_current_nfts()
879
1261
  assert len(coins_taker) == 1
880
1262
 
881
- maker_balance_pre = await wallet_maker.get_confirmed_balance()
882
- taker_balance_pre = await wallet_taker.get_confirmed_balance()
883
-
884
1263
  nft_to_offer = coins_maker[0]
885
1264
  nft_to_offer_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_offer.full_puzzle))
886
- nft_to_offer_asset_id: bytes32 = create_asset_id(nft_to_offer_info) # type: ignore
1265
+ assert nft_to_offer_info is not None
1266
+ nft_to_offer_asset_id = create_asset_id(nft_to_offer_info)
1267
+ assert nft_to_offer_asset_id is not None
887
1268
 
888
1269
  nft_to_take = coins_taker[0]
889
1270
  nft_to_take_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_take.full_puzzle))
890
- nft_to_take_asset_id: bytes32 = create_asset_id(nft_to_take_info) # type: ignore
1271
+ assert nft_to_take_info is not None
1272
+ nft_to_take_asset_id = create_asset_id(nft_to_take_info)
1273
+ assert nft_to_take_asset_id is not None
891
1274
 
892
- driver_dict: dict[bytes32, Optional[PuzzleInfo]] = {
1275
+ driver_dict: dict[bytes32, PuzzleInfo] = {
893
1276
  nft_to_offer_asset_id: nft_to_offer_info,
894
1277
  nft_to_take_asset_id: nft_to_take_info,
895
1278
  }
896
1279
 
897
1280
  maker_fee = uint64(10)
898
- offer_nft_for_nft = {nft_to_take_asset_id: 1, nft_to_offer_asset_id: -1}
1281
+ offer_nft_for_nft: dict[Union[bytes32, int], int] = {nft_to_take_asset_id: 1, nft_to_offer_asset_id: -1}
899
1282
 
900
- async with trade_manager_maker.wallet_state_manager.new_action_scope(DEFAULT_TX_CONFIG, push=False) as action_scope:
1283
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
1284
+ wallet_environments.tx_config, push=False
1285
+ ) as action_scope:
901
1286
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
902
1287
  offer_nft_for_nft, action_scope, driver_dict, fee=maker_fee
903
1288
  )
@@ -907,92 +1292,110 @@ async def test_nft_offer_nft_for_nft(
907
1292
 
908
1293
  taker_fee = uint64(1)
909
1294
 
910
- [_maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
1295
+ [_maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers(
911
1296
  [Offer.from_bytes(trade_make.offer)]
912
1297
  )
913
- peer = wallet_node_1.get_full_node_peer()
1298
+ peer = env_1.node.get_full_node_peer()
914
1299
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
915
- DEFAULT_TX_CONFIG, push=True, additional_signing_responses=signing_response
1300
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
916
1301
  ) as action_scope:
917
1302
  trade_take = await trade_manager_taker.respond_to_offer(
918
1303
  Offer.from_bytes(trade_make.offer), peer, action_scope, fee=taker_fee
919
1304
  )
920
1305
 
921
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
922
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1306
+ await wallet_environments.process_pending_states(
1307
+ [
1308
+ WalletStateTransition(
1309
+ pre_block_balance_updates={
1310
+ "xch": {
1311
+ "<=#spendable_balance": -maker_fee,
1312
+ "<=#max_send_amount": -maker_fee,
1313
+ "pending_coin_removal_count": 1,
1314
+ },
1315
+ "nft": {
1316
+ "pending_coin_removal_count": 1,
1317
+ },
1318
+ },
1319
+ post_block_balance_updates={
1320
+ "xch": {
1321
+ "unconfirmed_wallet_balance": -maker_fee,
1322
+ "confirmed_wallet_balance": -maker_fee,
1323
+ ">=#spendable_balance": 1,
1324
+ ">=#max_send_amount": 1,
1325
+ "pending_coin_removal_count": -1,
1326
+ },
1327
+ "nft": {
1328
+ "pending_coin_removal_count": -1,
1329
+ },
1330
+ },
1331
+ ),
1332
+ WalletStateTransition(
1333
+ pre_block_balance_updates={
1334
+ "xch": {
1335
+ "unconfirmed_wallet_balance": -taker_fee,
1336
+ "<=#spendable_balance": -taker_fee,
1337
+ "<=#max_send_amount": -taker_fee,
1338
+ ">=#pending_change": 1,
1339
+ "pending_coin_removal_count": 1,
1340
+ },
1341
+ "nft": {
1342
+ "pending_coin_removal_count": 1,
1343
+ },
1344
+ },
1345
+ post_block_balance_updates={
1346
+ "xch": {
1347
+ "confirmed_wallet_balance": -taker_fee,
1348
+ ">=#spendable_balance": 1,
1349
+ ">=#max_send_amount": 1,
1350
+ "<=#pending_change": -1,
1351
+ "pending_coin_removal_count": -1,
1352
+ },
1353
+ "nft": {
1354
+ "pending_coin_removal_count": -1,
1355
+ },
1356
+ },
1357
+ ),
1358
+ ]
1359
+ )
923
1360
 
924
1361
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
925
1362
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
926
- await time_out_assert(20, wallet_maker.get_confirmed_balance, maker_balance_pre - maker_fee)
927
- await time_out_assert(20, wallet_taker.get_confirmed_balance, taker_balance_pre - taker_fee)
928
1363
 
929
1364
  assert await nft_wallet_maker.get_nft_count() == 1
930
1365
  assert await nft_wallet_taker.get_nft_count() == 1
931
1366
 
932
1367
 
933
- @pytest.mark.limit_consensus_modes(allowed=[ConsensusMode.PLAIN], reason="save time")
934
- @pytest.mark.parametrize("trusted", [True, False])
935
- @pytest.mark.parametrize("reuse_puzhash", [True, False])
1368
+ @pytest.mark.limit_consensus_modes(reason="irrelevant")
1369
+ @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True)
936
1370
  @pytest.mark.anyio
937
- async def test_nft_offer_nft0_and_xch_for_cat(
938
- self_hostname: str,
939
- two_wallet_nodes: Any,
940
- trusted: Any,
941
- reuse_puzhash: bool,
942
- seeded_random: random.Random,
943
- ) -> None:
944
- full_nodes, wallets, _ = two_wallet_nodes
945
- full_node_api: FullNodeSimulator = full_nodes[0]
946
- full_node_server = full_node_api.server
947
- wallet_node_0, server_0 = wallets[0]
948
- wallet_node_1, server_1 = wallets[1]
949
- wallet_maker = wallet_node_0.wallet_state_manager.main_wallet
950
- wallet_taker = wallet_node_1.wallet_state_manager.main_wallet
951
-
952
- maker_ph = await wallet_maker.get_new_puzzlehash()
953
- taker_ph = await wallet_taker.get_new_puzzlehash()
954
- token_ph = bytes32.random(seeded_random)
955
-
956
- if trusted:
957
- wallet_node_0.config["trusted_peers"] = {
958
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
959
- }
960
- wallet_node_1.config["trusted_peers"] = {
961
- full_node_api.full_node.server.node_id.hex(): full_node_api.full_node.server.node_id.hex()
962
- }
963
- else:
964
- wallet_node_0.config["trusted_peers"] = {}
965
- wallet_node_1.config["trusted_peers"] = {}
966
-
967
- await server_0.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
968
- await server_1.start_client(PeerInfo(self_hostname, full_node_server.get_port()), None)
969
-
970
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(maker_ph))
971
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(taker_ph))
972
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
973
-
974
- funds = sum(calculate_pool_reward(uint32(i)) + calculate_base_farmer_reward(uint32(i)) for i in range(1, 2))
975
-
976
- await time_out_assert(20, wallet_maker.get_unconfirmed_balance, funds)
977
- await time_out_assert(20, wallet_maker.get_confirmed_balance, funds)
978
-
979
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
980
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
981
-
982
- tx_config = DEFAULT_TX_CONFIG.override(reuse_puzhash=reuse_puzhash)
1371
+ async def test_nft_offer_nft0_and_xch_for_cat(wallet_environments: WalletTestFramework) -> None:
1372
+ env_0 = wallet_environments.environments[0]
1373
+ env_1 = wallet_environments.environments[1]
1374
+ wallet_maker = env_0.xch_wallet
1375
+ wallet_taker = env_1.xch_wallet
1376
+ trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
1377
+ trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
1378
+ env_0.wallet_aliases = {
1379
+ "xch": 1,
1380
+ "nft": 2,
1381
+ "maker cat": 3,
1382
+ "taker cat": 4,
1383
+ }
1384
+ env_1.wallet_aliases = {
1385
+ "xch": 1,
1386
+ "nft": 2,
1387
+ "taker cat": 3,
1388
+ "maker cat": 4,
1389
+ }
983
1390
 
984
- # Create NFT wallets and nfts for maker and taker
985
1391
  nft_wallet_maker = await NFTWallet.create_new_nft_wallet(
986
- wallet_node_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
1392
+ env_0.wallet_state_manager, wallet_maker, name="NFT WALLET 1"
987
1393
  )
988
1394
 
989
1395
  nft_wallet_taker = await NFTWallet.create_new_nft_wallet(
990
- wallet_node_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
1396
+ env_1.wallet_state_manager, wallet_taker, name="NFT WALLET 2"
991
1397
  )
992
1398
 
993
- trade_manager_maker = wallet_maker.wallet_state_manager.trade_manager
994
- trade_manager_taker = wallet_taker.wallet_state_manager.trade_manager
995
-
996
1399
  metadata = Program.to(
997
1400
  [
998
1401
  ("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
@@ -1000,89 +1403,155 @@ async def test_nft_offer_nft0_and_xch_for_cat(
1000
1403
  ]
1001
1404
  )
1002
1405
 
1003
- async with nft_wallet_maker.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
1406
+ async with nft_wallet_maker.wallet_state_manager.new_action_scope(
1407
+ wallet_environments.tx_config, push=True
1408
+ ) as action_scope:
1004
1409
  await nft_wallet_maker.generate_new_nft(metadata, action_scope)
1005
- for tx in action_scope.side_effects.transactions:
1006
- if tx.spend_bundle is not None:
1007
- await time_out_assert_not_none(
1008
- 20, full_node_api.full_node.mempool_manager.get_spendbundle, tx.spend_bundle.name()
1009
- )
1010
-
1011
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
1012
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1013
1410
 
1411
+ await wallet_environments.process_pending_states(
1412
+ [
1413
+ WalletStateTransition(
1414
+ pre_block_balance_updates={
1415
+ "xch": {
1416
+ "confirmed_wallet_balance": 0,
1417
+ "unconfirmed_wallet_balance": -1,
1418
+ "<=#spendable_balance": -1,
1419
+ "<=#max_send_amount": -1,
1420
+ "pending_coin_removal_count": 1,
1421
+ ">=#pending_change": 1, # any amount increase
1422
+ "unspent_coin_count": 0,
1423
+ },
1424
+ "nft": {
1425
+ "init": True,
1426
+ "confirmed_wallet_balance": 0,
1427
+ "unconfirmed_wallet_balance": 0,
1428
+ "spendable_balance": 0,
1429
+ "max_send_amount": 0,
1430
+ "pending_coin_removal_count": 1, # a bit weird but correct?
1431
+ "pending_change": 0,
1432
+ "unspent_coin_count": 0,
1433
+ },
1434
+ },
1435
+ post_block_balance_updates={
1436
+ "xch": {
1437
+ "confirmed_wallet_balance": -1,
1438
+ "unconfirmed_wallet_balance": 0,
1439
+ ">=#spendable_balance": 1, # any amount increase
1440
+ ">=#max_send_amount": 1, # any amount increase
1441
+ "pending_coin_removal_count": -1,
1442
+ "<=#pending_change": -1, # any amount decrease
1443
+ "unspent_coin_count": 0,
1444
+ },
1445
+ "nft": {
1446
+ "pending_coin_removal_count": -1,
1447
+ "unspent_coin_count": 1,
1448
+ },
1449
+ },
1450
+ ),
1451
+ WalletStateTransition(pre_block_balance_updates={"nft": {"init": True}}),
1452
+ ]
1453
+ )
1014
1454
  coins_maker = await nft_wallet_maker.get_current_nfts()
1015
1455
  assert len(coins_maker) == 1
1456
+
1016
1457
  assert await nft_wallet_taker.get_nft_count() == 0
1017
1458
  # Create two new CATs and wallets for maker and taker
1018
1459
  cats_to_mint = 10000
1019
- async with wallet_maker.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
1460
+ async with wallet_maker.wallet_state_manager.new_action_scope(
1461
+ wallet_environments.tx_config, push=True
1462
+ ) as action_scope:
1020
1463
  cat_wallet_maker = await CATWallet.create_new_cat_wallet(
1021
- wallet_node_0.wallet_state_manager,
1464
+ env_0.wallet_state_manager,
1022
1465
  wallet_maker,
1023
1466
  {"identifier": "genesis_by_id"},
1024
1467
  uint64(cats_to_mint),
1025
1468
  action_scope,
1026
1469
  )
1027
- await time_out_assert(20, mempool_not_empty, True, full_node_api)
1028
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
1029
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1030
1470
 
1031
- async with wallet_taker.wallet_state_manager.new_action_scope(tx_config, push=True) as action_scope:
1471
+ async with wallet_taker.wallet_state_manager.new_action_scope(
1472
+ wallet_environments.tx_config, push=True
1473
+ ) as action_scope:
1032
1474
  cat_wallet_taker = await CATWallet.create_new_cat_wallet(
1033
- wallet_node_1.wallet_state_manager,
1475
+ env_1.wallet_state_manager,
1034
1476
  wallet_taker,
1035
1477
  {"identifier": "genesis_by_id"},
1036
1478
  uint64(cats_to_mint),
1037
1479
  action_scope,
1038
1480
  )
1039
- await time_out_assert(20, mempool_not_empty, True, full_node_api)
1040
-
1041
- await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_ph))
1042
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1043
-
1044
- await time_out_assert(20, cat_wallet_maker.get_confirmed_balance, cats_to_mint)
1045
- await time_out_assert(20, cat_wallet_maker.get_unconfirmed_balance, cats_to_mint)
1046
- await time_out_assert(20, cat_wallet_taker.get_confirmed_balance, cats_to_mint)
1047
- await time_out_assert(20, cat_wallet_taker.get_unconfirmed_balance, cats_to_mint)
1048
1481
 
1049
1482
  wallet_maker_for_taker_cat: CATWallet = await CATWallet.get_or_create_wallet_for_cat(
1050
- wallet_node_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id()
1483
+ env_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id()
1051
1484
  )
1052
1485
 
1053
- wallet_taker_for_maker_cat: CATWallet = await CATWallet.get_or_create_wallet_for_cat(
1054
- wallet_node_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id()
1486
+ await CATWallet.get_or_create_wallet_for_cat(
1487
+ env_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id()
1055
1488
  )
1056
1489
 
1057
- assert wallet_taker_for_maker_cat
1058
- # MAKE FIRST TRADE: 1 NFT for 10 taker cats
1059
- maker_balance_pre = await wallet_maker.get_confirmed_balance()
1060
- taker_balance_pre = await wallet_taker.get_confirmed_balance()
1061
- taker_cat_maker_balance_pre = await wallet_maker_for_taker_cat.get_confirmed_balance()
1062
- taker_cat_taker_balance_pre = await cat_wallet_taker.get_confirmed_balance()
1490
+ # mostly set_remainder here as minting CATs is tested elsewhere
1491
+ await wallet_environments.process_pending_states(
1492
+ [
1493
+ WalletStateTransition(
1494
+ pre_block_balance_updates={
1495
+ "xch": {"set_remainder": True},
1496
+ "maker cat": {
1497
+ "init": True,
1498
+ "set_remainder": True,
1499
+ },
1500
+ "taker cat": {
1501
+ "init": True,
1502
+ "set_remainder": True,
1503
+ },
1504
+ },
1505
+ post_block_balance_updates={
1506
+ "xch": {"set_remainder": True},
1507
+ "maker cat": {
1508
+ "set_remainder": True,
1509
+ },
1510
+ },
1511
+ ),
1512
+ WalletStateTransition(
1513
+ pre_block_balance_updates={
1514
+ "xch": {"set_remainder": True},
1515
+ "maker cat": {
1516
+ "init": True,
1517
+ "set_remainder": True,
1518
+ },
1519
+ "taker cat": {
1520
+ "init": True,
1521
+ "set_remainder": True,
1522
+ },
1523
+ },
1524
+ post_block_balance_updates={
1525
+ "xch": {"set_remainder": True},
1526
+ "taker cat": {
1527
+ "set_remainder": True,
1528
+ },
1529
+ },
1530
+ ),
1531
+ ]
1532
+ )
1063
1533
 
1534
+ # MAKE FIRST TRADE: 1 NFT for 10 taker cats
1064
1535
  nft_to_offer = coins_maker[0]
1065
1536
  nft_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_offer.full_puzzle))
1066
- nft_asset_id: bytes32 = create_asset_id(nft_info) # type: ignore
1067
- driver_dict: dict[bytes32, Optional[PuzzleInfo]] = {nft_asset_id: nft_info}
1537
+ assert nft_info is not None
1538
+ nft_asset_id = create_asset_id(nft_info)
1539
+ assert nft_asset_id is not None
1540
+ driver_dict: dict[bytes32, PuzzleInfo] = {nft_asset_id: nft_info}
1068
1541
 
1069
1542
  maker_fee = uint64(10)
1070
1543
  maker_xch_offered = 1000
1071
1544
  taker_cat_offered = 2500
1072
1545
  wallet_maker_id = wallet_maker.id()
1073
- offer_nft_for_cat = {
1546
+ offer_nft_for_cat: dict[Union[bytes32, int], int] = {
1074
1547
  wallet_maker_id: -maker_xch_offered,
1075
1548
  nft_asset_id: -1,
1076
1549
  wallet_maker_for_taker_cat.id(): taker_cat_offered,
1077
1550
  }
1078
- maker_unused_index = (
1079
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
1080
- ).index
1081
- taker_unused_index = (
1082
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
1083
- ).index
1084
-
1085
- async with trade_manager_maker.wallet_state_manager.new_action_scope(tx_config, push=False) as action_scope:
1551
+
1552
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
1553
+ wallet_environments.tx_config, push=False
1554
+ ) as action_scope:
1086
1555
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
1087
1556
  offer_nft_for_cat, action_scope, driver_dict, fee=maker_fee
1088
1557
  )
@@ -1090,15 +1559,13 @@ async def test_nft_offer_nft0_and_xch_for_cat(
1090
1559
  assert error is None
1091
1560
  assert trade_make is not None
1092
1561
 
1093
- [maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
1094
- [Offer.from_bytes(trade_make.offer)]
1095
- )
1562
+ [maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers([Offer.from_bytes(trade_make.offer)])
1096
1563
 
1097
1564
  taker_fee = uint64(1)
1098
1565
 
1099
- peer = wallet_node_1.get_full_node_peer()
1566
+ peer = env_1.node.get_full_node_peer()
1100
1567
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
1101
- tx_config, push=True, additional_signing_responses=signing_response
1568
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
1102
1569
  ) as action_scope:
1103
1570
  trade_take = await trade_manager_taker.respond_to_offer(
1104
1571
  maker_offer,
@@ -1107,71 +1574,113 @@ async def test_nft_offer_nft0_and_xch_for_cat(
1107
1574
  fee=taker_fee,
1108
1575
  )
1109
1576
 
1110
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1111
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1577
+ await wallet_environments.process_pending_states(
1578
+ [
1579
+ WalletStateTransition(
1580
+ pre_block_balance_updates={
1581
+ "xch": {
1582
+ "<=#spendable_balance": -(maker_fee + maker_xch_offered),
1583
+ "<=#max_send_amount": -(maker_fee + maker_xch_offered),
1584
+ "pending_coin_removal_count": 1,
1585
+ },
1586
+ "taker cat": {},
1587
+ "nft": {
1588
+ "pending_coin_removal_count": 1,
1589
+ },
1590
+ },
1591
+ post_block_balance_updates={
1592
+ "xch": {
1593
+ "unconfirmed_wallet_balance": -(maker_fee + maker_xch_offered),
1594
+ "confirmed_wallet_balance": -(maker_fee + maker_xch_offered),
1595
+ ">=#spendable_balance": 1,
1596
+ ">=#max_send_amount": 1,
1597
+ "pending_coin_removal_count": -1,
1598
+ },
1599
+ "taker cat": {
1600
+ "unconfirmed_wallet_balance": taker_cat_offered,
1601
+ "confirmed_wallet_balance": taker_cat_offered,
1602
+ "spendable_balance": taker_cat_offered,
1603
+ "max_send_amount": taker_cat_offered,
1604
+ "unspent_coin_count": 1,
1605
+ },
1606
+ "nft": {
1607
+ "pending_coin_removal_count": -1,
1608
+ "unspent_coin_count": -1,
1609
+ },
1610
+ },
1611
+ ),
1612
+ WalletStateTransition(
1613
+ pre_block_balance_updates={
1614
+ "xch": {
1615
+ "unconfirmed_wallet_balance": -taker_fee + maker_xch_offered,
1616
+ "<=#spendable_balance": -taker_fee + maker_xch_offered,
1617
+ "<=#max_send_amount": -taker_fee + maker_xch_offered,
1618
+ ">=#pending_change": 1,
1619
+ "pending_coin_removal_count": 1,
1620
+ },
1621
+ "taker cat": {
1622
+ "unconfirmed_wallet_balance": -taker_cat_offered,
1623
+ "<=#spendable_balance": -taker_cat_offered,
1624
+ "<=#max_send_amount": -taker_cat_offered,
1625
+ ">=#pending_change": 1,
1626
+ "pending_coin_removal_count": 1,
1627
+ },
1628
+ "nft": {},
1629
+ },
1630
+ post_block_balance_updates={
1631
+ "xch": {
1632
+ "confirmed_wallet_balance": -taker_fee + maker_xch_offered,
1633
+ ">=#spendable_balance": 1,
1634
+ ">=#max_send_amount": 1,
1635
+ "<=#pending_change": -1,
1636
+ "pending_coin_removal_count": -1,
1637
+ "unspent_coin_count": 1,
1638
+ },
1639
+ "taker cat": {
1640
+ "confirmed_wallet_balance": -taker_cat_offered,
1641
+ ">=#spendable_balance": 1,
1642
+ ">=#max_send_amount": 1,
1643
+ "<=#pending_change": -1,
1644
+ "pending_coin_removal_count": -1,
1645
+ },
1646
+ "nft": {
1647
+ "unspent_coin_count": 1,
1648
+ },
1649
+ },
1650
+ ),
1651
+ ]
1652
+ )
1112
1653
 
1113
1654
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
1114
1655
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
1115
-
1116
- taker_cat_maker_balance_post = await wallet_maker_for_taker_cat.get_confirmed_balance()
1117
- taker_cat_taker_balance_post = await cat_wallet_taker.get_confirmed_balance()
1118
- assert taker_cat_maker_balance_post == taker_cat_maker_balance_pre + taker_cat_offered
1119
- assert taker_cat_taker_balance_post == taker_cat_taker_balance_pre - taker_cat_offered
1120
- maker_balance_post = await wallet_maker.get_confirmed_balance()
1121
- taker_balance_post = await wallet_taker.get_confirmed_balance()
1122
- assert maker_balance_post == maker_balance_pre - maker_fee - maker_xch_offered
1123
- assert taker_balance_post == taker_balance_pre - taker_fee + maker_xch_offered
1124
1656
  coins_taker = await nft_wallet_taker.get_current_nfts()
1125
1657
  assert len(coins_taker) == 1
1126
-
1127
1658
  assert await nft_wallet_maker.get_nft_count() == 0
1128
- if reuse_puzhash:
1129
- # Check if unused index changed
1130
- assert (
1131
- maker_unused_index
1132
- == (
1133
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
1134
- ).index
1135
- )
1136
- assert (
1137
- taker_unused_index
1138
- == (
1139
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
1140
- ).index
1141
- )
1142
- else:
1143
- assert (
1144
- maker_unused_index
1145
- < (
1146
- await wallet_maker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
1147
- ).index
1148
- )
1149
- assert (
1150
- taker_unused_index
1151
- < (
1152
- await wallet_taker.wallet_state_manager.puzzle_store.get_current_derivation_record_for_wallet(uint32(1))
1153
- ).index
1154
- )
1659
+
1155
1660
  # Make an offer for taker NFT for multiple cats
1156
1661
  maker_cat_amount = 400
1157
1662
  taker_cat_amount = 500
1158
1663
 
1159
1664
  nft_to_buy = coins_taker[0]
1160
1665
  nft_to_buy_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_buy.full_puzzle))
1161
- nft_to_buy_asset_id: bytes32 = create_asset_id(nft_to_buy_info) # type: ignore
1666
+ assert nft_to_buy_info is not None
1667
+ nft_to_buy_asset_id = create_asset_id(nft_to_buy_info)
1668
+ assert nft_to_buy_asset_id is not None
1162
1669
 
1163
- driver_dict_to_buy: dict[bytes32, Optional[PuzzleInfo]] = {
1670
+ driver_dict_to_buy: dict[bytes32, PuzzleInfo] = {
1164
1671
  nft_to_buy_asset_id: nft_to_buy_info,
1165
1672
  }
1166
1673
 
1167
1674
  maker_fee = uint64(10)
1168
- offer_multi_cats_for_nft = {
1675
+ offer_multi_cats_for_nft: dict[Union[bytes32, int], int] = {
1169
1676
  nft_to_buy_asset_id: 1,
1170
1677
  wallet_maker_for_taker_cat.id(): -taker_cat_amount,
1171
1678
  cat_wallet_maker.id(): -maker_cat_amount,
1172
1679
  }
1173
1680
 
1174
- async with trade_manager_maker.wallet_state_manager.new_action_scope(tx_config, push=False) as action_scope:
1681
+ async with trade_manager_maker.wallet_state_manager.new_action_scope(
1682
+ wallet_environments.tx_config, push=False
1683
+ ) as action_scope:
1175
1684
  success, trade_make, error = await trade_manager_maker.create_offer_for_ids(
1176
1685
  offer_multi_cats_for_nft, action_scope, driver_dict_to_buy, fee=maker_fee
1177
1686
  )
@@ -1179,31 +1688,112 @@ async def test_nft_offer_nft0_and_xch_for_cat(
1179
1688
  assert error is None
1180
1689
  assert trade_make is not None
1181
1690
 
1182
- [maker_offer], signing_response = await wallet_node_0.wallet_state_manager.sign_offers(
1183
- [Offer.from_bytes(trade_make.offer)]
1184
- )
1691
+ [maker_offer], signing_response = await env_0.wallet_state_manager.sign_offers([Offer.from_bytes(trade_make.offer)])
1185
1692
 
1186
1693
  taker_fee = uint64(1)
1187
1694
 
1188
1695
  async with trade_manager_taker.wallet_state_manager.new_action_scope(
1189
- tx_config, push=True, additional_signing_responses=signing_response
1696
+ wallet_environments.tx_config, push=True, additional_signing_responses=signing_response
1190
1697
  ) as action_scope:
1191
1698
  trade_take = await trade_manager_taker.respond_to_offer(maker_offer, peer, action_scope, fee=taker_fee)
1192
1699
 
1193
- await full_node_api.process_transaction_records(records=action_scope.side_effects.transactions)
1194
- # check balances: taker wallet down an NFT, up cats
1195
- await full_node_api.wait_for_wallets_synced(wallet_nodes=[wallet_node_0, wallet_node_1], timeout=20)
1700
+ await wallet_environments.process_pending_states(
1701
+ [
1702
+ WalletStateTransition(
1703
+ pre_block_balance_updates={
1704
+ "xch": {
1705
+ "<=#spendable_balance": -maker_fee,
1706
+ "<=#max_send_amount": -maker_fee,
1707
+ "pending_coin_removal_count": 1,
1708
+ },
1709
+ "taker cat": {
1710
+ "<=#spendable_balance": -taker_cat_amount,
1711
+ "<=#max_send_amount": -taker_cat_amount,
1712
+ "pending_coin_removal_count": 1,
1713
+ },
1714
+ "maker cat": {
1715
+ "<=#spendable_balance": -maker_cat_amount,
1716
+ "<=#max_send_amount": -maker_cat_amount,
1717
+ "pending_coin_removal_count": 1,
1718
+ },
1719
+ "nft": {},
1720
+ },
1721
+ post_block_balance_updates={
1722
+ "xch": {
1723
+ "unconfirmed_wallet_balance": -maker_fee,
1724
+ "confirmed_wallet_balance": -maker_fee,
1725
+ ">=#spendable_balance": 1,
1726
+ ">=#max_send_amount": 1,
1727
+ "pending_coin_removal_count": -1,
1728
+ },
1729
+ "taker cat": {
1730
+ "unconfirmed_wallet_balance": -taker_cat_amount,
1731
+ "confirmed_wallet_balance": -taker_cat_amount,
1732
+ ">=#spendable_balance": 1,
1733
+ ">=#max_send_amount": 1,
1734
+ "pending_coin_removal_count": -1,
1735
+ },
1736
+ "maker cat": {
1737
+ "unconfirmed_wallet_balance": -maker_cat_amount,
1738
+ "confirmed_wallet_balance": -maker_cat_amount,
1739
+ ">=#spendable_balance": 1,
1740
+ ">=#max_send_amount": 1,
1741
+ "pending_coin_removal_count": -1,
1742
+ },
1743
+ "nft": {
1744
+ "unspent_coin_count": 1,
1745
+ },
1746
+ },
1747
+ ),
1748
+ WalletStateTransition(
1749
+ pre_block_balance_updates={
1750
+ "xch": {
1751
+ "unconfirmed_wallet_balance": -taker_fee,
1752
+ "<=#spendable_balance": -taker_fee,
1753
+ "<=#max_send_amount": -taker_fee,
1754
+ ">=#pending_change": 1,
1755
+ "pending_coin_removal_count": 1,
1756
+ },
1757
+ "taker cat": {
1758
+ "unconfirmed_wallet_balance": taker_cat_amount,
1759
+ },
1760
+ "maker cat": {
1761
+ "unconfirmed_wallet_balance": maker_cat_amount,
1762
+ },
1763
+ "nft": {
1764
+ "pending_coin_removal_count": 1,
1765
+ },
1766
+ },
1767
+ post_block_balance_updates={
1768
+ "xch": {
1769
+ "confirmed_wallet_balance": -taker_fee,
1770
+ ">=#spendable_balance": 1,
1771
+ ">=#max_send_amount": 1,
1772
+ "<=#pending_change": -1,
1773
+ "pending_coin_removal_count": -1,
1774
+ },
1775
+ "taker cat": {
1776
+ "confirmed_wallet_balance": taker_cat_amount,
1777
+ "spendable_balance": taker_cat_amount,
1778
+ "max_send_amount": taker_cat_amount,
1779
+ "unspent_coin_count": 1,
1780
+ },
1781
+ "maker cat": {
1782
+ "confirmed_wallet_balance": maker_cat_amount,
1783
+ "spendable_balance": maker_cat_amount,
1784
+ "max_send_amount": maker_cat_amount,
1785
+ "unspent_coin_count": 1,
1786
+ },
1787
+ "nft": {
1788
+ "pending_coin_removal_count": -1,
1789
+ "unspent_coin_count": -1,
1790
+ },
1791
+ },
1792
+ ),
1793
+ ]
1794
+ )
1196
1795
 
1197
1796
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make)
1198
1797
  await time_out_assert(20, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take)
1199
-
1200
- taker_cat_maker_balance_post_2 = await wallet_maker_for_taker_cat.get_confirmed_balance()
1201
- taker_cat_taker_balance_post_2 = await cat_wallet_taker.get_confirmed_balance()
1202
- assert taker_cat_maker_balance_post_2 == taker_cat_maker_balance_post - taker_cat_amount
1203
- assert taker_cat_taker_balance_post_2 == taker_cat_taker_balance_post + taker_cat_amount
1204
- maker_balance_post_2 = await wallet_maker.get_confirmed_balance()
1205
- taker_balance_post_2 = await wallet_taker.get_confirmed_balance()
1206
- assert maker_balance_post_2 == maker_balance_post - maker_fee
1207
- assert taker_balance_post_2 == taker_balance_post - taker_fee
1208
1798
  assert await nft_wallet_maker.get_nft_count() == 1
1209
1799
  assert await nft_wallet_taker.get_nft_count() == 0