Streamlined UNL/validator list:

The new code removes the ability to specify domain names
in the [validators] configuration block, and no longer
supports the [validators_site] option.

More details on the supported configurations are available
under doc/rippled-example.cfg.
This commit is contained in:
Nik Bougalis
2015-11-11 00:55:09 -08:00
parent 0a96f3a249
commit e0af6ec567
41 changed files with 971 additions and 2902 deletions

View File

@@ -1532,6 +1532,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\misc\impl\ValidatorList.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\misc\NetworkOPs.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
@@ -1552,18 +1556,14 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\app\misc\TxQ.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\misc\UniqueNodeList.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\misc\UniqueNodeList.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\misc\Validations.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\misc\Validations.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\app\misc\ValidatorList.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\paths\AccountCurrencies.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
@@ -1740,6 +1740,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\tests\ValidatorList_test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\tx\apply.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\app\tx\applySteps.h">
@@ -3371,22 +3375,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlLoad.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlNetwork.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlReset.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlScore.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\Unsubscribe.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>

View File

@@ -2271,6 +2271,9 @@
<ClCompile Include="..\..\src\ripple\app\misc\impl\TxQ.cpp">
<Filter>ripple\app\misc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\misc\impl\ValidatorList.cpp">
<Filter>ripple\app\misc\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\misc\NetworkOPs.cpp">
<Filter>ripple\app\misc</Filter>
</ClCompile>
@@ -2295,18 +2298,15 @@
<ClInclude Include="..\..\src\ripple\app\misc\TxQ.h">
<Filter>ripple\app\misc</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\misc\UniqueNodeList.cpp">
<Filter>ripple\app\misc</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\misc\UniqueNodeList.h">
<Filter>ripple\app\misc</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\misc\Validations.cpp">
<Filter>ripple\app\misc</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\misc\Validations.h">
<Filter>ripple\app\misc</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\app\misc\ValidatorList.h">
<Filter>ripple\app\misc</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\app\paths\AccountCurrencies.cpp">
<Filter>ripple\app\paths</Filter>
</ClCompile>
@@ -2463,6 +2463,9 @@
<ClCompile Include="..\..\src\ripple\app\tests\TxQ_test.cpp">
<Filter>ripple\app\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\app\tests\ValidatorList_test.cpp">
<Filter>ripple\app\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\app\tx\apply.h">
<Filter>ripple\app\tx</Filter>
</ClInclude>
@@ -4008,18 +4011,6 @@
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlList.cpp">
<Filter>ripple\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlLoad.cpp">
<Filter>ripple\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlNetwork.cpp">
<Filter>ripple\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlReset.cpp">
<Filter>ripple\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\UnlScore.cpp">
<Filter>ripple\rpc\handlers</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\rpc\handlers\Unsubscribe.cpp">
<Filter>ripple\rpc\handlers</Filter>
</ClCompile>

View File

@@ -503,17 +503,11 @@
#
# [validators]
#
# List of nodes to always accept as validators. Nodes are specified by domain
# or public key.
#
# For domains, rippled will probe for https web servers at the specified
# domain in the following order: ripple.DOMAIN, www.DOMAIN, DOMAIN
#
# For public key entries, a comment may optionally be specified after adding
# a space to the public key.
# List of the validation public keys of nodes to always accept as validators.
# A comment may, optionally, be associated with each entry, separated by
# whitespace from the validation public key.
#
# Examples:
# ripple.com
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
#
@@ -521,33 +515,27 @@
#
# [validators_file]
#
# Path to file contain a list of nodes to always accept as validators. Use
# this to specify a file other than this file to manage your validators list.
# Path to a file that contains the validation public keys of nodes to always
# accept as validators. A comment may, optionally, be associated with each
# entry, separated by whitespace from the validation public key.
#
# If this entry is not present or empty and no nodes from previous runs were
# found in the database, rippled will look for a validators.txt in the config
# directory. If not found there, it will attempt to retrieve the file from
# the [validators_site] web site.
#
# After specifying a different [validators_file] or changing the contents of
# the validators file, issue a RPC unl_load command to have rippled load the
# file.
# The contents of the file should include a [validators] entry, followed by
# a list of validation public keys of nodes to always accept as validators,
# one per line, optionally followed by a comment separated by whitespace:
#
# Specify the file by specifying its full path.
#
# Examples:
# C:/home/johndoe/ripple/validators.txt
# /home/johndoe/ripple/validators.txt
#
#
#
# [validators_site]
#
# Specifies where to find validators.txt for UNL boostrapping and RPC
# unl_network command.
#
# Example: ripple.com
# /home/ripple/validators.txt
# C:/home/ripple/validators.txt
#
# Example content:
# [validators]
# n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7 RL1
# n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj RL2
# n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C RL3
# n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS RL4
# n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA RL5
#
#
# [path_search]

View File

@@ -42,9 +42,9 @@
#include <ripple/app/misc/SHAMapStore.h>
#include <ripple/app/misc/TxQ.h>
#include <ripple/app/misc/Validations.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/app/paths/PathRequests.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/tx/apply.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
@@ -323,7 +323,7 @@ public:
TaggedCache <uint256, AcceptedLedger> m_acceptedLedgerCache;
std::unique_ptr <NetworkOPs> m_networkOPs;
std::unique_ptr <Cluster> cluster_;
std::unique_ptr <UniqueNodeList> m_deprecatedUNL;
std::unique_ptr <ValidatorList> validators_;
std::unique_ptr <ServerHandler> serverHandler_;
std::unique_ptr <AmendmentTable> m_amendmentTable;
std::unique_ptr <LoadFeeTrack> mFeeTrack;
@@ -446,8 +446,11 @@ public:
*m_jobQueue, *m_ledgerMaster, *m_jobQueue,
logs_->journal("NetworkOPs")))
// VFALCO NOTE LocalCredentials starts the deprecated UNL service
, m_deprecatedUNL (make_UniqueNodeList (*this, *m_jobQueue))
, cluster_ (std::make_unique<Cluster> (
logs_->journal("Overlay")))
, validators_ (std::make_unique<ValidatorList> (
logs_->journal("UniqueNodeList")))
, serverHandler_ (make_ServerHandler (*this, *m_networkOPs, get_io_service (),
*m_jobQueue, *m_networkOPs, *m_resourceManager, *m_collectorManager))
@@ -658,9 +661,9 @@ public:
return *mValidations;
}
UniqueNodeList& getUNL () override
ValidatorList& validators () override
{
return *m_deprecatedUNL;
return *validators_;
}
Cluster& cluster () override
@@ -1001,22 +1004,23 @@ void ApplicationImp::setup()
m_orderBookDB.setup (getLedgerMaster ().getCurrentLedger ());
cluster_ = make_Cluster (config (), logs_->journal("Overlay"));
if (!cluster_->load (config().section(SECTION_CLUSTER_NODES)))
{
m_journal.fatal << "Invalid entry in cluster configuration.";
throw std::exception();
}
if (!validators_->load (config().section (SECTION_VALIDATORS)))
{
m_journal.fatal << "Invalid entry in validator configuration.";
throw std::exception();
}
if (validators_->size () == 0 && !config_->RUN_STANDALONE)
m_journal.warning << "No validators are configured.";
// Begin validation and ip maintenance.
//
// - LocalCredentials maintains local information: including identity
// - and network connection persistence information.
//
// VFALCO NOTE this starts the UNL
m_localCredentials.start ();
//
// Set up UNL.
//
if (!config_->RUN_STANDALONE)
getUNL ().nodeBootstrap ();
m_nodeStore->tune (config_->getSize (siNodeCacheSize), config_->getSize (siNodeCacheAge));
m_ledgerMaster->tune (config_->getSize (siLedgerSize), config_->getSize (siLedgerAge));
family().treecache().setTargetSize (config_->getSize (siTreeCacheSize));

View File

@@ -45,7 +45,6 @@ class HashRouter;
class Logs;
class LoadFeeTrack;
class LocalCredentials;
class UniqueNodeList;
class JobQueue;
class InboundLedgers;
class InboundTransactions;
@@ -64,6 +63,7 @@ class TimeKeeper;
class TransactionMaster;
class TxQ;
class Validations;
class ValidatorList;
class Cluster;
class DatabaseCon;
@@ -117,7 +117,7 @@ public:
virtual LoadManager& getLoadManager () = 0;
virtual Overlay& overlay () = 0;
virtual TxQ& getTxQ() = 0;
virtual UniqueNodeList& getUNL () = 0;
virtual ValidatorList& validators () = 0;
virtual Cluster& cluster () = 0;
virtual Validations& getValidations () = 0;
virtual NodeStore::Database& getNodeStore () = 0;

View File

@@ -21,7 +21,6 @@
#include <ripple/core/DatabaseCon.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/main/LocalCredentials.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/StringUtilities.h>
@@ -52,8 +51,6 @@ void LocalCredentials::start ()
if (!app_.config().QUIET)
std::cerr << "NodeIdentity: " << mNodePublicKey.humanNodePublic () << std::endl;
app_.getUNL ().start ();
}
// Retrieve network identity.

View File

@@ -37,11 +37,11 @@
#include <ripple/app/main/LocalCredentials.h>
#include <ripple/app/misc/HashRouter.h>
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/app/misc/TxQ.h>
#include <ripple/app/misc/Validations.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/app/misc/impl/AccountTxPaging.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/tx/apply.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>

File diff suppressed because it is too large Load Diff

View File

@@ -1,86 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_APP_PEERS_UNIQUENODELIST_H_INCLUDED
#define RIPPLE_APP_PEERS_UNIQUENODELIST_H_INCLUDED
#include <ripple/app/main/Application.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple/protocol/RippleAddress.h>
#include <beast/threads/Stoppable.h>
#include <boost/filesystem.hpp>
#include <memory> // <memory>
namespace ripple {
class UniqueNodeList : public beast::Stoppable
{
protected:
explicit UniqueNodeList (Stoppable& parent);
public:
enum ValidatorSource
{
vsConfig = 'C', // rippled.cfg
vsInbound = 'I',
vsManual = 'M',
vsReferral = 'R',
vsTold = 'T',
vsValidator = 'V', // validators.txt
vsWeb = 'W',
};
// VFALCO TODO rename this to use the right coding style
using score = long;
public:
virtual ~UniqueNodeList () { }
// VFALCO TODO Roll this into the constructor so there is one less state.
virtual void start () = 0;
virtual void insertEphemeralKey (PublicKey pk, std::string comment) = 0;
virtual void deleteEphemeralKey (PublicKey const& pk) = 0;
// VFALCO TODO rename all these, the "node" prefix is redundant (lol)
virtual void nodeAddPublic (RippleAddress const& naNodePublic, ValidatorSource vsWhy, std::string const& strComment) = 0;
virtual void nodeAddDomain (std::string strDomain, ValidatorSource vsWhy, std::string const& strComment = "") = 0;
virtual void nodeRemovePublic (RippleAddress const& naNodePublic) = 0;
virtual void nodeRemoveDomain (std::string strDomain) = 0;
virtual void nodeReset () = 0;
virtual void nodeScore () = 0;
virtual bool nodeInUNL (RippleAddress const& naNodePublic) = 0;
virtual void nodeBootstrap () = 0;
virtual bool nodeLoad (boost::filesystem::path pConfig) = 0;
virtual void nodeNetwork () = 0;
virtual Json::Value getUnlJson () = 0;
virtual int iSourceScore (ValidatorSource vsWhy) = 0;
};
std::unique_ptr<UniqueNodeList>
make_UniqueNodeList (Application& app, beast::Stoppable& parent);
} // ripple
#endif

View File

@@ -24,7 +24,7 @@
#include <ripple/app/ledger/LedgerTiming.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/basics/chrono.h>
@@ -89,7 +89,7 @@ private:
RippleAddress signer = val->getSignerPublic ();
bool isCurrent = current (val);
if (! val->isTrusted() && app_.getUNL().nodeInUNL (signer))
if (!val->isTrusted() && app_.validators().trusted (signer))
val->setTrusted();
if (!val->isTrusted ())

View File

@@ -0,0 +1,121 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2015 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_APP_MISC_VALIDATORLIST_H_INCLUDED
#define RIPPLE_APP_MISC_VALIDATORLIST_H_INCLUDED
#include <ripple/basics/BasicConfig.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/UnorderedContainers.h>
#include <ripple/protocol/PublicKey.h>
#include <boost/optional.hpp>
#include <functional>
#include <memory>
#include <mutex>
namespace ripple {
class ValidatorList
{
private:
/** The non-ephemeral public keys from the configuration file. */
hash_map<PublicKey, std::string> permanent_;
/** The ephemeral public keys from manifests. */
hash_map<PublicKey, std::string> ephemeral_;
std::mutex mutable mutex_;
beast::Journal mutable j_;
public:
explicit
ValidatorList (beast::Journal j);
/** Determines whether a node is in the UNL
@return boost::none if the node isn't a member,
otherwise, the comment associated with the
node (which may be an empty string).
*/
boost::optional<std::string>
member (
RippleAddress const& identity) const;
/** Determines whether a node is in the UNL */
bool
trusted (
RippleAddress const& identity) const;
/** Insert a short-term validator key published in a manifest. */
bool
insertEphemeralKey (
PublicKey const& identity,
std::string const& comment);
/** Remove a short-term validator revoked in a manifest. */
bool
removeEphemeralKey (
PublicKey const& identity);
/** Insert a long-term validator key. */
bool
insertPermanentKey (
RippleAddress const& identity,
std::string const& comment);
/** Remove a long-term validator key. */
bool
removePermanentKey (
RippleAddress const& identity);
/** The number of installed permanent and ephemeral keys */
std::size_t
size () const;
/** Invokes the callback once for every node in the UNL.
@note You are not allowed to insert or remove any
nodes in the UNL from within the callback.
The arguments passed into the lambda are:
- The public key of the validator;
- A (possibly empty) comment.
- A boolean indicating whether this is a
permanent or ephemeral key;
*/
void
for_each (
std::function<void(PublicKey const&, std::string const&, bool)> func) const;
/** Load the list of trusted validators.
The section contains entries consisting of a base58
encoded validator public key, optionally followed by
a comment.
@return false if an entry could not be parsed or
contained an invalid validator public key,
true otherwise.
*/
bool
load (
Section const& validators);
};
}
#endif

View File

@@ -0,0 +1,208 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2015 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/basics/Slice.h>
#include <ripple/basics/StringUtilities.h>
#include <boost/regex.hpp>
namespace ripple {
static
PublicKey
asPublicKey(RippleAddress const& raPublicKey)
{
auto const& blob = raPublicKey.getNodePublic();
if (blob.empty())
LogicError ("Can't convert invalid RippleAddress to PublicKey");
return PublicKey(Slice(blob.data(), blob.size()));
}
ValidatorList::ValidatorList (beast::Journal j)
: j_ (j)
{
}
boost::optional<std::string>
ValidatorList::member (RippleAddress const& identity) const
{
std::lock_guard <std::mutex> sl (mutex_);
auto const publicKey = asPublicKey (identity);
auto ret = ephemeral_.find (publicKey);
if (ret != ephemeral_.end())
return ret->second;
ret = permanent_.find (publicKey);
if (ret != permanent_.end())
return ret->second;
return boost::none;
}
bool
ValidatorList::trusted (RippleAddress const& identity) const
{
return static_cast<bool> (member(identity));
}
bool
ValidatorList::insertEphemeralKey (
PublicKey const& identity,
std::string const& comment)
{
std::lock_guard <std::mutex> sl (mutex_);
if (permanent_.find (identity) != permanent_.end())
{
JLOG (j_.error) <<
toBase58 (TokenType::TOKEN_NODE_PUBLIC, identity) <<
": ephemeral key exists in permanent table!";
return false;
}
return ephemeral_.emplace (identity, comment).second;
}
bool
ValidatorList::removeEphemeralKey (
PublicKey const& identity)
{
std::lock_guard <std::mutex> sl (mutex_);
return ephemeral_.erase (identity);
}
bool
ValidatorList::insertPermanentKey (
RippleAddress const& identity,
std::string const& comment)
{
std::lock_guard <std::mutex> sl (mutex_);
auto const publicKey = asPublicKey (identity);
if (ephemeral_.find (publicKey) != ephemeral_.end())
{
JLOG (j_.error) <<
toBase58 (TokenType::TOKEN_NODE_PUBLIC, publicKey) <<
": permanent key exists in ephemeral table!";
return false;
}
return permanent_.emplace (publicKey, comment).second;
}
bool
ValidatorList::removePermanentKey (
RippleAddress const& identity)
{
std::lock_guard <std::mutex> sl (mutex_);
return permanent_.erase (asPublicKey (identity));
}
std::size_t
ValidatorList::size () const
{
std::lock_guard <std::mutex> sl (mutex_);
return permanent_.size () + ephemeral_.size ();
}
void
ValidatorList::for_each (
std::function<void(PublicKey const&, std::string const&, bool)> func) const
{
std::lock_guard <std::mutex> sl (mutex_);
for (auto const& v : permanent_)
func (v.first, v.second, false);
for (auto const& v : ephemeral_)
func (v.first, v.second, true);
}
bool
ValidatorList::load (
Section const& validators)
{
static boost::regex const re (
"[[:space:]]*" // skip leading whitespace
"([[:alnum:]]+)" // node identity
"(?:" // begin optional comment block
"[[:space:]]+" // (skip all leading whitespace)
"(?:" // begin optional comment
"(.*[^[:space:]]+)" // the comment
"[[:space:]]*" // (skip all trailing whitespace)
")?" // end optional comment
")?" // end optional comment block
);
JLOG (j_.debug) <<
"Loading configured validators";
std::size_t count = 0;
for (auto const& n : validators.values ())
{
JLOG (j_.trace) <<
"Processing '" << n << "'";
boost::smatch match;
if (!boost::regex_match (n, match, re))
{
JLOG (j_.error) <<
"Malformed entry: '" << n << "'";
return false;
}
auto const id = parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, match[1]);
if (!id)
{
JLOG (j_.error) <<
"Invalid node identity: " << match[1];
return false;
}
auto const ra = RippleAddress::createNodePublic (match[1]);
if (trusted (ra))
{
JLOG (j_.warning) <<
"Duplicate node identity: " << match[1];
continue;
}
if (insertPermanentKey(ra, trim_whitespace (match[2])))
++count;
}
JLOG (j_.debug) <<
"Loaded " << count << " entries";
return true;
}
}

View File

@@ -0,0 +1,280 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright 2015 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/basics/TestSuite.h>
#include <ripple/app/misc/ValidatorList.h>
namespace ripple {
namespace tests {
class ValidatorList_test : public ripple::TestSuite
{
private:
static
PublicKey
asPublicKey(RippleAddress const& raPublicKey)
{
auto const& blob = raPublicKey.getNodePublic();
if (blob.empty())
LogicError ("Can't convert invalid RippleAddress to PublicKey");
return PublicKey(Slice(blob.data(), blob.size()));
}
static
RippleAddress
randomNode ()
{
return RippleAddress::createNodePublic (
RippleAddress::createSeedRandom ());
}
static
bool
isPresent (
std::vector<RippleAddress> container,
RippleAddress const& item)
{
auto found = std::find (
std::begin (container),
std::end (container),
item);
return (found != std::end (container));
}
void
testConfigLoad ()
{
testcase ("Config Load");
auto validators = std::make_unique <ValidatorList> (beast::Journal ());
std::vector<RippleAddress> network;
while (network.size () != 8)
network.push_back (randomNode());
Section s1;
// Correct (empty) configuration
expect (validators->load (s1));
expect (validators->size() == 0);
// Correct configuration
s1.append (network[0].humanNodePublic());
s1.append (network[1].humanNodePublic() + " Comment");
s1.append (network[2].humanNodePublic() + " Multi Word Comment");
s1.append (network[3].humanNodePublic() + " Leading Whitespace");
s1.append (network[4].humanNodePublic() + " Trailing Whitespace ");
s1.append (network[5].humanNodePublic() + " Leading & Trailing Whitespace ");
s1.append (network[6].humanNodePublic() + " Leading, Trailing & Internal Whitespace ");
s1.append (network[7].humanNodePublic() + " ");
expect (validators->load (s1));
for (auto const& n : network)
expect (validators->trusted (n));
// Incorrect configurations:
Section s2;
s2.append ("NotAPublicKey");
expect (!validators->load (s2));
Section s3;
s3.append ("@" + network[0].humanNodePublic());
expect (!validators->load (s3));
Section s4;
s4.append (network[0].humanNodePublic() + "!");
expect (!validators->load (s4));
Section s5;
s5.append (network[0].humanNodePublic() + "! Comment");
expect (!validators->load (s5));
// Check if we properly terminate when we encounter
// a malformed or unparseable entry:
auto const badNode = randomNode();
auto const goodNode = randomNode ();
Section s6;
s6.append (badNode.humanNodePublic() + "XXX");
s6.append (goodNode.humanNodePublic());
expect (!validators->load (s6));
expect (!validators->trusted (badNode));
expect (!validators->trusted (goodNode));
}
void
testMembership ()
{
// The servers on the permanentValidators
std::vector<RippleAddress> permanentValidators;
std::vector<RippleAddress> ephemeralValidators;
while (permanentValidators.size () != 64)
permanentValidators.push_back (randomNode());
while (ephemeralValidators.size () != 64)
ephemeralValidators.push_back (randomNode());
{
testcase ("Membership: No Validators");
auto vl = std::make_unique <ValidatorList> (beast::Journal ());
for (auto const& v : permanentValidators)
expect (!vl->trusted (v));
for (auto const& v : ephemeralValidators)
expect (!vl->trusted (v));
}
{
testcase ("Membership: Non-Empty, Some Present, Some Not Present");
std::vector<RippleAddress> p (
permanentValidators.begin (),
permanentValidators.begin () + 16);
while (p.size () != 32)
p.push_back (randomNode());
std::vector<RippleAddress> e (
ephemeralValidators.begin (),
ephemeralValidators.begin () + 16);
while (e.size () != 32)
e.push_back (randomNode());
auto vl = std::make_unique <ValidatorList> (beast::Journal ());
for (auto const& v : p)
vl->insertPermanentKey (v, v.ToString());
for (auto const& v : e)
vl->insertEphemeralKey (asPublicKey (v), v.ToString());
for (auto const& v : p)
expect (vl->trusted (v));
for (auto const& v : e)
expect (vl->trusted (v));
for (auto const& v : permanentValidators)
expect (static_cast<bool>(vl->trusted (v)) == isPresent (p, v));
for (auto const& v : ephemeralValidators)
expect (static_cast<bool>(vl->trusted (v)) == isPresent (e, v));
}
}
void
testModification ()
{
testcase ("Insertion and Removal");
auto vl = std::make_unique <ValidatorList> (beast::Journal ());
auto const v = randomNode ();
// Inserting a new permanent key succeeds
expect (vl->insertPermanentKey (v, "Permanent"));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Permanent") == 0);
}
// Inserting the same permanent key fails:
expect (!vl->insertPermanentKey (v, ""));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Permanent") == 0);
}
// Inserting the same key as ephemeral fails:
expect (!vl->insertEphemeralKey (asPublicKey(v), "Ephemeral"));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Permanent") == 0);
}
// Removing the key as ephemeral fails:
expect (!vl->removeEphemeralKey (asPublicKey(v)));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Permanent") == 0);
}
// Deleting the key as permanent succeeds:
expect (vl->removePermanentKey (v));
expect (!static_cast<bool>(vl->trusted (v)));
// Insert an ephemeral validator key
expect (vl->insertEphemeralKey (asPublicKey(v), "Ephemeral"));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Ephemeral") == 0);
}
// Inserting the same ephemeral key fails
expect (!vl->insertEphemeralKey (asPublicKey(v), ""));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Ephemeral") == 0);
}
// Inserting the same key as permanent fails:
expect (!vl->insertPermanentKey (v, "Permanent"));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Ephemeral") == 0);
}
// Deleting the key as permanent fails:
expect (!vl->removePermanentKey (v));
{
auto member = vl->member (v);
expect (static_cast<bool>(member));
expect (member->compare("Ephemeral") == 0);
}
// Deleting the key as ephemeral succeeds:
expect (vl->removeEphemeralKey (asPublicKey(v)));
expect (!vl->trusted(v));
}
public:
void
run() override
{
testConfigLoad();
testMembership ();
testModification ();
}
};
BEAST_DEFINE_TESTSUITE(ValidatorList, app, ripple);
} // tests
} // ripple

View File

@@ -93,6 +93,8 @@ bool parseIpPort (std::string const& strSource, std::string& strIP, int& iPort);
bool parseUrl (std::string const& strUrl, std::string& strScheme,
std::string& strDomain, int& iPort, std::string& strPath);
std::string trim_whitespace (std::string str);
} // ripple
#endif

View File

@@ -189,4 +189,11 @@ bool parseUrl (std::string const& strUrl, std::string& strScheme, std::string& s
return bMatch;
}
std::string trim_whitespace (std::string str)
{
boost::trim (str);
return str;
}
} // ripple

View File

@@ -43,19 +43,6 @@
namespace ripple {
IniFileSections
parseIniFile (std::string const& strInput, const bool bTrim);
bool
getSingleSection (IniFileSections& secSource,
std::string const& strSection, std::string& strValue, beast::Journal j);
int
countSectionEntries (IniFileSections& secSource, std::string const& strSection);
IniFileSections::mapped_type*
getIniFileSection (IniFileSections& secSource, std::string const& strSection);
class Rules;
//------------------------------------------------------------------------------
@@ -91,31 +78,10 @@ struct SizedItem
class Config : public BasicConfig
{
public:
struct Helpers
{
// This replaces CONFIG_FILE_NAME
static char const* getConfigFileName ()
{
return "rippled.cfg";
}
static char const* getDatabaseDirName ()
{
return "db";
}
static char const* getValidatorsFileName ()
{
return "validators.txt";
}
};
//--------------------------------------------------------------------------
// Settings related to the configuration file location and directories
/** Returns the directory from which the configuration file was loaded. */
beast::File getConfigDir () const;
static char const* const configFileName;
static char const* const databaseDirName;
static char const* const validatorsFileName;
/** Returns the full path and filename of the debug log file. */
boost::filesystem::path getDebugLogFile () const;
@@ -123,31 +89,13 @@ public:
/** Returns the full path and filename of the entropy seed file. */
boost::filesystem::path getEntropyFile () const;
// DEPRECATED
boost::filesystem::path CONFIG_FILE; // used by UniqueNodeList
private:
boost::filesystem::path CONFIG_FILE;
boost::filesystem::path CONFIG_DIR;
boost::filesystem::path DEBUG_LOGFILE;
void load ();
beast::Journal j_;
public:
//--------------------------------------------------------------------------
// Settings related to validators
/** Return the path to the separate, optional validators file. */
beast::File getValidatorsFile () const;
/** Returns the optional URL to a trusted network source of validators. */
beast::URL getValidatorsURL () const;
// DEPRECATED
boost::filesystem::path VALIDATORS_FILE; // As specifed in rippled.cfg.
/** List of Validators entries from rippled.cfg */
std::vector <std::string> validators;
public:
//--------------------------------------------------------------------------
@@ -164,9 +112,6 @@ public:
bool SILENT = false; // No output to console after startup.
bool ELB_SUPPORT = false;
std::string VALIDATORS_SITE; // Where to find validators.txt on the Internet.
std::string VALIDATORS_URI; // URI of validators.txt.
std::string VALIDATORS_BASE; // Name
std::vector<std::string> IPS; // Peer IPs from rippled.cfg.
std::vector<std::string> IPS_FIXED; // Fixed Peer IPs from rippled.cfg.
std::vector<std::string> SNTP_SERVERS; // SNTP servers from rippled.cfg.
@@ -225,8 +170,7 @@ public:
RippleAddress VALIDATION_PUB;
RippleAddress VALIDATION_PRIV;
// Node/Cluster
std::vector<std::string> CLUSTER_NODES;
// Node
RippleAddress NODE_SEED;
RippleAddress NODE_PUB;
RippleAddress NODE_PRIV;

View File

@@ -64,7 +64,6 @@ struct ConfigSection
#define SECTION_VALIDATION_SEED "validation_seed"
#define SECTION_WEBSOCKET_PING_FREQ "websocket_ping_frequency"
#define SECTION_VALIDATORS "validators"
#define SECTION_VALIDATORS_SITE "validators_site"
} // ripple

View File

@@ -35,10 +35,7 @@
#include <boost/regex.hpp>
#include <fstream>
#include <iostream>
#ifndef DUMP_CONFIG
#define DUMP_CONFIG 0
#endif
#include <iterator>
namespace ripple {
@@ -110,15 +107,6 @@ getIniFileSection (IniFileSections& secSource, std::string const& strSection)
return smtResult;
}
int
countSectionEntries (IniFileSections& secSource, std::string const& strSection)
{
IniFileSections::mapped_type* pmtEntries =
getIniFileSection (secSource, strSection);
return pmtEntries ? pmtEntries->size () : 0;
}
bool getSingleSection (IniFileSections& secSource,
std::string const& strSection, std::string& strValue, beast::Journal j)
{
@@ -140,52 +128,16 @@ bool getSingleSection (IniFileSections& secSource,
return bSingle;
}
/** Parses a set of strings into IP::Endpoint
Strings which fail to parse are not included in the output. If a stream is
provided, human readable diagnostic error messages are written for each
failed parse.
@param out An OutputSequence to store the IP::Endpoint list
@param first The begining of the string input sequence
@param last The one-past-the-end of the string input sequence
*/
template <class OutputSequence, class InputIterator>
void
parseAddresses (OutputSequence& out, InputIterator first, InputIterator last,
beast::Journal::Stream stream = beast::Journal::Stream ())
{
while (first != last)
{
auto const str (*first);
++first;
{
beast::IP::Endpoint const addr (
beast::IP::Endpoint::from_string (str));
if (! is_unspecified (addr))
{
out.push_back (addr);
continue;
}
}
{
beast::IP::Endpoint const addr (
beast::IP::Endpoint::from_string_altform (str));
if (! is_unspecified (addr))
{
out.push_back (addr);
continue;
}
}
if (stream) stream <<
"Config: \"" << str << "\" is not a valid IP address.";
}
}
//------------------------------------------------------------------------------
//
// Config (DEPRECATED)
//
//------------------------------------------------------------------------------
char const* const Config::configFileName = "rippled.cfg";
char const* const Config::databaseDirName = "db";
char const* const Config::validatorsFileName = "validators.txt";
static
std::string
getEnvVar (char const* name)
@@ -214,12 +166,12 @@ void Config::setup (std::string const& strConf, bool bQuiet)
QUIET = bQuiet;
strDbPath = Helpers::getDatabaseDirName ();
strConfFile = strConf.empty () ? Helpers::getConfigFileName () : strConf;
strDbPath = databaseDirName;
VALIDATORS_BASE = Helpers::getValidatorsFileName ();
VALIDATORS_URI = boost::str (boost::format ("/%s") % VALIDATORS_BASE);
if (!strConf.empty())
strConfFile = strConf;
else
strConfFile = configFileName;
if (!strConf.empty ())
{
@@ -328,12 +280,6 @@ void Config::loadFromString (std::string const& fileContents)
build (secConfig);
if (auto s = getIniFileSection (secConfig, SECTION_VALIDATORS))
validators = *s;
if (auto s = getIniFileSection (secConfig, SECTION_CLUSTER_NODES))
CLUSTER_NODES = *s;
if (auto s = getIniFileSection (secConfig, SECTION_IPS))
IPS = *s;
@@ -372,8 +318,6 @@ void Config::loadFromString (std::string const& fileContents)
}
}
(void) getSingleSection (secConfig, SECTION_VALIDATORS_SITE, VALIDATORS_SITE, j_);
std::string strTemp;
if (getSingleSection (secConfig, SECTION_PEER_PRIVATE, strTemp, j_))
@@ -489,9 +433,84 @@ void Config::loadFromString (std::string const& fileContents)
if (getSingleSection (secConfig, SECTION_PATH_SEARCH_MAX, strTemp, j_))
PATH_SEARCH_MAX = beast::lexicalCastThrow <int> (strTemp);
// If a file was explicitly specified, then warn if the path is malformed
// or the file does not exist or is not a file.
// If no path was specified, then look for validators.txt in the same path
// as the config file - don't complain if we can't find it.
boost::filesystem::path validatorsFile;
if (getSingleSection (secConfig, SECTION_VALIDATORS_FILE, strTemp, j_))
{
VALIDATORS_FILE = strTemp;
validatorsFile = strTemp;
if (validatorsFile.empty ())
{
JLOG (j_.error) <<
"[" SECTION_VALIDATORS_FILE "]" <<
": " << strTemp <<
" is not a valid path";
validatorsFile.clear ();
}
else if (!boost::filesystem::exists (validatorsFile))
{
JLOG (j_.error) <<
"[" SECTION_VALIDATORS_FILE "]" <<
": the file " << validatorsFile <<
" does not exist";
validatorsFile.clear ();
}
else if (!boost::filesystem::is_regular_file (validatorsFile))
{
JLOG (j_.error) <<
"[" SECTION_VALIDATORS_FILE "]" <<
": the file " << validatorsFile <<
" is not a regular file";
validatorsFile.clear ();
}
}
else
{
validatorsFile = CONFIG_DIR / validatorsFileName;
if (!validatorsFile.empty ())
{
if(!boost::filesystem::exists (validatorsFile))
validatorsFile.clear();
else if (!boost::filesystem::is_regular_file (validatorsFile))
validatorsFile.clear();
}
}
if (!validatorsFile.empty () &&
boost::filesystem::exists (validatorsFile) &&
boost::filesystem::is_regular_file (validatorsFile))
{
std::ifstream ifsDefault (validatorsFile.native().c_str());
std::string data;
data.assign (
std::istreambuf_iterator<char>(ifsDefault),
std::istreambuf_iterator<char>());
auto iniFile = parseIniFile (data, true);
auto entries = getIniFileSection (
iniFile,
SECTION_VALIDATORS);
if (!entries)
{
JLOG (j_.error) <<
"[" SECTION_VALIDATORS_FILE "]" <<
": the file " << validatorsFile <<
" does not contain a [" SECTION_VALIDATORS <<
"] section";
}
else
{
section (SECTION_VALIDATORS).append (*entries);
}
}
if (getSingleSection (secConfig, SECTION_DEBUG_LOGFILE, strTemp, j_))
@@ -575,27 +594,6 @@ boost::filesystem::path Config::getDebugLogFile () const
return log_file;
}
beast::File Config::getConfigDir () const
{
beast::String const s (CONFIG_FILE.native().c_str ());
if (s.isNotEmpty ())
return beast::File (s).getParentDirectory ();
return beast::File::nonexistent ();
}
beast::File Config::getValidatorsFile () const
{
beast::String const s (VALIDATORS_FILE.native().c_str());
if (s.isNotEmpty() && getConfigDir() != beast::File::nonexistent())
return getConfigDir().getChildFile (s);
return beast::File::nonexistent ();
}
beast::URL Config::getValidatorsURL () const
{
return beast::parse_URL (VALIDATORS_SITE).second;
}
beast::File Config::getModuleDatabasePath () const
{
boost::filesystem::path dbPath (legacy ("database_path"));

View File

@@ -156,10 +156,10 @@ public:
if (dbPath.empty ())
{
dataDir_ = subDir_ / path (Config::Helpers::getDatabaseDirName ());
dataDir_ = subDir_ / path (Config::databaseDirName);
}
configFile_ = subDir_ / path (Config::Helpers::getConfigFileName ());
configFile_ = subDir_ / path (Config::configFileName);
{
if (!exists (subDir_))
{
@@ -338,7 +338,7 @@ port_wss_admin
auto& c (g.config ());
std::string const nativeDbPath =
absolute (path ("test_db") /
path (Config::Helpers::getDatabaseDirName ()))
path (Config::databaseDirName))
.string ();
expect (g.dataDirExists ());
expect (g.configFileExists ());

View File

@@ -953,10 +953,6 @@ public:
{ "unl_add", &RPCParser::parseUnlAdd, 1, 2 },
{ "unl_delete", &RPCParser::parseUnlDelete, 1, 1 },
{ "unl_list", &RPCParser::parseAsIs, 0, 0 },
{ "unl_load", &RPCParser::parseAsIs, 0, 0 },
{ "unl_network", &RPCParser::parseAsIs, 0, 0 },
{ "unl_reset", &RPCParser::parseAsIs, 0, 0 },
{ "unl_score", &RPCParser::parseAsIs, 0, 0 },
{ "validation_create", &RPCParser::parseValidationCreate, 0, 1 },
{ "validation_seed", &RPCParser::parseValidationSeed, 0, 1 },
{ "version", &RPCParser::parseAsIs, 0, 0 },

View File

@@ -23,7 +23,7 @@
#include <BeastConfig.h>
#include <ripple/app/main/Application.h>
#include <ripple/basics/chrono.h>
#include <ripple/core/Config.h>
#include <ripple/basics/BasicConfig.h>
#include <ripple/overlay/ClusterNode.h>
#include <ripple/protocol/RippleAddress.h>
#include <beast/hash/uhash.h>
@@ -76,9 +76,9 @@ public:
Cluster (beast::Journal j);
/** Determines whether a node belongs in the cluster
@return empty optional if the node isn't a member,
otherwise, the node's name (which may be
empty).
@return boost::none if the node isn't a member,
otherwise, the comment associated with the
node (which may be an empty string).
*/
boost::optional<std::string>
member (RippleAddress const& node) const;
@@ -106,10 +106,20 @@ public:
void
for_each (
std::function<void(ClusterNode const&)> func) const;
};
std::unique_ptr<Cluster>
make_Cluster (Config const& config, beast::Journal j);
/** Load the list of cluster nodes.
The section contains entries consisting of a base58
encoded node public key, optionally followed by
a comment.
@return false if an entry could not be parsed or
contained an invalid node public key,
true otherwise.
*/
bool
load (Section const& nodes);
};
} // ripple

View File

@@ -20,6 +20,7 @@
#include <BeastConfig.h>
#include <ripple/app/main/Application.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/StringUtilities.h>
#include <ripple/core/Config.h>
#include <ripple/core/TimeKeeper.h>
#include <ripple/overlay/Cluster.h>
@@ -93,51 +94,52 @@ Cluster::for_each (
func (ni);
}
std::unique_ptr<Cluster>
make_Cluster (Config const& config, beast::Journal j)
bool
Cluster::load (Section const& nodes)
{
static boost::regex const re (
"^" // start of line
"(?:\\s*)" // whitespace (optional)
"([a-zA-Z0-9]*)" // Node identity
"(?:\\s*)" // whitespace (optional)
"(.*\\S*)" // <value>
"(?:\\s*)" // whitespace (optional)
"[[:space:]]*" // skip leading whitespace
"([[:alnum:]]+)" // node identity
"(?:" // begin optional comment block
"[[:space:]]+" // (skip all leading whitespace)
"(?:" // begin optional comment
"(.*[^[:space:]]+)" // the comment
"[[:space:]]*" // (skip all trailing whitespace)
")?" // end optional comment
")?" // end optional comment block
);
auto cluster = std::make_unique<Cluster> (j);
for (auto const& n : config.CLUSTER_NODES)
for (auto const& n : nodes.values())
{
boost::smatch match;
if (!boost::regex_match (n, match, re))
{
JLOG (j.error) <<
JLOG (j_.error) <<
"Malformed entry: '" << n << "'";
continue;
return false;
}
auto const nid = RippleAddress::createNodePublic (match[1]);
if (!nid.isValid())
{
JLOG (j.error) <<
JLOG (j_.error) <<
"Invalid node identity: " << match[1];
continue;
return false;
}
if (cluster->member (nid))
if (member (nid))
{
JLOG (j.warning) <<
JLOG (j_.warning) <<
"Duplicate node identity: " << match[1];
continue;
}
cluster->update(nid, match[2]);
update(nid, trim_whitespace(match[2]));
}
return cluster;
return true;
}
} // ripple

View File

@@ -26,7 +26,6 @@
#include <ripple/overlay/impl/TMHello.h>
#include <ripple/overlay/impl/Tuning.h>
#include <ripple/overlay/Message.h>
#include <ripple/app/misc/UniqueNodeList.h> // move to .cpp
#include <ripple/protocol/BuildInfo.h>
#include <ripple/protocol/UintTypes.h>
#include <beast/asio/placeholders.h>

View File

@@ -18,8 +18,8 @@
//==============================================================================
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/basics/contract.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/core/DatabaseCon.h>
#include <ripple/overlay/impl/Manifest.h>
#include <ripple/protocol/RippleAddress.h>
@@ -158,7 +158,7 @@ ManifestCache::configValidatorKey(
void
ManifestCache::configManifest (
Manifest m, UniqueNodeList& unl, beast::Journal journal)
Manifest m, ValidatorList& unl, beast::Journal journal)
{
if (! m.verify())
{
@@ -228,7 +228,7 @@ ManifestCache::canApply (PublicKey const& pk, std::uint32_t seq,
ManifestDisposition
ManifestCache::applyManifest (
Manifest m, UniqueNodeList& unl, beast::Journal journal)
Manifest m, ValidatorList& unl, beast::Journal journal)
{
{
std::lock_guard<std::mutex> lock (mutex_);
@@ -307,7 +307,7 @@ ManifestCache::applyManifest (
m.masterKey, m.sequence, old->sequence);
}
unl.deleteEphemeralKey (old->signingKey);
unl.removeEphemeralKey (old->signingKey);
}
if (m.revoked ())
@@ -335,7 +335,7 @@ ManifestCache::applyManifest (
}
void ManifestCache::load (
DatabaseCon& dbCon, UniqueNodeList& unl, beast::Journal journal)
DatabaseCon& dbCon, ValidatorList& unl, beast::Journal journal)
{
static const char* const sql =
"SELECT RawData FROM ValidatorManifests;";

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_OVERLAY_MANIFEST_H_INCLUDED
#define RIPPLE_OVERLAY_MANIFEST_H_INCLUDED
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/basics/BasicConfig.h>
#include <ripple/basics/UnorderedContainers.h>
#include <ripple/protocol/PublicKey.h>
@@ -162,16 +162,16 @@ public:
~ManifestCache() = default;
void configValidatorKey(std::string const& line, beast::Journal journal);
void configManifest (Manifest m, UniqueNodeList& unl, beast::Journal journal);
void configManifest (Manifest m, ValidatorList& unl, beast::Journal journal);
void addTrustedKey (PublicKey const& pk, std::string comment);
ManifestDisposition
applyManifest (
Manifest m, UniqueNodeList& unl, beast::Journal journal);
Manifest m, ValidatorList& unl, beast::Journal journal);
void load (
DatabaseCon& dbCon, UniqueNodeList& unl, beast::Journal journal);
DatabaseCon& dbCon, ValidatorList& unl, beast::Journal journal);
void save (DatabaseCon& dbCon) const;
// A "for_each" for populated manifests only

View File

@@ -463,7 +463,10 @@ OverlayImpl::setupValidatorKeyManifests (BasicConfig const& config,
s = beast::base64_decode(s);
if (auto mo = make_Manifest (std::move (s)))
{
manifestCache_.configManifest (std::move (*mo), app_.getUNL (), journal_);
manifestCache_.configManifest (
std::move (*mo),
app_.validators(),
journal_);
}
else
{
@@ -476,7 +479,10 @@ OverlayImpl::setupValidatorKeyManifests (BasicConfig const& config,
journal_.warning << "No [validation_manifest] section in config";
}
manifestCache_.load (db, app_.getUNL(), journal_);
manifestCache_.load (
db,
app_.validators(),
journal_);
}
void
@@ -685,8 +691,10 @@ OverlayImpl::onManifests (
continue;
auto const serialized = mo->serialized;
auto const result =
manifestCache_.applyManifest (std::move(*mo), app_.getUNL(), journal);
auto const result = manifestCache_.applyManifest (
std::move(*mo),
app_.validators(),
journal);
if (result == ManifestDisposition::accepted)
{

View File

@@ -28,8 +28,8 @@
#include <ripple/app/misc/HashRouter.h>
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/misc/Validations.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/app/tx/apply.h>
#include <ripple/protocol/digest.h>
#include <ripple/basics/random.h>
@@ -1265,7 +1265,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMProposeSet> const& m)
return;
}
bool isTrusted = app_.getUNL ().nodeInUNL (signerPublic);
auto const isTrusted = app_.validators().trusted (signerPublic);
if (!isTrusted)
{
@@ -1594,7 +1594,8 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMValidation> const& m)
return;
}
bool isTrusted = app_.getUNL ().nodeInUNL (val->getSignerPublic ());
auto const isTrusted =
app_.validators().trusted(val->getSignerPublic ());
if (!isTrusted && (sanity_.load () == Sanity::insane))
{
p_journal_.debug <<
@@ -1606,9 +1607,13 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMValidation> const& m)
app_.getJobQueue ().addJob (
isTrusted ? jtVALIDATION_t : jtVALIDATION_ut,
"recvValidation->checkValidation",
[weak, val, isTrusted, m] (Job&) {
[weak, val, isTrusted, m] (Job&)
{
if (auto peer = weak.lock())
peer->checkValidation(val, isTrusted, m);
peer->checkValidation(
val,
isTrusted,
m);
});
}
else

View File

@@ -18,6 +18,7 @@
//==============================================================================
#include <BeastConfig.h>
#include <ripple/basics/BasicConfig.h>
#include <ripple/basics/TestSuite.h>
#include <ripple/overlay/Cluster.h>
#include <ripple/overlay/ClusterNode.h>
@@ -29,7 +30,7 @@ class cluster_test : public ripple::TestSuite
{
public:
std::unique_ptr<Cluster>
make_Cluster (std::vector<RippleAddress> const& nodes)
create (std::vector<RippleAddress> const& nodes)
{
auto cluster = std::make_unique <Cluster> (beast::Journal ());
@@ -58,7 +59,7 @@ public:
{
testcase ("Membership: Empty cluster");
auto c = make_Cluster ({});
auto c = create ({});
for (auto const& n : network)
expect (!c->member (n));
@@ -71,7 +72,7 @@ public:
while (cluster.size () != 32)
cluster.push_back (randomNode());
auto c = make_Cluster (cluster);
auto c = create (cluster);
for (auto const& n : network)
expect (!c->member (n));
@@ -86,7 +87,7 @@ public:
while (cluster.size () != 32)
cluster.push_back (randomNode());
auto c = make_Cluster (cluster);
auto c = create (cluster);
for (auto const& n : cluster)
expect (c->member (n));
@@ -106,7 +107,7 @@ public:
std::vector<RippleAddress> cluster (
network.begin (), network.begin () + 32);
auto c = make_Cluster (cluster);
auto c = create (cluster);
for (auto const& n : cluster)
expect (c->member (n));
@@ -126,7 +127,7 @@ public:
{
testcase ("Updating");
auto c = make_Cluster ({});
auto c = create ({});
auto const node = randomNode ();
std::uint32_t load = 0;
@@ -177,11 +178,78 @@ public:
}
}
void
testConfigLoad ()
{
testcase ("Config Load");
auto c = std::make_unique <Cluster> (beast::Journal ());
// The servers on the network
std::vector<RippleAddress> network;
while (network.size () != 8)
network.push_back (randomNode());
Section s1;
// Correct (empty) configuration
expect (c->load (s1));
expect (c->size() == 0);
// Correct configuration
s1.append (network[0].humanNodePublic());
s1.append (network[1].humanNodePublic() + " Comment");
s1.append (network[2].humanNodePublic() + " Multi Word Comment");
s1.append (network[3].humanNodePublic() + " Leading Whitespace");
s1.append (network[4].humanNodePublic() + " Trailing Whitespace ");
s1.append (network[5].humanNodePublic() + " Leading & Trailing Whitespace ");
s1.append (network[6].humanNodePublic() + " Leading, Trailing & Internal Whitespace ");
s1.append (network[7].humanNodePublic() + " ");
expect (c->load (s1));
for (auto const& n : network)
expect (c->member (n));
// Incorrect configurations
Section s2;
s2.append ("NotAPublicKey");
expect (!c->load (s2));
Section s3;
s3.append ("@" + network[0].humanNodePublic());
expect (!c->load (s3));
Section s4;
s4.append (network[0].humanNodePublic() + "!");
expect (!c->load (s4));
Section s5;
s5.append (network[0].humanNodePublic() + "! Comment");
expect (!c->load (s5));
// Check if we properly terminate when we encounter
// a malformed or unparseable entry:
auto const badNode = randomNode();
auto const goodNode = randomNode ();
Section s6;
s6.append (badNode.humanNodePublic() + "XXX");
s6.append (goodNode.humanNodePublic());
expect (!c->load (s6));
expect (!c->member (badNode));
expect (!c->member (goodNode));
}
void
run() override
{
testMembership ();
testUpdating ();
testConfigLoad ();
}
};

View File

@@ -26,7 +26,6 @@
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/Sign.h>
#include <ripple/protocol/STExchange.h>
#include <ripple/test/jtx.h>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
@@ -122,7 +121,7 @@ public:
return Manifest (m.serialized, m.masterKey, m.signingKey, m.sequence);
}
void testLoadStore (ManifestCache const& m, UniqueNodeList& unl)
void testLoadStore (ManifestCache const& m, ValidatorList& unl)
{
testcase ("load/store");
@@ -184,8 +183,8 @@ public:
run() override
{
ManifestCache cache;
test::jtx::Env env(*this);
auto& unl = env.app().getUNL();
beast::Journal journal;
auto unl = std::make_unique<ValidatorList> (journal);
{
testcase ("apply");
auto const accepted = ManifestDisposition::accepted;
@@ -193,8 +192,6 @@ public:
auto const stale = ManifestDisposition::stale;
auto const invalid = ManifestDisposition::invalid;
beast::Journal journal;
auto const sk_a = randomSecretKey();
auto const pk_a = derivePublicKey(KeyType::ed25519, sk_a);
auto const kp_a = randomKeyPair(KeyType::secp256k1);
@@ -210,26 +207,26 @@ public:
make_Manifest (KeyType::ed25519, sk_b, kp_b.first, 2, true); // broken
auto const fake = s_b1.serialized + '\0';
expect (cache.applyManifest (clone (s_a0), unl, journal) == untrusted,
expect (cache.applyManifest (clone (s_a0), *unl, journal) == untrusted,
"have to install a trusted key first");
cache.addTrustedKey (pk_a, "a");
cache.addTrustedKey (pk_b, "b");
expect (cache.applyManifest (clone (s_a0), unl, journal) == accepted);
expect (cache.applyManifest (clone (s_a0), unl, journal) == stale);
expect (cache.applyManifest (clone (s_a0), *unl, journal) == accepted);
expect (cache.applyManifest (clone (s_a0), *unl, journal) == stale);
expect (cache.applyManifest (clone (s_a1), unl, journal) == accepted);
expect (cache.applyManifest (clone (s_a1), unl, journal) == stale);
expect (cache.applyManifest (clone (s_a0), unl, journal) == stale);
expect (cache.applyManifest (clone (s_a1), *unl, journal) == accepted);
expect (cache.applyManifest (clone (s_a1), *unl, journal) == stale);
expect (cache.applyManifest (clone (s_a0), *unl, journal) == stale);
expect (cache.applyManifest (clone (s_b0), unl, journal) == accepted);
expect (cache.applyManifest (clone (s_b0), unl, journal) == stale);
expect (cache.applyManifest (clone (s_b0), *unl, journal) == accepted);
expect (cache.applyManifest (clone (s_b0), *unl, journal) == stale);
expect (!ripple::make_Manifest(fake));
expect (cache.applyManifest (clone (s_b2), unl, journal) == invalid);
expect (cache.applyManifest (clone (s_b2), *unl, journal) == invalid);
}
testLoadStore (cache, unl);
testLoadStore (cache, *unl);
}
};

View File

@@ -75,7 +75,7 @@ JSS ( action );
JSS ( acquiring ); // out: LedgerRequest
JSS ( address ); // out: PeerImp
JSS ( affected ); // out: AcceptedLedgerTx
JSS ( age ); // out: UniqueNodeList, NetworkOPs, Peers
JSS ( age ); // out: NetworkOPs, Peers
JSS ( alternatives ); // out: PathRequest, RipplePathFind
JSS ( amendment_blocked ); // out: NetworkOPs
JSS ( asks ); // out: Subscribe

View File

@@ -20,7 +20,7 @@
#include <BeastConfig.h>
#include <beast/utility/make_lock.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/json/json_value.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/ErrorCodes.h>
@@ -31,32 +31,28 @@
namespace ripple {
// {
// node: <domain>|<node_public>,
// node: <node_public>,
// comment: <comment> // optional
// }
Json::Value doUnlAdd (RPC::Context& context)
{
auto lock = beast::make_lock(context.app.getMasterMutex());
std::string strNode = context.params.isMember (jss::node)
? context.params[jss::node].asString () : "";
std::string strComment = context.params.isMember (jss::comment)
? context.params[jss::comment].asString () : "";
if (!context.params.isMember (jss::node))
return rpcError (rpcINVALID_PARAMS);
RippleAddress raNodePublic;
if (raNodePublic.setNodePublic (strNode))
if (raNodePublic.setNodePublic (context.params[jss::node].asString ()))
{
context.app.getUNL ().nodeAddPublic (
raNodePublic, UniqueNodeList::vsManual, strComment);
context.app.validators().insertPermanentKey (
raNodePublic,
context.params.isMember (jss::comment)
? context.params[jss::comment].asString ()
: "");
return RPC::makeObjectValue ("adding node by public key");
}
else
{
context.app.getUNL ().nodeAddDomain (
strNode, UniqueNodeList::vsManual, strComment);
return RPC::makeObjectValue ("adding node by domain");
}
return rpcError (rpcINVALID_PARAMS);
}
} // ripple

View File

@@ -19,7 +19,7 @@
#include <BeastConfig.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/protocol/ErrorCodes.h>
@@ -39,19 +39,14 @@ Json::Value doUnlDelete (RPC::Context& context)
if (!context.params.isMember (jss::node))
return rpcError (rpcINVALID_PARAMS);
auto strNode = context.params[jss::node].asString ();
RippleAddress raNodePublic;
if (raNodePublic.setNodePublic (strNode))
if (raNodePublic.setNodePublic (context.params[jss::node].asString ()))
{
context.app.getUNL ().nodeRemovePublic (raNodePublic);
context.app.validators().removePermanentKey (raNodePublic);
return RPC::makeObjectValue ("removing node by public key");
}
else
{
context.app.getUNL ().nodeRemoveDomain (strNode);
return RPC::makeObjectValue ("removing node by domain");
}
return rpcError (rpcINVALID_PARAMS);
}
} // ripple

View File

@@ -19,7 +19,7 @@
#include <BeastConfig.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/misc/ValidatorList.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/rpc/Context.h>
#include <beast/utility/make_lock.h>
@@ -31,7 +31,22 @@ Json::Value doUnlList (RPC::Context& context)
auto lock = beast::make_lock(context.app.getMasterMutex());
Json::Value obj (Json::objectValue);
obj[jss::unl] = context.app.getUNL ().getUnlJson ();
context.app.validators().for_each (
[&unl = obj[jss::unl]](
PublicKey const& publicKey,
std::string const& comment,
bool ephemeral)
{
Json::Value node (Json::objectValue);
node["publicKey"] = toBase58(
TokenType::TOKEN_NODE_PUBLIC, publicKey);
node["ephemeral"] = ephemeral;
if (!comment.empty())
node["comment"] = comment;
unl.append (node);
});
return obj;
}

View File

@@ -1,45 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/core/Config.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/net/RPCErr.h>
#include <ripple/rpc/impl/Handler.h>
#include <beast/utility/make_lock.h>
namespace ripple {
// Populate the UNL from a local validators.txt file.
Json::Value doUnlLoad (RPC::Context& context)
{
auto lock = beast::make_lock(context.app.getMasterMutex());
if (context.app.config().VALIDATORS_FILE.empty ()
|| !context.app.getUNL ().nodeLoad (context.app.config().VALIDATORS_FILE))
{
return rpcError (rpcLOAD_FAILED);
}
return RPC::makeObjectValue ("loading");
}
} // ripple

View File

@@ -1,41 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/rpc/impl/Handler.h>
#include <beast/utility/make_lock.h>
namespace ripple {
namespace RPC {
struct Context;
}
// Populate the UNL from ripple.com's validators.txt file.
Json::Value doUnlNetwork (RPC::Context& context)
{
auto lock = beast::make_lock(context.app.getMasterMutex());
context.app.getUNL ().nodeNetwork ();
return RPC::makeObjectValue ("fetching");
}
} // ripple

View File

@@ -1,40 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/rpc/impl/Handler.h>
#include <beast/utility/make_lock.h>
namespace ripple {
namespace RPC {
struct Context;
}
Json::Value doUnlReset (RPC::Context& context)
{
auto lock = beast::make_lock(context.app.getMasterMutex());
context.app.getUNL ().nodeReset ();
return RPC::makeObjectValue ("removing nodes");
}
} // ripple

View File

@@ -1,41 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2014 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <beast/utility/make_lock.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/net/RPCErr.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/rpc/Context.h>
#include <ripple/rpc/impl/Handler.h>
namespace ripple {
// unl_score
Json::Value doUnlScore (RPC::Context& context)
{
auto lock = beast::make_lock(context.app.getMasterMutex());
context.app.getUNL ().nodeScore ();
return RPC::makeObjectValue ("scoring requested");
}
} // ripple

View File

@@ -149,10 +149,6 @@ Handler handlerArray[] {
{ "unl_add", byRef (&doUnlAdd), Role::ADMIN, NO_CONDITION },
{ "unl_delete", byRef (&doUnlDelete), Role::ADMIN, NO_CONDITION },
{ "unl_list", byRef (&doUnlList), Role::ADMIN, NO_CONDITION },
{ "unl_load", byRef (&doUnlLoad), Role::ADMIN, NO_CONDITION },
{ "unl_network", byRef (&doUnlNetwork), Role::ADMIN, NO_CONDITION },
{ "unl_reset", byRef (&doUnlReset), Role::ADMIN, NO_CONDITION },
{ "unl_score", byRef (&doUnlScore), Role::ADMIN, NO_CONDITION },
{ "validation_create", byRef (&doValidationCreate), Role::ADMIN, NO_CONDITION },
{ "validation_seed", byRef (&doValidationSeed), Role::ADMIN, NO_CONDITION },
{ "wallet_propose", byRef (&doWalletPropose), Role::ADMIN, NO_CONDITION },

View File

@@ -25,9 +25,9 @@
#include <ripple/app/misc/HashRouter.cpp>
#include <ripple/app/misc/NetworkOPs.cpp>
#include <ripple/app/misc/SHAMapStoreImp.cpp>
#include <ripple/app/misc/UniqueNodeList.cpp>
#include <ripple/app/misc/Validations.cpp>
#include <ripple/app/misc/impl/AccountTxPaging.cpp>
#include <ripple/app/misc/impl/Transaction.cpp>
#include <ripple/app/misc/impl/TxQ.cpp>
#include <ripple/app/misc/impl/ValidatorList.cpp>

View File

@@ -34,3 +34,4 @@
#include <ripple/app/tests/OversizeMeta_test.cpp>
#include <ripple/app/tests/Taker.test.cpp>
#include <ripple/app/tests/TxQ_test.cpp>
#include <ripple/app/tests/ValidatorList_test.cpp>

View File

@@ -83,10 +83,6 @@
#include <ripple/rpc/handlers/UnlAdd.cpp>
#include <ripple/rpc/handlers/UnlDelete.cpp>
#include <ripple/rpc/handlers/UnlList.cpp>
#include <ripple/rpc/handlers/UnlLoad.cpp>
#include <ripple/rpc/handlers/UnlNetwork.cpp>
#include <ripple/rpc/handlers/UnlReset.cpp>
#include <ripple/rpc/handlers/UnlScore.cpp>
#include <ripple/rpc/handlers/Unsubscribe.cpp>
#include <ripple/rpc/handlers/ValidationCreate.cpp>
#include <ripple/rpc/handlers/ValidationSeed.cpp>