From d62d10ff30a7e1d1c99c6b1c5aa4895a2077a5b5 Mon Sep 17 00:00:00 2001 From: ytx1991 Date: Thu, 23 Jun 2022 21:32:08 -0700 Subject: [PATCH 1/2] Small fix for DID recovery --- chia/rpc/wallet_rpc_api.py | 9 ++++++--- chia/wallet/did_wallet/did_wallet.py | 10 +++++++++- tests/wallet/did_wallet/test_did.py | 9 ++++----- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/chia/rpc/wallet_rpc_api.py b/chia/rpc/wallet_rpc_api.py index 8f2495cb62..e9bc83a583 100644 --- a/chia/rpc/wallet_rpc_api.py +++ b/chia/rpc/wallet_rpc_api.py @@ -1224,7 +1224,7 @@ class WalletRpcApi: wallet: DIDWallet = self.service.wallet_state_manager.wallets[wallet_id] if len(request["attest_data"]) < wallet.did_info.num_of_backup_ids_needed: return {"success": False, "reason": "insufficient messages"} - + spend_bundle = None async with self.service.wallet_state_manager.lock: ( info_list, @@ -1243,14 +1243,17 @@ class WalletRpcApi: assert wallet.did_info.temp_puzhash is not None puzhash = wallet.did_info.temp_puzhash - success = await wallet.recovery_spend( + spend_bundle = await wallet.recovery_spend( wallet.did_info.temp_coin, puzhash, info_list, pubkey, message_spend_bundle, ) - return {"success": success} + if spend_bundle: + return {"success": True, "spend_bundle": spend_bundle} + else: + return {"success": False} async def did_get_pubkey(self, request): wallet_id = uint32(request["wallet_id"]) diff --git a/chia/wallet/did_wallet/did_wallet.py b/chia/wallet/did_wallet/did_wallet.py index 3510baa61b..fbb46e09a1 100644 --- a/chia/wallet/did_wallet/did_wallet.py +++ b/chia/wallet/did_wallet/did_wallet.py @@ -345,6 +345,7 @@ class DIDWallet: # This will be used in the recovery case where we don't have the parent info already async def coin_added(self, coin: Coin, _: uint32): """Notification from wallet state manager that wallet has been received.""" + self.log.info(f"DID wallet has been notified that coin was added: {coin.name()}:{coin}") inner_puzzle = await self.inner_puzzle_for_did_puzzle(coin.puzzle_hash) if self.did_info.temp_coin is not None: @@ -428,6 +429,13 @@ class DIDWallet: parent_info = None assert did_info.origin_coin is not None assert did_info.current_inner is not None + new_did_inner_puzhash = did_wallet_puzzles.get_inner_puzhash_by_p2( + new_puzhash, + did_info.backup_ids, + did_info.num_of_backup_ids_needed, + did_info.origin_coin.name(), + did_wallet_puzzles.metadata_to_program(json.loads(self.did_info.metadata)), + ) node = self.wallet_state_manager.wallet_node.get_full_node_peer() children = await self.wallet_state_manager.wallet_node.fetch_children(node, did_info.origin_coin.name()) while True: @@ -452,7 +460,7 @@ class DIDWallet: self.did_info.parent_info, did_info.current_inner, coin, - new_puzhash, + new_did_inner_puzhash, new_pubkey, False, did_info.metadata, diff --git a/tests/wallet/did_wallet/test_did.py b/tests/wallet/did_wallet/test_did.py index 42c23f29fa..35a07f2245 100644 --- a/tests/wallet/did_wallet/test_did.py +++ b/tests/wallet/did_wallet/test_did.py @@ -142,7 +142,6 @@ 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()) - print(f"pubkey: {pubkey}") for i in range(1, num_blocks): await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph)) @@ -160,7 +159,6 @@ class TestDIDWallet: pubkey, test_message_spend_bundle, ) - print(f"pubkey: {did_wallet_2}") await time_out_assert_not_none(5, full_node_api.full_node.mempool_manager.get_spendbundle, spend_bundle.name()) @@ -306,10 +304,11 @@ class TestDIDWallet: backup_data, ) assert did_wallet_4.wallet_info.name == "Profile 2" + pubkey = ( await did_wallet_4.wallet_state_manager.get_unused_derivation_record(did_wallet_2.wallet_info.id) ).pubkey - new_ph = await did_wallet_4.get_new_did_inner_hash() + new_ph = did_wallet_4.did_info.temp_puzhash message_spend_bundle, attest1 = await did_wallet.create_attestment(coin.name(), new_ph, pubkey) spend_bundle_list = await wallet_node.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(did_wallet.id()) @@ -332,7 +331,8 @@ class TestDIDWallet: for i in range(1, num_blocks): await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph2)) - + await time_out_assert(15, did_wallet_4.get_confirmed_balance, 0) + await time_out_assert(15, did_wallet_4.get_unconfirmed_balance, 0) await did_wallet_4.recovery_spend(coin, new_ph, test_info_list, pubkey, message_spend_bundle) spend_bundle_list = await wallet_node.wallet_state_manager.tx_store.get_unconfirmed_for_wallet( did_wallet_4.id() @@ -406,7 +406,6 @@ class TestDIDWallet: await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101) coins = await did_wallet.select_coins(1) coin = coins.pop() - print(f"Old coin id {coin.name()}") info = Program.to([]) pubkey = (await did_wallet.wallet_state_manager.get_unused_derivation_record(did_wallet.wallet_info.id)).pubkey try: From 7e7187aa9d6f1843cc7a398f8bdde03437c3fd01 Mon Sep 17 00:00:00 2001 From: ytx1991 Date: Fri, 24 Jun 2022 11:22:39 -0700 Subject: [PATCH 2/2] Fix nft_get_info API --- chia/rpc/wallet_rpc_api.py | 36 +++++++++------------- tests/wallet/nft_wallet/test_nft_wallet.py | 10 +++--- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/chia/rpc/wallet_rpc_api.py b/chia/rpc/wallet_rpc_api.py index e9bc83a583..45c8e3ec40 100644 --- a/chia/rpc/wallet_rpc_api.py +++ b/chia/rpc/wallet_rpc_api.py @@ -40,6 +40,7 @@ from chia.wallet.did_wallet.did_info import DID_HRP from chia.wallet.did_wallet.did_wallet import DIDWallet from chia.wallet.nft_wallet import nft_puzzles from chia.wallet.nft_wallet.nft_info import NFT_HRP, NFTInfo +from chia.wallet.nft_wallet.nft_puzzles import get_metadata_and_phs from chia.wallet.nft_wallet.nft_wallet import NFTWallet, NFTCoinInfo from chia.wallet.nft_wallet.uncurry_nft import UncurriedNFT from chia.wallet.outer_puzzles import AssetType @@ -1530,7 +1531,7 @@ class WalletRpcApi: log.exception(f"Failed to transfer NFT: {e}") return {"success": False, "error": str(e)} - async def nft_get_info(self, request: Dict) -> Optional[Dict]: + async def nft_get_info(self, request: Dict): assert self.service.wallet_state_manager is not None if "coin_id" not in request: return {"success": False, "error": "Coin ID is required."} @@ -1580,29 +1581,20 @@ class WalletRpcApi: # convert to NFTInfo try: # Check if the metadata is updated - inner_solution: Program = Program.from_bytes(bytes(coin_spend.solution)).rest().rest().first().first() full_puzzle: Program = Program.from_bytes(bytes(coin_spend.puzzle_reveal)) - update_condition = None - try: - for condition in inner_solution.rest().first().rest().as_iter(): - if condition.first().as_int() == -24: - update_condition = condition - break - except Exception: - log.info(f"Inner solution is not a metadata updater solution: {inner_solution}") + uncurried_nft: UncurriedNFT = UncurriedNFT.uncurry(full_puzzle) - if update_condition is not None: - metadata: Program = uncurried_nft.metadata - metadata = nft_puzzles.update_metadata(metadata, update_condition) - # Note: This is not the actual unspent NFT full puzzle. - # There is no way to rebuild the full puzzle in a different wallet. - # But it shouldn't have impact on generating the NFTInfo, since inner_puzzle is not used there. - full_puzzle = nft_puzzles.create_full_puzzle( - uncurried_nft.singleton_launcher_id, - metadata, - uncurried_nft.metadata_updater_hash, - uncurried_nft.inner_puzzle, - ) + metadata, p2_puzzle_hash = get_metadata_and_phs(uncurried_nft, coin_spend.solution) + # Note: This is not the actual unspent NFT full puzzle. + # There is no way to rebuild the full puzzle in a different wallet. + # But it shouldn't have impact on generating the NFTInfo, since inner_puzzle is not used there. + full_puzzle = nft_puzzles.create_full_puzzle( + uncurried_nft.singleton_launcher_id, + metadata, + uncurried_nft.metadata_updater_hash, + uncurried_nft.inner_puzzle, + ) + # Get launcher coin launcher_coin: List[CoinState] = await self.service.wallet_state_manager.wallet_node.get_coin_state( [uncurried_nft.singleton_launcher_id], peer=peer diff --git a/tests/wallet/nft_wallet/test_nft_wallet.py b/tests/wallet/nft_wallet/test_nft_wallet.py index 400d8d0667..db87dab40c 100644 --- a/tests/wallet/nft_wallet/test_nft_wallet.py +++ b/tests/wallet/nft_wallet/test_nft_wallet.py @@ -1089,14 +1089,12 @@ async def test_update_metadata_for_nft_did(two_wallet_nodes: Any, trusted: Any) await time_out_assert(10, wallet_0.get_confirmed_balance, 11999999999898) coins_response = await wait_rpc_state_condition( 5, - api_0.nft_get_nfts, - [dict(wallet_id=nft_wallet_0_id)], - lambda x: x["nft_list"] and len(x["nft_list"][0].metadata_uris) == 1, + api_0.nft_get_info, + [dict(wallet_id=nft_wallet_0_id, coin_id=nft_coin_id.hex(), latest=True)], + lambda x: x["nft_info"], ) - coins = coins_response["nft_list"] - assert len(coins) == 1 - coin = coins[0].to_json_dict() + coin = coins_response["nft_info"].to_json_dict() assert coin["mint_height"] > 0 uris = coin["data_uris"] assert len(uris) == 1