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 
38 boost::optional<std::string>
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 boost::none;
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  // We can't use auto here yet due to the libstdc++ issue
67  // described at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68190
69 
70  if (iter != nodes_.end())
71  {
72  if (reportTime <= iter->getReportTime())
73  return false;
74 
75  if (name.empty())
76  name = iter->name();
77 
78  iter = nodes_.erase(iter);
79  }
80 
81  nodes_.emplace_hint(iter, identity, name, loadFee, reportTime);
82  return true;
83 }
84 
85 void
86 Cluster::for_each(std::function<void(ClusterNode const&)> func) const
87 {
88  std::lock_guard lock(mutex_);
89  for (auto const& ni : nodes_)
90  func(ni);
91 }
92 
93 bool
94 Cluster::load(Section const& nodes)
95 {
96  static boost::regex const re(
97  "[[:space:]]*" // skip leading whitespace
98  "([[:alnum:]]+)" // node identity
99  "(?:" // begin optional comment block
100  "[[:space:]]+" // (skip all leading whitespace)
101  "(?:" // begin optional comment
102  "(.*[^[:space:]]+)" // the comment
103  "[[:space:]]*" // (skip all trailing whitespace)
104  ")?" // end optional comment
105  ")?" // end optional comment block
106  );
107 
108  for (auto const& n : nodes.values())
109  {
110  boost::smatch match;
111 
112  if (!boost::regex_match(n, match, re))
113  {
114  JLOG(j_.error()) << "Malformed entry: '" << n << "'";
115  return false;
116  }
117 
118  auto const id = parseBase58<PublicKey>(TokenType::NodePublic, match[1]);
119 
120  if (!id)
121  {
122  JLOG(j_.error()) << "Invalid node identity: " << match[1];
123  return false;
124  }
125 
126  if (member(*id))
127  {
128  JLOG(j_.warn()) << "Duplicate node identity: " << match[1];
129  continue;
130  }
131 
132  update(*id, trim_whitespace(match[2]));
133  }
134 
135  return true;
136 }
137 
138 } // namespace ripple
ripple::Section
Holds a collection of configuration values.
Definition: BasicConfig.h:43
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.
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:94
ripple::Section::values
std::vector< std::string > const & values() const
Returns all the values in the section.
Definition: BasicConfig.h:76
ripple::Cluster::member
boost::optional< std::string > member(PublicKey const &node) const
Determines whether a node belongs in the cluster.
Definition: Cluster.cpp:39
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::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:86
std::set
STL class.