Pass .cfg validators entries to Validators logic

This commit is contained in:
Vinnie Falco
2013-09-09 09:56:51 -07:00
parent adb6c39b92
commit 8866c2dc1f
20 changed files with 404 additions and 176 deletions

View File

@@ -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

View File

@@ -784,13 +784,19 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceFile.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.cpp">
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedURL.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -1517,8 +1523,9 @@
<ClInclude Include="..\..\modules\ripple_core\test\Results.h" />
<ClInclude Include="..\..\modules\ripple_core\test\SimplePayload.h" />
<ClInclude Include="..\..\modules\ripple_core\test\StateBase.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceFile.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedURL.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorsImp.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\Validators.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorsUtilities.h" />

View File

@@ -858,9 +858,6 @@
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\Validators.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
@@ -870,6 +867,12 @@
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorsUtilities.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceFile.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedURL.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\modules\ripple_app\ripple_app.h">
@@ -1679,9 +1682,6 @@
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedUri.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\Validators.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
@@ -1721,6 +1721,12 @@
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorsUtilities.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceFile.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceTrustedURL.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\modules\ripple_data\protocol\ripple.proto">

View File

@@ -188,6 +188,8 @@ public:
{
// VFALCO TODO remove these once the call is thread safe.
HashMaps::getInstance ().initializeNonce <size_t> ();
initValidatorsConfig ();
}
~ApplicationImp ()
@@ -202,6 +204,24 @@ public:
//--------------------------------------------------------------------------
// Initialize the Validators object with Config information.
void initValidatorsConfig ()
{
{
std::vector <std::string> 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 ();

View File

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

View File

@@ -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;
}

View File

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

View File

@@ -137,6 +137,12 @@ public:
*/
int peerPROXYListeningPort;
/** List of Validators entries from rippled.cfg */
std::vector <std::string> 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<std::string> VALIDATORS; // Validators from rippled.cfg.
std::vector<std::string> IPS; // Peer IPs from rippled.cfg.
std::vector<std::string> SNTP_SERVERS; // SNTP servers from rippled.cfg.

View File

@@ -13,6 +13,7 @@
#include "beast/modules/beast_core/system/BeforeBoost.h" // must come first
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
// 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/ValidatorSourceFile.h"
# include "validator/ValidatorSourceStrings.h"
# include "validator/ValidatorSourceTrustedUri.h"
# include "validator/ValidatorsImp.h" // private
# 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"
}

View File

@@ -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"

View File

@@ -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 <ValidatorSourceFile> object (
new ValidatorSourceFileImp (path));
return object.release ();
}

View File

@@ -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

View File

@@ -15,9 +15,11 @@ public:
{
}
Array <Info> fetch (CancelCallback&)
Result fetch (CancelCallback&)
{
return Array <Info> ();
Result result;
return result;
}
private:

View File

@@ -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

View File

@@ -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 <HTTPClientBase> 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 <ValidatorSourceTrustedURL> object (
new ValidatorSourceTrustedURLImp (url));
return object.release ();
}

View File

@@ -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

View File

@@ -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 <Info> fetch (CancelCallback&)
{
return Array <Info> ();
}
private:
String const m_uri;
};
//------------------------------------------------------------------------------
ValidatorSourceTrustedUri* ValidatorSourceTrustedUri::New (String const& uri)
{
ScopedPointer <ValidatorSourceTrustedUri> object (
new ValidatorSourceTrustedUriImp (uri));
return object.release ();
}

View File

@@ -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 Config>
class PeerLogic : public TestOverlay::PeerLogicBase <Config>
{
public:
typedef TestOverlay::PeerLogicBase <Config> 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 <Config> (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 <Info> fetch (CancelCallback& cancel)
Result fetch (CancelCallback& cancel)
{
Array <Info> 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 ()

View File

@@ -50,7 +50,16 @@ public:
returns `true`.
This call will block.
*/
virtual Array <Info> fetch (CancelCallback& callback) = 0;
struct Result
{
Result ();
void swapWith (Result& other);
bool success;
String message;
Array <Info> 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 <std::string> 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

View File

@@ -67,10 +67,13 @@ public:
}
};
typedef HashMap <KeyType, Info, KeyType::HashFunction> MapType;
//typedef HashMap <KeyType, Info, KeyType::HashFunction> MapType;
typedef boost::unordered_map <KeyType, Info, KeyType::HashFunction> 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 <Source::Info> 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 <SourceInfo> SourcesType;
typedef DynamicList <SourceDesc> SourcesType;
//----------------------------------------------------------------------
@@ -152,11 +154,11 @@ public:
{
}
KeyType key;
int refCount;
};
typedef HashMap <KeyType, ValidatorInfo, KeyType::HashFunction> MapType;
//typedef HashMap <KeyType, ValidatorInfo, KeyType::HashFunction> MapType;
typedef boost::unordered_map <KeyType, ValidatorInfo, KeyType::HashFunction> 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.
//
@@ -182,9 +176,24 @@ public:
NoOpCancelCallback cancelCallback;
Array <Source::Info> list (object->fetch (cancelCallback));
Source::Result result (object->fetch (cancelCallback));
addSourceInfo (list);
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 <MapType::iterator, bool> 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 <Source::Info> 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);
if (result.success)
{
// Add the new source info to the map
addSourceInfo (list);
addSourceInfo (result.list);
// Swap lists
info.list.swapWith (list);
desc.result.swapWith (result);
// Remove the old source info from the map
removeSourceInfo (list);
removeSourceInfo (result.list);
// 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 <std::string> 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);