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

Amendment:
- MPTokensV1

New Transactions:
- MPTokenIssuanceCreate
- MPTokenIssuanceDestroy
- MPTokenIssuanceSet
- MPTokenAuthorize

Modified Transactions:
- Payment
- Clawback

New Objects:
- MPTokenIssuance
- MPToken

API updates:
- ledger_entry
- account_objects
- ledger_data

Other:
- Add += and -= operators to ValueProxy

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>
Co-authored-by: Ed Hennis <ed@ripple.com>
Co-authored-by: John Freeman <jfreeman08@gmail.com>
This commit is contained in:
Gregory Tsipenyuk
2024-10-29 15:19:28 -04:00
committed by GitHub
parent 63209c2646
commit 23c37fa506
92 changed files with 7115 additions and 1088 deletions

View File

@@ -29,7 +29,7 @@ public:
// Create a raw, non-integral amount from mantissa and exponent
STAmount static raw(std::uint64_t mantissa, int exponent)
{
return STAmount({Currency(3), AccountID(3)}, mantissa, exponent);
return STAmount(Issue{Currency(3), AccountID(3)}, mantissa, exponent);
}
template <class Integer>

View File

@@ -62,7 +62,6 @@ public:
amount.issue(),
mantissa,
amount.exponent(),
amount.native(),
amount.negative(),
STAmount::unchecked{}};
}
@@ -82,7 +81,6 @@ public:
amount.issue(),
mantissa,
amount.exponent(),
amount.native(),
amount.negative(),
STAmount::unchecked{}};
}

View File

@@ -394,6 +394,7 @@ public:
auto const& sf1Outer = sfSequence;
auto const& sf2Outer = sfExpiration;
auto const& sf3Outer = sfQualityIn;
auto const& sf4Outer = sfAmount;
auto const& sf4 = sfSignature;
auto const& sf5 = sfPublicKey;
@@ -425,6 +426,7 @@ public:
{sf1Outer, soeREQUIRED},
{sf2Outer, soeOPTIONAL},
{sf3Outer, soeDEFAULT},
{sf4Outer, soeOPTIONAL},
{sf4, soeOPTIONAL},
{sf5, soeDEFAULT},
};
@@ -492,6 +494,16 @@ public:
BEAST_EXPECT(st[sf1Outer] == 4);
BEAST_EXPECT(st[sf2Outer] == 4);
BEAST_EXPECT(st[sf2Outer] == st[sf1Outer]);
st[sf1Outer] += 1;
BEAST_EXPECT(st[sf1Outer] == 5);
st[sf4Outer] = STAmount{1};
BEAST_EXPECT(st[sf4Outer] == STAmount{1});
st[sf4Outer] += STAmount{1};
BEAST_EXPECT(st[sf4Outer] == STAmount{2});
st[sf1Outer] -= 1;
BEAST_EXPECT(st[sf1Outer] == 4);
st[sf4Outer] -= STAmount{1};
BEAST_EXPECT(st[sf4Outer] == STAmount{1});
}
// Write templated object
@@ -540,6 +552,16 @@ public:
BEAST_EXPECT(st[sf3Outer] == 0);
BEAST_EXPECT(*st[~sf3Outer] == 0);
BEAST_EXPECT(!!st[~sf3Outer]);
st[sf1Outer] += 1;
BEAST_EXPECT(st[sf1Outer] == 1);
st[sf4Outer] = STAmount{1};
BEAST_EXPECT(st[sf4Outer] == STAmount{1});
st[sf4Outer] += STAmount{1};
BEAST_EXPECT(st[sf4Outer] == STAmount{2});
st[sf1Outer] -= 1;
BEAST_EXPECT(st[sf1Outer] == 0);
st[sf4Outer] -= STAmount{1};
BEAST_EXPECT(st[sf4Outer] == STAmount{1});
}
// coercion operator to std::optional

View File

@@ -1361,6 +1361,31 @@ public:
0x10, 0x00, 0x73, 0x00, 0x81, 0x14, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0xe5, 0xfe};
constexpr unsigned char payload4[] = {
0x12, 0x00, 0x65, 0x24, 0x00, 0x00, 0x00, 0x00, 0x20, 0x1e, 0x00,
0x4f, 0x00, 0x00, 0x20, 0x1f, 0x03, 0xf6, 0x00, 0x00, 0x20, 0x20,
0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x68, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
0x73, 0x00, 0x81, 0x14, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x65, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe5, 0xfe, 0xf3, 0xe7, 0xe5, 0x65, 0x24, 0x00, 0x00, 0x00, 0x00,
0x20, 0x1e, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x20, 0x1f, 0x03, 0xf6,
0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x59,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x12, 0x00, 0x65, 0x24, 0x00, 0x00, 0x00,
0x00, 0x20, 0x1e, 0x00, 0x4f, 0x00, 0x00, 0x20, 0x1f, 0x03, 0xf6,
0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x35, 0x24, 0x59,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x00, 0x54, 0x72, 0x61, 0x6e, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x24, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xe5, 0xfe, 0xf3, 0xe7, 0xe5, 0x65, 0x24,
0x00, 0x00, 0x00, 0x00, 0x20, 0x1e, 0x00, 0x6f, 0x00, 0x00, 0x20,
0xf6, 0x00, 0x00, 0x03, 0x1f, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
0x35, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x73, 0x00, 0x81, 0x14,
0x00, 0x10, 0x00, 0x73, 0x00, 0x81, 0x14, 0x00, 0x10, 0x00, 0x00,
0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0xe5, 0xfe};
// Construct an STObject with 11 levels of object nesting so the
// maximum nesting level exception is thrown.
{
@@ -1574,6 +1599,18 @@ public:
fail("An exception should have been thrown");
}
catch (std::exception const& ex)
{
BEAST_EXPECT(
strcmp(ex.what(), "gFID: uncommon name out of range 0") == 0);
}
try
{
ripple::SerialIter sit{payload4};
auto stx = std::make_shared<ripple::STTx const>(sit);
fail("An exception should have been thrown");
}
catch (std::exception const& ex)
{
BEAST_EXPECT(strcmp(ex.what(), "Unknown field") == 0);
}