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