-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
XLS-46: Dynamic Non Fungible Tokens (dNFTs) #4838
Conversation
Tests are for the next commits. Tests, guards and code related to tfTrustLine/fixRemoveNFTokenAutoTrustLine are removed in my draft as well |
Also would want to point out that this change would require a Clio ETL update as well, as it introduces a new transaction. Would be happy to help 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should also add
constexpr std::uint32_t const tfNFTokenModifyMask = ~tfUniversal;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unnecessary - all the other transactions that don't have any flags just use the tfUniversalMask
variable instead of creating a new one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, unless new flags are looking to be added in the future 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but a new variable can be added then.
if (uri.length() == 0 || uri.length() > maxTokenURILength) | ||
return temMALFORMED; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to check
if (txFlags & tfNFTokenModifyMask)
return temINVALID_FLAG;
src/ripple/protocol/Feature.h
Outdated
@@ -352,6 +352,8 @@ extern uint256 const featureXChainBridge; | |||
extern uint256 const fixDisallowIncomingV1; | |||
extern uint256 const featureDID; | |||
extern uint256 const fixFillOrKill; | |||
extern uint256 const featureDNFT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would call this featureDynamicNFT
to be a bit more descriptive
src/ripple/protocol/TxFlags.h
Outdated
constexpr std::uint32_t const tfTransferable = 0x00000008; | ||
constexpr std::uint32_t const tfMutable = 0x00000016; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flags are bitmasks, they should only be one bit and the number is already in hex.
constexpr std::uint32_t const tfMutable = 0x00000016; | |
constexpr std::uint32_t const tfMutable = 0x00000010; |
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
|
||
return tesSUCCESS; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: files should end with a newline
@@ -0,0 +1,31 @@ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs the standard license/disclaimer text (ditto for NFTokenModify.cpp
)
auto const nftID = ctx.tx[sfNFTokenID]; | ||
auto const account = ctx.tx[sfAccount]; | ||
|
||
if (!account || !nftID) | ||
return temMALFORMED; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is unneeded - it'll be checked by TxFormats
(it'll also crash when you try to fetch those values from ctx.tx
if you don't use the ~
anyways)
@@ -0,0 +1,96 @@ | |||
|
|||
#include <ripple/app/tx/impl/NFTokenModify.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new transaction type needs to be added to ripple/protocol/TxFormats.h
and ripple/protocol/impl/TxFormats.cpp
and ripple/app/tx/impl/applySteps.cpp
- otherwise rippled doesn't know it exists
I would suggest add a validation in Otherwise, I see two problems:
So I think adding a validation to check for offers, even though it will be some extra work as the owner would need to cancel all the offers, but that's reasonable. Any thoughts? |
Great point! I agree it makes totally sense to first check if offers are available and if so, to cancel them all ? Would you say, if offers available then let Thanks for the noticing this edge scenario Shawn 🤗 |
Both are possible solutions, I don't really have a strong opinion. To summarize the two options:
This code will return error if the number of offers exceeds 500, and therefore would require the owner to manually cancel them. Similarly, Please feel free to make the call, as I think both are acceptable solutions, unless other people think otherwise. 😄 |
But there is still a concern, what if, in the same ledger, the owner submits a I'm not sure of this either and I think we may want to double check this edge case in unit test if it's something we would care about. |
return ret; | ||
|
||
auto const nftID = ctx.tx[sfNFTokenID]; | ||
auto const account = ctx.tx[sfAccount]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the Discussion, sfAccount
is a reserved common field for transaction types, it should be sfOwner
.
NotTEC | ||
NFTokenModify::preflight(PreflightContext const& ctx) | ||
{ | ||
if (!ctx.rules.enabled(featureDNFT)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NonFungibleTokensV1_1
must be also enabled
NFTokenModify::doApply() | ||
{ | ||
auto const nftokenID = ctx_.tx[sfNFTokenID]; | ||
auto const account = ctx_.tx[sfAccount]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NFToken must be found from sfOwner
.
if (ctx_.tx.isFieldPresent(sfURI)) { | ||
auto newURI = ctx_.tx[sfURI]; | ||
tokenAndPage->token[sfURI] = newURI; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the URI is a required field in the Standard, this condition is always true if it is followed.
If the URI can be deleted, the URI field should be an optional field.
I think it would be appropriate to change the URI field in Standard to an optional field.
And overwrite the URI if it exists in the transaction and delete the URI if it does not.
To resolve this concern. I would propose an update to the spec, such that the owner can only submit a |
@@ -97,6 +97,9 @@ deleteTokenOffer(ApplyView& view, std::shared_ptr<SLE> const& offer); | |||
bool | |||
compareTokens(uint256 const& a, uint256 const& b); | |||
|
|||
TER | |||
updateToken(ApplyView& view, AccountID const& owner, STObject&& nft, std::shared_ptr<SLE>&& page); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should this method be called modifyToken
to match the transaction name?
std::uint32_t const NFTokenMintMask = | ||
ctx.rules.enabled(fixRemoveNFTokenAutoTrustLine) ? tfNFTokenMintMask | ||
: tfNFTokenMintOldMask; | ||
ctx.rules.enabled(featureDNFT) ? tfNFTokenMintMask | ||
: tfNFTokenMintOldMask; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old mask should still also be used based on if fixRemoveNFTokenAutoTrustLine
is enabled (this may make the mask a bit complicated, so it might be worth constructing it here instead of having several variables).
I think all of that is irrelevant as the issuer can just update the NFToken after the sale. Wether the change happens before the sale or after is irrelevant imo. Personally I wouldn't do anything with the offers. If clio cant handle this then thats a design flaw on clio and no one should be limiting themselves because clio cant do something. |
This actually has nothing to do with clio, but yes it's only a minor detail. If everyone feels good about it, then I don't have any concern. |
Closing this in favor of #5048 |
High Level Overview of Change
This Amendment adds functionality to update the
URI
of XLS-20 NFTs by adding:URI
NFTokenMint
transaction to allowNFTokenModify
to execute successfully on given NFT.Context of Change
Changes and spec: XLS-46
Type of Change
.gitignore
, formatting, dropping support for older tooling)API Impact
libxrpl
change (any change that may affectlibxrpl
or dependents oflibxrpl
)Future Tasks
Test case for:
NFTokenModify
lsfMutable
(new flag forNFTokenMint
)