From 8866c2dc1f1e659c3665a7e765d93a63a81d4026 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Mon, 9 Sep 2013 09:56:51 -0700 Subject: [PATCH] Pass .cfg validators entries to Validators logic --- BeastConfig.h | 4 +- Builds/VisualStudio2012/RippleD.vcxproj | 11 +- .../VisualStudio2012/RippleD.vcxproj.filters | 18 +- .../ripple_app/main/ripple_Application.cpp | 20 +++ modules/ripple_app/peers/ripple_Peer.cpp | 2 +- .../peers/ripple_UniqueNodeList.cpp | 4 +- .../ripple_core/functional/ripple_Config.cpp | 7 +- .../ripple_core/functional/ripple_Config.h | 7 +- modules/ripple_core/ripple_core.cpp | 14 +- modules/ripple_core/ripple_core.h | 10 ++ .../validator/ValidatorSourceFile.cpp | 40 +++++ .../validator/ValidatorSourceFile.h | 19 +++ .../validator/ValidatorSourceStrings.cpp | 6 +- .../validator/ValidatorSourceStrings.h | 1 - .../validator/ValidatorSourceTrustedURL.cpp | 47 ++++++ ...ustedUri.h => ValidatorSourceTrustedURL.h} | 8 +- .../validator/ValidatorSourceTrustedUri.cpp | 36 ---- modules/ripple_core/validator/Validators.cpp | 154 +++++++++++------- modules/ripple_core/validator/Validators.h | 37 ++++- modules/ripple_core/validator/ValidatorsImp.h | 135 ++++++++++----- 20 files changed, 404 insertions(+), 176 deletions(-) create mode 100644 modules/ripple_core/validator/ValidatorSourceFile.cpp create mode 100644 modules/ripple_core/validator/ValidatorSourceFile.h create mode 100644 modules/ripple_core/validator/ValidatorSourceTrustedURL.cpp rename modules/ripple_core/validator/{ValidatorSourceTrustedUri.h => ValidatorSourceTrustedURL.h} (52%) delete mode 100644 modules/ripple_core/validator/ValidatorSourceTrustedUri.cpp diff --git a/BeastConfig.h b/BeastConfig.h index 96c801dc55..99cea070c7 100644 --- a/BeastConfig.h +++ b/BeastConfig.h @@ -168,8 +168,8 @@ // Here temporarily to turn off new Validations code while it // is being written. // -#ifndef RIPPLE_USE_NEW_VALIDATIONS -#define RIPPLE_USE_NEW_VALIDATIONS 0 +#ifndef RIPPLE_USE_NEW_VALIDATORS +#define RIPPLE_USE_NEW_VALIDATORS 0 #endif #endif diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 16785ea0be..94b21a6717 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -784,13 +784,19 @@ true true + + true + true + true + true + true true true true - + true true true @@ -1517,8 +1523,9 @@ + - + diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index a33e3e6e83..03d006a343 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -858,9 +858,6 @@ [1] Ripple\ripple_core\validator - - [1] Ripple\ripple_core\validator - [1] Ripple\ripple_core\validator @@ -870,6 +867,12 @@ [1] Ripple\ripple_core\validator + + [1] Ripple\ripple_core\validator + + + [1] Ripple\ripple_core\validator + @@ -1679,9 +1682,6 @@ [1] Ripple\ripple_core\validator - - [1] Ripple\ripple_core\validator - [1] Ripple\ripple_core\validator @@ -1721,6 +1721,12 @@ [1] Ripple\ripple_core\validator + + [1] Ripple\ripple_core\validator + + + [1] Ripple\ripple_core\validator + diff --git a/modules/ripple_app/main/ripple_Application.cpp b/modules/ripple_app/main/ripple_Application.cpp index 0c782f789f..d1a0679b50 100644 --- a/modules/ripple_app/main/ripple_Application.cpp +++ b/modules/ripple_app/main/ripple_Application.cpp @@ -188,6 +188,8 @@ public: { // VFALCO TODO remove these once the call is thread safe. HashMaps::getInstance ().initializeNonce (); + + initValidatorsConfig (); } ~ApplicationImp () @@ -202,6 +204,24 @@ public: //-------------------------------------------------------------------------- + // Initialize the Validators object with Config information. + void initValidatorsConfig () + { + { + std::vector const& strings (getConfig().validators); + if (! strings.empty ()) + m_validators->addStrings (strings); + } + + { + String const& localValidatorsPath (getConfig().localValidatorsPath); + if (localValidatorsPath != String::empty) + m_validators->addFile (localValidatorsPath); + } + } + + //-------------------------------------------------------------------------- + static void callScheduledTask (NodeStore::Scheduler::Task* task, Job&) { task->performScheduledTask (); diff --git a/modules/ripple_app/peers/ripple_Peer.cpp b/modules/ripple_app/peers/ripple_Peer.cpp index 5c25c61655..f4cef8144c 100644 --- a/modules/ripple_app/peers/ripple_Peer.cpp +++ b/modules/ripple_app/peers/ripple_Peer.cpp @@ -1465,7 +1465,7 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru //---------------------------------------------------------------------- // { -#if RIPPLE_USE_NEW_VALIDATIONS +#if RIPPLE_USE_NEW_VALIDATORS SerializedValidation const& sv (*val); Validators::ReceivedValidation rv; rv.ledgerHash = sv.getLedgerHash (); diff --git a/modules/ripple_app/peers/ripple_UniqueNodeList.cpp b/modules/ripple_app/peers/ripple_UniqueNodeList.cpp index 39deee2ecd..8e061ea8ef 100644 --- a/modules/ripple_app/peers/ripple_UniqueNodeList.cpp +++ b/modules/ripple_app/peers/ripple_UniqueNodeList.cpp @@ -459,14 +459,14 @@ public: } // Always load from rippled.cfg - if (!getConfig ().VALIDATORS.empty ()) + if (!getConfig ().validators.empty ()) { RippleAddress naInvalid; // Don't want a referrer on added entries. WriteLog (lsINFO, UniqueNodeList) << boost::str (boost::format ("Bootstrapping UNL: loading from '%s'.") % getConfig ().CONFIG_FILE); - if (processValidators ("local", getConfig ().CONFIG_FILE.string (), naInvalid, vsConfig, &getConfig ().VALIDATORS)) + if (processValidators ("local", getConfig ().CONFIG_FILE.string (), naInvalid, vsConfig, &getConfig ().validators)) bLoaded = true; } diff --git a/modules/ripple_core/functional/ripple_Config.cpp b/modules/ripple_core/functional/ripple_Config.cpp index 4305547162..3394324988 100644 --- a/modules/ripple_core/functional/ripple_Config.cpp +++ b/modules/ripple_core/functional/ripple_Config.cpp @@ -261,8 +261,8 @@ void Config::load () if (smtTmp) { - VALIDATORS = *smtTmp; - // SectionEntriesPrint(&VALIDATORS, SECTION_VALIDATORS); + validators = *smtTmp; + // SectionEntriesPrint(&validators, SECTION_VALIDATORS); } smtTmp = SectionEntries (secConfig, SECTION_CLUSTER_NODES); @@ -525,7 +525,10 @@ void Config::load () (void) SectionSingleB (secConfig, SECTION_SMS_URL, SMS_URL); if (SectionSingleB (secConfig, SECTION_VALIDATORS_FILE, strTemp)) + { + localValidatorsPath = strTemp; VALIDATORS_FILE = strTemp; + } if (SectionSingleB (secConfig, SECTION_DEBUG_LOGFILE, strTemp)) DEBUG_LOGFILE = strTemp; diff --git a/modules/ripple_core/functional/ripple_Config.h b/modules/ripple_core/functional/ripple_Config.h index 6825e3c942..c0251f95dd 100644 --- a/modules/ripple_core/functional/ripple_Config.h +++ b/modules/ripple_core/functional/ripple_Config.h @@ -137,6 +137,12 @@ public: */ int peerPROXYListeningPort; + /** List of Validators entries from rippled.cfg */ + std::vector validators; + + /** Path to local validators.txt file from rippled.cfg */ + String localValidatorsPath; + //-------------------------------------------------------------------------- bool ELB_SUPPORT; // Support Amazon ELB @@ -144,7 +150,6 @@ public: 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 with testnet-, if needed. - std::vector VALIDATORS; // Validators from rippled.cfg. std::vector IPS; // Peer IPs from rippled.cfg. std::vector SNTP_SERVERS; // SNTP servers from rippled.cfg. diff --git a/modules/ripple_core/ripple_core.cpp b/modules/ripple_core/ripple_core.cpp index 2021c6ac9f..73ae137552 100644 --- a/modules/ripple_core/ripple_core.cpp +++ b/modules/ripple_core/ripple_core.cpp @@ -13,6 +13,7 @@ #include "beast/modules/beast_core/system/BeforeBoost.h" // must come first #include #include +#include #include // For NodeStore backends @@ -21,9 +22,6 @@ #include "../ripple_leveldb/ripple_leveldb.h" #include "../ripple_mdb/ripple_mdb.h" -// For Validators -//#include "../ripple_net/ripple_net.h" - namespace ripple { @@ -64,11 +62,13 @@ namespace ripple # include "validator/ValidatorsUtilities.h" #include "validator/ValidatorsUtilities.cpp" -# include "validator/ValidatorSourceStrings.h" -# include "validator/ValidatorSourceTrustedUri.h" -# include "validator/ValidatorsImp.h" // private +# include "validator/ValidatorSourceFile.h" +# include "validator/ValidatorSourceStrings.h" +# include "validator/ValidatorSourceTrustedURL.h" +# include "validator/ValidatorsImp.h" +#include "validator/ValidatorSourceFile.cpp" #include "validator/ValidatorSourceStrings.cpp" -#include "validator/ValidatorSourceTrustedUri.cpp" +#include "validator/ValidatorSourceTrustedURL.cpp" #include "validator/Validators.cpp" } diff --git a/modules/ripple_core/ripple_core.h b/modules/ripple_core/ripple_core.h index 3cbe914455..2defc8b5d6 100644 --- a/modules/ripple_core/ripple_core.h +++ b/modules/ripple_core/ripple_core.h @@ -7,6 +7,16 @@ #ifndef RIPPLE_CORE_RIPPLEHEADER #define RIPPLE_CORE_RIPPLEHEADER +// For Validators +// +// VFALCO NOTE It is unfortunate that we are exposing boost/asio.hpp +// needlessly. Its only required because of the buffers types. +// The HTTPClient interface doesn't need asio (although the +// implementation does. This is also reuqired for +// UniformResourceLocator. +// +#include "beast/modules/beast_asio/beast_asio.h" + #include "../ripple_basics/ripple_basics.h" #include "../ripple_data/ripple_data.h" diff --git a/modules/ripple_core/validator/ValidatorSourceFile.cpp b/modules/ripple_core/validator/ValidatorSourceFile.cpp new file mode 100644 index 0000000000..83c253c096 --- /dev/null +++ b/modules/ripple_core/validator/ValidatorSourceFile.cpp @@ -0,0 +1,40 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +class ValidatorSourceFileImp : public ValidatorSourceFile +{ +public: + ValidatorSourceFileImp (String const& path) + : m_path (path) + , m_file (File::getCurrentWorkingDirectory().getChildFile (path)) + { + } + + ~ValidatorSourceFileImp () + { + } + + Result fetch (CancelCallback&) + { + Result result; + + return result; + } + +private: + String m_path; + File m_file; +}; + +//------------------------------------------------------------------------------ + +ValidatorSourceFile* ValidatorSourceFile::New (String const& path) +{ + ScopedPointer object ( + new ValidatorSourceFileImp (path)); + + return object.release (); +} diff --git a/modules/ripple_core/validator/ValidatorSourceFile.h b/modules/ripple_core/validator/ValidatorSourceFile.h new file mode 100644 index 0000000000..235d046a09 --- /dev/null +++ b/modules/ripple_core/validator/ValidatorSourceFile.h @@ -0,0 +1,19 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCEFILE_H_INCLUDED +#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCEFILE_H_INCLUDED + +/** Provides validators from a text file. + Typically this will come from a local configuration file. +*/ +class ValidatorSourceFile : public Validators::Source +{ +public: + static ValidatorSourceFile* New (String const& path); +}; + +#endif diff --git a/modules/ripple_core/validator/ValidatorSourceStrings.cpp b/modules/ripple_core/validator/ValidatorSourceStrings.cpp index 1c987f4b96..bc3c5360ee 100644 --- a/modules/ripple_core/validator/ValidatorSourceStrings.cpp +++ b/modules/ripple_core/validator/ValidatorSourceStrings.cpp @@ -15,9 +15,11 @@ public: { } - Array fetch (CancelCallback&) + Result fetch (CancelCallback&) { - return Array (); + Result result; + + return result; } private: diff --git a/modules/ripple_core/validator/ValidatorSourceStrings.h b/modules/ripple_core/validator/ValidatorSourceStrings.h index df1e04e364..9fc1fa427c 100644 --- a/modules/ripple_core/validator/ValidatorSourceStrings.h +++ b/modules/ripple_core/validator/ValidatorSourceStrings.h @@ -8,7 +8,6 @@ #define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCESTRINGS_H_INCLUDED /** Provides validators from a set of Validator strings. - Typically this will come from a local configuration file. */ class ValidatorSourceStrings : public Validators::Source diff --git a/modules/ripple_core/validator/ValidatorSourceTrustedURL.cpp b/modules/ripple_core/validator/ValidatorSourceTrustedURL.cpp new file mode 100644 index 0000000000..98bca1a63b --- /dev/null +++ b/modules/ripple_core/validator/ValidatorSourceTrustedURL.cpp @@ -0,0 +1,47 @@ +//------------------------------------------------------------------------------ +/* + Copyright (c) 2011-2013, OpenCoin, Inc. +*/ +//============================================================================== + +class ValidatorSourceTrustedURLImp : public ValidatorSourceTrustedURL +{ +public: + explicit ValidatorSourceTrustedURLImp (UniformResourceLocator const& url) + : m_url (url) + { + } + + ~ValidatorSourceTrustedURLImp () + { + } + + Result fetch (CancelCallback&) + { + Result result; + + ScopedPointer client (HTTPClientBase::New ()); + + HTTPClientBase::Result httpResult (client->get (m_url)); + + if (httpResult.error == 0) + { + } + + return result; + } + +private: + UniformResourceLocator m_url; +}; + +//------------------------------------------------------------------------------ + +ValidatorSourceTrustedURL* ValidatorSourceTrustedURL::New ( + UniformResourceLocator const& url) +{ + ScopedPointer object ( + new ValidatorSourceTrustedURLImp (url)); + + return object.release (); +} diff --git a/modules/ripple_core/validator/ValidatorSourceTrustedUri.h b/modules/ripple_core/validator/ValidatorSourceTrustedURL.h similarity index 52% rename from modules/ripple_core/validator/ValidatorSourceTrustedUri.h rename to modules/ripple_core/validator/ValidatorSourceTrustedURL.h index 5f5ea0087e..b7fe122d17 100644 --- a/modules/ripple_core/validator/ValidatorSourceTrustedUri.h +++ b/modules/ripple_core/validator/ValidatorSourceTrustedURL.h @@ -4,15 +4,15 @@ */ //============================================================================== -#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURI_H_INCLUDED -#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURI_H_INCLUDED +#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURL_H_INCLUDED +#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURL_H_INCLUDED /** Provides validators from a trusted URI (e.g. HTTPS) */ -class ValidatorSourceTrustedUri : public Validators::Source +class ValidatorSourceTrustedURL : public Validators::Source { public: - static ValidatorSourceTrustedUri* New (String const& uri); + static ValidatorSourceTrustedURL* New (UniformResourceLocator const& url); }; #endif diff --git a/modules/ripple_core/validator/ValidatorSourceTrustedUri.cpp b/modules/ripple_core/validator/ValidatorSourceTrustedUri.cpp deleted file mode 100644 index 67b26f569a..0000000000 --- a/modules/ripple_core/validator/ValidatorSourceTrustedUri.cpp +++ /dev/null @@ -1,36 +0,0 @@ -//------------------------------------------------------------------------------ -/* - Copyright (c) 2011-2013, OpenCoin, Inc. -*/ -//============================================================================== - -class ValidatorSourceTrustedUriImp : public ValidatorSourceTrustedUri -{ -public: - explicit ValidatorSourceTrustedUriImp (String const& uri) - : m_uri (uri) - { - } - - ~ValidatorSourceTrustedUriImp () - { - } - - Array fetch (CancelCallback&) - { - return Array (); - } - -private: - String const m_uri; -}; - -//------------------------------------------------------------------------------ - -ValidatorSourceTrustedUri* ValidatorSourceTrustedUri::New (String const& uri) -{ - ScopedPointer object ( - new ValidatorSourceTrustedUriImp (uri)); - - return object.release (); -} diff --git a/modules/ripple_core/validator/Validators.cpp b/modules/ripple_core/validator/Validators.cpp index 036971df4a..10d10eb673 100644 --- a/modules/ripple_core/validator/Validators.cpp +++ b/modules/ripple_core/validator/Validators.cpp @@ -35,10 +35,6 @@ ChosenValidators -------------------------------------------------------------------------------- David: - I've cut 2 of the 6 active client-facing servers to hyper. Since then, we've - had 5 spinouts on 3 servers, none of them on the 2 I've cut over. But they - are also the most recently restarted servers, so it's not a 100% fair test. - Maybe OC should have a URL that you can query to get the latest list of URI's for OC-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 @@ -57,7 +53,6 @@ TODO: - What to do if you're a rippled administrator - Overview of how ChosenValidators works - Goals: Make default configuration of rippled secure. * Ship with TrustedUriList @@ -74,59 +69,25 @@ What determines that a validator is good? * Measurements of constructive/destructive behavior is calculated in units of percentage of ledgers for which the behavior is measured. - -Nouns - - Validator - - Signs ledgers and participate in consensus - - Fields - * Public key - * Friendly name - * Jurisdiction - * Org type: profit, nonprofit, "profit/gateway" - - Metadata - * Visible on the network? - * On the consensus ledger? - * Percentage of recent participation in consensus - * Frequency of stalling the consensus process - - ValidatorSource - - Abstract - - Provides a list of Validator - - ValidatorList - - Essentially an array of Validator - - ValidatorSourceTrustedUri - - ValidatorSource which uses HTTPS and a predefined URI - - Domain owner is responsible for removing bad validators - - ValidatorSourceTrustedUri::List - - Essentially an array of ValidatorSourceTrustedUri - - Can be read from a file - - LocalFileValidatorSource - - ValidatorSource which reads information from a local file. - - TrustedUriList // A copy of this ships with the app - * has a KnownValidators - - KnownValidators - * A series of KnownValidator that comes from a TrustedUri - * Persistent storage has a timestamp - - RankedValidators - * Created as the union of all KnownValidators with "weight" being the - number of appearances. - - ChosenValidators - * Result of the algorithm that chooses a random subset of RankedKnownValidators - * "local health" percentage is the percent of validations from this list that - you've seen recently. And have they been behaving. */ //------------------------------------------------------------------------------ +Validators::Source::Result::Result () + : success (false) + , message ("uninitialized") +{ +} + +void Validators::Source::Result::swapWith (Result& other) +{ + std::swap (success, other.success); + std::swap (message, other.message); + list.swapWith (other.list); +} + +//------------------------------------------------------------------------------ + Validators* Validators::New () { return new ValidatorsImp (nullptr); @@ -142,6 +103,72 @@ public: numberOfTestValidators = 1000 }; + //-------------------------------------------------------------------------- + + struct Payload + { + Payload () + { + } + }; + + template + class PeerLogic : public TestOverlay::PeerLogicBase + { + public: + typedef TestOverlay::PeerLogicBase Base; + typedef typename Config::Payload Payload; + typedef typename Base::Connection Connection; + typedef typename Base::Peer Peer; + typedef typename Base::Message Message; + typedef typename Config::SizeType SizeType; + + explicit PeerLogic (Peer& peer) + : TestOverlay::PeerLogicBase (peer) + { + } + + ~PeerLogic () + { + } + + void step () + { + if (this->peer().id () == 1) + { + if (this->peer().network().steps() == 0) + { + this->peer().network().state().increment(); + this->peer().send_all (Payload (1)); + } + } + } + + void receive (Connection const& c, Message const& m) + { + if (this->peer().id () != 1) + { + this->peer().network().state().increment(); + this->peer().send_all_if (Message (m.id(), + m.payload().withHop ()), + typename Connection::IsNotPeer (c.peer())); + } + } + }; + + struct Params : TestOverlay::ConfigType < + Params, + TestOverlay::StateBase, + PeerLogic + > + { + typedef TestOverlay::PremadeInitPolicy <250, 3> InitPolicy; + }; + + typedef Params::Network Network; + + //-------------------------------------------------------------------------- + struct TestSource : Validators::Source { TestSource (String const& name, uint32 start, uint32 end) @@ -151,17 +178,22 @@ public: { } - Array fetch (CancelCallback& cancel) + Result fetch (CancelCallback& cancel) { - Array list; - list.ensureStorageAllocated (numberOfTestValidators); + Result result; + + result.success = true; + result.message = String::empty; + result.list.ensureStorageAllocated (numberOfTestValidators); + for (uint32 i = m_start ; i < m_end; ++i) { Info info; info.key = Validators::KeyType::createFromInteger (i); - list.add (info); + result.list.add (info); } - return list; + + return result; } String m_name; @@ -173,11 +205,15 @@ public: void addSources (ValidatorsImp::Logic& logic) { +#if 0 logic.addSource (new TestSource ("source 1", 0, 1000)); logic.addSource (new TestSource ("source 2", 200, 1500)); logic.addSource (new TestSource ("source 3", 500, 2000)); logic.addSource (new TestSource ("source 4", 750, 2200)); logic.addSource (new TestSource ("source 5", 1500, 3200)); +#else + logic.addSource (new TestSource ("source 1", 0, 1)); +#endif } void testLogic () diff --git a/modules/ripple_core/validator/Validators.h b/modules/ripple_core/validator/Validators.h index a93e708015..9a9e356a91 100644 --- a/modules/ripple_core/validator/Validators.h +++ b/modules/ripple_core/validator/Validators.h @@ -50,7 +50,16 @@ public: returns `true`. This call will block. */ - virtual Array fetch (CancelCallback& callback) = 0; + struct Result + { + Result (); + void swapWith (Result& other); + + bool success; + String message; + Array list; + }; + virtual Result fetch (CancelCallback& callback) = 0; }; //-------------------------------------------------------------------------- @@ -68,12 +77,14 @@ public: */ virtual ~Validators () { } - /** Add a live source of validators. - The caller loses ownership of the object. - Thread safety: - Can be called from any thread. - */ - virtual void addSource (Source* source) = 0; + /** Add a static source of validators from a string array. */ + /** @{ */ + virtual void addStrings (std::vector const& strings) = 0; + virtual void addStrings (StringArray const& stringArray) = 0; + /** @} */ + + /** Add a static source of validators from a text file. */ + virtual void addFile (String const& path) = 0; /** Add a static source of validators. The Source is called to fetch once and the results are kept @@ -85,6 +96,18 @@ public: */ virtual void addStaticSource (Source* source) = 0; + /** Add a live source of validators from a trusted URL. + The URL will be contacted periodically to update the list. + */ + virtual void addTrustedURL (UniformResourceLocator const& url) = 0; + + /** Add a live source of validators. + The caller loses ownership of the object. + Thread safety: + Can be called from any thread. + */ + virtual void addSource (Source* source) = 0; + //-------------------------------------------------------------------------- // Trusted Validators diff --git a/modules/ripple_core/validator/ValidatorsImp.h b/modules/ripple_core/validator/ValidatorsImp.h index 1ed15b4306..57217c4672 100644 --- a/modules/ripple_core/validator/ValidatorsImp.h +++ b/modules/ripple_core/validator/ValidatorsImp.h @@ -67,10 +67,13 @@ public: } }; - typedef HashMap MapType; + //typedef HashMap MapType; + typedef boost::unordered_map MapType; - ChosenList () + ChosenList (std::size_t expectedSize = 0) { + // Available only in recent boost versions? + //m_map.reserve (expectedSize); } std::size_t size () const noexcept @@ -102,7 +105,7 @@ public: public: // Information associated with each Source // - struct SourceInfo + struct SourceDesc { enum { @@ -121,25 +124,24 @@ public: Time whenToFetch; int numberOfFailures; - // The result of hte last fetch - Array list; + // The result of the last fetch + Source::Result result; //------------------------------------------------------------------ - SourceInfo () noexcept + SourceDesc () noexcept : status (statusNone) , whenToFetch (Time::getCurrentTime ()) , numberOfFailures (0) { - list.ensureStorageAllocated (keysPreallocationSize); } - ~SourceInfo () + ~SourceDesc () { } }; - typedef DynamicList SourcesType; + typedef DynamicList SourcesType; //---------------------------------------------------------------------- @@ -152,11 +154,11 @@ public: { } - KeyType key; int refCount; }; - typedef HashMap MapType; + //typedef HashMap MapType; + typedef boost::unordered_map MapType; //---------------------------------------------------------------------- @@ -165,14 +167,6 @@ public: { } - // Add a live source to the list of sources. - // - void addSource (Source* source) - { - SourceInfo& info (*m_sources.emplace_back ()); - info.source = source; - } - // Add a one-time static source. // Fetch is called right away, this call blocks. // @@ -181,10 +175,25 @@ public: ScopedPointer object (source); NoOpCancelCallback cancelCallback; - - Array list (object->fetch (cancelCallback)); - addSourceInfo (list); + Source::Result result (object->fetch (cancelCallback)); + + if (result.success) + { + addSourceInfo (result.list); + } + else + { + // VFALCO NOTE Maybe log the error and message? + } + } + + // Add a live source to the list of sources. + // + void addSource (Source* source) + { + SourceDesc& desc (*m_sources.emplace_back ()); + desc.source = source; } // Called when we receive a validation from a peer. @@ -212,10 +221,11 @@ public: for (std::size_t i = 0; i < list.size (); ++i) { Source::Info const& info (list.getReference (i)); - MapType::Result result (m_map.insert (info.key)); - ValidatorInfo& validatorInfo (result.iter->value ()); + std::pair result ( + m_map.emplace (info.key, ValidatorInfo ())); + ValidatorInfo& validatorInfo (result.first->second); ++validatorInfo.refCount; - if (result.inserted) + if (result.second) { // This is a new one markDirtyChosenList (); @@ -233,11 +243,11 @@ public: Source::Info const& info (list.getReference (i)); MapType::iterator iter (m_map.find (info.key)); bassert (iter != m_map.end ()); - ValidatorInfo& validatorInfo (iter->value ()); + ValidatorInfo& validatorInfo (iter->second); if (--validatorInfo.refCount == 0) { // Last reference removed - m_map.erase (info.key); + m_map.erase (iter); markDirtyChosenList (); } } @@ -245,26 +255,39 @@ public: // Fetch one source // - void fetchSource (SourceInfo& info, Source::CancelCallback& callback) + void fetchSource (SourceDesc& desc, Source::CancelCallback& callback) { - Array list (info.source->fetch (callback)); + Source::Result result (desc.source->fetch (callback)); + if (! callback.shouldCancel ()) { // Reset fetch timer for the source. - info.whenToFetch = Time::getCurrentTime () + + desc.whenToFetch = Time::getCurrentTime () + RelativeTime (secondsBetweenFetches); - // Add the new source info to the map - addSourceInfo (list); + if (result.success) + { + // Add the new source info to the map + addSourceInfo (result.list); - // Swap lists - info.list.swapWith (list); + // Swap lists + desc.result.swapWith (result); - // Remove the old source info from the map - removeSourceInfo (list); + // Remove the old source info from the map + removeSourceInfo (result.list); - // See if we need to rebuild - checkDirtyChosenList (); + // See if we need to rebuild + checkDirtyChosenList (); + + // Reset failure status + desc.numberOfFailures = 0; + desc.status = SourceDesc::statusFetched; + } + else + { + ++desc.numberOfFailures; + desc.status = SourceDesc::statusFailed; + } } } @@ -276,9 +299,9 @@ public: for (SourcesType::iterator iter = m_sources.begin (); ! callback.shouldCancel () && iter != m_sources.end (); ++iter) { - SourceInfo& info (*iter); - if (info.whenToFetch <= currentTime) - fetchSource (info, callback); + SourceDesc& desc (*iter); + if (desc.whenToFetch <= currentTime) + fetchSource (desc, callback); } } @@ -305,14 +328,13 @@ public: // void buildChosenList () { - ChosenList::Ptr list (new ChosenList); + ChosenList::Ptr list (new ChosenList (m_map.size ())); for (MapType::iterator iter = m_map.begin (); iter != m_map.end (); ++iter) { - //ValidatorInfo const& validatorInfo (iter->value ()); ChosenList::Info info; - list->insert (iter->key (), info); + list->insert (iter->first, info); } // This is thread safe @@ -364,6 +386,31 @@ public: { } + void addStrings (std::vector const& strings) + { + StringArray stringArray; + stringArray.ensureStorageAllocated (strings.size()); + for (std::size_t i = 0; i < strings.size(); ++i) + stringArray.add (strings [i]); + addStrings (stringArray); + } + + void addStrings (StringArray const& stringArray) + { + addStaticSource ( + ValidatorSourceStrings::New (stringArray)); + } + + void addFile (String const& path) + { + addStaticSource (ValidatorSourceFile::New (path)); + } + + void addTrustedURL (UniformResourceLocator const& url) + { + addSource (ValidatorSourceTrustedURL::New (url)); + } + void addSource (Source* source) { m_thread.call (&Logic::addSource, &m_logic, source);