Remove duplicate nft wallet deletion in reorg (#13892)

* Remove duplicate nft wallet deltion in reorg

* Fix unit test

* Fix get latest coin bug

* Add unit test
This commit is contained in:
Kronus91 2022-11-26 18:22:16 -08:00 committed by GitHub
parent f100101940
commit 13cd8a2ef2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 15 deletions

View File

@ -247,7 +247,7 @@ class WalletRpcApi:
),
)
async def get_latest_coin_spend(
async def get_latest_singleton_coin_spend(
self, peer: Optional[WSChiaConnection], coin_id: bytes32, latest: bool = True
) -> Tuple[CoinSpend, CoinState]:
if peer is None:
@ -264,15 +264,15 @@ class WalletRpcApi:
coin_state_list = await self.service.wallet_state_manager.wallet_node.fetch_children(
coin_state.coin.name(), peer=peer
)
odd_coin = 0
odd_coin = None
for coin in coin_state_list:
if coin.coin.amount % 2 == 1:
odd_coin += 1
if odd_coin > 1:
raise ValueError("This is not a singleton, multiple children coins found.")
if odd_coin == 0:
if odd_coin is not None:
raise ValueError("This is not a singleton, multiple children coins found.")
odd_coin = coin
if odd_coin is None:
raise ValueError("Cannot find child coin, please wait then retry.")
coin_state = coin_state_list[0]
coin_state = odd_coin
# Get parent coin
parent_coin_state_list: List[CoinState] = await self.service.wallet_state_manager.wallet_node.get_coin_state(
[coin_state.coin.parent_coin_info], peer=peer
@ -1734,7 +1734,7 @@ class WalletRpcApi:
coin_id = bytes32.from_hexstr(coin_id)
# Get coin state
peer: Optional[WSChiaConnection] = self.service.get_full_node_peer()
coin_spend, coin_state = await self.get_latest_coin_spend(peer, coin_id, request.get("latest", True))
coin_spend, coin_state = await self.get_latest_singleton_coin_spend(peer, coin_id, request.get("latest", True))
full_puzzle: Program = Program.from_bytes(bytes(coin_spend.puzzle_reveal))
uncurried = uncurry_puzzle(full_puzzle)
curried_args = match_did_puzzle(uncurried.mod, uncurried.args)
@ -2180,7 +2180,7 @@ class WalletRpcApi:
# Get coin state
peer: Optional[WSChiaConnection] = self.service.get_full_node_peer()
assert peer is not None
coin_spend, coin_state = await self.get_latest_coin_spend(peer, coin_id, request.get("latest", True))
coin_spend, coin_state = await self.get_latest_singleton_coin_spend(peer, coin_id, request.get("latest", True))
# convert to NFTInfo
# Check if the metadata is updated
full_puzzle: Program = Program.from_bytes(bytes(coin_spend.puzzle_reveal))

View File

@ -1633,10 +1633,6 @@ class WalletStateManager:
remove: bool = await wallet.rewind(height)
if remove:
remove_ids.append(wallet_id)
if wallet.type() == WalletType.NFT.value:
assert isinstance(wallet, NFTWallet)
if await wallet.get_nft_count() == 0:
remove_ids.append(wallet_id)
for wallet_id in remove_ids:
await self.user_store.delete_wallet(wallet_id)

View File

@ -828,7 +828,7 @@ class TestDIDWallet:
spend_bundle = spend_bundle_list[0].spend_bundle
await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, spend_bundle.name())
for i in range(1, num_blocks):
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph1))
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph))
await time_out_assert(15, did_wallet_1.get_confirmed_balance, 101)
await time_out_assert(15, did_wallet_1.get_unconfirmed_balance, 101)
response = await api_0.did_get_info({"coin_id": did_wallet_1.did_info.origin_coin.name().hex()})
@ -843,6 +843,32 @@ class TestDIDWallet:
assert response["recovery_list_hash"] == Program(Program.to([])).get_tree_hash().hex()
assert decode_puzzle_hash(response["p2_address"]).hex() == response["hints"][0]
# Test non-singleton coin
coin = (await wallet.select_coins(uint64(1))).pop()
assert coin.amount % 2 == 1
response = await api_0.did_get_info({"coin_id": coin.name().hex()})
assert not response["success"]
# Test multiple odd coins
coin_1 = (await wallet.select_coins(uint64(1), exclude=[coin])).pop()
assert coin_1.amount % 2 == 0
tx = await wallet.generate_signed_transaction(
1,
ph1,
fee,
exclude_coins=set([coin]),
)
await wallet.push_transaction(tx)
for i in range(1, num_blocks):
await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph1))
await time_out_assert(15, wallet1.get_confirmed_balance, 2000000000001)
try:
await api_0.did_get_info({"coin_id": coin_1.name().hex()})
# We expect a ValueError here
assert False
except ValueError:
pass
@pytest.mark.parametrize(
"trusted",
[True, False],

View File

@ -245,7 +245,7 @@ async def test_nft_wallet_creation_and_transfer(two_wallet_nodes: Any, trusted:
assert False
await full_node_api.reorg_from_index_to_new_index(ReorgProtocol(uint32(height - 1), uint32(height + 1), ph1, None))
await time_out_assert(30, get_nft_count, 0, nft_wallet_0)
await time_out_assert(30, get_wallet_number, 1, wallet_node_0.wallet_state_manager)
await time_out_assert(30, get_wallet_number, 2, wallet_node_0.wallet_state_manager)
nft_wallet_0 = await NFTWallet.create_new_nft_wallet(
wallet_node_0.wallet_state_manager, wallet_0, name="NFT WALLET 1"