mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-09 11:46:49 +00:00
Compare commits
5 Commits
tapanito/p
...
gregtatcam
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
440e7e3ebc | ||
|
|
69ed8b6970 | ||
|
|
4451fa33f6 | ||
|
|
a1d33e98e5 | ||
|
|
2f015e9c65 |
@@ -11,6 +11,8 @@
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <boost/endian/conversion.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -45,6 +47,10 @@ STIssue::STIssue(SerialIter& sit, SField const& name) : STBase{name}
|
||||
{
|
||||
MPTID mptID;
|
||||
std::uint32_t sequence = sit.get32();
|
||||
// MPTID stores the sequence in canonical big-endian bytes. STIssue
|
||||
// ledger bytes are the legacy LE-host encoding, so convert the
|
||||
// native get32() value to LE bytes before copying into the MPTID.
|
||||
sequence = boost::endian::native_to_little(sequence);
|
||||
static_assert(MPTID::size() == sizeof(sequence) + sizeof(currencyOrAccount));
|
||||
memcpy(mptID.data(), &sequence, sizeof(sequence));
|
||||
memcpy(
|
||||
@@ -100,6 +106,10 @@ STIssue::add(Serializer& s) const
|
||||
s.addBitString(noAccount());
|
||||
std::uint32_t sequence = 0;
|
||||
memcpy(&sequence, issue.getMptID().data(), sizeof(sequence));
|
||||
// The MPTID bytes are canonical big-endian. Interpret those bytes
|
||||
// as the legacy LE-host value so add32() writes the preserved
|
||||
// STIssue wire bytes on every host endian.
|
||||
sequence = boost::endian::little_to_native(sequence);
|
||||
s.add32(sequence);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,14 +3,20 @@
|
||||
#include <test/jtx/amount.h> // IWYU pragma: keep
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/beast/unit_test/suite.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/MPTIssue.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STIssue.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl::test {
|
||||
|
||||
class STIssue_test : public beast::unit_test::Suite
|
||||
@@ -137,12 +143,61 @@ public:
|
||||
"000000000000000000000000000000000000000000000002");
|
||||
}
|
||||
|
||||
void
|
||||
testMPTSerialization()
|
||||
{
|
||||
testcase("MPT serialization");
|
||||
using namespace jtx;
|
||||
Account const alice{"alice"};
|
||||
|
||||
// 0x01020304 pins canonical MPTID bytes 01 02 03 04 and
|
||||
// preserved STIssue wire bytes 04 03 02 01 on BE and LE.
|
||||
std::array<std::uint32_t, 3> const vectors = {0x00000001, 0x01020304, 0xa1b2c3d4};
|
||||
|
||||
for (auto const vector : vectors)
|
||||
{
|
||||
MPTID const mptID = makeMptID(vector, alice);
|
||||
MPTIssue const issue{mptID};
|
||||
STIssue const stIssue(sfAsset, Asset{issue});
|
||||
|
||||
Serializer actual;
|
||||
stIssue.add(actual);
|
||||
|
||||
// STIssue preserves the existing little-endian validator ledger bytes.
|
||||
Serializer expected;
|
||||
expected.addBitString(alice.id());
|
||||
expected.addBitString(noAccount());
|
||||
{
|
||||
std::array<unsigned char, 4> const bytes{
|
||||
static_cast<unsigned char>(vector),
|
||||
static_cast<unsigned char>(vector >> 8),
|
||||
static_cast<unsigned char>(vector >> 16),
|
||||
static_cast<unsigned char>(vector >> 24)};
|
||||
expected.addRaw(bytes.data(), bytes.size());
|
||||
}
|
||||
|
||||
BEAST_EXPECTS(strHex(actual) == strHex(expected), strHex(actual));
|
||||
|
||||
// Decoding the preserved wire format must recover the canonical MPTID.
|
||||
SerialIter iter(expected.slice());
|
||||
STIssue const decoded(iter, sfAsset);
|
||||
BEAST_EXPECT(decoded.holds<MPTIssue>());
|
||||
BEAST_EXPECT(decoded.value().get<MPTIssue>().getMptID() == mptID);
|
||||
|
||||
// A decoded ledger value must serialize back to the same bytes.
|
||||
Serializer roundTrip;
|
||||
decoded.add(roundTrip);
|
||||
BEAST_EXPECTS(strHex(roundTrip) == strHex(expected), strHex(roundTrip));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
// compliments other unit tests to ensure complete coverage
|
||||
testConstructor();
|
||||
testCompare();
|
||||
testMPTSerialization();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user