rippled
ApplyStateTable.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/json/to_string.h>
22 #include <ripple/ledger/detail/ApplyStateTable.h>
23 #include <ripple/protocol/Feature.h>
24 #include <ripple/protocol/st.h>
25 #include <cassert>
26 
27 namespace ripple {
28 namespace detail {
29 
30 void
32 {
34  for (auto const& item : items_)
35  {
36  auto const& sle = item.second.second;
37  switch (item.second.first)
38  {
39  case Action::cache:
40  break;
41  case Action::erase:
42  to.rawErase(sle);
43  break;
44  case Action::insert:
45  to.rawInsert(sle);
46  break;
47  case Action::modify:
48  to.rawReplace(sle);
49  break;
50  };
51  }
52 }
53 
56 {
57  std::size_t ret = 0;
58  for (auto& item : items_)
59  {
60  switch (item.second.first)
61  {
62  case Action::erase:
63  case Action::insert:
64  case Action::modify:
65  ++ret;
66  default:
67  break;
68  }
69  }
70  return ret;
71 }
72 
73 void
75  ReadView const& to,
76  std::function<void(
77  uint256 const& key,
78  bool isDelete,
79  std::shared_ptr<SLE const> const& before,
80  std::shared_ptr<SLE const> const& after)> const& func) const
81 {
82  for (auto& item : items_)
83  {
84  switch (item.second.first)
85  {
86  case Action::erase:
87  func(
88  item.first,
89  true,
90  to.read(keylet::unchecked(item.first)),
91  item.second.second);
92  break;
93 
94  case Action::insert:
95  func(item.first, false, nullptr, item.second.second);
96  break;
97 
98  case Action::modify:
99  func(
100  item.first,
101  false,
102  to.read(keylet::unchecked(item.first)),
103  item.second.second);
104  break;
105 
106  default:
107  break;
108  }
109  }
110 }
111 
112 void
114  OpenView& to,
115  STTx const& tx,
116  TER ter,
117  std::optional<STAmount> const& deliver,
118  beast::Journal j)
119 {
120  // Build metadata and insert
121  auto const sTx = std::make_shared<Serializer>();
122  tx.add(*sTx);
124  if (!to.open())
125  {
126  TxMeta meta(tx.getTransactionID(), to.seq());
127  if (deliver)
128  meta.setDeliveredAmount(*deliver);
129  Mods newMod;
130  for (auto& item : items_)
131  {
132  SField const* type;
133  switch (item.second.first)
134  {
135  default:
136  case Action::cache:
137  continue;
138  case Action::erase:
139  type = &sfDeletedNode;
140  break;
141  case Action::insert:
142  type = &sfCreatedNode;
143  break;
144  case Action::modify:
145  type = &sfModifiedNode;
146  break;
147  }
148  auto const origNode = to.read(keylet::unchecked(item.first));
149  auto curNode = item.second.second;
150  if ((type == &sfModifiedNode) && (*curNode == *origNode))
151  continue;
152  std::uint16_t nodeType = curNode
153  ? curNode->getFieldU16(sfLedgerEntryType)
154  : origNode->getFieldU16(sfLedgerEntryType);
155  meta.setAffectedNode(item.first, *type, nodeType);
156  if (type == &sfDeletedNode)
157  {
158  assert(origNode && curNode);
159  threadOwners(to, meta, origNode, newMod, j);
160 
161  STObject prevs(sfPreviousFields);
162  for (auto const& obj : *origNode)
163  {
164  // go through the original node for
165  // modified fields saved on modification
166  if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) &&
167  !curNode->hasMatchingEntry(obj))
168  prevs.emplace_back(obj);
169  }
170 
171  if (!prevs.empty())
172  meta.getAffectedNode(item.first)
173  .emplace_back(std::move(prevs));
174 
175  STObject finals(sfFinalFields);
176  for (auto const& obj : *curNode)
177  {
178  // go through the final node for final fields
179  if (obj.getFName().shouldMeta(
181  finals.emplace_back(obj);
182  }
183 
184  if (!finals.empty())
185  meta.getAffectedNode(item.first)
186  .emplace_back(std::move(finals));
187  }
188  else if (type == &sfModifiedNode)
189  {
190  assert(curNode && origNode);
191 
192  if (curNode->isThreadedType()) // thread transaction to node
193  // item modified
194  threadItem(meta, curNode);
195 
196  STObject prevs(sfPreviousFields);
197  for (auto const& obj : *origNode)
198  {
199  // search the original node for values saved on modify
200  if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) &&
201  !curNode->hasMatchingEntry(obj))
202  prevs.emplace_back(obj);
203  }
204 
205  if (!prevs.empty())
206  meta.getAffectedNode(item.first)
207  .emplace_back(std::move(prevs));
208 
209  STObject finals(sfFinalFields);
210  for (auto const& obj : *curNode)
211  {
212  // search the final node for values saved always
213  if (obj.getFName().shouldMeta(
215  finals.emplace_back(obj);
216  }
217 
218  if (!finals.empty())
219  meta.getAffectedNode(item.first)
220  .emplace_back(std::move(finals));
221  }
222  else if (type == &sfCreatedNode) // if created, thread to owner(s)
223  {
224  assert(curNode && !origNode);
225  threadOwners(to, meta, curNode, newMod, j);
226 
227  if (curNode->isThreadedType()) // always thread to self
228  threadItem(meta, curNode);
229 
230  STObject news(sfNewFields);
231  for (auto const& obj : *curNode)
232  {
233  // save non-default values
234  if (!obj.isDefault() &&
235  obj.getFName().shouldMeta(
237  news.emplace_back(obj);
238  }
239 
240  if (!news.empty())
241  meta.getAffectedNode(item.first)
242  .emplace_back(std::move(news));
243  }
244  else
245  {
246  assert(false);
247  }
248  }
249 
250  // add any new modified nodes to the modification set
251  for (auto& mod : newMod)
252  to.rawReplace(mod.second);
253 
254  sMeta = std::make_shared<Serializer>();
255  meta.addRaw(*sMeta, ter, to.txCount());
256 
257  // VFALCO For diagnostics do we want to show
258  // metadata even when the base view is open?
259  JLOG(j.trace()) << "metadata " << meta.getJson(JsonOptions::none);
260  }
261  to.rawTxInsert(tx.getTransactionID(), sTx, sMeta);
262  apply(to);
263 }
264 
265 //---
266 
267 bool
268 ApplyStateTable::exists(ReadView const& base, Keylet const& k) const
269 {
270  auto const iter = items_.find(k.key);
271  if (iter == items_.end())
272  return base.exists(k);
273  auto const& item = iter->second;
274  auto const& sle = item.second;
275  switch (item.first)
276  {
277  case Action::erase:
278  return false;
279  case Action::cache:
280  case Action::insert:
281  case Action::modify:
282  break;
283  }
284  if (!k.check(*sle))
285  return false;
286  return true;
287 }
288 
289 auto
291  ReadView const& base,
292  key_type const& key,
294 {
295  std::optional<key_type> next = key;
296  items_t::const_iterator iter;
297  // Find base successor that is
298  // not also deleted in our list
299  do
300  {
301  next = base.succ(*next, last);
302  if (!next)
303  break;
304  iter = items_.find(*next);
305  } while (iter != items_.end() && iter->second.first == Action::erase);
306  // Find non-deleted successor in our list
307  for (iter = items_.upper_bound(key); iter != items_.end(); ++iter)
308  {
309  if (iter->second.first != Action::erase)
310  {
311  // Found both, return the lower key
312  if (!next || next > iter->first)
313  next = iter->first;
314  break;
315  }
316  }
317  // Nothing in our list, return
318  // what we got from the parent.
319  if (last && next >= last)
320  return std::nullopt;
321  return next;
322 }
323 
325 ApplyStateTable::read(ReadView const& base, Keylet const& k) const
326 {
327  auto const iter = items_.find(k.key);
328  if (iter == items_.end())
329  return base.read(k);
330  auto const& item = iter->second;
331  auto const& sle = item.second;
332  switch (item.first)
333  {
334  case Action::erase:
335  return nullptr;
336  case Action::cache:
337  case Action::insert:
338  case Action::modify:
339  break;
340  };
341  if (!k.check(*sle))
342  return nullptr;
343  return sle;
344 }
345 
347 ApplyStateTable::peek(ReadView const& base, Keylet const& k)
348 {
349  auto iter = items_.lower_bound(k.key);
350  if (iter == items_.end() || iter->first != k.key)
351  {
352  auto const sle = base.read(k);
353  if (!sle)
354  return nullptr;
355  // Make our own copy
356  using namespace std;
357  iter = items_.emplace_hint(
358  iter,
359  piecewise_construct,
360  forward_as_tuple(sle->key()),
361  forward_as_tuple(Action::cache, make_shared<SLE>(*sle)));
362  return iter->second.second;
363  }
364  auto const& item = iter->second;
365  auto const& sle = item.second;
366  switch (item.first)
367  {
368  case Action::erase:
369  return nullptr;
370  case Action::cache:
371  case Action::insert:
372  case Action::modify:
373  break;
374  };
375  if (!k.check(*sle))
376  return nullptr;
377  return sle;
378 }
379 
380 void
382 {
383  auto const iter = items_.find(sle->key());
384  if (iter == items_.end())
385  LogicError("ApplyStateTable::erase: missing key");
386  auto& item = iter->second;
387  if (item.second != sle)
388  LogicError("ApplyStateTable::erase: unknown SLE");
389  switch (item.first)
390  {
391  case Action::erase:
392  LogicError("ApplyStateTable::erase: double erase");
393  break;
394  case Action::insert:
395  items_.erase(iter);
396  break;
397  case Action::cache:
398  case Action::modify:
399  item.first = Action::erase;
400  break;
401  }
402 }
403 
404 void
406 {
407  using namespace std;
408  auto const result = items_.emplace(
409  piecewise_construct,
410  forward_as_tuple(sle->key()),
412  if (result.second)
413  return;
414  auto& item = result.first->second;
415  switch (item.first)
416  {
417  case Action::erase:
418  LogicError("ApplyStateTable::rawErase: double erase");
419  break;
420  case Action::insert:
421  items_.erase(result.first);
422  break;
423  case Action::cache:
424  case Action::modify:
425  item.first = Action::erase;
426  item.second = sle;
427  break;
428  }
429 }
430 
431 void
433 {
434  auto const iter = items_.lower_bound(sle->key());
435  if (iter == items_.end() || iter->first != sle->key())
436  {
437  using namespace std;
439  iter,
440  piecewise_construct,
441  forward_as_tuple(sle->key()),
443  return;
444  }
445  auto& item = iter->second;
446  switch (item.first)
447  {
448  case Action::cache:
449  LogicError("ApplyStateTable::insert: already cached");
450  case Action::insert:
451  LogicError("ApplyStateTable::insert: already inserted");
452  case Action::modify:
453  LogicError("ApplyStateTable::insert: already modified");
454  case Action::erase:
455  break;
456  }
457  item.first = Action::modify;
458  item.second = sle;
459 }
460 
461 void
463 {
464  auto const iter = items_.lower_bound(sle->key());
465  if (iter == items_.end() || iter->first != sle->key())
466  {
467  using namespace std;
469  iter,
470  piecewise_construct,
471  forward_as_tuple(sle->key()),
473  return;
474  }
475  auto& item = iter->second;
476  switch (item.first)
477  {
478  case Action::erase:
479  LogicError("ApplyStateTable::replace: already erased");
480  case Action::cache:
481  item.first = Action::modify;
482  break;
483  case Action::insert:
484  case Action::modify:
485  break;
486  }
487  item.second = sle;
488 }
489 
490 void
492 {
493  auto const iter = items_.find(sle->key());
494  if (iter == items_.end())
495  LogicError("ApplyStateTable::update: missing key");
496  auto& item = iter->second;
497  if (item.second != sle)
498  LogicError("ApplyStateTable::update: unknown SLE");
499  switch (item.first)
500  {
501  case Action::erase:
502  LogicError("ApplyStateTable::update: erased");
503  break;
504  case Action::cache:
505  item.first = Action::modify;
506  break;
507  case Action::insert:
508  case Action::modify:
509  break;
510  };
511 }
512 
513 void
515 {
516  dropsDestroyed_ += fee;
517 }
518 
519 //------------------------------------------------------------------------------
520 
521 // Insert this transaction to the SLE's threading list
522 void
524 {
525  key_type prevTxID;
526  LedgerIndex prevLgrID;
527 
528  if (!sle->thread(meta.getTxID(), meta.getLgrSeq(), prevTxID, prevLgrID))
529  return;
530 
531  if (!prevTxID.isZero())
532  {
533  auto& node = meta.getAffectedNode(sle, sfModifiedNode);
534 
535  if (node.getFieldIndex(sfPreviousTxnID) == -1)
536  {
537  assert(node.getFieldIndex(sfPreviousTxnLgrSeq) == -1);
538  node.setFieldH256(sfPreviousTxnID, prevTxID);
539  node.setFieldU32(sfPreviousTxnLgrSeq, prevLgrID);
540  }
541 
542  assert(node.getFieldH256(sfPreviousTxnID) == prevTxID);
543  assert(node.getFieldU32(sfPreviousTxnLgrSeq) == prevLgrID);
544  }
545 }
546 
549  ReadView const& base,
550  key_type const& key,
551  Mods& mods,
552  beast::Journal j)
553 {
554  {
555  auto miter = mods.find(key);
556  if (miter != mods.end())
557  {
558  assert(miter->second);
559  return miter->second;
560  }
561  }
562  {
563  auto iter = items_.find(key);
564  if (iter != items_.end())
565  {
566  auto const& item = iter->second;
567  if (item.first == Action::erase)
568  {
569  // The Destination of an Escrow or a PayChannel may have been
570  // deleted. In that case the account we're threading to will
571  // not be found and it is appropriate to return a nullptr.
572  JLOG(j.warn()) << "Trying to thread to deleted node";
573  return nullptr;
574  }
575  if (item.first != Action::cache)
576  return item.second;
577 
578  // If it's only cached, then the node is being modified only by
579  // metadata; fall through and track it in the mods table.
580  }
581  }
582  auto c = base.read(keylet::unchecked(key));
583  if (!c)
584  {
585  // The Destination of an Escrow or a PayChannel may have been
586  // deleted. In that case the account we're threading to will
587  // not be found and it is appropriate to return a nullptr.
588  JLOG(j.warn()) << "ApplyStateTable::getForMod: key not found";
589  return nullptr;
590  }
591  auto sle = std::make_shared<SLE>(*c);
592  mods.emplace(key, sle);
593  return sle;
594 }
595 
596 void
598  ReadView const& base,
599  TxMeta& meta,
600  AccountID const& to,
601  Mods& mods,
602  beast::Journal j)
603 {
604  auto const sle = getForMod(base, keylet::account(to).key, mods, j);
605  if (!sle)
606  {
607  // The Destination of an Escrow or PayChannel may have been deleted.
608  // In that case the account we are threading to will not be found.
609  // So this logging is just a warning.
610  JLOG(j.warn()) << "Threading to non-existent account: " << toBase58(to);
611  return;
612  }
613  threadItem(meta, sle);
614 }
615 
616 void
618  ReadView const& base,
619  TxMeta& meta,
620  std::shared_ptr<SLE const> const& sle,
621  Mods& mods,
622  beast::Journal j)
623 {
624  LedgerEntryType const ledgerType{sle->getType()};
625  switch (ledgerType)
626  {
627  case ltACCOUNT_ROOT: {
628  // Nothing to do
629  break;
630  }
631  case ltRIPPLE_STATE: {
632  threadTx(base, meta, (*sle)[sfLowLimit].getIssuer(), mods, j);
633  threadTx(base, meta, (*sle)[sfHighLimit].getIssuer(), mods, j);
634  break;
635  }
636  default: {
637  // If sfAccount is present, thread to that account
638  if (auto const optSleAcct{(*sle)[~sfAccount]})
639  threadTx(base, meta, *optSleAcct, mods, j);
640 
641  // Don't thread a check's sfDestination unless the amendment is
642  // enabled
643  if (ledgerType == ltCHECK &&
645  break;
646 
647  // If sfDestination is present, thread to that account
648  if (auto const optSleDest{(*sle)[~sfDestination]})
649  threadTx(base, meta, *optSleDest, mods, j);
650  }
651  }
652 }
653 
654 } // namespace detail
655 } // namespace ripple
ripple::sfPreviousTxnLgrSeq
const SF_UINT32 sfPreviousTxnLgrSeq
ripple::OpenView::txCount
std::size_t txCount() const
Return the number of tx inserted since creation.
Definition: OpenView.cpp:124
ripple::detail::ApplyStateTable::size
std::size_t size() const
Definition: ApplyStateTable.cpp:55
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::Rules::enabled
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition: Rules.cpp:94
std::shared_ptr
STL class.
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::sfDestination
const SF_ACCOUNT sfDestination
ripple::SField::sMD_Always
@ sMD_Always
Definition: SField.h:121
ripple::SField::sMD_DeleteFinal
@ sMD_DeleteFinal
Definition: SField.h:119
ripple::detail::ApplyStateTable::insert
void insert(ReadView const &base, std::shared_ptr< SLE > const &sle)
Definition: ApplyStateTable.cpp:432
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:55
std::map::find
T find(T... args)
ripple::detail::ApplyStateTable::visit
void visit(ReadView const &base, std::function< void(uint256 const &key, bool isDelete, std::shared_ptr< SLE const > const &before, std::shared_ptr< SLE const > const &after)> const &func) const
Definition: ApplyStateTable.cpp:74
ripple::RawView::rawDestroyXRP
virtual void rawDestroyXRP(XRPAmount const &fee)=0
Destroy XRP.
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::STObject::empty
bool empty() const
Definition: STObject.h:871
std::map::emplace
T emplace(T... args)
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::sfFinalFields
const SField sfFinalFields
ripple::detail::ApplyStateTable::exists
bool exists(ReadView const &base, Keylet const &k) const
Definition: ApplyStateTable.cpp:268
std::function
ripple::SField::sMD_ChangeOrig
@ sMD_ChangeOrig
Definition: SField.h:117
ripple::ltCHECK
@ ltCHECK
A ledger object which describes a check.
Definition: LedgerFormats.h:136
ripple::detail::ApplyStateTable::threadItem
static void threadItem(TxMeta &meta, std::shared_ptr< SLE > const &to)
Definition: ApplyStateTable.cpp:523
ripple::detail::ApplyStateTable::Action::cache
@ cache
ripple::RawView::rawReplace
virtual void rawReplace(std::shared_ptr< SLE > const &sle)=0
Unconditionally replace a state item.
ripple::sfDeletedNode
const SField sfDeletedNode
ripple::SField::sMD_Create
@ sMD_Create
Definition: SField.h:120
ripple::detail::ApplyStateTable::destroyXRP
void destroyXRP(XRPAmount const &fee)
Definition: ApplyStateTable.cpp:514
ripple::detail::ApplyStateTable::dropsDestroyed_
XRPAmount dropsDestroyed_
Definition: ApplyStateTable.h:52
ripple::detail::ApplyStateTable::replace
void replace(ReadView const &base, std::shared_ptr< SLE > const &sle)
Definition: ApplyStateTable.cpp:462
ripple::RawView::rawErase
virtual void rawErase(std::shared_ptr< SLE > const &sle)=0
Delete an existing state item.
ripple::TxMeta
Definition: TxMeta.h:32
ripple::Keylet::key
uint256 key
Definition: Keylet.h:40
ripple::base_uint< 256 >
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
ripple::RawView
Interface for ledger entry changes.
Definition: RawView.h:36
std::map::emplace_hint
T emplace_hint(T... args)
ripple::base_uint::isZero
bool isZero() const
Definition: base_uint.h:532
ripple::detail::ApplyStateTable::apply
void apply(RawView &to) const
Definition: ApplyStateTable.cpp:31
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:133
ripple::detail::ApplyStateTable::threadOwners
void threadOwners(ReadView const &base, TxMeta &meta, std::shared_ptr< SLE const > const &sle, Mods &mods, beast::Journal j)
Definition: ApplyStateTable.cpp:617
ripple::RawView::rawInsert
virtual void rawInsert(std::shared_ptr< SLE > const &sle)=0
Unconditionally insert a state item.
ripple::fixCheckThreading
const uint256 fixCheckThreading
ripple::sfNewFields
const SField sfNewFields
ripple::OpenView::rawReplace
void rawReplace(std::shared_ptr< SLE > const &sle) override
Unconditionally replace a state item.
Definition: OpenView.cpp:245
ripple::JsonOptions::none
@ none
ripple::TERSubset< CanCvtToTER >
ripple::TxMeta::addRaw
void addRaw(Serializer &, TER, std::uint32_t index)
Definition: TxMeta.cpp:212
ripple::OpenView::open
bool open() const override
Returns true if this reflects an open ledger.
Definition: OpenView.h:175
ripple::sfModifiedNode
const SField sfModifiedNode
ripple::ReadView::exists
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
std::map::erase
T erase(T... args)
ripple::detail::ApplyStateTable::erase
void erase(ReadView const &base, std::shared_ptr< SLE > const &sle)
Definition: ApplyStateTable.cpp:381
ripple::detail::ApplyStateTable::Action::erase
@ erase
ripple::STTx
Definition: STTx.h:45
ripple::detail::ApplyStateTable::threadTx
void threadTx(ReadView const &base, TxMeta &meta, AccountID const &to, Mods &mods, beast::Journal j)
Definition: ApplyStateTable.cpp:597
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::sfPreviousTxnID
const SF_UINT256 sfPreviousTxnID
std::uint16_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
std::forward_as_tuple
T forward_as_tuple(T... args)
ripple::keylet::unchecked
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
Definition: Indexes.cpp:297
ripple::TxMeta::getJson
Json::Value getJson(JsonOptions p) const
Definition: TxMeta.h:90
ripple::detail::ApplyStateTable::read
std::shared_ptr< SLE const > read(ReadView const &base, Keylet const &k) const
Definition: ApplyStateTable.cpp:325
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::detail::ApplyStateTable::rawErase
void rawErase(ReadView const &base, std::shared_ptr< SLE > const &sle)
Definition: ApplyStateTable.cpp:405
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:191
ripple::sfPreviousFields
const SField sfPreviousFields
ripple::detail::ApplyStateTable::getForMod
std::shared_ptr< SLE > getForMod(ReadView const &base, key_type const &key, Mods &mods, beast::Journal j)
Definition: ApplyStateTable.cpp:548
ripple::TxMeta::getLgrSeq
std::uint32_t getLgrSeq() const
Definition: TxMeta.h:58
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::ReadView
A view into a ledger.
Definition: ReadView.h:125
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::map::lower_bound
T lower_bound(T... args)
ripple::sfLedgerEntryType
const SF_UINT16 sfLedgerEntryType
ripple::OpenView::rawTxInsert
void rawTxInsert(key_type const &key, std::shared_ptr< Serializer const > const &txn, std::shared_ptr< Serializer const > const &metaData) override
Add a transaction to the tx map.
Definition: OpenView.cpp:261
ripple::LedgerEntryType
LedgerEntryType
Identifiers for on-ledger objects.
Definition: LedgerFormats.h:53
ripple::TxMeta::getAffectedNode
STObject & getAffectedNode(SLE::ref node, SField const &type)
Definition: TxMeta.cpp:167
ripple::SField
Identifies fields.
Definition: SField.h:112
ripple::ReadView::seq
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Definition: ReadView.h:193
ripple::ReadView::rules
virtual Rules const & rules() const =0
Returns the tx processing rules.
ripple::TxMeta::getTxID
uint256 const & getTxID() const
Definition: TxMeta.h:53
std
STL namespace.
ripple::LogicError
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:48
ripple::ltACCOUNT_ROOT
@ ltACCOUNT_ROOT
A ledger object which describes an account.
Definition: LedgerFormats.h:59
cassert
ripple::TxMeta::setDeliveredAmount
void setDeliveredAmount(STAmount const &delivered)
Definition: TxMeta.h:111
ripple::sfCreatedNode
const SField sfCreatedNode
ripple::detail::ApplyStateTable::update
void update(ReadView const &base, std::shared_ptr< SLE > const &sle)
Definition: ApplyStateTable.cpp:491
ripple::detail::ApplyStateTable::succ
std::optional< key_type > succ(ReadView const &base, key_type const &key, std::optional< key_type > const &last) const
Definition: ApplyStateTable.cpp:290
ripple::OpenView::read
std::shared_ptr< SLE const > read(Keylet const &k) const override
Return the state item associated with a key.
Definition: OpenView.cpp:171
std::optional< STAmount >
ripple::after
static bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition: Escrow.cpp:88
std::size_t
ripple::Keylet::check
bool check(STLedgerEntry const &) const
Returns true if the SLE matches the type.
Definition: Keylet.cpp:26
ripple::sfAccount
const SF_ACCOUNT sfAccount
ripple::ltRIPPLE_STATE
@ ltRIPPLE_STATE
A ledger object which describes a bidirectional trust line.
Definition: LedgerFormats.h:74
std::map::end
T end(T... args)
ripple::detail::ApplyStateTable::Action::modify
@ modify
ripple::SField::sMD_ChangeNew
@ sMD_ChangeNew
Definition: SField.h:118
ripple::detail::ApplyStateTable::peek
std::shared_ptr< SLE > peek(ReadView const &base, Keylet const &k)
Definition: ApplyStateTable.cpp:347
ripple::detail::ApplyStateTable::items_
items_t items_
Definition: ApplyStateTable.h:51
std::unordered_map
STL class.
ripple::detail::ApplyStateTable::Action::insert
@ insert
ripple::TxMeta::setAffectedNode
void setAffectedNode(uint256 const &, SField const &type, std::uint16_t nodeType)
Definition: TxMeta.cpp:90
ripple::XRPAmount
Definition: XRPAmount.h:46