rippled
Loading...
Searching...
No Matches
TxMeta.cpp
1#include <xrpl/basics/Blob.h>
2#include <xrpl/basics/base_uint.h>
3#include <xrpl/basics/contract.h>
4#include <xrpl/beast/utility/instrumentation.h>
5#include <xrpl/protocol/AccountID.h>
6#include <xrpl/protocol/SField.h>
7#include <xrpl/protocol/STAccount.h>
8#include <xrpl/protocol/STAmount.h>
9#include <xrpl/protocol/STLedgerEntry.h>
10#include <xrpl/protocol/STObject.h>
11#include <xrpl/protocol/Serializer.h>
12#include <xrpl/protocol/TER.h>
13#include <xrpl/protocol/TxMeta.h>
14
15#include <boost/container/flat_set.hpp>
16
17#include <cstdint>
18#include <stdexcept>
19#include <string>
20
21namespace ripple {
22
23TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
24 : transactionID_(txid)
25 , ledgerSeq_(ledger)
26 , nodes_(obj.getFieldArray(sfAffectedNodes))
27{
28 result_ = obj.getFieldU8(sfTransactionResult);
29 index_ = obj.getFieldU32(sfTransactionIndex);
30
31 auto affectedNodes =
32 dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
33 XRPL_ASSERT(
34 affectedNodes,
35 "ripple::TxMeta::TxMeta(STObject) : type cast succeeded");
36 if (affectedNodes)
37 nodes_ = *affectedNodes;
38
40}
41
42TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, Blob const& vec)
43 : transactionID_(txid), ledgerSeq_(ledger), nodes_(sfAffectedNodes, 32)
44{
45 SerialIter sit(makeSlice(vec));
46
47 STObject obj(sit, sfMetadata);
48 result_ = obj.getFieldU8(sfTransactionResult);
49 index_ = obj.getFieldU32(sfTransactionIndex);
50 nodes_ = obj.getFieldArray(sfAffectedNodes);
51
53}
54
56 : transactionID_(transactionID)
57 , ledgerSeq_(ledger)
58 , index_(std::numeric_limits<std::uint32_t>::max())
59 , result_(255)
60 , nodes_(sfAffectedNodes)
61{
62 nodes_.reserve(32);
63}
64
65void
67 uint256 const& node,
68 SField const& type,
69 std::uint16_t nodeType)
70{
71 // make sure the node exists and force its type
72 for (auto& n : nodes_)
73 {
74 if (n.getFieldH256(sfLedgerIndex) == node)
75 {
76 n.setFName(type);
77 n.setFieldU16(sfLedgerEntryType, nodeType);
78 return;
79 }
80 }
81
83 STObject& obj = nodes_.back();
84
85 XRPL_ASSERT(
86 obj.getFName() == type,
87 "ripple::TxMeta::setAffectedNode : field type match");
88 obj.setFieldH256(sfLedgerIndex, node);
89 obj.setFieldU16(sfLedgerEntryType, nodeType);
90}
91
92boost::container::flat_set<AccountID>
94{
95 boost::container::flat_set<AccountID> list;
96 list.reserve(10);
97
98 // This code should match the behavior of the JS method:
99 // Meta#getAffectedAccounts
100 for (auto const& node : nodes_)
101 {
102 int index = node.getFieldIndex(
103 (node.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);
104
105 if (index != -1)
106 {
107 auto const* inner =
108 dynamic_cast<STObject const*>(&node.peekAtIndex(index));
109 XRPL_ASSERT(
110 inner,
111 "ripple::getAffectedAccounts : STObject type cast succeeded");
112 if (inner)
113 {
114 for (auto const& field : *inner)
115 {
116 if (auto sa = dynamic_cast<STAccount const*>(&field))
117 {
118 XRPL_ASSERT(
119 !sa->isDefault(),
120 "ripple::getAffectedAccounts : account is set");
121 if (!sa->isDefault())
122 list.insert(sa->value());
123 }
124 else if (
125 (field.getFName() == sfLowLimit) ||
126 (field.getFName() == sfHighLimit) ||
127 (field.getFName() == sfTakerPays) ||
128 (field.getFName() == sfTakerGets))
129 {
130 auto lim = dynamic_cast<STAmount const*>(&field);
131 XRPL_ASSERT(
132 lim,
133 "ripple::getAffectedAccounts : STAmount type cast "
134 "succeeded");
135
136 if (lim != nullptr)
137 {
138 auto issuer = lim->getIssuer();
139
140 if (issuer.isNonZero())
141 list.insert(issuer);
142 }
143 }
144 else if (field.getFName() == sfMPTokenIssuanceID)
145 {
146 auto mptID =
147 dynamic_cast<STBitString<192> const*>(&field);
148 if (mptID != nullptr)
149 {
150 auto issuer = MPTIssue(mptID->value()).getIssuer();
151
152 if (issuer.isNonZero())
153 list.insert(issuer);
154 }
155 }
156 }
157 }
158 }
159 }
160
161 return list;
162}
163
166{
167 uint256 index = node->key();
168 for (auto& n : nodes_)
169 {
170 if (n.getFieldH256(sfLedgerIndex) == index)
171 return n;
172 }
174 STObject& obj = nodes_.back();
175
176 XRPL_ASSERT(
177 obj.getFName() == type,
178 "ripple::TxMeta::getAffectedNode(SLE::ref) : field type match");
179 obj.setFieldH256(sfLedgerIndex, index);
180 obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
181
182 return obj;
183}
184
187{
188 for (auto& n : nodes_)
189 {
190 if (n.getFieldH256(sfLedgerIndex) == node)
191 return n;
192 }
193 // LCOV_EXCL_START
194 UNREACHABLE("ripple::TxMeta::getAffectedNode(uint256) : node not found");
195 Throw<std::runtime_error>("Affected node not found");
196 return *(nodes_.begin()); // Silence compiler warning.
197 // LCOV_EXCL_STOP
198}
199
202{
203 STObject metaData(sfTransactionMetaData);
204 XRPL_ASSERT(result_ != 255, "ripple::TxMeta::getAsObject : result_ is set");
205 metaData.setFieldU8(sfTransactionResult, result_);
206 metaData.setFieldU32(sfTransactionIndex, index_);
207 metaData.emplace_back(nodes_);
209 metaData.setFieldAmount(sfDeliveredAmount, *deliveredAmount_);
210
211 if (parentBatchID_.has_value())
212 metaData.setFieldH256(sfParentBatchID, *parentBatchID_);
213
214 return metaData;
215}
216
217void
219{
220 result_ = TERtoInt(result);
221 index_ = index;
222 XRPL_ASSERT(
223 (result_ == 0) || ((result_ > 100) && (result_ <= 255)),
224 "ripple::TxMeta::addRaw : valid TER input");
225
226 nodes_.sort([](STObject const& o1, STObject const& o2) {
227 return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex);
228 });
229
230 getAsObject().add(s);
231}
232
233} // namespace ripple
AccountID const & getIssuer() const
Definition MPTIssue.cpp:21
Identifies fields.
Definition SField.h:127
void sort(bool(*compare)(STObject const &o1, STObject const &o2))
Definition STArray.cpp:178
void reserve(std::size_t n)
Definition STArray.h:247
void push_back(STObject const &object)
Definition STArray.h:193
STObject & back()
Definition STArray.h:174
iterator begin()
Definition STArray.h:205
SField const & getFName() const
Definition STBase.cpp:124
unsigned char getFieldU8(SField const &field) const
Definition STObject.cpp:584
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:683
STBase const * peekAtPField(SField const &field) const
Definition STObject.cpp:438
void setFieldH256(SField const &field, uint256 const &)
Definition STObject.cpp:756
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:596
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:732
void setFieldU8(SField const &field, unsigned char)
Definition STObject.cpp:726
void add(Serializer &s) const override
Definition STObject.cpp:122
void setFieldAmount(SField const &field, STAmount const &)
Definition STObject.cpp:792
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:738
std::size_t emplace_back(Args &&... args)
Definition STObject.h:962
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:626
std::optional< uint256 > parentBatchID_
Definition TxMeta.h:115
std::optional< STAmount > deliveredAmount_
Definition TxMeta.h:114
std::uint32_t index_
Definition TxMeta.h:111
STArray nodes_
Definition TxMeta.h:117
TxMeta(uint256 const &transactionID, std::uint32_t ledger)
Definition TxMeta.cpp:55
void setAffectedNode(uint256 const &, SField const &type, std::uint16_t nodeType)
Definition TxMeta.cpp:66
STObject getAsObject() const
Definition TxMeta.cpp:201
void setAdditionalFields(STObject const &obj)
Definition TxMeta.h:81
boost::container::flat_set< AccountID > getAffectedAccounts() const
Return a list of accounts affected by this transaction.
Definition TxMeta.cpp:93
void addRaw(Serializer &, TER, std::uint32_t index)
Definition TxMeta.cpp:218
STObject & getAffectedNode(SLE::ref node, SField const &type)
Definition TxMeta.cpp:165
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:225
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition TER.h:356
@ transactionID
transaction plus signature to give transaction ID
STL namespace.
T has_value(T... args)