xrpld
Loading...
Searching...
No Matches
STIssue.cpp
1#include <xrpl/protocol/STIssue.h>
2
3#include <xrpl/basics/contract.h>
4#include <xrpl/json/json_value.h>
5#include <xrpl/protocol/AccountID.h>
6#include <xrpl/protocol/Asset.h>
7#include <xrpl/protocol/Issue.h>
8#include <xrpl/protocol/MPTIssue.h>
9#include <xrpl/protocol/SField.h>
10#include <xrpl/protocol/STBase.h>
11#include <xrpl/protocol/Serializer.h>
12#include <xrpl/protocol/UintTypes.h>
13
14#include <boost/endian/conversion.hpp>
15
16#include <cstddef>
17#include <cstdint>
18#include <cstring>
19#include <stdexcept>
20#include <string>
21#include <utility>
22
23namespace xrpl {
24
25STIssue::STIssue(SField const& name) : STBase{name}
26{
27}
28
29STIssue::STIssue(SerialIter& sit, SField const& name) : STBase{name}
30{
31 auto const currencyOrAccount = sit.get160();
32
33 if (isXRP(Currency::fromRaw(currencyOrAccount)))
34 {
35 asset_ = xrpIssue();
36 }
37 // Check if MPT
38 else
39 {
40 // MPT is serialized as:
41 // - 160 bits MPT issuer account
42 // - 160 bits black hole account
43 // - 32 bits sequence
44 AccountID const account = AccountID::fromRaw(sit.get160());
45 // MPT
46 if (noAccount() == account)
47 {
48 MPTID mptID;
49 std::uint32_t sequence = sit.get32();
50 // MPTID stores the sequence in canonical big-endian bytes. STIssue
51 // ledger bytes are the legacy LE-host encoding, so convert the
52 // native get32() value to LE bytes before copying into the MPTID.
53 sequence = boost::endian::native_to_little(sequence);
54 static_assert(MPTID::size() == sizeof(sequence) + sizeof(currencyOrAccount));
55 memcpy(mptID.data(), &sequence, sizeof(sequence));
56 memcpy(
57 mptID.data() + sizeof(sequence),
58 currencyOrAccount.data(),
59 sizeof(currencyOrAccount));
60 MPTIssue const issue{mptID};
61 asset_ = issue;
62 }
63 else
64 {
65 Issue issue;
66 issue.currency = currencyOrAccount;
67 issue.account = account;
68 if (!isConsistent(issue))
69 Throw<std::runtime_error>("invalid issue: currency and account native mismatch");
70 asset_ = issue;
71 }
72 }
73}
74
77{
78 return STI_ISSUE;
79}
80
83{
84 return asset_.getText();
85}
86
89{
90 json::Value jv;
91 asset_.setJson(jv);
92 return jv;
93}
94
95void
97{
98 asset_.visit(
99 [&](Issue const& issue) {
100 s.addBitString(issue.currency);
101 if (!isXRP(issue.currency))
102 s.addBitString(issue.account);
103 },
104 [&](MPTIssue const& issue) {
105 s.addBitString(issue.getIssuer());
107 std::uint32_t sequence = 0;
108 memcpy(&sequence, issue.getMptID().data(), sizeof(sequence));
109 // The MPTID bytes are canonical big-endian. Interpret those bytes
110 // as the legacy LE-host value so add32() writes the preserved
111 // STIssue wire bytes on every host endian.
112 sequence = boost::endian::little_to_native(sequence);
113 s.add32(sequence);
114 });
115}
116
117bool
119{
120 auto const* v = dynamic_cast<STIssue const*>(&t);
121 return (v != nullptr) && (*v == *this);
122}
123
124bool
126{
127 return asset_.visit(
128 [](Issue const& issue) { return issue == xrpIssue(); },
129 [](MPTIssue const&) { return false; });
130}
131
132STBase*
133STIssue::copy(std::size_t n, void* buf) const
134{
135 return emplace(n, buf, *this);
136}
137
138STBase*
140{
141 return emplace(n, buf, std::move(*this));
142}
143
145issueFromJson(SField const& name, json::Value const& v)
146{
147 return STIssue{name, assetFromJson(v)};
148}
149
150} // namespace xrpl
Represents a JSON value.
Definition json_value.h:117
static BaseUInt fromRaw(Container const &c)
Definition base_uint.h:302
pointer data()
Definition base_uint.h:117
static constexpr std::size_t size()
Definition base_uint.h:548
A currency issued by an account.
Definition Issue.h:18
Currency currency
Definition Issue.h:20
AccountID account
Definition Issue.h:21
AccountID const & getIssuer() const
Definition Issue.h:30
Identifies fields.
Definition SField.h:132
A type which can be exported to a well known binary format.
Definition STBase.h:129
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition STBase.h:226
void add(Serializer &s) const override
Definition STIssue.cpp:96
bool isDefault() const override
Definition STIssue.cpp:125
STIssue()=default
Asset asset_
Definition STIssue.h:23
SerializedTypeID getSType() const override
Definition STIssue.cpp:76
STBase * copy(std::size_t n, void *buf) const override
Definition STIssue.cpp:133
json::Value getJson(JsonOptions) const override
Definition STIssue.cpp:88
std::string getText() const override
Definition STIssue.cpp:82
STBase * move(std::size_t n, void *buf) override
Definition STIssue.cpp:139
bool isEquivalent(STBase const &t) const override
Definition STIssue.cpp:118
uint160 get160()
Definition Serializer.h:373
int addBitString(BaseUInt< Bits, Tag > const &v)
Definition Serializer.h:106
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:108
Issue issueFromJson(json::Value const &v)
Definition Issue.cpp:89
bool isXRP(AccountID const &c)
Definition AccountID.h:84
SerializedTypeID
Definition SField.h:94
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
Definition UintTypes.h:54
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
AccountID const & noAccount()
A placeholder for empty accounts.
bool isConsistent(Asset const &asset)
Definition Asset.h:323
Asset assetFromJson(json::Value const &jv)
Definition Asset.cpp:59
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
Note, should be treated as flags that can be | and &.
Definition STBase.h:22