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  j_,
59  cm_.collector(),
62  return fbCache_.emplace(shardIndex, std::move(fbCache)).first->second;
63 }
64 
65 int
67 {
68  size_t sz{0};
70  for (auto const& e : fbCache_)
71  sz += e.second->size();
72  return sz;
73 }
74 
77 {
78  auto const shardIndex{app_.getShardStore()->seqToShardIndex(ledgerSeq)};
80  if (auto const it{tnCache_.find(shardIndex)}; it != tnCache_.end())
81  return it->second;
82 
83  // Create a cache for the corresponding shard
84  auto tnCache{std::make_shared<TreeNodeCache>(
85  "Shard family tree node cache shard " + std::to_string(shardIndex),
88  stopwatch(),
89  j_)};
90  return tnCache_.emplace(shardIndex, std::move(tnCache)).first->second;
91 }
92 
95 {
96  int cacheSz{0};
97  int trackSz{0};
99  for (auto const& e : tnCache_)
100  {
101  cacheSz += e.second->getCacheSize();
102  trackSz += e.second->getTrackSize();
103  }
104  return {cacheSz, trackSz};
105 }
106 
107 void
109 {
110  {
112  for (auto it = fbCache_.cbegin(); it != fbCache_.cend();)
113  {
114  it->second->sweep();
115 
116  // Remove cache if empty
117  if (it->second->size() == 0)
118  it = fbCache_.erase(it);
119  else
120  ++it;
121  }
122  }
123 
125  for (auto it = tnCache_.cbegin(); it != tnCache_.cend();)
126  {
127  it->second->sweep();
128 
129  // Remove cache if empty
130  if (it->second->getTrackSize() == 0)
131  it = tnCache_.erase(it);
132  else
133  ++it;
134  }
135 }
136 
137 void
139 {
140  {
142  maxSeq_ = 0;
143  }
144 
145  {
147  fbCache_.clear();
148  }
149 
151  tnCache_.clear();
152 }
153 
154 void
156 {
157  JLOG(j_.error()) << "Missing node in ledger sequence " << seq;
158 
160  if (maxSeq_ == 0)
161  {
162  maxSeq_ = seq;
163 
164  do
165  {
166  // Try to acquire the most recent missing ledger
167  seq = maxSeq_;
168 
169  lock.unlock();
170 
171  // This can invoke the missing node handler
173 
174  lock.lock();
175  } while (maxSeq_ != seq);
176  }
177  else if (maxSeq_ < seq)
178  {
179  // We found a more recent ledger with a missing node
180  maxSeq_ = seq;
181  }
182 }
183 
184 void
186 {
187  if (hash.isNonZero())
188  {
189  JLOG(j_.error()) << "Missing node in " << to_string(hash);
190 
192  hash, seq, InboundLedger::Reason::SHARD);
193  }
194 }
195 
196 } // 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:76
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:536
ripple::ShardFamily::cm_
CollectorManager & cm_
Definition: ShardFamily.h:103
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:155
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:106
ripple::Application::getInboundLedgers
virtual InboundLedgers & getInboundLedgers()=0
ripple::ShardFamily::acquire
void acquire(uint256 const &hash, std::uint32_t seq)
Definition: ShardFamily.cpp:185
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:138
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:66
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:94
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::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:110
ripple::ShardFamily::sweep
void sweep() override
Definition: ShardFamily.cpp:108
ripple::ShardFamily::j_
const beast::Journal j_
Definition: ShardFamily.h:104
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::LedgerMaster::getHashBySeq
uint256 getHashBySeq(std::uint32_t index)
Get a ledger's hash by sequence number using the cache.
Definition: LedgerMaster.cpp:1739
ripple::InboundLedger::Reason::SHARD
@ SHARD
ripple::getShardStore
static NodeStore::Database & getShardStore(Application &app)
Definition: ShardFamily.cpp:29