Merge pull request #12051 from Chia-Network/nft1_did_recovery_fix

Small fix for DID recovery
This commit is contained in:
William Allen 2022-06-24 18:38:56 -05:00 committed by GitHub
commit 136a97dfd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 37 deletions

View File

@ -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
@ -1224,7 +1225,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 +1244,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"])
@ -1527,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."}
@ -1577,20 +1581,10 @@ 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)
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.
@ -1600,6 +1594,7 @@ class WalletRpcApi:
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

View File

@ -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,

View File

@ -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:

View File

@ -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