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

Add NFTokenPages to account_objects RPC #4352

Merged
merged 8 commits into from
Apr 5, 2023

Conversation

RichardAH
Copy link
Collaborator

@RichardAH RichardAH commented Nov 25, 2022

High Level Overview of Change

Fix #4347

NFTokenPages consume owner count and therefore should be returned by the account_objects RPC, lest users be unaware where their owner count has been allocated.

Credit to @scottschurr for unit test / bug fixes and polishing.

It is technically possible to iterate NFTokenPages using existing RPC calls, but it is hacky to do this, requires additional calls and increases complexity (without gain) for wallet / app developers. Therefore I strongly advise this PR is merged.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

@RichardAH
Copy link
Collaborator Author

Longest suite times:
   43.0s ripple.tx.Offer
   35.1s ripple.app.ValidatorSite
   21.7s ripple.rpc.NodeToShardRPC
   21.2s ripple.tx.NFToken
   18.4s ripple.tx.NFTokenBurn
   14.0s ripple.app.Flow
   14.0s ripple.app.ShardArchiveHandler
   13.6s ripple.app.TheoreticalQuality
    8.8s ripple.tx.NFTokenDir
    8.2s ripple.app.LedgerReplayer
341.8s, 204 suites, 1528 cases, 532270 tests total, 0 failures

@cjcobb23
Copy link
Contributor

Why exactly is it hacky to do this client side? We have the account_nfts RPC for this: https://xrpl.org/account_nfts.html. Maybe I am misunderstanding something though.

@RichardAH
Copy link
Collaborator Author

Why exactly is it hacky to do this client side? We have the account_nfts RPC for this: https://xrpl.org/account_nfts.html. Maybe I am misunderstanding something though.

account_nfts does not tell you anything about how many NFT pages you have and thus nothing about how much ownercount has been reserved by those pages. Everything that contributes to your ownercount should be displayed in account_objects.

@cjcobb23
Copy link
Contributor

cjcobb23 commented Nov 30, 2022

Why exactly is it hacky to do this client side? We have the account_nfts RPC for this: https://xrpl.org/account_nfts.html. Maybe I am misunderstanding something though.

account_nfts does not tell you anything about how many NFT pages you have and thus nothing about how much ownercount has been reserved by those pages. Everything that contributes to your ownercount should be displayed in account_objects.

Does account_objects tell you about pages? It looks like account_objects just shows the raw ledger objects themselves, and doesn't say anything about the pages those objects are in.

Edit: Nevermind, I think I get it. We charge users per owned object, as well as per owned NFTokenPage. NFTs don't exist outside of pages, whereas account objects are stored by themselves, and the directory nodes just link to them.

@RichardAH
Copy link
Collaborator Author

Edit: Nevermind, I think I get it. We charge users per owned object, as well as per owned NFTokenPage. NFTs don't exist outside of pages, whereas account objects are stored by themselves, and the directory nodes just link to them.

Correct. Normally users are not charged for directory pages, but in the NFT amendment, they are. So, although they wouldn't normally be displayed, in this case these pages need to be displayed in account_objects.

Copy link
Collaborator

@ximinez ximinez left a comment

Choose a reason for hiding this comment

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

The only real dealbreaker here is dereferencing the unseated optional.

src/ripple/rpc/impl/RPCHelpers.cpp Outdated Show resolved Hide resolved
src/test/rpc/AccountObjects_test.cpp Show resolved Hide resolved
src/test/rpc/AccountObjects_test.cpp Outdated Show resolved Hide resolved
src/test/rpc/AccountObjects_test.cpp Outdated Show resolved Hide resolved
src/test/rpc/AccountObjects_test.cpp Outdated Show resolved Hide resolved
src/test/rpc/AccountObjects_test.cpp Outdated Show resolved Hide resolved
src/ripple/rpc/impl/RPCHelpers.cpp Show resolved Hide resolved
@RichardAH
Copy link
Collaborator Author

@ximinez I added a fix for the unguarded std::optional. As to the unit tests, those were written by @scottschurr so I will let him discuss. Unfortunately I don't have time at the moment.

Copy link
Collaborator

@scottschurr scottschurr left a comment

Choose a reason for hiding this comment

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

Sorry to be slow responding to the earlier comments.

I've incorporated the changes suggested by @ximinez in the top commit of this branch: https://github.com/scottschurr/rippled/commits/RichardAH-nftpage_accobjs. @RichardAH, if you could cherry pick that commit onto this branch then I believe all of @ximinez's comments will be addressed. Thanks.

@intelliot
Copy link
Collaborator

@RichardAH this is ready for your perusal, at your convenience

@RichardAH
Copy link
Collaborator Author

Sorry for the late reply. Cherry-picked @scottschurr 's commit (thanks!)
Looks like this still merge-conflict-free so whenever you want to merge it is fine by me

@intelliot
Copy link
Collaborator

This requires at least 2 code reviews. @HowardHinnant @scottschurr could you review, or suggest other reviewer(s)?

Copy link
Collaborator

@scottschurr scottschurr left a comment

Choose a reason for hiding this comment

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

👍 LGTM. It might be good to have @ximinez give it a quick looking over so he can make sure all the comments he made have been addressed. But as far as I'm concerned it's good to go.

@@ -171,25 +252,27 @@ getAccountObjects(
found = true;
}

// it's possible that the returned NFTPages exactly filled the
// response. Check for that condition.
if (i == mlimit && mlimit < limit)
Copy link
Collaborator

Choose a reason for hiding this comment

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

curious why i == mlimit was preferred here over than writing 0 == mlimit

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's been a while. As I recall this change was motivated by one of the new unit tests (that failed before this change). FWIW, i is incrementing inside the outer for loop, so I suspect that a comparison to 0 would not give the correct results.

Copy link
Collaborator

Choose a reason for hiding this comment

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

ah sorry i misread the code.

Copy link
Collaborator

@shawnxie999 shawnxie999 left a comment

Choose a reason for hiding this comment

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

looks good

@@ -510,7 +730,7 @@ class AccountObjects_test : public beast::unit_test::suite
auto const& ticket = resp[jss::result][jss::account_objects][0u];
Copy link
Collaborator

Choose a reason for hiding this comment

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

test failing on this line

Copy link
Collaborator

Choose a reason for hiding this comment

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

@shawnxie999, sorry, more details please? I'm not seeing any unit test failures on my local Mac build. Are you seeing a unit test failure on your local machine? Are you reporting a CI failure (which is known to be flaky)?

Copy link
Collaborator

Choose a reason for hiding this comment

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

oh sorry, i was just pointing out the CI failure, which seemed to have failed on both ubuntu and mac

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for the clarification @shawnxie999. I am seeing two CI unit tests failures currently:

  • Ubuntu: #65 failed: AccountLinesRPC_test.cpp(730)
  • Mac: #65 failed: AccountLinesRPC_test.cpp(732)

AccountLinesRPC_test.cpp has a file name that looks a lot like this file, but it's not the same file. When I look in the source for that file the reported failing lines don't align with a BEAST_EXPECT. So I'm inclined to suspect those are just two more flaky failures. I wish that were not the case...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for the clarification. It's my first time seeing a flaky ubuntu test, if it is the case. All good.

BEAST_EXPECT(nftPage[sfNFTokens.jsonName].size() == 1);
BEAST_EXPECT(
nftPage[sfNFTokens.jsonName][0u][sfNFToken.jsonName]
[sfNFTokenID.jsonName] == to_string(nftID));
Copy link
Collaborator

Choose a reason for hiding this comment

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

@scottschurr just curious isnt string comparison more expensive than comparing in uint256?

Copy link
Collaborator

@scottschurr scottschurr Mar 27, 2023

Choose a reason for hiding this comment

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

@shawnxie999, yes. string comparison is more expensive than numeric comparisons. However nftPage is a JSON object. All accounts are represented in a JSON object as std::strings. So something had to be converted, either a uint256 to a std::string or a std::string to a uint256, before the comparison could take place.

I probably chose the conversion to string so it would make debugging easier if something went wrong. But I wasn't thinking very hard about efficiency in the unit test.

@intelliot intelliot assigned ximinez and unassigned scottschurr Mar 28, 2023
@intelliot
Copy link
Collaborator

It might be good to have @ximinez give it a quick looking over so he can make sure all the comments he made have been addressed.

Copy link
Contributor

@HowardHinnant HowardHinnant left a comment

Choose a reason for hiding this comment

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

Looks good.

Copy link
Collaborator

@ximinez ximinez left a comment

Choose a reason for hiding this comment

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

Everything looks good from my earlier comments. One unit test is failing right now, due to interactions with my earlier PR #4361. Fortunately, I noticed the incompatibility at the time, and coded up a fix. Cherry pick this commit, and you should be good to go: ximinez@b633d47

Copy link
Collaborator

@ximinez ximinez left a comment

Choose a reason for hiding this comment

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

Looks good to go.

@intelliot
Copy link
Collaborator

Related Clio PR: XRPLF/clio#780

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

account_objects method does not return NFTokenPages (Version: 1.9.4)
7 participants