rippled
ShardFamily.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2020 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/ledger/LedgerMaster.h>
21 #include <ripple/app/main/Application.h>
22 #include <ripple/app/main/Tuning.h>
23 #include <ripple/nodestore/DatabaseShard.h>
24 #include <ripple/shamap/ShardFamily.h>
25 #include <tuple>
26 
27 namespace ripple {
28 
29 static NodeStore::Database&
31 {
32  auto const dbPtr = app.getShardStore();
33  assert(dbPtr);
34  return *dbPtr;
35 }
36 
38  : app_(app)
39  , db_(getShardStore(app))
40  , cm_(cm)
41  , j_(app.journal("ShardFamily"))
42  , tnTargetSize_(app.config().getValueFor(SizedItem::treeCacheSize, 0))
43  , tnTargetAge_(app.config().getValueFor(SizedItem::treeCacheAge, 0))
44 {
45 }
46 
49 {
50  auto const shardIndex{app_.getShardStore()->seqToShardIndex(ledgerSeq)};
52  if (auto const it{fbCache_.find(shardIndex)}; it != fbCache_.end())
53  return it->second;
54 
55  // Create a cache for the corresponding shard
56  auto fbCache{std::make_shared<FullBelowCache>(
57  "Shard family full below cache shard " + std::to_string(shardIndex),
58  stopwatch(),
59  j_,
60  cm_.collector(),
63  return fbCache_.emplace(shardIndex, std::move(fbCache)).first->second;
64 }
65 
66 int
68 {
69  size_t sz{0};
71  for (auto const& e : fbCache_)
72  sz += e.second->size();
73  return sz;
74 }
75 
78 {
79  auto const shardIndex{app_.getShardStore()->seqToShardIndex(ledgerSeq)};
81  if (auto const it{tnCache_.find(shardIndex)}; it != tnCache_.end())
82  return it->second;
83 
84  // Create a cache for the corresponding shard
85  auto tnCache{std::make_shared<TreeNodeCache>(
86  "Shard family tree node cache shard " + std::to_string(shardIndex),
89  stopwatch(),
90  j_)};
91  return tnCache_.emplace(shardIndex, std::move(tnCache)).first->second;
92 }
93 
96 {
97  int cacheSz{0};
98  int trackSz{0};
100  for (auto const& e : tnCache_)
101  {
102  cacheSz += e.second->getCacheSize();
103  trackSz += e.second->getTrackSize();
104  }
105  return {cacheSz, trackSz};
106 }
107 
108 void
110 {
111  {
113  for (auto it = fbCache_.cbegin(); it != fbCache_.cend();)
114  {
115  it->second->sweep();
116 
117  // Remove cache if empty
118  if (it->second->size() == 0)
119  it = fbCache_.erase(it);
120  else
121  ++it;
122  }
123  }
124 
126  for (auto it = tnCache_.cbegin(); it != tnCache_.cend();)
127  {
128  it->second->sweep();
129 
130  // Remove cache if empty
131  if (it->second->getTrackSize() == 0)
132  it = tnCache_.erase(it);
133  else
134  ++it;
135  }
136 }
137 
138 void
140 {
141  {
143  maxSeq_ = 0;
144  }
145 
146  {
148  fbCache_.clear();
149  }
150 
152  tnCache_.clear();
153 }
154 
155 void
157 {
158  std::ignore = nodeHash;
159  JLOG(j_.error()) << "Missing node in ledger sequence " << seq;
160 
162  if (maxSeq_ == 0)
163  {
164  maxSeq_ = seq;
165 
166  do
167  {
168  // Try to acquire the most recent missing ledger
169  seq = maxSeq_;
170 
171  lock.unlock();
172 
173  // This can invoke the missing node handler
175 
176  lock.lock();
177  } while (maxSeq_ != seq);
178  }
179  else if (maxSeq_ < seq)
180  {
181  // We found a more recent ledger with a missing node
182  maxSeq_ = seq;
183  }
184 }
185 
186 void
188 {
189  if (hash.isNonZero())
190  {
191  JLOG(j_.error()) << "Missing node in " << to_string(hash);
192 
194  hash, seq, InboundLedger::Reason::SHARD);
195  }
196 }
197 
198 } // namespace ripple
ripple::Application
Definition: Application.h:115
ripple::ShardFamily::getTreeNodeCache
std::shared_ptr< TreeNodeCache > getTreeNodeCache(std::uint32_t ledgerSeq) override
Return a pointer to the Family Tree Node Cache.
Definition: ShardFamily.cpp:77
ripple::ShardFamily::maxSeqMutex_
std::mutex maxSeqMutex_
Definition: ShardFamily.h:117
std::shared_ptr
STL class.
ripple::SizedItem
SizedItem
Definition: Config.h:48
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:537
ripple::ShardFamily::cm_
CollectorManager & cm_
Definition: ShardFamily.h:104
std::pair
ripple::ShardFamily::app_
Application & app_
Definition: ShardFamily.h:102
ripple::CollectorManager
Provides the beast::insight::Collector service.
Definition: CollectorManager.h:29
ripple::SizedItem::treeCacheAge
@ treeCacheAge
std::lock_guard
STL class.
ripple::Application::getShardStore
virtual NodeStore::DatabaseShard * getShardStore()=0
tuple
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:88
ripple::fullBelowExpiration
constexpr std::chrono::seconds fullBelowExpiration
Definition: app/main/Tuning.h:26
ripple::ShardFamily::fbCache_
std::unordered_map< std::uint32_t, std::shared_ptr< FullBelowCache > > fbCache_
Definition: ShardFamily.h:107
ripple::Application::getInboundLedgers
virtual InboundLedgers & getInboundLedgers()=0
ripple::ShardFamily::acquire
void acquire(uint256 const &hash, std::uint32_t seq)
Definition: ShardFamily.cpp:187
ripple::base_uint< 256 >
ripple::ShardFamily::ShardFamily
ShardFamily()=delete
ripple::ShardFamily::fbCacheMutex_
std::mutex fbCacheMutex_
Definition: ShardFamily.h:108
ripple::ShardFamily::getFullBelowCache
std::shared_ptr< FullBelowCache > getFullBelowCache(std::uint32_t ledgerSeq) override
Return a pointer to the Family Full Below Cache.
Definition: ShardFamily.cpp:48
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::InboundLedgers::acquire
virtual std::shared_ptr< Ledger const > acquire(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason)=0
std::unique_lock
STL class.
std::to_string
T to_string(T... args)
ripple::ShardFamily::reset
void reset() override
Definition: ShardFamily.cpp:139
beast::Journal::error
Stream error() const
Definition: Journal.h:333
std::uint32_t
ripple::ShardFamily::tnCache_
std::unordered_map< std::uint32_t, std::shared_ptr< TreeNodeCache > > tnCache_
Definition: ShardFamily.h:110
ripple::ShardFamily::getFullBelowCacheSize
int getFullBelowCacheSize()
Return the number of entries in the cache.
Definition: ShardFamily.cpp:67
ripple::fullBelowTargetSize
constexpr std::size_t fullBelowTargetSize
Definition: app/main/Tuning.h:25
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::ShardFamily::getTreeNodeCacheSize
std::pair< int, int > getTreeNodeCacheSize()
Return a pair where the first item is the number of items cached and the second item is the number of...
Definition: ShardFamily.cpp:95
ripple::ShardFamily::tnTargetAge_
const std::chrono::seconds tnTargetAge_
Definition: ShardFamily.h:113
ripple::ShardFamily::tnTargetSize_
const int tnTargetSize_
Definition: ShardFamily.h:112
ripple::SizedItem::treeCacheSize
@ treeCacheSize
ripple::ShardFamily::maxSeq_
LedgerIndex maxSeq_
Definition: ShardFamily.h:116
ripple::NodeStore::Database::seqToShardIndex
std::uint32_t seqToShardIndex(std::uint32_t ledgerSeq) const noexcept
Calculates the shard index for a given ledger sequence.
Definition: Database.h:283
ripple::ShardFamily::tnCacheMutex_
std::mutex tnCacheMutex_
Definition: ShardFamily.h:111
ripple::ShardFamily::sweep
void sweep() override
Definition: ShardFamily.cpp:109
ripple::ShardFamily::j_
const beast::Journal j_
Definition: ShardFamily.h:105
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::CollectorManager::collector
virtual beast::insight::Collector::ptr const & collector()=0
ripple::ShardFamily::missingNodeAcquireBySeq
void missingNodeAcquireBySeq(std::uint32_t seq, uint256 const &nodeHash) override
Acquire ledger that has a missing node by ledger sequence.
Definition: ShardFamily.cpp:156
ripple::LedgerMaster::getHashBySeq
uint256 getHashBySeq(std::uint32_t index)
Get a ledger's hash by sequence number using the cache.
Definition: LedgerMaster.cpp:1743
ripple::InboundLedger::Reason::SHARD
@ SHARD
ripple::getShardStore
static NodeStore::Database & getShardStore(Application &app)
Definition: ShardFamily.cpp:30