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 
26 namespace ripple {
27 
28 static NodeStore::Database&
30 {
31  auto const dbPtr = app.getShardStore();
32  assert(dbPtr);
33  return *dbPtr;
34 }
35 
37  : app_(app)
38  , db_(getShardStore(app))
39  , cm_(cm)
40  , j_(app.journal("ShardFamily"))
41  , tnTargetSize_(app.config().getValueFor(SizedItem::treeCacheSize, 0))
42  , tnTargetAge_(app.config().getValueFor(SizedItem::treeCacheAge, 0))
43 {
44 }
45 
48 {
49  auto const shardIndex{app_.getShardStore()->seqToShardIndex(ledgerSeq)};
51  if (auto const it{fbCache_.find(shardIndex)}; it != fbCache_.end())
52  return it->second;
53 
54  // Create a cache for the corresponding shard
55  auto fbCache{std::make_shared<FullBelowCache>(
56  "Shard family full below cache shard " + std::to_string(shardIndex),
57  stopwatch(),
58  cm_.collector(),
61  return fbCache_.emplace(shardIndex, std::move(fbCache)).first->second;
62 }
63 
64 int
66 {
67  size_t sz{0};
69  for (auto const& e : fbCache_)
70  sz += e.second->size();
71  return sz;
72 }
73 
76 {
77  auto const shardIndex{app_.getShardStore()->seqToShardIndex(ledgerSeq)};
79  if (auto const it{tnCache_.find(shardIndex)}; it != tnCache_.end())
80  return it->second;
81 
82  // Create a cache for the corresponding shard
83  auto tnCache{std::make_shared<TreeNodeCache>(
84  "Shard family tree node cache shard " + std::to_string(shardIndex),
87  stopwatch(),
88  j_)};
89  return tnCache_.emplace(shardIndex, std::move(tnCache)).first->second;
90 }
91 
94 {
95  int cacheSz{0};
96  int trackSz{0};
98  for (auto const& e : tnCache_)
99  {
100  cacheSz += e.second->getCacheSize();
101  trackSz += e.second->getTrackSize();
102  }
103  return {cacheSz, trackSz};
104 }
105 
106 void
108 {
109  {
111  for (auto it = fbCache_.cbegin(); it != fbCache_.cend();)
112  {
113  it->second->sweep();
114 
115  // Remove cache if empty
116  if (it->second->size() == 0)
117  it = fbCache_.erase(it);
118  else
119  ++it;
120  }
121  }
122 
124  for (auto it = tnCache_.cbegin(); it != tnCache_.cend();)
125  {
126  it->second->sweep();
127 
128  // Remove cache if empty
129  if (it->second->getTrackSize() == 0)
130  it = tnCache_.erase(it);
131  else
132  ++it;
133  }
134 }
135 
136 void
138 {
139  {
141  maxSeq_ = 0;
142  }
143 
144  {
146  fbCache_.clear();
147  }
148 
150  tnCache_.clear();
151 }
152 
153 void
155 {
156  JLOG(j_.error()) << "Missing node in ledger sequence " << seq;
157 
159  if (maxSeq_ == 0)
160  {
161  maxSeq_ = seq;
162 
163  do
164  {
165  // Try to acquire the most recent missing ledger
166  seq = maxSeq_;
167 
168  lock.unlock();
169 
170  // This can invoke the missing node handler
172 
173  lock.lock();
174  } while (maxSeq_ != seq);
175  }
176  else if (maxSeq_ < seq)
177  {
178  // We found a more recent ledger with a missing node
179  maxSeq_ = seq;
180  }
181 }
182 
183 void
185 {
186  if (hash.isNonZero())
187  {
188  JLOG(j_.error()) << "Missing node in " << to_string(hash);
189 
191  hash, seq, InboundLedger::Reason::SHARD);
192  }
193 }
194 
195 } // namespace ripple
ripple::Application
Definition: Application.h:97
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:75
ripple::ShardFamily::maxSeqMutex_
std::mutex maxSeqMutex_
Definition: ShardFamily.h:116
std::shared_ptr
STL class.
ripple::SizedItem
SizedItem
Definition: Config.h:48
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:444
ripple::ShardFamily::cm_
CollectorManager & cm_
Definition: ShardFamily.h:103
ripple::NodeStore::DatabaseShard::seqToShardIndex
virtual std::uint32_t seqToShardIndex(std::uint32_t seq) const =0
Calculates the shard index for a given ledger sequence.
std::pair
ripple::ShardFamily::app_
Application & app_
Definition: ShardFamily.h:101
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
ripple::ShardFamily::missingNode
void missingNode(std::uint32_t seq) override
Definition: ShardFamily.cpp:154
ripple::stopwatch
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:86
ripple::fullBelowExpiration
constexpr std::chrono::seconds fullBelowExpiration
Definition: app/main/Tuning.h:26
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::ShardFamily::fbCache_
std::unordered_map< std::uint32_t, std::shared_ptr< FullBelowCache > > fbCache_
Definition: ShardFamily.h:106
ripple::Application::getInboundLedgers
virtual InboundLedgers & getInboundLedgers()=0
ripple::ShardFamily::acquire
void acquire(uint256 const &hash, std::uint32_t seq)
Definition: ShardFamily.cpp:184
ripple::base_uint< 256 >
ripple::ShardFamily::ShardFamily
ShardFamily()=delete
ripple::ShardFamily::fbCacheMutex_
std::mutex fbCacheMutex_
Definition: ShardFamily.h:107
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:47
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:137
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:109
ripple::ShardFamily::getFullBelowCacheSize
int getFullBelowCacheSize()
Return the number of entries in the cache.
Definition: ShardFamily.cpp:65
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:93
ripple::ShardFamily::tnTargetAge_
const std::chrono::seconds tnTargetAge_
Definition: ShardFamily.h:112
ripple::ShardFamily::tnTargetSize_
const int tnTargetSize_
Definition: ShardFamily.h:111
ripple::SizedItem::treeCacheSize
@ treeCacheSize
ripple::ShardFamily::maxSeq_
LedgerIndex maxSeq_
Definition: ShardFamily.h:115
ripple::ShardFamily::tnCacheMutex_
std::mutex tnCacheMutex_
Definition: ShardFamily.h:110
ripple::ShardFamily::sweep
void sweep() override
Definition: ShardFamily.cpp:107
ripple::ShardFamily::j_
const beast::Journal j_
Definition: ShardFamily.h:104
ripple::CollectorManager::collector
virtual beast::insight::Collector::ptr const & collector()=0
ripple::LedgerMaster::getHashBySeq
uint256 getHashBySeq(std::uint32_t index)
Get a ledger's hash by sequence number using the cache.
Definition: LedgerMaster.cpp:1593
ripple::InboundLedger::Reason::SHARD
@ SHARD
ripple::getShardStore
static NodeStore::Database & getShardStore(Application &app)
Definition: ShardFamily.cpp:29