Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Main dids data hash #11440

Merged
merged 4 commits into from
May 9, 2022
Merged

Main dids data hash #11440

merged 4 commits into from
May 9, 2022

Conversation

ytx1991
Copy link
Contributor

@ytx1991 ytx1991 commented May 4, 2022

The issue is because the data hash is expected to be a hex, but it is a string. Since JSON doesn't support hex number, use string instead

@ytx1991 ytx1991 requested a review from paninaro May 4, 2022 21:52
@ytx1991 ytx1991 changed the base branch from main to main_dids May 4, 2022 21:53
Copy link
Contributor

@arvidn arvidn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is because the data hash is expected to be a hex, but it is a string. Since JSON doesn't support hex number, use string instead

hex is a string representation of binary data. The code you're pointing at is encoding binary data as hex in order to ship it as a json string. Can you elaborate on what the problem is?

Are you experiencing some error that you believe is caused by this message encoding?

@@ -110,7 +110,7 @@ async def test_nft_wallet_trade_chia_and_cat(self, three_wallet_nodes, trusted):
metadata = Program.to(
[
("u", ["https://www.chia.net/img/branding/chia-logo.svg"]),
("h", 0xD4584AD463139FA8C0D9F68F4B59F185),
("h", "0xD4584AD463139FA8C0D9F68F4B59F185"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a good idea to encode data as an ascii string.

@@ -142,7 +142,7 @@ def get_nft_info_from_puzzle(puzzle: Program, nft_coin: Coin) -> NFTInfo:
uncurried_nft.owner_did.as_python(),
uint64(uncurried_nft.trade_price_percentage.as_int()),
data_uris,
uncurried_nft.data_hash.as_python().hex(),
str(uncurried_nft.data_hash.as_python(), "utf-8"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the data is not valid utf-8, this would throw. There's no test covering this case. (but I think this change is poorly justified to begin with)

@paninaro
Copy link
Contributor

paninaro commented May 5, 2022

The issue is because the data hash is expected to be a hex, but it is a string. Since JSON doesn't support hex number, use string instead

hex is a string representation of binary data. The code you're pointing at is encoding binary data as hex in order to ship it as a json string. Can you elaborate on what the problem is?

Are you experiencing some error that you believe is caused by this message encoding?

The issue I'm seeing is in the JSON representation of the hash, so I would expect the fix to be at the RPC level. I previously used the nft_mint_nft RPC to create an NFT with the data hash specified as the string "c520c99955118784734af730590cf74e9c8961b9036b772052597fdb5206ee40" in the JSON payload. Expecting the hash to be provided as a string in the JSON seems correct to me, so I would expect the RPC to convert that string to a byte array (interpreted as hex bytes) if that's what the CLVM is expecting.

Similarly, when calling the nft_get_nfts RPC, the corresponding data hash was returned as the string "63353230633939393535313138373834373334616637333035393063663734653963383936316239303336623737323035323539376664623532303665653430". It may be that this code is already doing the right thing, and that the conversion only needs to occur in the nft_mint_nft RPC, but I haven't done a full accounting.

@paninaro
Copy link
Contributor

paninaro commented May 5, 2022

Maybe it's as simple as making this change:

image

@ytx1991
Copy link
Contributor Author

ytx1991 commented May 5, 2022

There are two problems.

  1. Like Jeff explained, this is a string in the JSON payload, but I agree it can be covert to bytes at RPC level.
  2. If the fields in the metadata can be any type then people who want to uncurry it needs to know this info, since different types have different uncurry ways.

From my POV, it's better to use a general type for all fields in stead of arbitrary types. If we want to support multiples type in the metadata, I suggest to add a type info field to indicate the way of uncurry and casting.

@github-actions github-actions bot added the merge_conflict Branch has conflicts that prevent merge to main label May 6, 2022
@github-actions
Copy link
Contributor

github-actions bot commented May 6, 2022

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@lgtm-com
Copy link

lgtm-com bot commented May 6, 2022

This pull request introduces 1 alert when merging b3197d5 into ecf7cd8 - view on LGTM.com

new alerts:

  • 1 for Unused import

@ytx1991 ytx1991 requested a review from arvidn May 6, 2022 23:40
@github-actions
Copy link
Contributor

github-actions bot commented May 7, 2022

Conflicts have been resolved. A maintainer will review the pull request shortly.

@github-actions github-actions bot removed the merge_conflict Branch has conflicts that prevent merge to main label May 7, 2022
try:
uncurried_nft = UncurriedNFT.uncurry(puzzle)
except Exception:
# The parent is not an NFT which means we need to scrub all of its children from our DB
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a test covering this case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a deep look, I think this case is impossible. Since we already checked and successfully uncurried NFT before this point. I will just remove this exception section

@@ -212,7 +212,7 @@ async def test_nft_wallet_rpc_creation_and_list(two_wallet_nodes: Any, trusted:
{
"wallet_id": nft_wallet_0_id,
"artist_address": ph,
"hash": 0xD4584AD463139FA8C0D9F68F4B59F184,
"hash": "0xD4584AD463139FA8C0D9F68F4B59F184",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand your rationale for changing this from a (compact and efficient) binary representation to a (slow and inflated) ascii string representation.

Even if there's a really good reason to represent this hash in ascii-form, surely you wouldn't need the 0x prefix.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be misunderstanding something actually, I was thinking that this was part of the smart contract, but this is the API to our RPC client, right? So this isn't really in a place where we have the ambition to be efficient, since we already use JSON at this level. And presumably the client class will turn this hash into a string when encoding it as JSON anyway.

However, I think there's a consistency argument to be made. The "artist_address" is a puzzle hash, fundamentally the same type as this "hash". They should probably use the same representation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, the tests are bypassing the normal JSON serialization/deserialization that would be applied in RpcServer, so the onus is on the test writer to ensure that the requests/responses are JSON compatible. In this case, the hash(es) being supplied as raw bytes is incorrect, as that isn't directly possible with JSON. Ideally we should come up with a test fixture (or something) that can wrap an RPC API object instance and enforce JSON compatibility.

I agree that we should be consistent, using strings to pass around hashes (puzzle hashes, data hashes, etc.)

@arvidn
Copy link
Contributor

arvidn commented May 7, 2022

please make sure to have unit tests covering the new cases you're adding, and ideally covering other cases that lack tests as well. If the code needs to be refactored in order to be tested, I think that's fine.

return await self.handle_nft(coin_spend, iter(nft_curried_args))
try:
uncurried_nft = UncurriedNFT.uncurry(Program.from_bytes(bytes(coin_spend.puzzle_reveal)))
except Exception:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets be a bit more specific here, as can easily lead to very hard to debug bugs

@altendky altendky mentioned this pull request May 9, 2022
1 task
@trepca trepca merged commit 3b417e7 into main_dids May 9, 2022
@ytx1991 ytx1991 deleted the main_dids_data_hash branch May 10, 2022 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants