rippled
Loading...
Searching...
No Matches
TxMeta.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Log.h>
21#include <xrpl/basics/contract.h>
22#include <xrpl/json/to_string.h>
23#include <xrpl/protocol/STAccount.h>
24#include <xrpl/protocol/TxMeta.h>
25#include <string>
26
27namespace ripple {
28
29template <class T>
31 uint256 const& txid,
32 std::uint32_t ledger,
33 T const& data,
35 : mTransactionID(txid), mLedger(ledger), mNodes(sfAffectedNodes, 32)
36{
37 SerialIter sit(makeSlice(data));
38
39 STObject obj(sit, sfMetadata);
40 mResult = obj.getFieldU8(sfTransactionResult);
41 mIndex = obj.getFieldU32(sfTransactionIndex);
42 mNodes = *dynamic_cast<STArray*>(&obj.getField(sfAffectedNodes));
43
44 if (obj.isFieldPresent(sfDeliveredAmount))
45 setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));
46}
47
48TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
49 : mTransactionID(txid)
50 , mLedger(ledger)
51 , mNodes(obj.getFieldArray(sfAffectedNodes))
52{
53 mResult = obj.getFieldU8(sfTransactionResult);
54 mIndex = obj.getFieldU32(sfTransactionIndex);
55
56 auto affectedNodes =
57 dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
58 XRPL_ASSERT(
59 affectedNodes,
60 "ripple::TxMeta::TxMeta(STObject) : type cast succeeded");
61 if (affectedNodes)
62 mNodes = *affectedNodes;
63
64 if (obj.isFieldPresent(sfDeliveredAmount))
65 setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));
66}
67
68TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, Blob const& vec)
69 : TxMeta(txid, ledger, vec, CtorHelper())
70{
71}
72
74 uint256 const& txid,
75 std::uint32_t ledger,
76 std::string const& data)
77 : TxMeta(txid, ledger, data, CtorHelper())
78{
79}
80
82 : mTransactionID(transactionID)
83 , mLedger(ledger)
84 , mIndex(static_cast<std::uint32_t>(-1))
85 , mResult(255)
86 , mNodes(sfAffectedNodes)
87{
88 mNodes.reserve(32);
89}
90
91void
93 uint256 const& node,
94 SField const& type,
95 std::uint16_t nodeType)
96{
97 // make sure the node exists and force its type
98 for (auto& n : mNodes)
99 {
100 if (n.getFieldH256(sfLedgerIndex) == node)
101 {
102 n.setFName(type);
103 n.setFieldU16(sfLedgerEntryType, nodeType);
104 return;
105 }
106 }
107
109 STObject& obj = mNodes.back();
110
111 XRPL_ASSERT(
112 obj.getFName() == type,
113 "ripple::TxMeta::setAffectedNode : field type match");
114 obj.setFieldH256(sfLedgerIndex, node);
115 obj.setFieldU16(sfLedgerEntryType, nodeType);
116}
117
118boost::container::flat_set<AccountID>
120{
121 boost::container::flat_set<AccountID> list;
122 list.reserve(10);
123
124 // This code should match the behavior of the JS method:
125 // Meta#getAffectedAccounts
126 for (auto const& it : mNodes)
127 {
128 int index = it.getFieldIndex(
129 (it.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);
130
131 if (index != -1)
132 {
133 auto inner = dynamic_cast<STObject const*>(&it.peekAtIndex(index));
134 XRPL_ASSERT(
135 inner,
136 "ripple::getAffectedAccounts : STObject type cast succeeded");
137 if (inner)
138 {
139 for (auto const& field : *inner)
140 {
141 if (auto sa = dynamic_cast<STAccount const*>(&field))
142 {
143 XRPL_ASSERT(
144 !sa->isDefault(),
145 "ripple::getAffectedAccounts : account is set");
146 if (!sa->isDefault())
147 list.insert(sa->value());
148 }
149 else if (
150 (field.getFName() == sfLowLimit) ||
151 (field.getFName() == sfHighLimit) ||
152 (field.getFName() == sfTakerPays) ||
153 (field.getFName() == sfTakerGets))
154 {
155 auto lim = dynamic_cast<STAmount const*>(&field);
156 XRPL_ASSERT(
157 lim,
158 "ripple::getAffectedAccounts : STAmount type cast "
159 "succeeded");
160
161 if (lim != nullptr)
162 {
163 auto issuer = lim->getIssuer();
164
165 if (issuer.isNonZero())
166 list.insert(issuer);
167 }
168 }
169 }
170 }
171 }
172 }
173
174 return list;
175}
176
179{
180 uint256 index = node->key();
181 for (auto& n : mNodes)
182 {
183 if (n.getFieldH256(sfLedgerIndex) == index)
184 return n;
185 }
187 STObject& obj = mNodes.back();
188
189 XRPL_ASSERT(
190 obj.getFName() == type,
191 "ripple::TxMeta::getAffectedNode(SLE::ref) : field type match");
192 obj.setFieldH256(sfLedgerIndex, index);
193 obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
194
195 return obj;
196}
197
200{
201 for (auto& n : mNodes)
202 {
203 if (n.getFieldH256(sfLedgerIndex) == node)
204 return n;
205 }
206 UNREACHABLE("ripple::TxMeta::getAffectedNode(uint256) : node not found");
207 Throw<std::runtime_error>("Affected node not found");
208 return *(mNodes.begin()); // Silence compiler warning.
209}
210
213{
214 STObject metaData(sfTransactionMetaData);
215 XRPL_ASSERT(mResult != 255, "ripple::TxMeta::getAsObject : result is set");
216 metaData.setFieldU8(sfTransactionResult, mResult);
217 metaData.setFieldU32(sfTransactionIndex, mIndex);
218 metaData.emplace_back(mNodes);
219 if (hasDeliveredAmount())
220 metaData.setFieldAmount(sfDeliveredAmount, getDeliveredAmount());
221 return metaData;
222}
223
224void
226{
227 mResult = TERtoInt(result);
228 mIndex = index;
229 XRPL_ASSERT(
230 (mResult == 0) || ((mResult > 100) && (mResult <= 255)),
231 "ripple::TxMeta::addRaw : valid TER input");
232
233 mNodes.sort([](STObject const& o1, STObject const& o2) {
234 return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex);
235 });
236
237 getAsObject().add(s);
238}
239
240} // namespace ripple
Identifies fields.
Definition: SField.h:144
void sort(bool(*compare)(const STObject &o1, const STObject &o2))
Definition: STArray.cpp:188
void reserve(std::size_t n)
Definition: STArray.h:266
void push_back(STObject const &object)
Definition: STArray.h:212
STObject & back()
Definition: STArray.h:193
iterator begin()
Definition: STArray.h:224
SField const & getFName() const
Definition: STBase.cpp:134
unsigned char getFieldU8(SField const &field) const
Definition: STObject.cpp:573
const STBase * peekAtPField(SField const &field) const
Definition: STObject.cpp:427
void setFieldH256(SField const &field, uint256 const &)
Definition: STObject.cpp:729
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:585
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:705
void setFieldU8(SField const &field, unsigned char)
Definition: STObject.cpp:699
void add(Serializer &s) const override
Definition: STObject.cpp:111
void setFieldAmount(SField const &field, STAmount const &)
Definition: STObject.cpp:759
STBase & getField(SField const &field)
Definition: STObject.cpp:410
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:635
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:454
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:711
std::size_t emplace_back(Args &&... args)
Definition: STObject.h:959
uint256 getFieldH256(SField const &field) const
Definition: STObject.cpp:615
TxMeta(uint256 const &txID, std::uint32_t ledger, T const &data, CtorHelper)
Definition: TxMeta.cpp:30
STArray mNodes
Definition: TxMeta.h:139
bool hasDeliveredAmount() const
Definition: TxMeta.h:126
STAmount getDeliveredAmount() const
Definition: TxMeta.h:117
void setAffectedNode(uint256 const &, SField const &type, std::uint16_t nodeType)
Definition: TxMeta.cpp:92
STObject getAsObject() const
Definition: TxMeta.cpp:212
void setDeliveredAmount(STAmount const &delivered)
Definition: TxMeta.h:111
std::uint32_t mIndex
Definition: TxMeta.h:134
boost::container::flat_set< AccountID > getAffectedAccounts() const
Return a list of accounts affected by this transaction.
Definition: TxMeta.cpp:119
void addRaw(Serializer &, TER, std::uint32_t index)
Definition: TxMeta.cpp:225
STObject & getAffectedNode(SLE::ref node, SField const &type)
Definition: TxMeta.cpp:178
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
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:243
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition: TER.h:353
@ transactionID
transaction plus signature to give transaction ID
STL namespace.