-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Amendment XLS-35: URIToken — Lightweight first-class NFTs #4456
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
base: develop
Are you sure you want to change the base?
Conversation
@dangell7 is this ready for review? |
note: there are merge conflicts you'd need to resolve |
fdf58df
to
321d08c
Compare
321d08c
to
dbb3b51
Compare
Ready for review |
I am requesting a code review on this. Anyone feel like reviewing it please? |
From the ripple side, @ledhed2222 will be able to help provide code review on this. In terms of timing, I'm predicting he will be able to get to this in two weeks or so It would be great if we can seek additional help from non-ripple in terms for code review so that we can get more community representation/participation in this process. Would anyone else be able to help review? 🙏 |
just started taking a look at this :) |
src/ripple/app/tx/impl/URIToken.h
Outdated
//------------------------------------------------------------------------------ | ||
/* | ||
This file is part of rippled: https://github.com/ripple/rippled | ||
Copyright (c) 2014 Ripple Labs Inc. |
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.
year is 2023
src/ripple/app/tx/impl/URIToken.cpp
Outdated
//------------------------------------------------------------------------------ | ||
/* | ||
This file is part of rippled: https://github.com/ripple/rippled | ||
Copyright (c) 2017 Ripple Labs Inc. |
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.
please use 2023 :)
|
||
auto const uri = ctx.tx.getFieldVL(sfURI); | ||
|
||
if (uri.size() < 1 || uri.size() > 256) |
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.
what do you think about making 256 a constant in the header file?
switch (tt) | ||
{ | ||
case ttURITOKEN_MINT: { | ||
if (flags & tfURITokenMintMask) |
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.
what do you think about splitting out the bodies of each switch statement into their own functions, for readability?
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.
answered below in followup question.
src/ripple/app/tx/impl/URIToken.cpp
Outdated
if (flags & tfURITokenNonMintMask) | ||
return temINVALID_FLAG; | ||
|
||
auto amt = ctx.tx.getFieldAmount(sfAmount); |
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.
i believe this could be const
|
||
switch (tt) | ||
{ | ||
case ttURITOKEN_MINT: { |
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.
what's the rationale behind using a switch here (and above)? avoiding a new call stack frame?
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.
@RichardAH thoughts?
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.
a switch is the correct structure to use here:
- preflight checks are identical between two pairs of the five txn types, the switch allows fall through logic.
- the code is very clear, using another structure would make it less clear.
src/ripple/app/tx/impl/URIToken.cpp
Outdated
|
||
case ttURITOKEN_CREATE_SELL_OFFER: { | ||
if (account_ != *owner) | ||
return tecNO_PERMISSION; |
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 think this is already checked in preclaim, right?
return tesSUCCESS; | ||
} | ||
|
||
case ttURITOKEN_CREATE_SELL_OFFER: { |
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.
what do you think about the idea of adding these fields to the mint transaction, so that a user can mint and set a sale price (poss with destination) in one tx? since this is the same object seems like that could be useful and easy
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.
@RichardAH thoughts?
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 a pretty good idea imho
src/ripple/app/tx/impl/URIToken.cpp
Outdated
if (!sle) | ||
return tefINTERNAL; | ||
|
||
uint16_t tt = ctx_.tx.getFieldU16(sfTransactionType); |
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.
could be const i believe
src/ripple/app/tx/impl/URIToken.cpp
Outdated
return tecINSUFFICIENT_RESERVE; | ||
} | ||
|
||
uint32_t flags = ctx_.tx.getFlags(); |
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.
could be const i believe
|
||
switch (tt) | ||
{ | ||
case ttURITOKEN_MINT: { |
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.
what do you think about making each of these switch bodies their own private methods, for readability?
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.
Do you mean creating a preflight/preclaim/doApply for each or just moving them into a different method?
sleU->makeFieldAbsent(sfDestination); | ||
view().update(sleU); | ||
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.
it's a bit surprising to me that buying my own token has the same behavior as canceling my sell offer. what's the rationale?
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.
What behavior would you expect or anything specific that made you question it?
From an accounting/reconciliation POV I can see your point as this might need to be recorded for those purposes.
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.
It's a valid purchase it just results in 0 movement of objects or funds.
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.
i think a comment to clarify would be helpful :)
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 also allows me to buy it from myself even though i haven't listed it for sale. it's really confusing to me and i'm not sure that that means it is a valid purchase. i could see it in the case where i have listed it for sale and then i attempt to buy it from myself
src/ripple/app/tx/impl/URIToken.cpp
Outdated
|
||
dstAmt = purchaseAmount; | ||
static Rate const parityRate(QUALITY_ONE); | ||
auto xferRate = transferRate(view(), saleAmount->getIssuer()); |
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.
can be const
@ledhed2222 Thank you very much for your time and review of the code. I have marked everything that I have updated with a thumbs up. Richard and I are going to address some of the other comments and then I will push the changes for a second review. |
0, // quality in | ||
0, // quality out | ||
j); // journal | ||
!isTesSuccess(ter)) |
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.
i like that you commented all these arguments 👍 :)
// if a trustline was created then the ownercount stays the same on | ||
// the seller +1 TL -1 URIToken | ||
if (!lineCreated && !isXRP(purchaseAmount)) | ||
adjustOwnerCount(view(), sleOwner, -1, j); |
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.
shouldn't we also decrement the owner count if the purchase isXRP
too?
@@ -139,6 +139,13 @@ enum TxType : std::uint16_t | |||
/** This transaction accepts an existing offer to buy or sell an existing NFT. */ | |||
ttNFTOKEN_ACCEPT_OFFER = 29, | |||
|
|||
/** This transaction mints/burns/buys/sells a URI TOKEN */ |
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, These transactions mint/burn/buy/sell a URI TOKEN
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.
see comments :)
@dangell7 - at your convenience, please respond to the comments above |
lacks reviews - community is welcome to review. |
High Level Overview of Change
The URIToken Amendment (XLS-35d) provides a lightweight alternative to XLS20 suitable for both main-net and side-chains.
The amendment adds:
A new type of ledger object: ltURI_TOKEN
A new serialized field: URITokenID
Five new transaction types:
URITokenMint
URITokenBurn
URITokenBuy
URITokenCreateSellOffer
URITokenCancelSellOffer