rippled
RippleLineCache.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/app/paths/RippleLineCache.h>
21 #include <ripple/app/paths/TrustLine.h>
22 #include <ripple/ledger/OpenView.h>
23 
24 namespace ripple {
25 
27  std::shared_ptr<ReadView const> const& ledger,
29  : ledger_(ledger), journal_(j)
30 {
31  JLOG(journal_.debug()) << "created for ledger " << ledger_->info().seq;
32 }
33 
35 {
36  JLOG(journal_.debug()) << "destroyed for ledger " << ledger_->info().seq
37  << " with " << lines_.size() << " accounts and "
38  << totalLineCount_ << " distinct trust lines.";
39 }
40 
43  AccountID const& accountID,
44  LineDirection direction)
45 {
46  auto const hash = hasher_(accountID);
47  AccountKey key(accountID, direction, hash);
48  AccountKey otherkey(
49  accountID,
52  hash);
53 
55 
56  auto [it, inserted] = [&]() {
57  if (auto otheriter = lines_.find(otherkey); otheriter != lines_.end())
58  {
59  // The whole point of using the direction flag is to reduce the
60  // number of trust line objects held in memory. Ensure that there is
61  // only a single set of trustlines in the cache per account.
62  auto const size = otheriter->second ? otheriter->second->size() : 0;
63  JLOG(journal_.info())
64  << "Request for "
65  << (direction == LineDirection::outgoing ? "outgoing"
66  : "incoming")
67  << " trust lines for account " << accountID << " found " << size
68  << (direction == LineDirection::outgoing ? " incoming"
69  : " outgoing")
70  << " trust lines. "
71  << (direction == LineDirection::outgoing
72  ? "Deleting the subset of incoming"
73  : "Returning the superset of outgoing")
74  << " trust lines. ";
75  if (direction == LineDirection::outgoing)
76  {
77  // This request is for the outgoing set, but there is already a
78  // subset of incoming lines in the cache. Erase that subset
79  // to be replaced by the full set. The full set will be built
80  // below, and will be returned, if needed, on subsequent calls
81  // for either value of outgoing.
82  assert(size <= totalLineCount_);
83  totalLineCount_ -= size;
84  lines_.erase(otheriter);
85  }
86  else
87  {
88  // This request is for the incoming set, but there is
89  // already a superset of the outgoing trust lines in the cache.
90  // The path finding engine will disregard the non-rippling trust
91  // lines, so to prevent them from being stored twice, return the
92  // outgoing set.
93  key = otherkey;
94  return std::pair{otheriter, false};
95  }
96  }
97  return lines_.emplace(key, nullptr);
98  }();
99 
100  if (inserted)
101  {
102  assert(it->second == nullptr);
103  auto lines =
104  PathFindTrustLine::getItems(accountID, *ledger_, direction);
105  if (lines.size())
106  {
107  it->second = std::make_shared<std::vector<PathFindTrustLine>>(
108  std::move(lines));
109  totalLineCount_ += it->second->size();
110  }
111  }
112 
113  assert(!it->second || (it->second->size() > 0));
114  auto const size = it->second ? it->second->size() : 0;
115  JLOG(journal_.trace()) << "getRippleLines for ledger "
116  << ledger_->info().seq << " found " << size
118  ? " outgoing"
119  : " incoming")
120  << " lines for " << (inserted ? "new " : "existing ")
121  << accountID << " out of a total of "
122  << lines_.size() << " accounts and "
123  << totalLineCount_ << " trust lines";
124 
125  return it->second;
126 }
127 
128 } // namespace ripple
std::shared_ptr
STL class.
ripple::LineDirection
LineDirection
Describes how an account was found in a path, and how to find the next set of paths.
Definition: TrustLine.h:41
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
std::pair
ripple::RippleLineCache::mLock
std::mutex mLock
Definition: RippleLineCache.h:66
ripple::RippleLineCache::ledger_
std::shared_ptr< ReadView const > ledger_
Definition: RippleLineCache.h:69
std::lock_guard
STL class.
ripple::RippleLineCache::AccountKey
Definition: RippleLineCache.h:73
ripple::base_uint< 160, detail::AccountIDTag >
ripple::RippleLineCache::totalLineCount_
std::size_t totalLineCount_
Definition: RippleLineCache.h:127
ripple::LineDirection::outgoing
@ outgoing
beast::Journal::info
Stream info() const
Definition: Journal.h:321
ripple::LineDirection::incoming
@ incoming
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::RippleLineCache::~RippleLineCache
~RippleLineCache()
Definition: RippleLineCache.cpp:34
ripple::RippleLineCache::RippleLineCache
RippleLineCache(std::shared_ptr< ReadView const > const &l, beast::Journal j)
Definition: RippleLineCache.cpp:26
ripple::RippleLineCache::hasher_
ripple::hardened_hash hasher_
Definition: RippleLineCache.h:68
ripple::RippleLineCache::lines_
hash_map< AccountKey, std::shared_ptr< std::vector< PathFindTrustLine > >, AccountKey::Hash > lines_
Definition: RippleLineCache.h:126
ripple::RippleLineCache::getRippleLines
std::shared_ptr< std::vector< PathFindTrustLine > > getRippleLines(AccountID const &accountID, LineDirection direction)
Find the trust lines associated with an account.
Definition: RippleLineCache.cpp:42
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::RippleLineCache::AccountKey::direction_
LineDirection direction_
Definition: RippleLineCache.h:76
ripple::PathFindTrustLine::getItems
static std::vector< PathFindTrustLine > getItems(AccountID const &accountID, ReadView const &view, LineDirection direction)
Definition: TrustLine.cpp:89
ripple::RippleLineCache::journal_
beast::Journal journal_
Definition: RippleLineCache.h:71