mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 06:25:51 +00:00
Add single asset vault (XLS-65d) (#5224)
- Specification: XRPLF/XRPL-Standards#239 - Amendment: `SingleAssetVault` - Implements a vault feature used to store a fungible asset (XRP, IOU, or MPT, but not NFT) and to receive shares in the vault (an MPT) in exchange. - A vault can be private or public. - A private vault can use permissioned domains, subject to the `PermissionedDomains` amendment. - Shares can be exchanged back into asset with `VaultWithdraw`. - Permissions on the asset in the vault are transitively applied on shares in the vault. - Issuer of the asset in the vault can clawback with `VaultClawback`. - Extended `MPTokenIssuance` with `DomainID`, used by the permissioned domain on the vault shares. Co-authored-by: John Freeman <jfreeman08@gmail.com>
This commit is contained in:
@@ -18,12 +18,16 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/beast/core/LexicalCast.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
@@ -115,4 +119,100 @@ operator<<(std::ostream& out, STNumber const& rhs)
|
||||
return out << rhs.getText();
|
||||
}
|
||||
|
||||
NumberParts
|
||||
partsFromString(std::string const& number)
|
||||
{
|
||||
static boost::regex const reNumber(
|
||||
"^" // the beginning of the string
|
||||
"([-+]?)" // (optional) + or - character
|
||||
"(0|[1-9][0-9]*)" // a number (no leading zeroes, unless 0)
|
||||
"(\\.([0-9]+))?" // (optional) period followed by any number
|
||||
"([eE]([+-]?)([0-9]+))?" // (optional) E, optional + or -, any number
|
||||
"$",
|
||||
boost::regex_constants::optimize);
|
||||
|
||||
boost::smatch match;
|
||||
|
||||
if (!boost::regex_match(number, match, reNumber))
|
||||
Throw<std::runtime_error>("'" + number + "' is not a number");
|
||||
|
||||
// Match fields:
|
||||
// 0 = whole input
|
||||
// 1 = sign
|
||||
// 2 = integer portion
|
||||
// 3 = whole fraction (with '.')
|
||||
// 4 = fraction (without '.')
|
||||
// 5 = whole exponent (with 'e')
|
||||
// 6 = exponent sign
|
||||
// 7 = exponent number
|
||||
|
||||
bool negative = (match[1].matched && (match[1] == "-"));
|
||||
|
||||
std::uint64_t mantissa;
|
||||
int exponent;
|
||||
|
||||
if (!match[4].matched) // integer only
|
||||
{
|
||||
mantissa = boost::lexical_cast<std::uint64_t>(std::string(match[2]));
|
||||
exponent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// integer and fraction
|
||||
mantissa = boost::lexical_cast<std::uint64_t>(match[2] + match[4]);
|
||||
exponent = -(match[4].length());
|
||||
}
|
||||
|
||||
if (match[5].matched)
|
||||
{
|
||||
// we have an exponent
|
||||
if (match[6].matched && (match[6] == "-"))
|
||||
exponent -= boost::lexical_cast<int>(std::string(match[7]));
|
||||
else
|
||||
exponent += boost::lexical_cast<int>(std::string(match[7]));
|
||||
}
|
||||
|
||||
return {mantissa, exponent, negative};
|
||||
}
|
||||
|
||||
STNumber
|
||||
numberFromJson(SField const& field, Json::Value const& value)
|
||||
{
|
||||
NumberParts parts;
|
||||
|
||||
if (value.isInt())
|
||||
{
|
||||
if (value.asInt() >= 0)
|
||||
{
|
||||
parts.mantissa = value.asInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
parts.mantissa = -value.asInt();
|
||||
parts.negative = true;
|
||||
}
|
||||
}
|
||||
else if (value.isUInt())
|
||||
{
|
||||
parts.mantissa = value.asUInt();
|
||||
}
|
||||
else if (value.isString())
|
||||
{
|
||||
parts = partsFromString(value.asString());
|
||||
// Only strings can represent out-of-range values.
|
||||
if (parts.mantissa > std::numeric_limits<std::int64_t>::max())
|
||||
Throw<std::range_error>("too high");
|
||||
}
|
||||
else
|
||||
{
|
||||
Throw<std::runtime_error>("not a number");
|
||||
}
|
||||
|
||||
std::int64_t mantissa = parts.mantissa;
|
||||
if (parts.negative)
|
||||
mantissa = -mantissa;
|
||||
|
||||
return STNumber{field, Number{mantissa, parts.exponent}};
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
Reference in New Issue
Block a user