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);