rippled
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 <ripple/basics/Log.h>
21 #include <ripple/basics/contract.h>
22 #include <ripple/json/to_string.h>
23 #include <ripple/protocol/STAccount.h>
24 #include <ripple/protocol/TxMeta.h>
25 #include <string>
26 
27 namespace ripple {
28 
29 template <class T>
31  uint256 const& txid,
32  std::uint32_t ledger,
33  T const& data,
34  CtorHelper)
35  : mTransactionID(txid), mLedger(ledger), mNodes(sfAffectedNodes, 32)
36 {
37  SerialIter sit(makeSlice(data));
38 
39  STObject obj(sit, sfMetadata);
42  mNodes = *dynamic_cast<STArray*>(&obj.getField(sfAffectedNodes));
43 
46 }
47 
48 TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
49  : mTransactionID(txid)
50  , mLedger(ledger)
51  , mNodes(obj.getFieldArray(sfAffectedNodes))
52 {
55 
56  auto affectedNodes =
57  dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
58  assert(affectedNodes);
59  if (affectedNodes)
60  mNodes = *affectedNodes;
61 
64 }
65 
66 TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, Blob const& vec)
67  : TxMeta(txid, ledger, vec, CtorHelper())
68 {
69 }
70 
72  uint256 const& txid,
73  std::uint32_t ledger,
74  std::string const& data)
75  : TxMeta(txid, ledger, data, CtorHelper())
76 {
77 }
78 
79 TxMeta::TxMeta(uint256 const& transactionID, std::uint32_t ledger)
80  : mTransactionID(transactionID)
81  , mLedger(ledger)
82  , mIndex(static_cast<std::uint32_t>(-1))
83  , mResult(255)
84  , mNodes(sfAffectedNodes)
85 {
86  mNodes.reserve(32);
87 }
88 
89 void
91  uint256 const& node,
92  SField const& type,
93  std::uint16_t nodeType)
94 {
95  // make sure the node exists and force its type
96  for (auto& n : mNodes)
97  {
98  if (n.getFieldH256(sfLedgerIndex) == node)
99  {
100  n.setFName(type);
101  n.setFieldU16(sfLedgerEntryType, nodeType);
102  return;
103  }
104  }
105 
106  mNodes.push_back(STObject(type));
107  STObject& obj = mNodes.back();
108 
109  assert(obj.getFName() == type);
110  obj.setFieldH256(sfLedgerIndex, node);
111  obj.setFieldU16(sfLedgerEntryType, nodeType);
112 }
113 
114 boost::container::flat_set<AccountID>
116 {
117  boost::container::flat_set<AccountID> list;
118  list.reserve(10);
119 
120  // This code should match the behavior of the JS method:
121  // Meta#getAffectedAccounts
122  for (auto const& it : mNodes)
123  {
124  int index = it.getFieldIndex(
125  (it.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);
126 
127  if (index != -1)
128  {
129  auto inner = dynamic_cast<STObject const*>(&it.peekAtIndex(index));
130  assert(inner);
131  if (inner)
132  {
133  for (auto const& field : *inner)
134  {
135  if (auto sa = dynamic_cast<STAccount const*>(&field))
136  {
137  assert(!sa->isDefault());
138  if (!sa->isDefault())
139  list.insert(sa->value());
140  }
141  else if (
142  (field.getFName() == sfLowLimit) ||
143  (field.getFName() == sfHighLimit) ||
144  (field.getFName() == sfTakerPays) ||
145  (field.getFName() == sfTakerGets))
146  {
147  auto lim = dynamic_cast<STAmount const*>(&field);
148  assert(lim);
149 
150  if (lim != nullptr)
151  {
152  auto issuer = lim->getIssuer();
153 
154  if (issuer.isNonZero())
155  list.insert(issuer);
156  }
157  }
158  }
159  }
160  }
161  }
162 
163  return list;
164 }
165 
166 STObject&
168 {
169  uint256 index = node->key();
170  for (auto& n : mNodes)
171  {
172  if (n.getFieldH256(sfLedgerIndex) == index)
173  return n;
174  }
175  mNodes.push_back(STObject(type));
176  STObject& obj = mNodes.back();
177 
178  assert(obj.getFName() == type);
179  obj.setFieldH256(sfLedgerIndex, index);
180  obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
181 
182  return obj;
183 }
184 
185 STObject&
187 {
188  for (auto& n : mNodes)
189  {
190  if (n.getFieldH256(sfLedgerIndex) == node)
191  return n;
192  }
193  assert(false);
194  Throw<std::runtime_error>("Affected node not found");
195  return *(mNodes.begin()); // Silence compiler warning.
196 }
197 
198 STObject
200 {
202  assert(mResult != 255);
205  metaData.emplace_back(mNodes);
206  if (hasDeliveredAmount())
208  return metaData;
209 }
210 
211 void
213 {
214  mResult = TERtoInt(result);
215  mIndex = index;
216  assert((mResult == 0) || ((mResult > 100) && (mResult <= 255)));
217 
218  mNodes.sort([](STObject const& o1, STObject const& o2) {
220  });
221 
222  getAsObject().add(s);
223 }
224 
225 } // namespace ripple
ripple::TxMeta::mResult
int mResult
Definition: TxMeta.h:133
ripple::makeSlice
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:241
ripple::sfMetadata
const SField sfMetadata
std::string
STL class.
std::shared_ptr< STLedgerEntry >
ripple::STObject::setFieldU16
void setFieldU16(SField const &field, std::uint16_t)
Definition: STObject.cpp:653
ripple::sfTransactionMetaData
const SField sfTransactionMetaData
ripple::TxMeta::getAsObject
STObject getAsObject() const
Definition: TxMeta.cpp:199
std::vector< unsigned char >
ripple::STObject::getFieldU8
unsigned char getFieldU8(SField const &field) const
Definition: STObject.cpp:547
ripple::sfLedgerIndex
const SF_UINT256 sfLedgerIndex
ripple::STArray::push_back
void push_back(STObject const &object)
Definition: STArray.h:212
ripple::TxMeta::mIndex
std::uint32_t mIndex
Definition: TxMeta.h:132
ripple::sfFinalFields
const SField sfFinalFields
ripple::TERtoInt
constexpr TERUnderlyingType TERtoInt(TELcodes v)
Definition: TER.h:301
ripple::TxMeta::TxMeta
TxMeta(uint256 const &txID, std::uint32_t ledger, T const &data, CtorHelper)
Definition: TxMeta.cpp:30
ripple::TxMeta::CtorHelper
Definition: TxMeta.h:35
ripple::TxMeta::mNodes
STArray mNodes
Definition: TxMeta.h:137
ripple::TxMeta
Definition: TxMeta.h:32
ripple::base_uint< 256 >
ripple::sfTakerPays
const SF_AMOUNT sfTakerPays
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
ripple::sfDeliveredAmount
const SF_AMOUNT sfDeliveredAmount
ripple::STObject::setFieldU8
void setFieldU8(SField const &field, unsigned char)
Definition: STObject.cpp:647
ripple::STObject::setFieldAmount
void setFieldAmount(SField const &field, STAmount const &)
Definition: STObject.cpp:707
ripple::sfNewFields
const SField sfNewFields
ripple::sfAffectedNodes
const SField sfAffectedNodes
ripple::STObject::setFieldH256
void setFieldH256(SField const &field, uint256 const &)
Definition: STObject.cpp:677
ripple::TERSubset< CanCvtToTER >
ripple::STArray
Definition: STArray.h:28
ripple::TxMeta::addRaw
void addRaw(Serializer &, TER, std::uint32_t index)
Definition: TxMeta.cpp:212
ripple::STAmount
Definition: STAmount.h:45
ripple::sfTakerGets
const SF_AMOUNT sfTakerGets
ripple::SerialIter
Definition: Serializer.h:310
ripple::HashPrefix::transactionID
@ transactionID
transaction plus signature to give transaction ID
std::uint32_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
ripple::TxMeta::getAffectedAccounts
boost::container::flat_set< AccountID > getAffectedAccounts() const
Return a list of accounts affected by this transaction.
Definition: TxMeta.cpp:115
ripple::STArray::sort
void sort(bool(*compare)(const STObject &o1, const STObject &o2))
Definition: STArray.cpp:188
ripple::sfTransactionIndex
const SF_UINT32 sfTransactionIndex
ripple::STBase::getFName
SField const & getFName() const
Definition: STBase.cpp:132
ripple::STArray::begin
iterator begin()
Definition: STArray.h:224
ripple::Serializer
Definition: Serializer.h:39
ripple::STAccount
Definition: STAccount.h:29
ripple::STObject::emplace_back
std::size_t emplace_back(Args &&... args)
Definition: STObject.h:907
ripple::STObject::add
void add(Serializer &s) const override
Definition: STObject.cpp:85
ripple::STObject
Definition: STObject.h:51
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::STObject::peekAtPField
const STBase * peekAtPField(SField const &field) const
Definition: STObject.cpp:401
ripple::sfTransactionResult
const SF_UINT8 sfTransactionResult
ripple::sfLedgerEntryType
const SF_UINT16 sfLedgerEntryType
ripple::TxMeta::getAffectedNode
STObject & getAffectedNode(SLE::ref node, SField const &type)
Definition: TxMeta.cpp:167
ripple::SField
Identifies fields.
Definition: SField.h:112
ripple::STObject::getField
STBase & getField(SField const &field)
Definition: STObject.cpp:384
std
STL namespace.
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:428
ripple::TxMeta::hasDeliveredAmount
bool hasDeliveredAmount() const
Definition: TxMeta.h:124
ripple::TxMeta::setDeliveredAmount
void setDeliveredAmount(STAmount const &delivered)
Definition: TxMeta.h:111
ripple::sfCreatedNode
const SField sfCreatedNode
ripple::STArray::back
STObject & back()
Definition: STArray.h:193
ripple::TxMeta::getDeliveredAmount
STAmount getDeliveredAmount() const
Definition: TxMeta.h:117
ripple::STObject::getFieldU32
std::uint32_t getFieldU32(SField const &field) const
Definition: STObject.cpp:559
ripple::STObject::setFieldU32
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:659
ripple::TxMeta::setAffectedNode
void setAffectedNode(uint256 const &, SField const &type, std::uint16_t nodeType)
Definition: TxMeta.cpp:90
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:603
ripple::STArray::reserve
void reserve(std::size_t n)
Definition: STArray.h:266
ripple::STObject::getFieldH256
uint256 getFieldH256(SField const &field) const
Definition: STObject.cpp:583
string