Add a new serialized type: STNumber (#5121)

`STNumber` lets objects and transactions contain multiple fields for
quantities of XRP, IOU, or MPT without duplicating information about the
"issue" (represented by `STIssue`). It is a straightforward serialization of
the `Number` type that uniformly represents those quantities.

---------

Co-authored-by: John Freeman <jfreeman08@gmail.com>
Co-authored-by: Howard Hinnant <howard.hinnant@gmail.com>
This commit is contained in:
Elliot Lee
2024-11-25 12:12:35 -08:00
parent 0ec17b6026
commit f419c18056
15 changed files with 470 additions and 58 deletions

View File

@@ -21,6 +21,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/digest.h>
#include <cstdint>
#include <type_traits>
namespace ripple {
@@ -34,17 +35,6 @@ Serializer::add16(std::uint16_t i)
return ret;
}
int
Serializer::add32(std::uint32_t i)
{
int ret = mData.size();
mData.push_back(static_cast<unsigned char>(i >> 24));
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
mData.push_back(static_cast<unsigned char>(i & 0xff));
return ret;
}
int
Serializer::add32(HashPrefix p)
{
@@ -56,21 +46,6 @@ Serializer::add32(HashPrefix p)
return add32(safe_cast<std::uint32_t>(p));
}
int
Serializer::add64(std::uint64_t i)
{
int ret = mData.size();
mData.push_back(static_cast<unsigned char>(i >> 56));
mData.push_back(static_cast<unsigned char>((i >> 48) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 40) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 32) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
mData.push_back(static_cast<unsigned char>(i & 0xff));
return ret;
}
template <>
int
Serializer::addInteger(unsigned char i)
@@ -410,6 +385,30 @@ SerialIter::get64()
(std::uint64_t(t[6]) << 8) + std::uint64_t(t[7]);
}
std::int32_t
SerialIter::geti32()
{
if (remain_ < 4)
Throw<std::runtime_error>("invalid SerialIter geti32");
auto t = p_;
p_ += 4;
used_ += 4;
remain_ -= 4;
return boost::endian::load_big_s32(t);
}
std::int64_t
SerialIter::geti64()
{
if (remain_ < 8)
Throw<std::runtime_error>("invalid SerialIter geti64");
auto t = p_;
p_ += 8;
used_ += 8;
remain_ -= 8;
return boost::endian::load_big_s64(t);
}
void
SerialIter::getFieldID(int& type, int& name)
{