rippled
Cluster.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/main/Application.h>
21 #include <ripple/basics/Log.h>
22 #include <ripple/basics/StringUtilities.h>
23 #include <ripple/core/Config.h>
24 #include <ripple/core/TimeKeeper.h>
25 #include <ripple/overlay/Cluster.h>
26 #include <ripple/overlay/ClusterNode.h>
27 #include <ripple/protocol/jss.h>
28 #include <ripple/protocol/tokens.h>
29 #include <boost/regex.hpp>
30 #include <memory.h>
31 
32 namespace ripple {
33 
35 {
36 }
37 
39 Cluster::member(PublicKey const& identity) const
40 {
41  std::lock_guard lock(mutex_);
42 
43  auto iter = nodes_.find(identity);
44  if (iter == nodes_.end())
45  return std::nullopt;
46  return iter->name();
47 }
48 
51 {
52  std::lock_guard lock(mutex_);
53 
54  return nodes_.size();
55 }
56 
57 bool
59  PublicKey const& identity,
60  std::string name,
61  std::uint32_t loadFee,
62  NetClock::time_point reportTime)
63 {
64  std::lock_guard lock(mutex_);
65 
66  auto iter = nodes_.find(identity);
67 
68  if (iter != nodes_.end())
69  {
70  if (reportTime <= iter->getReportTime())
71  return false;
72 
73  if (name.empty())
74  name = iter->name();
75 
76  iter = nodes_.erase(iter);
77  }
78 
79  nodes_.emplace_hint(iter, identity, name, loadFee, reportTime);
80  return true;
81 }
82 
83 void
84 Cluster::for_each(std::function<void(ClusterNode const&)> func) const
85 {
86  std::lock_guard lock(mutex_);
87  for (auto const& ni : nodes_)
88  func(ni);
89 }
90 
91 bool
92 Cluster::load(Section const& nodes)
93 {
94  static boost::regex const re(
95  "[[:space:]]*" // skip leading whitespace
96  "([[:alnum:]]+)" // node identity
97  "(?:" // begin optional comment block
98  "[[:space:]]+" // (skip all leading whitespace)
99  "(?:" // begin optional comment
100  "(.*[^[:space:]]+)" // the comment
101  "[[:space:]]*" // (skip all trailing whitespace)
102  ")?" // end optional comment
103  ")?" // end optional comment block
104  );
105 
106  for (auto const& n : nodes.values())
107  {
108  boost::smatch match;
109 
110  if (!boost::regex_match(n, match, re))
111  {
112  JLOG(j_.error()) << "Malformed entry: '" << n << "'";
113  return false;
114  }
115 
116  auto const id = parseBase58<PublicKey>(TokenType::NodePublic, match[1]);
117 
118  if (!id)
119  {
120  JLOG(j_.error()) << "Invalid node identity: " << match[1];
121  return false;
122  }
123 
124  if (member(*id))
125  {
126  JLOG(j_.warn()) << "Duplicate node identity: " << match[1];
127  continue;
128  }
129 
130  update(*id, trim_whitespace(match[2]));
131  }
132 
133  return true;
134 }
135 
136 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:42
ripple::ClusterNode
Definition: ClusterNode.h:30
ripple::Cluster::Cluster
Cluster(beast::Journal j)
Definition: Cluster.cpp:34
std::string
STL class.
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
std::lock_guard
STL class.
ripple::Cluster::member
std::optional< std::string > member(PublicKey const &node) const
Determines whether a node belongs in the cluster.
Definition: Cluster.cpp:39
std::function
ripple::Cluster::update
bool update(PublicKey const &identity, std::string name, std::uint32_t loadFee=0, NetClock::time_point reportTime=NetClock::time_point{})
Store information about the state of a cluster node.
Definition: Cluster.cpp:58
ripple::trim_whitespace
std::string trim_whitespace(std::string str)
ripple::Cluster::load
bool load(Section const &nodes)
Load the list of cluster nodes.
Definition: Cluster.cpp:92
ripple::Section::values
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition: BasicConfig.h:77
ripple::Cluster::j_
beast::Journal j_
Definition: Cluster.h:68
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
beast::Journal::error
Stream error() const
Definition: Journal.h:333
std::chrono::time_point
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint32_t
ripple::Cluster::size
std::size_t size() const
The number of nodes in the cluster list.
Definition: Cluster.cpp:50
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Cluster::mutex_
std::mutex mutex_
Definition: Cluster.h:67
ripple::Cluster::nodes_
std::set< ClusterNode, Comparator > nodes_
Definition: Cluster.h:66
std::string::empty
T empty(T... args)
ripple::TokenType::NodePublic
@ NodePublic
std::optional< std::string >
std::size_t
ripple::Cluster::for_each
void for_each(std::function< void(ClusterNode const &)> func) const
Invokes the callback once for every cluster node.
Definition: Cluster.cpp:84