diff --git a/chia/_tests/wallet/nft_wallet/test_nft_1_offers.py b/chia/_tests/wallet/nft_wallet/test_nft_1_offers.py index e8af3626d7f7..0b09bc0d2c5b 100644 --- a/chia/_tests/wallet/nft_wallet/test_nft_1_offers.py +++ b/chia/_tests/wallet/nft_wallet/test_nft_1_offers.py @@ -9,8 +9,10 @@ from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework from chia._tests.util.time_out_assert import time_out_assert +from chia._tests.wallet.cat_wallet.test_cat_wallet import mint_cat from chia.types.blockchain_format.program import Program from chia.wallet.cat_wallet.cat_wallet import CATWallet +from chia.wallet.cat_wallet.r_cat_wallet import RCATWallet from chia.wallet.did_wallet.did_wallet import DIDWallet from chia.wallet.nft_wallet.nft_wallet import NFTWallet from chia.wallet.outer_puzzles import create_asset_id, match_puzzle @@ -777,8 +779,11 @@ async def test_nft_offer_sell_did_to_did(wallet_environments: WalletTestFramewor @pytest.mark.limit_consensus_modes @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True) @pytest.mark.parametrize("zero_royalties", [True, False]) +@pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet]) @pytest.mark.anyio -async def test_nft_offer_sell_nft_for_cat(wallet_environments: WalletTestFramework, zero_royalties: bool) -> None: +async def test_nft_offer_sell_nft_for_cat( + wallet_environments: WalletTestFramework, zero_royalties: bool, wallet_type: type[CATWallet] +) -> None: env_maker = wallet_environments.environments[0] env_taker = wallet_environments.environments[1] wallet_maker = env_maker.xch_wallet @@ -910,46 +915,24 @@ async def test_nft_offer_sell_nft_for_cat(wallet_environments: WalletTestFramewo # Create new CAT and wallets for maker and taker # Trade them between maker and taker to ensure multiple coins for each cat - cats_to_mint = 100000 + cats_to_mint = uint64(100000) cats_to_trade = uint64(10000) - async with wallet_maker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_maker = await CATWallet.create_new_cat_wallet( - env_maker.wallet_state_manager, - wallet_maker, - {"identifier": "genesis_by_id"}, - uint64(cats_to_mint), - action_scope, - ) - - await wallet_environments.process_pending_states( - [ - WalletStateTransition( - pre_block_balance_updates={ - "xch": { - "set_remainder": True, - }, - "cat": { - "init": True, - "set_remainder": True, - }, - }, - post_block_balance_updates={ - "xch": { - "set_remainder": True, - }, - "cat": { - "set_remainder": True, - }, - }, - ), - WalletStateTransition(), - ] + cat_wallet_maker = await mint_cat( + wallet_environments, + env_maker, + "xch", + "cat", + cats_to_mint, + wallet_type, + "cat", ) - cat_wallet_taker: CATWallet = await CATWallet.get_or_create_wallet_for_cat( - env_taker.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id() + if wallet_type is RCATWallet: + extra_args: Any = (bytes32.zeros,) + else: + extra_args = tuple() + cat_wallet_taker: CATWallet = await wallet_type.get_or_create_wallet_for_cat( + env_taker.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id(), *extra_args ) await env_taker.change_balances({"cat": {"init": True}}) @@ -1120,8 +1103,11 @@ async def test_nft_offer_sell_nft_for_cat(wallet_environments: WalletTestFramewo @pytest.mark.limit_consensus_modes @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True) @pytest.mark.parametrize("test_change", [True, False]) +@pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet]) @pytest.mark.anyio -async def test_nft_offer_request_nft_for_cat(wallet_environments: WalletTestFramework, test_change: bool) -> None: +async def test_nft_offer_request_nft_for_cat( + wallet_environments: WalletTestFramework, test_change: bool, wallet_type: type[CATWallet] +) -> None: env_maker = wallet_environments.environments[0] env_taker = wallet_environments.environments[1] wallet_maker = env_maker.xch_wallet @@ -1255,46 +1241,24 @@ async def test_nft_offer_request_nft_for_cat(wallet_environments: WalletTestFram # Create new CAT and wallets for maker and taker # Trade them between maker and taker to ensure multiple coins for each cat - cats_to_mint = 100000 + cats_to_mint = uint64(100000) cats_to_trade = uint64(20000) - async with wallet_maker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_maker = await CATWallet.create_new_cat_wallet( - env_maker.wallet_state_manager, - wallet_maker, - {"identifier": "genesis_by_id"}, - uint64(cats_to_mint), - action_scope, - ) - - await wallet_environments.process_pending_states( - [ - WalletStateTransition( - pre_block_balance_updates={ - "xch": { - "set_remainder": True, - }, - "cat": { - "init": True, - "set_remainder": True, - }, - }, - post_block_balance_updates={ - "xch": { - "set_remainder": True, - }, - "cat": { - "set_remainder": True, - }, - }, - ), - WalletStateTransition(), - ] + cat_wallet_maker = await mint_cat( + wallet_environments, + env_maker, + "xch", + "cat", + cats_to_mint, + wallet_type, + "cat", ) - await CATWallet.get_or_create_wallet_for_cat( - env_taker.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id() + if wallet_type is RCATWallet: + extra_args: Any = (bytes32.zeros,) + else: + extra_args = tuple() + await wallet_type.get_or_create_wallet_for_cat( + env_taker.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id(), *extra_args ) await env_taker.change_balances({"cat": {"init": True}}) @@ -1690,8 +1654,11 @@ async def get_trade_and_status(trade_manager: Any, trade: Any) -> TradeStatus: [{"num_environments": 2, "blocks_needed": [3, 3], "config_overrides": {"automatically_add_unknown_cats": True}}], indirect=True, ) +@pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet]) @pytest.mark.anyio -async def test_complex_nft_offer(wallet_environments: WalletTestFramework, royalty_pts: tuple[int, int, int]) -> None: +async def test_complex_nft_offer( + wallet_environments: WalletTestFramework, royalty_pts: tuple[int, int, int], wallet_type: type[CATWallet] +) -> None: """ This test is going to create an offer where the maker offers 1 NFT and 1 CAT for 2 NFTs, an XCH and a CAT """ @@ -1729,20 +1696,24 @@ async def test_complex_nft_offer(wallet_environments: WalletTestFramework, royal ph_taker = await action_scope.get_puzzle_hash(wallet_taker.wallet_state_manager) CAT_AMOUNT = uint64(100000000) - async with wallet_maker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_maker = await CATWallet.create_new_cat_wallet( - wsm_maker, wallet_maker, {"identifier": "genesis_by_id"}, CAT_AMOUNT, action_scope - ) - async with wallet_taker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_taker = await CATWallet.create_new_cat_wallet( - wsm_taker, wallet_taker, {"identifier": "genesis_by_id"}, CAT_AMOUNT, action_scope - ) - await env_maker.change_balances({"cat_maker": {"init": True}}) - await env_taker.change_balances({"cat_taker": {"init": True}}) + cat_wallet_maker = await mint_cat( + wallet_environments, + env_maker, + "xch", + "cat_maker", + CAT_AMOUNT, + wallet_type, + "cat_maker", + ) + cat_wallet_taker = await mint_cat( + wallet_environments, + env_taker, + "xch", + "cat_taker", + CAT_AMOUNT, + wallet_type, + "cat_taker", + ) # We'll need these later basic_nft_wallet_maker = await NFTWallet.create_new_nft_wallet(wsm_maker, wallet_maker, name="NFT WALLET MAKER") @@ -2025,6 +1996,11 @@ async def test_complex_nft_offer(wallet_environments: WalletTestFramework, royal { "type": "CAT", "tail": "0x" + cat_wallet_taker.get_asset_id(), + **( + {} + if wallet_type is CATWallet + else {"also": {"type": "revocation layer", "hidden_puzzle_hash": "0x" + bytes32.zeros.hex()}} + ), } ), } @@ -2090,7 +2066,8 @@ async def test_complex_nft_offer(wallet_environments: WalletTestFramework, royal + taker_royalty_summary[nft_to_offer_asset_id_taker_2][0]["amount"] ) - xch_coins = int(XCH_REQUESTED / 1_750_000_000_000) + 2 + # in the zero royalty case, exact change ends up being selected which complicates things a bit + xch_coins = int(XCH_REQUESTED / 1_750_000_000_000) + 2 - (1 if royalty_basis_pts_maker == 0 else 0) fee_coins = int(FEE / 1_750_000_000_000) + 1 if FEE > 1_750_000_000_000 else 1 await wallet_environments.process_pending_states( [ @@ -2151,7 +2128,7 @@ async def test_complex_nft_offer(wallet_environments: WalletTestFramework, royal "unconfirmed_wallet_balance": -XCH_REQUESTED - maker_xch_royalties_expected - FEE, "<=#spendable_balance": -XCH_REQUESTED - maker_xch_royalties_expected - FEE, "<=#max_send_amount": -XCH_REQUESTED - maker_xch_royalties_expected - FEE, - ">=#pending_change": 1, + ">=#pending_change": 0, "pending_coin_removal_count": xch_coins + fee_coins, }, "cat_taker": { @@ -2173,9 +2150,9 @@ async def test_complex_nft_offer(wallet_environments: WalletTestFramework, royal post_block_balance_updates={ "xch": { "confirmed_wallet_balance": -XCH_REQUESTED - maker_xch_royalties_expected - FEE, - ">=#spendable_balance": 1, - ">=#max_send_amount": 1, - "<=#pending_change": -1, + ">=#spendable_balance": 0, + ">=#max_send_amount": 0, + "<=#pending_change": 0, "pending_coin_removal_count": -fee_coins - xch_coins, # Parametrizations make unspent_coin_count too complicated "set_remainder": True, diff --git a/chia/_tests/wallet/nft_wallet/test_nft_offers.py b/chia/_tests/wallet/nft_wallet/test_nft_offers.py index 80eb211f06cf..816f17f8b6ba 100644 --- a/chia/_tests/wallet/nft_wallet/test_nft_offers.py +++ b/chia/_tests/wallet/nft_wallet/test_nft_offers.py @@ -5,11 +5,14 @@ import pytest from chia_rs.sized_bytes import bytes32 from chia_rs.sized_ints import uint64 +from typing_extensions import Any from chia._tests.environments.wallet import WalletStateTransition, WalletTestFramework from chia._tests.util.time_out_assert import time_out_assert +from chia._tests.wallet.cat_wallet.test_cat_wallet import mint_cat from chia.types.blockchain_format.program import Program from chia.wallet.cat_wallet.cat_wallet import CATWallet +from chia.wallet.cat_wallet.r_cat_wallet import RCATWallet from chia.wallet.nft_wallet.nft_wallet import NFTWallet from chia.wallet.outer_puzzles import create_asset_id, match_puzzle from chia.wallet.puzzle_drivers import PuzzleInfo @@ -696,8 +699,9 @@ async def test_nft_offer_with_metadata_update(wallet_environments: WalletTestFra @pytest.mark.limit_consensus_modes(reason="irrelevant") @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True) +@pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet]) @pytest.mark.anyio -async def test_nft_offer_nft_for_cat(wallet_environments: WalletTestFramework) -> None: +async def test_nft_offer_nft_for_cat(wallet_environments: WalletTestFramework, wallet_type: type[CATWallet]) -> None: env_0 = wallet_environments.environments[0] env_1 = wallet_environments.environments[1] wallet_maker = env_0.xch_wallet @@ -785,73 +789,42 @@ async def test_nft_offer_nft_for_cat(wallet_environments: WalletTestFramework) - assert await nft_wallet_taker.get_nft_count() == 0 # Create two new CATs and wallets for maker and taker - cats_to_mint = 10000 - async with wallet_maker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_maker = await CATWallet.create_new_cat_wallet( - env_0.wallet_state_manager, - wallet_maker, - {"identifier": "genesis_by_id"}, - uint64(cats_to_mint), - action_scope, - ) - - async with wallet_taker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_taker = await CATWallet.create_new_cat_wallet( - env_1.wallet_state_manager, - wallet_taker, - {"identifier": "genesis_by_id"}, - uint64(cats_to_mint), - action_scope, - ) + cats_to_mint = uint64(10000) + cat_wallet_maker = await mint_cat( + wallet_environments, + env_0, + "xch", + "maker cat", + cats_to_mint, + wallet_type, + "maker cat", + ) - # mostly set_remainder here as minting CATs is tested elsewhere - await wallet_environments.process_pending_states( - [ - WalletStateTransition( - pre_block_balance_updates={ - "xch": {"set_remainder": True}, - "maker cat": { - "init": True, - "set_remainder": True, - }, - }, - post_block_balance_updates={ - "xch": {"set_remainder": True}, - "maker cat": { - "set_remainder": True, - }, - }, - ), - WalletStateTransition( - pre_block_balance_updates={ - "xch": {"set_remainder": True}, - "taker cat": { - "init": True, - "set_remainder": True, - }, - }, - post_block_balance_updates={ - "xch": {"set_remainder": True}, - "taker cat": { - "set_remainder": True, - }, - }, - ), - ] + cat_wallet_taker = await mint_cat( + wallet_environments, + env_1, + "xch", + "taker cat", + cats_to_mint, + wallet_type, + "taker cat", ) - wallet_maker_for_taker_cat: CATWallet = await CATWallet.get_or_create_wallet_for_cat( - env_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id() + if wallet_type is RCATWallet: + extra_args: Any = (bytes32.zeros,) + else: + extra_args = tuple() + wallet_maker_for_taker_cat: CATWallet = await wallet_type.get_or_create_wallet_for_cat( + env_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id(), *extra_args ) - await CATWallet.get_or_create_wallet_for_cat( - env_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id() + await wallet_type.get_or_create_wallet_for_cat( + env_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id(), *extra_args ) + await env_0.change_balances({"taker cat": {"init": True}}) + await env_1.change_balances({"maker cat": {"init": True}}) + # MAKE FIRST TRADE: 1 NFT for 10 taker cats nft_to_offer = coins_maker[0] nft_info: Optional[PuzzleInfo] = match_puzzle(uncurry_puzzle(nft_to_offer.full_puzzle)) @@ -902,9 +875,7 @@ async def test_nft_offer_nft_for_cat(wallet_environments: WalletTestFramework) - "<=#max_send_amount": -maker_fee, "pending_coin_removal_count": 1, }, - "taker cat": { - "init": True, - }, + "taker cat": {}, "nft": { "pending_coin_removal_count": 1, }, @@ -940,9 +911,7 @@ async def test_nft_offer_nft_for_cat(wallet_environments: WalletTestFramework) - ">=#pending_change": 1, "pending_coin_removal_count": 1, }, - "maker cat": { - "init": True, - }, + "maker cat": {}, "taker cat": { "unconfirmed_wallet_balance": -taker_cat_offered, "<=#spendable_balance": -taker_cat_offered, @@ -1367,8 +1336,11 @@ async def test_nft_offer_nft_for_nft(wallet_environments: WalletTestFramework) - @pytest.mark.limit_consensus_modes(reason="irrelevant") @pytest.mark.parametrize("wallet_environments", [{"num_environments": 2, "blocks_needed": [1, 1]}], indirect=True) +@pytest.mark.parametrize("wallet_type", [CATWallet, RCATWallet]) @pytest.mark.anyio -async def test_nft_offer_nft0_and_xch_for_cat(wallet_environments: WalletTestFramework) -> None: +async def test_nft_offer_nft0_and_xch_for_cat( + wallet_environments: WalletTestFramework, wallet_type: type[CATWallet] +) -> None: env_0 = wallet_environments.environments[0] env_1 = wallet_environments.environments[1] wallet_maker = env_0.xch_wallet @@ -1456,80 +1428,41 @@ async def test_nft_offer_nft0_and_xch_for_cat(wallet_environments: WalletTestFra assert await nft_wallet_taker.get_nft_count() == 0 # Create two new CATs and wallets for maker and taker - cats_to_mint = 10000 - async with wallet_maker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_maker = await CATWallet.create_new_cat_wallet( - env_0.wallet_state_manager, - wallet_maker, - {"identifier": "genesis_by_id"}, - uint64(cats_to_mint), - action_scope, - ) + cats_to_mint = uint64(10000) + cat_wallet_maker = await mint_cat( + wallet_environments, + env_0, + "xch", + "maker cat", + cats_to_mint, + CATWallet, + "maker cat", + ) - async with wallet_taker.wallet_state_manager.new_action_scope( - wallet_environments.tx_config, push=True - ) as action_scope: - cat_wallet_taker = await CATWallet.create_new_cat_wallet( - env_1.wallet_state_manager, - wallet_taker, - {"identifier": "genesis_by_id"}, - uint64(cats_to_mint), - action_scope, - ) + cat_wallet_taker = await mint_cat( + wallet_environments, + env_1, + "xch", + "taker cat", + cats_to_mint, + CATWallet, + "taker cat", + ) + if wallet_type is RCATWallet: + extra_args: Any = (bytes32.zeros,) + else: + extra_args = tuple() wallet_maker_for_taker_cat: CATWallet = await CATWallet.get_or_create_wallet_for_cat( - env_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id() + env_0.wallet_state_manager, wallet_maker, cat_wallet_taker.get_asset_id(), *extra_args ) await CATWallet.get_or_create_wallet_for_cat( - env_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id() + env_1.wallet_state_manager, wallet_taker, cat_wallet_maker.get_asset_id(), *extra_args ) - # mostly set_remainder here as minting CATs is tested elsewhere - await wallet_environments.process_pending_states( - [ - WalletStateTransition( - pre_block_balance_updates={ - "xch": {"set_remainder": True}, - "maker cat": { - "init": True, - "set_remainder": True, - }, - "taker cat": { - "init": True, - "set_remainder": True, - }, - }, - post_block_balance_updates={ - "xch": {"set_remainder": True}, - "maker cat": { - "set_remainder": True, - }, - }, - ), - WalletStateTransition( - pre_block_balance_updates={ - "xch": {"set_remainder": True}, - "maker cat": { - "init": True, - "set_remainder": True, - }, - "taker cat": { - "init": True, - "set_remainder": True, - }, - }, - post_block_balance_updates={ - "xch": {"set_remainder": True}, - "taker cat": { - "set_remainder": True, - }, - }, - ), - ] - ) + await env_0.change_balances({"taker cat": {"init": True}}) + await env_1.change_balances({"maker cat": {"init": True}}) # MAKE FIRST TRADE: 1 NFT for 10 taker cats nft_to_offer = coins_maker[0]