Skip to content

Commit

Permalink
Chang UINT64 amounts to base 10 display (#35)
Browse files Browse the repository at this point in the history
* MPT amount base 10

* add assert

* revert formatting

* test

* add test for maxamt

* clang

* parse as base 10 for all mpt amounts
  • Loading branch information
shawnxie999 authored Sep 19, 2024
1 parent 6364440 commit 921e978
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 27 deletions.
24 changes: 19 additions & 5 deletions src/libxrpl/protocol/STInteger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,25 @@ STUInt64::getText() const
template <>
Json::Value STUInt64::getJson(JsonOptions) const
{
std::string str(16, 0);
auto ret = std::to_chars(str.data(), str.data() + str.size(), value_, 16);
assert(ret.ec == std::errc());
str.resize(std::distance(str.data(), ret.ptr));
return str;
auto convertToString = [](uint64_t const value, int const base) {
assert(base == 10 || base == 16);
std::string str(
base == 10 ? 20 : 16, 0); // Allocate space depending on base
auto ret =
std::to_chars(str.data(), str.data() + str.size(), value, base);
assert(ret.ec == std::errc());
str.resize(std::distance(str.data(), ret.ptr));
return str;
};

if (auto const& fName = getFName(); fName == sfMaximumAmount ||
fName == sfOutstandingAmount || fName == sfLockedAmount ||
fName == sfMPTAmount)
{
return convertToString(value_, 10); // Convert to base 10
}

return convertToString(value_, 16); // Convert to base 16
}

} // namespace ripple
10 changes: 9 additions & 1 deletion src/libxrpl/protocol/STParsedJSON.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,16 @@ parseLeaf(

std::uint64_t val;

bool const useBase10 = field == sfMaximumAmount ||
field == sfOutstandingAmount ||
field == sfLockedAmount || field == sfMPTAmount;

// if the field is amount, serialize as base 10
auto [p, ec] = std::from_chars(
str.data(), str.data() + str.size(), val, 16);
str.data(),
str.data() + str.size(),
val,
useBase10 ? 10 : 16);

if (ec != std::errc() || (p != str.data() + str.size()))
Throw<std::invalid_argument>("invalid data");
Expand Down
30 changes: 22 additions & 8 deletions src/test/app/MPToken_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ class MPToken_test : public beast::unit_test::suite

// tries to set a txfee while not enabling in the flag
mptAlice.create(
{.maxAmt = 100,
{.maxAmt = "100",
.assetScale = 0,
.transferFee = 1,
.metadata = "test",
.err = temMALFORMED});

// tries to set a txfee greater than max
mptAlice.create(
{.maxAmt = 100,
{.maxAmt = "100",
.assetScale = 0,
.transferFee = maxTransferFee + 1,
.metadata = "test",
Expand All @@ -70,31 +70,37 @@ class MPToken_test : public beast::unit_test::suite

// tries to set a txfee while not enabling transfer
mptAlice.create(
{.maxAmt = 100,
{.maxAmt = "100",
.assetScale = 0,
.transferFee = maxTransferFee,
.metadata = "test",
.err = temMALFORMED});

// empty metadata returns error
mptAlice.create(
{.maxAmt = 100,
{.maxAmt = "100",
.assetScale = 0,
.transferFee = 0,
.metadata = "",
.err = temMALFORMED});

// MaximumAmout of 0 returns error
mptAlice.create(
{.maxAmt = 0,
{.maxAmt = "0",
.assetScale = 1,
.transferFee = 1,
.metadata = "test",
.err = temMALFORMED});

// MaximumAmount larger than 63 bit returns error
mptAlice.create(
{.maxAmt = 0xFFFFFFFFFFFFFFF0ull,
{.maxAmt = "18446744073709551600", // FFFFFFFFFFFFFFF0
.assetScale = 0,
.transferFee = 0,
.metadata = "test",
.err = temMALFORMED});
mptAlice.create(
{.maxAmt = "9223372036854775808", // 8000000000000000
.assetScale = 0,
.transferFee = 0,
.metadata = "test",
Expand All @@ -116,13 +122,21 @@ class MPToken_test : public beast::unit_test::suite
Env env{*this, features};
MPTTester mptAlice(env, alice);
mptAlice.create(
{.maxAmt = 0x7FFFFFFFFFFFFFFF,
{.maxAmt = "9223372036854775807", // 7FFFFFFFFFFFFFFF
.assetScale = 1,
.transferFee = 10,
.metadata = "123",
.ownerCount = 1,
.flags = tfMPTCanLock | tfMPTRequireAuth | tfMPTCanEscrow |
tfMPTCanTrade | tfMPTCanTransfer | tfMPTCanClawback});

// Get the hash for the most recent transaction.
std::string const txHash{
env.tx()->getJson(JsonOptions::none)[jss::hash].asString()};

Json::Value const result = env.rpc("tx", txHash)[jss::result];
BEAST_EXPECT(
result[sfMaximumAmount.getJsonName()] == "9223372036854775807");
}
}

Expand Down Expand Up @@ -781,7 +795,7 @@ class MPToken_test : public beast::unit_test::suite
MPTTester mptAlice(env, alice, {.holders = {&bob}});

mptAlice.create(
{.maxAmt = 100,
{.maxAmt = "100",
.ownerCount = 1,
.holderCount = 0,
.flags = tfMPTCanTransfer});
Expand Down
13 changes: 1 addition & 12 deletions src/test/jtx/impl/mpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,6 @@ namespace ripple {
namespace test {
namespace jtx {

static std::array<std::uint8_t, 8>
uint64ToByteArray(std::uint64_t value)
{
value = boost::endian::native_to_big(value);
std::array<std::uint8_t, 8> result;
std::memcpy(result.data(), &value, sizeof(value));
return result;
}

void
mptflags::operator()(Env& env) const
{
Expand Down Expand Up @@ -105,10 +96,8 @@ MPTTester::create(const MPTCreate& arg)
jv[sfTransferFee.jsonName] = *arg.transferFee;
if (arg.metadata)
jv[sfMPTokenMetadata.jsonName] = strHex(*arg.metadata);

// convert maxAmt to hex string, since json doesn't accept 64-bit int
if (arg.maxAmt)
jv[sfMaximumAmount.jsonName] = strHex(uint64ToByteArray(*arg.maxAmt));
jv[sfMaximumAmount.jsonName] = *arg.maxAmt;
if (submit(arg, jv) != tesSUCCESS)
{
// Verify issuance doesn't exist
Expand Down
2 changes: 1 addition & 1 deletion src/test/jtx/mpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ struct MPTConstr

struct MPTCreate
{
std::optional<std::int64_t> maxAmt = std::nullopt;
std::optional<std::string> maxAmt = std::nullopt;
std::optional<std::uint8_t> assetScale = std::nullopt;
std::optional<std::uint16_t> transferFee = std::nullopt;
std::optional<std::string> metadata = std::nullopt;
Expand Down

0 comments on commit 921e978

Please sign in to comment.