From 2bfae2f0ac87af10c65b4617526a83b1c8ec6802 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 18 Jul 2015 13:07:37 -0700 Subject: [PATCH] Tidy up UNL module: * Renamed module to unl * Renamed classes and members * Removed cyclic dependency in Horizon --- Builds/VisualStudio2013/RippleD.vcxproj | 43 ++- .../VisualStudio2013/RippleD.vcxproj.filters | 64 ++-- SConstruct | 5 +- src/ripple/app/ledger/impl/LedgerMaster.cpp | 2 +- src/ripple/app/main/Application.cpp | 10 +- src/ripple/app/main/Application.h | 4 +- src/ripple/overlay/impl/OverlayImpl.cpp | 12 + src/ripple/overlay/impl/PeerImp.cpp | 11 +- src/ripple/overlay/impl/PeerImp.h | 25 +- src/ripple/unity/{validators.cpp => unl.cpp} | 10 +- .../Connection.h => unl/Horizon.h} | 33 +- src/ripple/{validators => unl}/README.md | 0 src/ripple/unl/UNLManager.h | 83 ++++ .../impl/BasicHorizon.cpp} | 4 +- .../impl/BasicHorizon.h} | 89 +++-- src/ripple/{validators => unl}/impl/Logic.cpp | 17 +- src/ripple/{validators => unl}/impl/Logic.h | 22 +- src/ripple/{validators => unl}/impl/Store.h | 6 +- .../{validators => unl}/impl/StoreSqdb.cpp | 4 +- .../{validators => unl}/impl/StoreSqdb.h | 8 +- src/ripple/{validators => unl}/impl/Tuning.h | 6 +- src/ripple/unl/impl/UNLManager.cpp | 354 ++++++++++++++++++ src/ripple/{validators => unl}/make_Manager.h | 8 +- .../validators/tests/Validators.test.cpp | 39 -- 24 files changed, 673 insertions(+), 186 deletions(-) rename src/ripple/unity/{validators.cpp => unl.cpp} (80%) rename src/ripple/{validators/Connection.h => unl/Horizon.h} (68%) rename src/ripple/{validators => unl}/README.md (100%) create mode 100644 src/ripple/unl/UNLManager.h rename src/ripple/{validators/impl/ConnectionImp.cpp => unl/impl/BasicHorizon.cpp} (93%) rename src/ripple/{validators/impl/ConnectionImp.h => unl/impl/BasicHorizon.h} (74%) rename src/ripple/{validators => unl}/impl/Logic.cpp (92%) rename src/ripple/{validators => unl}/impl/Logic.h (86%) rename src/ripple/{validators => unl}/impl/Store.h (91%) rename src/ripple/{validators => unl}/impl/StoreSqdb.cpp (95%) rename src/ripple/{validators => unl}/impl/StoreSqdb.h (90%) rename src/ripple/{validators => unl}/impl/Tuning.h (90%) create mode 100644 src/ripple/unl/impl/UNLManager.cpp rename src/ripple/{validators => unl}/make_Manager.h (89%) delete mode 100644 src/ripple/validators/tests/Validators.test.cpp diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index cb3e963e44..bc104f0bad 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -3908,7 +3908,9 @@ True True - + + True + True @@ -3918,36 +3920,37 @@ ..\..\src\websocketpp;%(AdditionalIncludeDirectories) ..\..\src\websocketpp;%(AdditionalIncludeDirectories) - + - - True + + True + True - + - - True + + True + True - + - + - - True + + True + True - + - + - - True + + True + True - + - - True - - + diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index 7d252272f2..ecd220f76d 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -436,14 +436,11 @@ {5DB3CD0B-B361-B301-9562-697CA8A52B68} - - {B23DCD4C-1622-2C31-4562-87F2F95D3884} + + {843C622F-AA52-E6C5-D3EB-D4B6D564B395} - - {3D1F0CBE-9B69-D29E-EAAE-E5A1204068BC} - - - {663AE0EE-6781-C2F4-8D04-0D5D30AC0773} + + {416459B4-BDA4-31D6-834A-88932E767F37} {44780F86-42D3-2F2B-0846-5AEE2CA6D7FE} @@ -4563,7 +4560,7 @@ ripple\unity - + ripple\unity @@ -4572,44 +4569,41 @@ ripple\unity - - ripple\validators + + ripple\unl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators\impl + + ripple\unl\impl - - ripple\validators + + ripple\unl - - ripple\validators\tests - - - ripple\validators + + ripple\unl ripple\websocket diff --git a/SConstruct b/SConstruct index c2bce4f74c..1eedf758ac 100644 --- a/SConstruct +++ b/SConstruct @@ -679,7 +679,8 @@ def get_classic_sources(toolchain): append_sources(result, *list_sources('src/ripple/rpc', '.cpp')) append_sources(result, *list_sources('src/ripple/shamap', '.cpp')) append_sources(result, *list_sources('src/ripple/test', '.cpp')) - + append_sources(result, *list_sources('src/ripple/unl', '.cpp')) + append_sources( result, *list_sources('src/ripple/nodestore', '.cpp'), @@ -716,6 +717,7 @@ def get_unity_sources(toolchain): 'src/ripple/unity/rpcx.cpp', 'src/ripple/unity/shamap.cpp', 'src/ripple/unity/test.cpp', + 'src/ripple/unity/unl.cpp', ) append_sources( @@ -843,7 +845,6 @@ for tu_style in ['classic', 'unity']: 'src/ripple/unity/ripple.proto.cpp', 'src/ripple/unity/resource.cpp', 'src/ripple/unity/server.cpp', - 'src/ripple/unity/validators.cpp', 'src/ripple/unity/websocket02.cpp' ) diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index d0f86b1e35..1934225d16 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include #include #include // diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 035d1e5fc4..556f8355df 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include @@ -291,7 +291,7 @@ public: std::unique_ptr m_networkOPs; std::unique_ptr m_deprecatedUNL; std::unique_ptr serverHandler_; - std::unique_ptr m_validators; + std::unique_ptr m_validators; std::unique_ptr m_amendmentTable; std::unique_ptr mFeeTrack; std::unique_ptr mHashRouter; @@ -407,8 +407,8 @@ public: , serverHandler_ (make_ServerHandler (*m_networkOPs, get_io_service (), *m_jobQueue, *m_networkOPs, *m_resourceManager, *m_collectorManager)) - , m_validators (Validators::make_Manager(*this, get_io_service(), - m_logs.journal("UVL"), getConfig ())) + , m_validators (unl::make_Manager(*this, get_io_service(), + m_logs.journal("UNL"), getConfig ())) , m_amendmentTable (make_AmendmentTable (weeks(2), MAJORITY_FRACTION, @@ -570,7 +570,7 @@ public: return cachedSLEs_; } - Validators::Manager& getValidators () + unl::Manager& getValidators () { return *m_validators; } diff --git a/src/ripple/app/main/Application.h b/src/ripple/app/main/Application.h index 9dc4a86f11..c169867a7b 100644 --- a/src/ripple/app/main/Application.h +++ b/src/ripple/app/main/Application.h @@ -31,7 +31,7 @@ namespace boost { namespace asio { class io_service; } } namespace ripple { -namespace Validators { class Manager; } +namespace unl { class Manager; } namespace Resource { class Manager; } namespace NodeStore { class Database; } @@ -98,7 +98,7 @@ public: virtual JobQueue& getJobQueue () = 0; virtual NodeCache& getTempNodeCache () = 0; virtual CachedSLEs& cachedSLEs() = 0; - virtual Validators::Manager& getValidators () = 0; + virtual unl::Manager& getValidators () = 0; virtual AmendmentTable& getAmendmentTable() = 0; virtual IHashRouter& getHashRouter () = 0; virtual LoadFeeTrack& getFeeTrack () = 0; diff --git a/src/ripple/overlay/impl/OverlayImpl.cpp b/src/ripple/overlay/impl/OverlayImpl.cpp index 9b00fe2e03..b6a914b1c5 100644 --- a/src/ripple/overlay/impl/OverlayImpl.cpp +++ b/src/ripple/overlay/impl/OverlayImpl.cpp @@ -111,6 +111,18 @@ OverlayImpl::Timer::on_timer (error_code ec) overlay_.sendEndpoints(); overlay_.autoConnect(); + { + std::lock_guard< + std::recursive_mutex> lock (overlay_.mutex_); + for (auto const& e : overlay_.m_publicKeyMap) + { + auto const sp = e.second.lock(); + if (sp) + if (sp->unlHorizon_->shouldDrop()) + sp->fail("Poor UNL horizon"); + } + } + if ((++overlay_.timer_count_ % Tuning::checkSeconds) == 0) overlay_.check(); diff --git a/src/ripple/overlay/impl/PeerImp.cpp b/src/ripple/overlay/impl/PeerImp.cpp index 67e7119ca9..609c649e8a 100644 --- a/src/ripple/overlay/impl/PeerImp.cpp +++ b/src/ripple/overlay/impl/PeerImp.cpp @@ -81,7 +81,8 @@ PeerImp::PeerImp (id_t id, endpoint_type remote_endpoint, , fee_ (Resource::feeLightPeer) , slot_ (slot) , http_message_(std::move(request)) - , validatorsConnection_(getApp().getValidators().newConnection(id)) + , unlHorizon_(getApp().getValidators().insert(id, + slotToHorizonKind(*slot_))) { } @@ -425,7 +426,10 @@ PeerImp::close() void PeerImp::fail(std::string const& reason) { - assert(strand_.running_in_this_thread()); + if(! strand_.running_in_this_thread()) + return strand_.post(std::bind ( + (void(Peer::*)(std::string const&))&PeerImp::fail, + shared_from_this(), reason)); if (socket_.is_open()) if (journal_.debug) journal_.debug << reason; @@ -1803,7 +1807,8 @@ PeerImp::checkValidation (Job&, STValidation::pointer val, } #if RIPPLE_HOOK_VALIDATORS - validatorsConnection_->onValidation(*val); + getApp().getValidators().onMessage( + unlHorizon_, *packet, *val); #endif if (getApp().getOPs ().recvValidation( diff --git a/src/ripple/overlay/impl/PeerImp.h b/src/ripple/overlay/impl/PeerImp.h index 2f06506c4a..27f9cad2c3 100644 --- a/src/ripple/overlay/impl/PeerImp.h +++ b/src/ripple/overlay/impl/PeerImp.h @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -160,10 +160,10 @@ private: int large_sendq_ = 0; int no_ping_ = 0; std::unique_ptr load_event_; - std::unique_ptr validatorsConnection_; + std::unique_ptr unlHorizon_; bool hopsAware_ = false; - //-------------------------------------------------------------------------- + friend class OverlayImpl; public: PeerImp (PeerImp const&) = delete; @@ -325,13 +325,13 @@ public: bool isHighLatency() const override; + void + fail(std::string const& reason); + private: void close(); - void - fail(std::string const& reason); - void fail(std::string const& name, error_code ec); @@ -436,6 +436,16 @@ private: state_ = new_state; } + unl::Horizon::Kind + slotToHorizonKind (PeerFinder::Slot const& slot) + { + if(slot.fixed()) + return unl::Horizon::kindTrusted; + if(slot.inbound()) + return unl::Horizon::kindUntrusted; + return unl::Horizon::kindManaged; + } + //-------------------------------------------------------------------------- void @@ -511,7 +521,8 @@ PeerImp::PeerImp (std::unique_ptr&& ssl_bundle, , fee_ (Resource::feeLightPeer) , slot_ (std::move(slot)) , http_message_(std::move(response)) - , validatorsConnection_(getApp().getValidators().newConnection(id)) + , unlHorizon_(getApp().getValidators().insert(id, + slotToHorizonKind(*slot_))) { read_buffer_.commit (boost::asio::buffer_copy(read_buffer_.prepare( boost::asio::buffer_size(buffers)), buffers)); diff --git a/src/ripple/unity/validators.cpp b/src/ripple/unity/unl.cpp similarity index 80% rename from src/ripple/unity/validators.cpp rename to src/ripple/unity/unl.cpp index a85b1a2a2c..aa473b1c85 100644 --- a/src/ripple/unity/validators.cpp +++ b/src/ripple/unity/unl.cpp @@ -18,8 +18,8 @@ //============================================================================== #include -#include -#include -#include -#include -#include + +#include +#include +#include +#include diff --git a/src/ripple/validators/Connection.h b/src/ripple/unl/Horizon.h similarity index 68% rename from src/ripple/validators/Connection.h rename to src/ripple/unl/Horizon.h index 3632448bb5..7e9b4fe119 100644 --- a/src/ripple/validators/Connection.h +++ b/src/ripple/unl/Horizon.h @@ -17,22 +17,35 @@ */ //============================================================================== -#ifndef RIPPLE_VALIDATORS_CONNECTION_H_INCLUDED -#define RIPPLE_VALIDATORS_CONNECTION_H_INCLUDED - -#include +#ifndef RIPPLE_UNL_HORIZON_H_INCLUDED +#define RIPPLE_UNL_HORIZON_H_INCLUDED namespace ripple { -namespace Validators { +namespace unl { -/** Represents validator concerns on a protocol connection. */ -class Connection +/** Maintains validator horizon statistics on a connection. */ +class Horizon { public: - virtual ~Connection() = default; + enum Kind + { + /* Outbound made by autoconnect. + Can be dropped. + */ + kindManaged, - /** Called when a signed validation is received on the connection. */ - virtual void onValidation (STValidation const& v) = 0; + /* Inbound. */ + kindUntrusted, + + /* Fixed or cluster peer. + Can't be dropped. + */ + kindTrusted + }; + + virtual ~Horizon() = default; + + virtual bool shouldDrop() = 0; }; } diff --git a/src/ripple/validators/README.md b/src/ripple/unl/README.md similarity index 100% rename from src/ripple/validators/README.md rename to src/ripple/unl/README.md diff --git a/src/ripple/unl/UNLManager.h b/src/ripple/unl/UNLManager.h new file mode 100644 index 0000000000..2dd9acd647 --- /dev/null +++ b/src/ripple/unl/UNLManager.h @@ -0,0 +1,83 @@ +//------------------------------------------------------------------------------ +/* + 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_UNL_MANAGER_H_INCLUDED +#define RIPPLE_UNL_MANAGER_H_INCLUDED + +#include "ripple.pb.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ripple { +namespace unl { + +/** Maintains the list of chosen validators. + The algorithm for acquiring, building, and calculating metadata on + the list of chosen validators is critical to the health of the network. + All operations are performed asynchronously on an internal thread. +*/ +class Manager : public beast::PropertyStream::Source +{ +protected: + Manager(); + +public: + /** Destroy the object. + Any pending source fetch operations are aborted. This will block + until any pending database I/O has completed and the thread has + stopped. + */ + virtual ~Manager() = default; + + virtual + std::unique_ptr + insert (int id, Horizon::Kind kind) = 0; + + virtual + void + erase (std::unique_ptr c) = 0; + + /** Called when a signed validation is received + Preconditions: + Signature check passed + Effects: + */ + virtual + void + onMessage (std::unique_ptr const& h, + protocol::TMValidation const& m, + STValidation const& v) = 0; + + /** Called when a ledger is built. */ + virtual + void + onLedgerClosed (LedgerIndex index, + LedgerHash const& hash, LedgerHash const& parent) = 0; +}; + +} +} + +#endif diff --git a/src/ripple/validators/impl/ConnectionImp.cpp b/src/ripple/unl/impl/BasicHorizon.cpp similarity index 93% rename from src/ripple/validators/impl/ConnectionImp.cpp rename to src/ripple/unl/impl/BasicHorizon.cpp index b8902a844d..da958c71bb 100644 --- a/src/ripple/validators/impl/ConnectionImp.cpp +++ b/src/ripple/unl/impl/BasicHorizon.cpp @@ -18,10 +18,10 @@ //============================================================================== #include -#include +#include namespace ripple { -namespace Validators { +namespace unl { } } diff --git a/src/ripple/validators/impl/ConnectionImp.h b/src/ripple/unl/impl/BasicHorizon.h similarity index 74% rename from src/ripple/validators/impl/ConnectionImp.h rename to src/ripple/unl/impl/BasicHorizon.h index f2cb58484a..5e4cead2f3 100644 --- a/src/ripple/validators/impl/ConnectionImp.h +++ b/src/ripple/unl/impl/BasicHorizon.h @@ -17,18 +17,23 @@ */ //============================================================================== -#ifndef RIPPLE_VALIDATORS_CONNECTIONIMP_H_INCLUDED -#define RIPPLE_VALIDATORS_CONNECTIONIMP_H_INCLUDED +#ifndef RIPPLE_UNL_BASICHORIZON_H_INCLUDED +#define RIPPLE_UNL_BASICHORIZON_H_INCLUDED +#include "ripple.pb.h" #include +#include +#include #include -#include -#include +#include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -36,12 +41,15 @@ #include namespace ripple { -namespace Validators { +namespace unl { -class ConnectionImp - : public Connection +class BasicHorizon + : public Horizon { private: + using clock_type = beast::abstract_clock< + std::chrono::steady_clock>; + // Metadata on a validation source struct Source { @@ -89,14 +97,20 @@ private: using Item = std::pair; - Logic& logic_; + clock_type& clock_; + clock_type::time_point const start_; beast::WrappedSink sink_; beast::Journal journal_; + Kind const kind_; std::mutex mutex_; boost::optional ledger_; boost::container::flat_set items_; boost::container::flat_map sources_; boost::container::flat_set good_; + std::set view_; + + boost::optional< + clock_type::time_point> lastHops1_; static std::string @@ -108,23 +122,58 @@ private: } public: - template - ConnectionImp (int id, Logic& logic, Clock& clock) - : logic_ (logic) - , sink_ (logic.journal(), makePrefix(id)) + BasicHorizon (int id, Kind kind, + beast::Journal journal, clock_type& clock) + : clock_ (clock) + , start_ (clock_.now()) + , sink_ (journal, makePrefix(id)) , journal_ (sink_) + , kind_ (kind) { - logic_.add(*this); } - ~ConnectionImp() + ~BasicHorizon() { - logic_.remove(*this); + } + + bool + shouldDrop() override + { + std::lock_guard lock(mutex_); + auto const now = clock_.now(); + if ((now - start_) < std::chrono::minutes{1}) + return false; + if (! lastHops1_) + return true; + return (*lastHops1_ - now) >= + std::chrono::minutes{1}; + } + + Kind kind() const + { + return kind_; + } + + // Returns the current set of synchronized + // validators seen on this horizon. + // + std::set + view() const + { + return view_; } void - onValidation (STValidation const& v) override + onMessage (protocol::TMValidation const& m, + STValidation const& v) { + //if (m.hops() == 1) + if (m.has_hops()) + { + // directly connected + lastHops1_ = clock_.now(); + } + auto const key = v.getSignerPublic(); auto const ledger = v.getLedgerHash(); @@ -133,7 +182,8 @@ public: if (! items_.emplace(ledger, key).second) return; if (journal_.debug) journal_.debug << - "onValidation: " << ledger; + "onMessage: hops=" << m.hops() << + ", ledger=" << ledger; #if 0 auto const result = sources_.emplace( std::piecewise_construct, std::make_tuple(key), @@ -149,9 +199,6 @@ public: if (result.first->second.onHit()) good_.insert(key); } - - // This can call onLedger, do it last - logic_.onValidation(v); } // Called when a supermajority of @@ -160,7 +207,7 @@ public: onLedger (LedgerHash const& ledger) { std::lock_guard lock(mutex_); - if (journal_.debug) journal_.debug << + if (journal_.trace) journal_.trace << "onLedger: " << ledger; assert(ledger != ledger_); ledger_ = ledger; diff --git a/src/ripple/validators/impl/Logic.cpp b/src/ripple/unl/impl/Logic.cpp similarity index 92% rename from src/ripple/validators/impl/Logic.cpp rename to src/ripple/unl/impl/Logic.cpp index 220e6ac4a5..46ccfb0d80 100644 --- a/src/ripple/validators/impl/Logic.cpp +++ b/src/ripple/unl/impl/Logic.cpp @@ -18,8 +18,8 @@ //============================================================================== #include -#include -#include +#include +#include /* @@ -57,7 +57,7 @@ Most important thing that we do: */ namespace ripple { -namespace Validators { +namespace unl { Logic::Logic (Store& store, beast::Journal journal) : /*store_ (store) @@ -77,14 +77,14 @@ Logic::load() } void -Logic::add (ConnectionImp& c) +Logic::insert (BasicHorizon& c) { std::lock_guard lock(mutex_); connections_.insert(&c); } void -Logic::remove (ConnectionImp& c) +Logic::erase (BasicHorizon& c) { std::lock_guard lock(mutex_); connections_.erase(&c); @@ -104,7 +104,8 @@ Logic::onTimer() } void -Logic::onValidation (STValidation const& v) +Logic::onMessage (protocol::TMValidation const& m, + STValidation const& v) { assert(v.isFieldPresent (sfLedgerSequence)); auto const seq_no = @@ -128,7 +129,7 @@ Logic::onValidation (STValidation const& v) { //ledgers_.clear(); latest_ = *result.first; - if (journal_.info) journal_.info << + if (journal_.trace) journal_.trace << "Accepted " << latest_.second.seq_no << " (" << ledger << ")"; for (auto& _ : connections_) @@ -141,7 +142,7 @@ void Logic::onLedgerClosed (LedgerIndex index, LedgerHash const& hash, LedgerHash const& parent) { - if (journal_.info) journal_.info << + if (journal_.trace) journal_.trace << "onLedgerClosed: " << index << " " << hash << " (parent " << parent << ")"; } diff --git a/src/ripple/validators/impl/Logic.h b/src/ripple/unl/impl/Logic.h similarity index 86% rename from src/ripple/validators/impl/Logic.h rename to src/ripple/unl/impl/Logic.h index 22a087525d..20788d30c4 100644 --- a/src/ripple/validators/impl/Logic.h +++ b/src/ripple/unl/impl/Logic.h @@ -17,15 +17,16 @@ */ //============================================================================== -#ifndef RIPPLE_VALIDATORS_LOGIC_H_INCLUDED -#define RIPPLE_VALIDATORS_LOGIC_H_INCLUDED +#ifndef RIPPLE_UNL_LOGIC_H_INCLUDED +#define RIPPLE_UNL_LOGIC_H_INCLUDED #include #include #include #include -#include -#include +#include +#include +#include #include #include #include @@ -36,9 +37,9 @@ #include namespace ripple { -namespace Validators { +namespace unl { -class ConnectionImp; +class BasicHorizon; class Logic { @@ -69,7 +70,7 @@ private: beast::aged_unordered_map > ledgers_; std::pair latest_; // last fully validated - boost::container::flat_set connections_; + boost::container::flat_set connections_; //boost::container::flat_set< @@ -88,10 +89,10 @@ public: void load(); void - add (ConnectionImp& c); + insert (BasicHorizon& c); void - remove (ConnectionImp& c); + erase (BasicHorizon& c); bool isStale (STValidation const& v); @@ -100,7 +101,8 @@ public: onTimer(); void - onValidation (STValidation const& v); + onMessage (protocol::TMValidation const& m, + STValidation const& v); void onLedgerClosed (LedgerIndex index, diff --git a/src/ripple/validators/impl/Store.h b/src/ripple/unl/impl/Store.h similarity index 91% rename from src/ripple/validators/impl/Store.h rename to src/ripple/unl/impl/Store.h index abc3003877..6d3ee1aa48 100644 --- a/src/ripple/validators/impl/Store.h +++ b/src/ripple/unl/impl/Store.h @@ -17,11 +17,11 @@ */ //============================================================================== -#ifndef RIPPLE_VALIDATORS_STORE_H_INCLUDED -#define RIPPLE_VALIDATORS_STORE_H_INCLUDED +#ifndef RIPPLE_UNL_STORE_H_INCLUDED +#define RIPPLE_UNL_STORE_H_INCLUDED namespace ripple { -namespace Validators { +namespace unl { /** Abstract persistence for Validators data. */ class Store diff --git a/src/ripple/validators/impl/StoreSqdb.cpp b/src/ripple/unl/impl/StoreSqdb.cpp similarity index 95% rename from src/ripple/validators/impl/StoreSqdb.cpp rename to src/ripple/unl/impl/StoreSqdb.cpp index e686e26843..d319838ea8 100644 --- a/src/ripple/validators/impl/StoreSqdb.cpp +++ b/src/ripple/unl/impl/StoreSqdb.cpp @@ -18,13 +18,13 @@ //============================================================================== #include -#include +#include #include #include #include namespace ripple { -namespace Validators { +namespace unl { StoreSqdb::StoreSqdb (beast::Journal journal) : m_journal (journal) diff --git a/src/ripple/validators/impl/StoreSqdb.h b/src/ripple/unl/impl/StoreSqdb.h similarity index 90% rename from src/ripple/validators/impl/StoreSqdb.h rename to src/ripple/unl/impl/StoreSqdb.h index f5a5082dcf..4a56b3761a 100644 --- a/src/ripple/validators/impl/StoreSqdb.h +++ b/src/ripple/unl/impl/StoreSqdb.h @@ -17,16 +17,16 @@ */ //============================================================================== -#ifndef RIPPLE_VALIDATORS_STORESQDB_H_INCLUDED -#define RIPPLE_VALIDATORS_STORESQDB_H_INCLUDED +#ifndef RIPPLE_UNL_STORESQDB_H_INCLUDED +#define RIPPLE_UNL_STORESQDB_H_INCLUDED -#include +#include #include #include #include namespace ripple { -namespace Validators { +namespace unl { /** Database persistence for Validators using SQLite */ class StoreSqdb : public Store diff --git a/src/ripple/validators/impl/Tuning.h b/src/ripple/unl/impl/Tuning.h similarity index 90% rename from src/ripple/validators/impl/Tuning.h rename to src/ripple/unl/impl/Tuning.h index d1aabdbe0e..a8a1ee735b 100644 --- a/src/ripple/validators/impl/Tuning.h +++ b/src/ripple/unl/impl/Tuning.h @@ -17,11 +17,11 @@ */ //============================================================================== -#ifndef RIPPLE_VALIDATORS_TUNING_H_INCLUDED -#define RIPPLE_VALIDATORS_TUNING_H_INCLUDED +#ifndef RIPPLE_UNL_TUNING_H_INCLUDED +#define RIPPLE_UNL_TUNING_H_INCLUDED namespace ripple { -namespace Validators { +namespace unl { } } diff --git a/src/ripple/unl/impl/UNLManager.cpp b/src/ripple/unl/impl/UNLManager.cpp new file mode 100644 index 0000000000..7cf0d7bd41 --- /dev/null +++ b/src/ripple/unl/impl/UNLManager.cpp @@ -0,0 +1,354 @@ +//------------------------------------------------------------------------------ +/* + 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. +*/ +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // + +/** ChosenValidators (formerly known as UNL) + + Motivation: + + To protect the integrity of the shared ledger data structure, Validators + independently sign LedgerHash objects with their RipplePublicKey. These + signed Validations are propagated through the peer to peer network so + that other nodes may inspect them. Every peer and client on the network + gains confidence in a ledger and its associated chain of previous ledgers + by maintaining a suitably sized list of Validator public keys that it + trusts. + + The most important factors in choosing Validators for a ChosenValidators + list (the name we will use to designate such a list) are the following: + + - That different Validators are not controlled by one entity + - That each Validator participates in a majority of ledgers + - That a Validator does not sign ledgers which fail consensus + + This module maintains ChosenValidators list. The list is built from a set + of independent Source objects, which may come from the configuration file, + a separate file, a URL from some trusted domain, or from the network itself. + + In order that rippled administrators may publish their ChosenValidators + list at a URL on a trusted domain that they own, this module compiles + statistics on ledgers signed by validators and stores them in a database. + From this database reports and alerts may be generated so that up-to-date + information about the health of the set of ChosenValidators is always + availabile. + + In addition to the automated statistics provided by the module, it is + expected that organizations and meta-organizations will form from + stakeholders such as gateways who publish their own lists and provide + "best practices" to further refine the quality of validators placed into + ChosenValidators list. + + + ---------------------------------------------------------------------------- + + Unorganized Notes: + + David: + Maybe RL should have a URL that you can query to get the latest list of URI's + for RL-approved organzations that publish lists of validators. The server and + client can ship with that master trust URL and also the list of URI's at the + time it's released, in case for some reason it can't pull from RL. That would + make the default installation safe even against major changes in the + organizations that publish validator lists. + + The difference is that if an organization that provides lists of validators + goes rogue, administrators don't have to act. + + TODO: + Write up from end-user perspective on the deployment and administration + of this feature, on the wiki. "DRAFT" or "PROPOSE" to mark it as provisional. + Template: https://ripple.com/wiki/Federation_protocol + - What to do if you're a publisher of ValidatorList + - What to do if you're a rippled administrator + - Overview of how ChosenValidators works + + Goals: + Make default configuration of rippled secure. + * Ship with TrustedUriList + * Also have a preset RankedValidators + Eliminate administrative burden of maintaining + Produce the ChosenValidators list. + Allow quantitative analysis of network health. + + What determines that a validator is good? + - Are they present (i.e. sending validations) + - Are they on the consensus ledger + - What percentage of consensus rounds do they participate in + - Are they stalling consensus + * Measurements of constructive/destructive behavior is + calculated in units of percentage of ledgers for which + the behavior is measured. + + What we want from the unique node list: + - Some number of trusted roots (known by domain) + probably organizations whose job is to provide a list of validators + - We imagine the IRGA for example would establish some group whose job is to + maintain a list of validators. There would be a public list of criteria + that they would use to vet the validator. Things like: + * Not anonymous + * registered business + * Physical location + * Agree not to cease operations without notice / arbitrarily + * Responsive to complaints + - Identifiable jurisdiction + * Homogeneity in the jurisdiction is a business risk + * If all validators are in the same jurisdiction this is a business risk + - OpenCoin sets criteria for the organizations + - Rippled will ship with a list of trusted root "certificates" + In other words this is a list of trusted domains from which the software + can contact each trusted root and retrieve a list of "good" validators + and then do something with that information + - All the validation information would be public, including the broadcast + messages. + - The goal is to easily identify bad actors and assess network health + * Malicious intent + * Or, just hardware problems (faulty drive or memory) + + +*/ + +#include +#include + +namespace ripple { + +/** Executor which dispatches to JobQueue threads at a given JobType. */ +class job_executor +{ +private: + struct impl + { + impl (JobQueue& ex_, JobType type_, std::string const& name_) + : ex(ex_), type(type_), name(name_) + { + } + + JobQueue& ex; + JobType type; + std::string name; + }; + + std::shared_ptr impl_; + +public: + job_executor (JobType type, std::string const& name, + JobQueue& ex) + : impl_(std::make_shared(ex, type, name)) + { + } + + template + void + post (Handler&& handler) + { + impl_->ex.addJob(impl_->type, impl_->name, + std::forward(handler)); + } + + template + void + dispatch (Handler&& handler) + { + impl_->ex.addJob(impl_->type, impl_->name, + std::forward(handler)); + } + + template + void + defer (Handler&& handler) + { + impl_->ex.addJob(impl_->type, impl_->name, + std::forward(handler)); + } +}; + +//------------------------------------------------------------------------------ + +namespace unl { + +// template +class ManagerImp + : public Manager + , public beast::Stoppable +{ +public: + boost::asio::io_service& io_service_; + boost::asio::io_service::strand strand_; + beast::asio::waitable_executor exec_; + boost::asio::basic_waitable_timer< + std::chrono::steady_clock> timer_; + beast::Journal journal_; + StoreSqdb store_; + Logic logic_; + SociConfig sociConfig_; + + ManagerImp (Stoppable& parent, boost::asio::io_service& io_service, + beast::Journal journal, BasicConfig const& config) + : Stoppable ("Validators::Manager", parent) + , io_service_(io_service) + , strand_(io_service_) + , timer_(io_service_) + , journal_ (journal) + , store_ (journal_) + , logic_ (store_, journal_) + , sociConfig_ (config, "validators") + { + } + + ~ManagerImp() + { + } + + //-------------------------------------------------------------------------- + // + // Manager + // + //-------------------------------------------------------------------------- + + std::unique_ptr + insert (int id, Horizon::Kind kind) override + { + auto c = std::make_unique( + id, kind, logic_.journal(), stopwatch()); + logic_.insert(*c); + return std::move(c); + } + + void + erase (std::unique_ptr c) override + { + logic_.erase(dynamic_cast(*c)); + } + + void + onMessage (std::unique_ptr const& h, + protocol::TMValidation const& m, + STValidation const& v) override + { + if (! m.has_hops()) + return; + auto& hi = dynamic_cast(*h); + hi.onMessage(m, v); + logic_.onMessage(m, v); + } + + void + onLedgerClosed (LedgerIndex index, + LedgerHash const& hash, LedgerHash const& parent) override + { + logic_.onLedgerClosed (index, hash, parent); + } + + //-------------------------------------------------------------------------- + // + // Stoppable + // + //-------------------------------------------------------------------------- + + void onPrepare() + { + init(); + } + + void onStart() + { + } + + void onStop() + { + boost::system::error_code ec; + timer_.cancel(ec); + + logic_.stop(); + + exec_.async_wait([this]() { stopped(); }); + } + + //-------------------------------------------------------------------------- + // + // PropertyStream + // + //-------------------------------------------------------------------------- + + void onWrite (beast::PropertyStream::Map& map) + { + } + + //-------------------------------------------------------------------------- + // + // ManagerImp + // + //-------------------------------------------------------------------------- + + void init() + { + store_.open (sociConfig_); + logic_.load (); + } + + void + onTimer (boost::system::error_code ec) + { + if (ec) + { + if (ec != boost::asio::error::operation_aborted) + journal_.error << + "onTimer: " << ec.message(); + return; + } + + logic_.onTimer(); + + timer_.expires_from_now(std::chrono::seconds(1), ec); + timer_.async_wait(strand_.wrap(exec_.wrap( + std::bind(&ManagerImp::onTimer, this, + beast::asio::placeholders::error)))); + } +}; + +//------------------------------------------------------------------------------ + +Manager::Manager () + : beast::PropertyStream::Source ("validators") +{ +} + +std::unique_ptr +make_Manager(beast::Stoppable& parent, + boost::asio::io_service& io_service, + beast::Journal journal, + BasicConfig const& config) +{ + return std::make_unique(parent, + io_service, journal, config); +} +} +} diff --git a/src/ripple/validators/make_Manager.h b/src/ripple/unl/make_Manager.h similarity index 89% rename from src/ripple/validators/make_Manager.h rename to src/ripple/unl/make_Manager.h index d4d8333e6f..eab96aa435 100644 --- a/src/ripple/validators/make_Manager.h +++ b/src/ripple/unl/make_Manager.h @@ -17,10 +17,10 @@ */ //============================================================================== -#ifndef RIPPLE_VALIDATORS_MAKE_MANAGER_H_INCLUDED -#define RIPPLE_VALIDATORS_MAKE_MANAGER_H_INCLUDED +#ifndef RIPPLE_UNL_MAKE_MANAGER_H_INCLUDED +#define RIPPLE_UNL_MAKE_MANAGER_H_INCLUDED -#include +#include #include #include #include @@ -29,7 +29,7 @@ namespace ripple { class BasicConfig; -namespace Validators { +namespace unl { std::unique_ptr make_Manager (beast::Stoppable& stoppableParent, diff --git a/src/ripple/validators/tests/Validators.test.cpp b/src/ripple/validators/tests/Validators.test.cpp deleted file mode 100644 index f8ee944768..0000000000 --- a/src/ripple/validators/tests/Validators.test.cpp +++ /dev/null @@ -1,39 +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. -*/ -//============================================================================== - -#include -#include - -namespace ripple { -namespace Validators { - -class Validators_test : public beast::unit_test::suite -{ -public: - void - run() - { - pass(); - } -}; - -BEAST_DEFINE_TESTSUITE_MANUAL(Validators,validators,ripple); - -} -}