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  const STObject* inner =
130  dynamic_cast<const STObject*>(&it.peekAtIndex(index));
131  assert(inner);
132  if (inner)
133  {
134  for (auto const& field : *inner)
135  {
136  if (auto sa = dynamic_cast<STAccount const*>(&field))
137  {
138  assert(!sa->isDefault());
139  if (!sa->isDefault())
140  list.insert(sa->value());
141  }
142  else if (
143  (field.getFName() == sfLowLimit) ||
144  (field.getFName() == sfHighLimit) ||
145  (field.getFName() == sfTakerPays) ||
146  (field.getFName() == sfTakerGets))
147  {
148  const STAmount* lim =
149  dynamic_cast<const STAmount*>(&field);
150  assert(lim);
151 
152  if (lim != nullptr)
153  {
154  auto issuer = lim->getIssuer();
155 
156  if (issuer.isNonZero())
157  list.insert(issuer);
158  }
159  }
160  }
161  }
162  }
163  }
164 
165  return list;
166 }
167 
168 STObject&
170 {
171  uint256 index = node->key();
172  for (auto& n : mNodes)
173  {
174  if (n.getFieldH256(sfLedgerIndex) == index)
175  return n;
176  }
177  mNodes.push_back(STObject(type));
178  STObject& obj = mNodes.back();
179 
180  assert(obj.getFName() == type);
181  obj.setFieldH256(sfLedgerIndex, index);
182  obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
183 
184  return obj;
185 }
186 
187 STObject&
189 {
190  for (auto& n : mNodes)
191  {
192  if (n.getFieldH256(sfLedgerIndex) == node)
193  return n;
194  }
195  assert(false);
196  Throw<std::runtime_error>("Affected node not found");
197  return *(mNodes.begin()); // Silence compiler warning.
198 }
199 
200 STObject
202 {
204  assert(mResult != 255);
207  metaData.emplace_back(mNodes);
208  if (hasDeliveredAmount())
210  return metaData;
211 }
212 
213 void
215 {
216  mResult = TERtoInt(result);
217  mIndex = index;
218  assert((mResult == 0) || ((mResult > 100) && (mResult <= 255)));
219 
220  mNodes.sort([](STObject const& o1, STObject const& o2) {
222  });
223 
224  getAsObject().add(s);
225 }
226 
227 } // 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:201
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:298
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::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:351
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:214
ripple::STAmount
Definition: STAmount.h:44
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:169
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