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 xrpl {
22
23TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
24 : transactionID_(txid), ledgerSeq_(ledger), nodes_(obj.getFieldArray(sfAffectedNodes))
25{
26 result_ = obj.getFieldU8(sfTransactionResult);
27 index_ = obj.getFieldU32(sfTransactionIndex);
28
29 auto affectedNodes = dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
30 XRPL_ASSERT(affectedNodes, "xrpl::TxMeta::TxMeta(STObject) : type cast succeeded");
31 if (affectedNodes != nullptr)
32 nodes_ = *affectedNodes;
33
35}
36
37TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, Blob const& vec)
38 : transactionID_(txid), ledgerSeq_(ledger), nodes_(sfAffectedNodes, 32)
39{
40 SerialIter sit(makeSlice(vec));
41
42 STObject const obj(sit, sfMetadata);
43 result_ = obj.getFieldU8(sfTransactionResult);
44 index_ = obj.getFieldU32(sfTransactionIndex);
45 nodes_ = obj.getFieldArray(sfAffectedNodes);
46
48}
49
51 : transactionID_(transactionID)
52 , ledgerSeq_(ledger)
53 , index_(std::numeric_limits<std::uint32_t>::max())
54 , result_(255)
55 , nodes_(sfAffectedNodes)
56{
57 nodes_.reserve(32);
58}
59
60void
61TxMeta::setAffectedNode(uint256 const& node, SField const& type, std::uint16_t nodeType)
62{
63 // make sure the node exists and force its type
64 for (auto& n : nodes_)
65 {
66 if (n.getFieldH256(sfLedgerIndex) == node)
67 {
68 n.setFName(type);
69 n.setFieldU16(sfLedgerEntryType, nodeType);
70 return;
71 }
72 }
73
75 STObject& obj = nodes_.back();
76
77 XRPL_ASSERT(obj.getFName() == type, "xrpl::TxMeta::setAffectedNode : field type match");
78 obj.setFieldH256(sfLedgerIndex, node);
79 obj.setFieldU16(sfLedgerEntryType, nodeType);
80}
81
82boost::container::flat_set<AccountID>
84{
85 boost::container::flat_set<AccountID> list;
86 list.reserve(10);
87
88 // This code should match the behavior of the JS method:
89 // Meta#getAffectedAccounts
90 for (auto const& node : nodes_)
91 {
92 int const index =
93 node.getFieldIndex((node.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);
94
95 if (index != -1)
96 {
97 auto const* inner = dynamic_cast<STObject const*>(&node.peekAtIndex(index));
98 XRPL_ASSERT(inner, "xrpl::getAffectedAccounts : STObject type cast succeeded");
99 if (inner != nullptr)
100 {
101 for (auto const& field : *inner)
102 {
103 if (auto sa = dynamic_cast<STAccount const*>(&field))
104 {
105 XRPL_ASSERT(!sa->isDefault(), "xrpl::getAffectedAccounts : account is set");
106 if (!sa->isDefault())
107 list.insert(sa->value());
108 }
109 else if (
110 (field.getFName() == sfLowLimit) || (field.getFName() == sfHighLimit) ||
111 (field.getFName() == sfTakerPays) || (field.getFName() == sfTakerGets))
112 {
113 auto lim = dynamic_cast<STAmount const*>(&field);
114 XRPL_ASSERT(
115 lim,
116 "xrpl::getAffectedAccounts : STAmount type cast "
117 "succeeded");
118
119 if (lim != nullptr)
120 {
121 auto issuer = lim->getIssuer();
122
123 if (issuer.isNonZero())
124 list.insert(issuer);
125 }
126 }
127 else if (field.getFName() == sfMPTokenIssuanceID)
128 {
129 auto mptID = dynamic_cast<STBitString<192> const*>(&field);
130 if (mptID != nullptr)
131 {
132 auto issuer = MPTIssue(mptID->value()).getIssuer();
133
134 if (issuer.isNonZero())
135 list.insert(issuer);
136 }
137 }
138 }
139 }
140 }
141 }
142
143 return list;
144}
145
148{
149 uint256 const index = node->key();
150 for (auto& n : nodes_)
151 {
152 if (n.getFieldH256(sfLedgerIndex) == index)
153 return n;
154 }
156 STObject& obj = nodes_.back();
157
158 XRPL_ASSERT(
159 obj.getFName() == type, "xrpl::TxMeta::getAffectedNode(SLE::ref) : field type match");
160 obj.setFieldH256(sfLedgerIndex, index);
161 obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
162
163 return obj;
164}
165
168{
169 for (auto& n : nodes_)
170 {
171 if (n.getFieldH256(sfLedgerIndex) == node)
172 return n;
173 }
174 // LCOV_EXCL_START
175 UNREACHABLE("xrpl::TxMeta::getAffectedNode(uint256) : node not found");
176 Throw<std::runtime_error>("Affected node not found");
177 return *(nodes_.begin()); // Silence compiler warning.
178 // LCOV_EXCL_STOP
179}
180
183{
184 STObject metaData(sfTransactionMetaData);
185 XRPL_ASSERT(result_ != 255, "xrpl::TxMeta::getAsObject : result_ is set");
186 metaData.setFieldU8(sfTransactionResult, result_);
187 metaData.setFieldU32(sfTransactionIndex, index_);
188 metaData.emplace_back(nodes_);
190 metaData.setFieldAmount(sfDeliveredAmount, *deliveredAmount_);
191
192 if (parentBatchID_.has_value())
193 metaData.setFieldH256(sfParentBatchID, *parentBatchID_);
194
195 return metaData;
196}
197
198void
200{
201 result_ = TERtoInt(result);
202 index_ = index;
203 XRPL_ASSERT(
204 (result_ == 0) || ((result_ > 100) && (result_ <= 255)),
205 "xrpl::TxMeta::addRaw : valid TER input");
206
207 nodes_.sort([](STObject const& o1, STObject const& o2) {
208 return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex);
209 });
210
211 getAsObject().add(s);
212}
213
214} // namespace xrpl
AccountID const & getIssuer() const
Definition MPTIssue.cpp:21
Identifies fields.
Definition SField.h:126
void push_back(STObject const &object)
Definition STArray.h:189
void reserve(std::size_t n)
Definition STArray.h:243
iterator begin()
Definition STArray.h:201
void sort(bool(*compare)(STObject const &o1, STObject const &o2))
Definition STArray.cpp:175
STObject & back()
Definition STArray.h:170
SField const & getFName() const
Definition STBase.cpp:125
void setFieldU8(SField const &field, unsigned char)
Definition STObject.cpp:723
unsigned char getFieldU8(SField const &field) const
Definition STObject.cpp:581
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:593
std::size_t emplace_back(Args &&... args)
Definition STObject.h:989
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:735
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:680
void setFieldAmount(SField const &field, STAmount const &)
Definition STObject.cpp:789
void add(Serializer &s) const override
Definition STObject.cpp:119
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:729
uint256 getFieldH256(SField const &field) const
Definition STObject.cpp:623
STBase const * peekAtPField(SField const &field) const
Definition STObject.cpp:429
void setFieldH256(SField const &field, uint256 const &)
Definition STObject.cpp:753
boost::container::flat_set< AccountID > getAffectedAccounts() const
Return a list of accounts affected by this transaction.
Definition TxMeta.cpp:83
void setAffectedNode(uint256 const &, SField const &type, std::uint16_t nodeType)
Definition TxMeta.cpp:61
void setAdditionalFields(STObject const &obj)
Definition TxMeta.h:80
std::optional< uint256 > parentBatchID_
Definition TxMeta.h:114
std::optional< STAmount > deliveredAmount_
Definition TxMeta.h:113
STArray nodes_
Definition TxMeta.h:116
int result_
Definition TxMeta.h:111
STObject & getAffectedNode(SLE::ref node, SField const &type)
Definition TxMeta.cpp:147
void addRaw(Serializer &, TER, std::uint32_t index)
Definition TxMeta.cpp:199
STObject getAsObject() const
Definition TxMeta.cpp:182
std::uint32_t index_
Definition TxMeta.h:110
TxMeta(uint256 const &transactionID, std::uint32_t ledger)
Definition TxMeta.cpp:50
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
@ transactionID
transaction plus signature to give transaction ID
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition TER.h:355
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:215
T has_value(T... args)