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

Introduce MPT support (XLS-33d): #5143

Merged
merged 61 commits into from
Oct 29, 2024

Conversation

gregtatcam
Copy link
Collaborator

High Level Overview of Change

New Transactions:

  • MPTokenIssuanceCreate
  • MPTokenIssuanceDestory
  • MPTokenIssuanceSet
  • MPTokenAuthorize

Modified Transactions:

  • Payment
  • Clawback

New Objects:

  • MPTokenIssuance
  • MPToken

API updates:

  • ledger_entry
  • account_objects
  • ledger_data

Refactor:

  • Add new types Asset, MPTIssue, MPTAmount to handle MPT amount.
  • Add SOElement constructor overload to describe the amount fields, which may have MPT amount (currently only sfAmount). The constructors are used in TxFormats to define fields supporting MPT.

Context of Change

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)
  • Performance (increase or change in throughput and/or latency)
  • Tests (you added tests for code that already exists, or your new feature included in this PR)
  • Documentation update
  • Chore (no impact to binary, e.g. .gitignore, formatting, dropping support for older tooling)
  • Release

API Impact

  • Public API: New feature (new methods and/or new fields)
  • Public API: Breaking change (in general, breaking changes should only impact the next api_version)
  • libxrpl change (any change that may affect libxrpl or dependents of libxrpl)
  • Peer protocol change (must be backward compatible or bump the peer protocol version)

Test Plan

Added test for new feature:

  • MPT

Future Tasks

Integrate MPT into XRPL DEX.

Copy link

codecov bot commented Sep 19, 2024

Codecov Report

Attention: Patch coverage is 86.32931% with 181 lines in your changes missing coverage. Please review.

Project coverage is 77.5%. Comparing base (63209c2) to head (9ce2061).
Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
src/libxrpl/protocol/STAmount.cpp 79.4% 35 Missing ⚠️
src/xrpld/app/tx/detail/InvariantCheck.cpp 66.3% 30 Missing ⚠️
src/xrpld/ledger/detail/View.cpp 88.8% 20 Missing ⚠️
src/libxrpl/protocol/MPTIssue.cpp 46.7% 16 Missing ⚠️
src/libxrpl/basics/MPTAmount.cpp 12.5% 14 Missing ⚠️
src/xrpld/rpc/handlers/LedgerEntry.cpp 68.6% 11 Missing ⚠️
src/xrpld/app/tx/detail/MPTokenAuthorize.cpp 92.2% 9 Missing ⚠️
src/libxrpl/protocol/Asset.cpp 71.4% 6 Missing ⚠️
src/libxrpl/protocol/STParsedJSON.cpp 62.5% 6 Missing ⚠️
src/xrpld/app/tx/detail/Payment.cpp 95.5% 6 Missing ⚠️
... and 12 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           develop   #5143     +/-   ##
=========================================
+ Coverage     76.1%   77.5%   +1.4%     
=========================================
  Files          762     777     +15     
  Lines        61469   65829   +4360     
  Branches      8121    8185     +64     
=========================================
+ Hits         46807   51024   +4217     
- Misses       14662   14805    +143     
Files with missing lines Coverage Δ
include/xrpl/basics/MPTAmount.h 100.0% <100.0%> (ø)
include/xrpl/basics/Number.h 100.0% <100.0%> (ø)
include/xrpl/basics/XRPAmount.h 98.8% <ø> (+<0.1%) ⬆️
include/xrpl/basics/base_uint.h 96.8% <ø> (+0.1%) ⬆️
include/xrpl/protocol/AmountConversions.h 87.7% <100.0%> (+0.2%) ⬆️
include/xrpl/protocol/Feature.h 100.0% <ø> (ø)
include/xrpl/protocol/Indexes.h 100.0% <ø> (ø)
include/xrpl/protocol/Issue.h 100.0% <100.0%> (ø)
include/xrpl/protocol/MPTIssue.h 100.0% <100.0%> (ø)
include/xrpl/protocol/Rate.h 100.0% <ø> (ø)
... and 56 more

... and 530 files with indirect coverage changes

Impacted file tree graph

@gregtatcam gregtatcam force-pushed the feature/mpt-v1-var-issues branch 2 times, most recently from 4ca85a2 to ba5f67c Compare September 19, 2024 14:22
New Transactions:
- MPTokenIssuanceCreate
- MPTokenIssuanceDestory
- MPTokenIssuanceSet
- MPTokenAuthorize

Modified Transactions:
- Payment
- Clawback

New Objects:
- MPTokenIssuance
- MPTokenAuthorize

API updates:
- ledger_entry
- account_objects
- ledger_data

Read full spec: https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0033d-multi-purpose-tokens

---------

Co-authored-by: Shawn Xie <shawnxie920@gmail.com>
Co-authored-by: Howard Hinnant <howard.hinnant@gmail.com>
lsfMPTCanClawback = 0x00000040,

// ltMPTOKEN
lsfMPTAuthorized = 0x00000002,
Copy link
Contributor

Choose a reason for hiding this comment

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

lsfMPTLocked, lsfMPTCanLock and lsfMPTAuthorized do not have unique values within this enum. Is that on purpose?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The LedgerSpecificFlags enum is really just a way to define a bunch of constants. The flags are unique per ledger object type. Those are divided by the comment / label before each one. It might be worthwhile to split them into one per object type, but that's probably beyond the scope of this PR.

Copy link
Collaborator

@thejohnfreeman thejohnfreeman left a comment

Choose a reason for hiding this comment

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

Submitting the first phase of my review, a complete review of the changes to libxrpl.

include/xrpl/basics/MPTAmount.h Outdated Show resolved Hide resolved
include/xrpl/basics/MPTAmount.h Outdated Show resolved Hide resolved
include/xrpl/basics/MPTAmount.h Outdated Show resolved Hide resolved
include/xrpl/protocol/Asset.h Show resolved Hide resolved
include/xrpl/protocol/UintTypes.h Outdated Show resolved Hide resolved
src/libxrpl/protocol/LedgerFormats.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/LedgerFormats.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/LedgerFormats.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/LedgerFormats.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STTx.cpp Outdated Show resolved Hide resolved
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.

Partial review:

include/xrpl/basics/MPTAmount.h Outdated Show resolved Hide resolved
src/test/jtx/impl/mpt.cpp Outdated Show resolved Hide resolved
include/xrpl/basics/MPTAmount.h Outdated Show resolved Hide resolved
include/xrpl/protocol/Asset.h Show resolved Hide resolved
include/xrpl/protocol/LedgerFormats.h Outdated Show resolved Hide resolved
include/xrpl/protocol/SOTemplate.h Outdated Show resolved Hide resolved
include/xrpl/protocol/SOTemplate.h Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
gregtatcam and others added 3 commits October 1, 2024 13:25
Co-authored-by: Ed Hennis <ed@ripple.com>
Update MPT Payment errors to be consistent with IOU Payment.
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.

Partial review


namespace ripple {

class MPTAmount : private boost::totally_ordered<MPTAmount>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Seeing how similar MPTAmount is to XRPAmount it's a pity that they aren't implemented with common code. I.e. through a base class, or a template or something. Rather than diving down the potential rabbit hole of implementing it, I'm just going to leave this note here for someone else or for future reference.

Copy link
Collaborator

Choose a reason for hiding this comment

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

My opinion:

  • They should be called MPTNumber and XRPNumber because they represent quantities, while STAmount represents a quantity plus an asset / issue / unit (however you want to think of it). These are more like Number, and convert directly to and from it.
  • All of the arithmetic is moving to Number after the switchover anyway. In due time, when we retire that amendment, effectively locking it in permanently, then I think we can remove MPTAmount and XRPAmount.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Should IOUAmount change too? I think that Amount better communicates what the value is. I don't think you'd say number when talking about tokens or currencies even if the values don't have associate unit. And XRPAmount doesn't need an issue, it's implicit. Also doesn't seem like this refactoring has to be done in MPT PR. But this is just my opinion. I'll change if everyone thinks Number is better. There are over 300 instances of XRPAmount, MPTAmount, IOUAmount.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I created a ticket to refactor MPTAmount and XRPAmount to use a common code + renaming.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I'm not asking it to be done here, or at all even. Was just stating my position. My opinion is that IOUAmount should be renamed too (in an ideal world), and my only reason for these renames is that STAmount has quantity + issue, while these {XRP,IOU,MPT}Amounts only have quantity, like Number, which is their common representation. The alternative fix is to rename STAmount to a different suffix, but I think that would be even more disruptive, especially to external projects.

include/xrpl/protocol/STAmount.h Show resolved Hide resolved
include/xrpl/protocol/STAmount.h Outdated Show resolved Hide resolved
include/xrpl/protocol/STAmount.h Outdated Show resolved Hide resolved
src/xrpld/app/misc/NetworkOPs.cpp Show resolved Hide resolved
src/libxrpl/protocol/LedgerFormats.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/LedgerFormats.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/MPTIssue.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/xrpld/ledger/detail/View.cpp Outdated Show resolved Hide resolved
gregtatcam and others added 2 commits October 2, 2024 07:47
include/xrpl/protocol/Asset.h Outdated Show resolved Hide resolved

namespace ripple {

class MPTAmount : private boost::totally_ordered<MPTAmount>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

My opinion:

  • They should be called MPTNumber and XRPNumber because they represent quantities, while STAmount represents a quantity plus an asset / issue / unit (however you want to think of it). These are more like Number, and convert directly to and from it.
  • All of the arithmetic is moving to Number after the switchover anyway. In due time, when we retire that amendment, effectively locking it in permanently, then I think we can remove MPTAmount and XRPAmount.

include/xrpl/basics/MPTAmount.h Outdated Show resolved Hide resolved
include/xrpl/protocol/Indexes.h Outdated Show resolved Hide resolved
include/xrpl/protocol/Indexes.h Outdated Show resolved Hide resolved
include/xrpl/protocol/MPTIssue.h Show resolved Hide resolved
include/xrpl/protocol/jss.h Outdated Show resolved Hide resolved
src/libxrpl/protocol/STTx.cpp Show resolved Hide resolved
include/xrpl/protocol/UintTypes.h Show resolved Hide resolved
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.

Partial review

src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
src/libxrpl/protocol/STAmount.cpp Outdated Show resolved Hide resolved
gregtatcam and others added 4 commits October 3, 2024 08:45
Co-authored-by: Ed Hennis <ed@ripple.com>
use std::min, std::max

Co-authored-by: Ed Hennis <ed@ripple.com>
* Refactor getSNValue/getMPTValue
* Use std::min, std::max
* Fix min/max values for MPT
if (flagsIn != flagsOut)
sle->setFieldU32(sfFlags, flagsOut);

view().update(sle);
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can move this statement into the previous branch.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we'd like to keep it here because other transactors have it similar (eg. AccountSet). Also potential in the future we may add new functionalities to this transactor so might as well leave it here.

include/xrpl/protocol/Asset.h Outdated Show resolved Hide resolved
include/xrpl/protocol/detail/transactions.macro Outdated Show resolved Hide resolved
src/xrpld/app/tx/detail/MPTokenAuthorize.cpp Outdated Show resolved Hide resolved
Comment on lines 80 to 84
auto const sleMptIssuance = ctx.view.read(
keylet::mptIssuance(ctx.tx[sfMPTokenIssuanceID]));
assert(sleMptIssuance);
if (!sleMptIssuance)
return tefINTERNAL;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel like this check is technically unnecessary. We assert it is always true.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ed proposed this change

Copy link
Collaborator

Choose a reason for hiding this comment

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

It would make more sense to remove the assert

if (flagsIn != flagsOut)
sleMpt->setFieldU32(sfFlags, flagsOut);

view.update(sleMpt);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This line can move into the previous then-block.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Doesn't hurt to leave it as it as is IMO

src/xrpld/ledger/View.h Show resolved Hide resolved
src/xrpld/ledger/detail/View.cpp Show resolved Hide resolved
src/xrpld/ledger/detail/View.cpp Show resolved Hide resolved
if (!ctx.rules.enabled(featureMPTokensV1))
return temDISABLED;

if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
Copy link
Collaborator

Choose a reason for hiding this comment

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

These branches, here and elsewhere, can all be simplified.

Suggested change
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
if (auto const ret = preflight1(ctx))

Copy link
Collaborator

@shawnxie999 shawnxie999 Oct 23, 2024

Choose a reason for hiding this comment

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

I think this is fine. Every other transactions has this. And we are returning the tec code if it is not tesSuccess, so I dont see how this simplification would work.

Copy link
Collaborator

Choose a reason for hiding this comment

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

"Other transactions have this" is not a good reason. This simplification works because a TER evaluates to true if it is not success, just like a Linux error code.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You know, I've gotten so used to seeing the symbolic isTesSuccess, that I've never really thought about the fact that tesSUCCESS == 0. But, yeah, this optimization / simplification should work.

The question is what does it gain us?
On one hand, if I see isTesSuccess (or any of the other is* test functions), I don't have to think about the underlying enum values. Additionally, isTesSuccess is defined as

inline bool
isTesSuccess(TER x)
{
    return ((x) == tesSUCCESS);
}

Since that's inline, when compiled it should just boil down to x == 0. As an optimization, this probably doesn't gain much.

On the other hand, as a simplification, it does read a lot nicer, and fits the pattern we use everywhere else the result can be evaluated as a bool. I think I personally would adjust pretty quickly to seeing it this way, so I still wouldn't have to think about the underlying values.

My vote is to remove the call to isTesSuccess, and optionally add a comment anywhere it's removed to remind readers that this works.

Suggested change
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
// tesSUCCESS = 0, so any other return will be returned.
if (auto const ret = preflight1(ctx))

Copy link
Collaborator

Choose a reason for hiding this comment

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

Another idea, similar to my first suggestion:

Suggested change
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
// tesSUCCESS == 0. Any other value indicates an error.
if (auto const err = preflight1(ctx))

(then return err;)
Using the name err instantly communicates "This function will return an error if it doesn't succeed."

@Bronek
Copy link
Collaborator

Bronek commented Oct 23, 2024

#5042 is blocked by this PR

@Bronek Bronek mentioned this pull request Oct 23, 2024
9 tasks
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.

I'm adding this comment just to reset Github's "Show changes since your last review" pointer.

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.

Done! (Other than pending changes / requests.)

src/test/app/MPToken_test.cpp Outdated Show resolved Hide resolved
src/test/app/MPToken_test.cpp Outdated Show resolved Hide resolved
src/test/app/MPToken_test.cpp Show resolved Hide resolved
src/test/app/MPToken_test.cpp Outdated Show resolved Hide resolved
src/test/app/MPToken_test.cpp Outdated Show resolved Hide resolved
src/test/app/MPToken_test.cpp Show resolved Hide resolved
gregtatcam and others added 2 commits October 24, 2024 18:48
Co-authored-by: Ed Hennis <ed@ripple.com>
* Update MPT unit-test
src/xrpld/ledger/detail/View.cpp Show resolved Hide resolved
src/xrpld/ledger/detail/View.cpp Show resolved Hide resolved
include/xrpl/protocol/detail/sfields.macro Show resolved Hide resolved
include/xrpl/protocol/Protocol.h Show resolved Hide resolved
src/test/app/MPToken_test.cpp Outdated Show resolved Hide resolved
src/test/app/MPToken_test.cpp Show resolved Hide resolved
* rename

* space
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.

A couple of my comments remain unaddressed:

#5143 (comment)

#5143 (comment)

#5143 (review)

  • src/test/app/MPToken_test.cpp
  • src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h

gregtatcam and others added 2 commits October 29, 2024 12:37
* Remove asserts in tests
* Update copyright
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.

I think we're there.

@shawnxie999 shawnxie999 added the Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. label Oct 29, 2024
@ximinez ximinez merged commit 23c37fa into XRPLF:develop Oct 29, 2024
19 of 20 checks passed
This was referenced Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants