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 // Here temporarily to turn off new Validations code while it
// is being written. // is being written.
// //
#ifndef RIPPLE_USE_NEW_VALIDATIONS #ifndef RIPPLE_USE_NEW_VALIDATORS
#define RIPPLE_USE_NEW_VALIDATIONS 0 #define RIPPLE_USE_NEW_VALIDATORS 0
#endif #endif
#endif #endif

View File

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

View File

@@ -858,9 +858,6 @@
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.cpp"> <ClCompile Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter> <Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile> </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"> <ClCompile Include="..\..\modules\ripple_core\validator\Validators.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter> <Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile> </ClCompile>
@@ -870,6 +867,12 @@
<ClCompile Include="..\..\modules\ripple_core\validator\ValidatorsUtilities.cpp"> <ClCompile Include="..\..\modules\ripple_core\validator\ValidatorsUtilities.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter> <Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile> </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>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\modules\ripple_app\ripple_app.h"> <ClInclude Include="..\..\modules\ripple_app\ripple_app.h">
@@ -1679,9 +1682,6 @@
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.h"> <ClInclude Include="..\..\modules\ripple_core\validator\ValidatorSourceStrings.h">
<Filter>[1] Ripple\ripple_core\validator</Filter> <Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude> </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"> <ClInclude Include="..\..\modules\ripple_core\validator\Validators.h">
<Filter>[1] Ripple\ripple_core\validator</Filter> <Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude> </ClInclude>
@@ -1721,6 +1721,12 @@
<ClInclude Include="..\..\modules\ripple_core\validator\ValidatorsUtilities.h"> <ClInclude Include="..\..\modules\ripple_core\validator\ValidatorsUtilities.h">
<Filter>[1] Ripple\ripple_core\validator</Filter> <Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude> </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>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\..\modules\ripple_data\protocol\ripple.proto"> <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. // VFALCO TODO remove these once the call is thread safe.
HashMaps::getInstance ().initializeNonce <size_t> (); HashMaps::getInstance ().initializeNonce <size_t> ();
initValidatorsConfig ();
} }
~ApplicationImp () ~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&) static void callScheduledTask (NodeStore::Scheduler::Task* task, Job&)
{ {
task->performScheduledTask (); 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); SerializedValidation const& sv (*val);
Validators::ReceivedValidation rv; Validators::ReceivedValidation rv;
rv.ledgerHash = sv.getLedgerHash (); rv.ledgerHash = sv.getLedgerHash ();

View File

@@ -459,14 +459,14 @@ public:
} }
// Always load from rippled.cfg // Always load from rippled.cfg
if (!getConfig ().VALIDATORS.empty ()) if (!getConfig ().validators.empty ())
{ {
RippleAddress naInvalid; // Don't want a referrer on added entries. RippleAddress naInvalid; // Don't want a referrer on added entries.
WriteLog (lsINFO, UniqueNodeList) << boost::str (boost::format ("Bootstrapping UNL: loading from '%s'.") WriteLog (lsINFO, UniqueNodeList) << boost::str (boost::format ("Bootstrapping UNL: loading from '%s'.")
% getConfig ().CONFIG_FILE); % 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; bLoaded = true;
} }

View File

@@ -261,8 +261,8 @@ void Config::load ()
if (smtTmp) if (smtTmp)
{ {
VALIDATORS = *smtTmp; validators = *smtTmp;
// SectionEntriesPrint(&VALIDATORS, SECTION_VALIDATORS); // SectionEntriesPrint(&validators, SECTION_VALIDATORS);
} }
smtTmp = SectionEntries (secConfig, SECTION_CLUSTER_NODES); smtTmp = SectionEntries (secConfig, SECTION_CLUSTER_NODES);
@@ -525,7 +525,10 @@ void Config::load ()
(void) SectionSingleB (secConfig, SECTION_SMS_URL, SMS_URL); (void) SectionSingleB (secConfig, SECTION_SMS_URL, SMS_URL);
if (SectionSingleB (secConfig, SECTION_VALIDATORS_FILE, strTemp)) if (SectionSingleB (secConfig, SECTION_VALIDATORS_FILE, strTemp))
{
localValidatorsPath = strTemp;
VALIDATORS_FILE = strTemp; VALIDATORS_FILE = strTemp;
}
if (SectionSingleB (secConfig, SECTION_DEBUG_LOGFILE, strTemp)) if (SectionSingleB (secConfig, SECTION_DEBUG_LOGFILE, strTemp))
DEBUG_LOGFILE = strTemp; DEBUG_LOGFILE = strTemp;

View File

@@ -137,6 +137,12 @@ public:
*/ */
int peerPROXYListeningPort; 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 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_SITE; // Where to find validators.txt on the Internet.
std::string VALIDATORS_URI; // URI of validators.txt. std::string VALIDATORS_URI; // URI of validators.txt.
std::string VALIDATORS_BASE; // Name with testnet-, if needed. 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> IPS; // Peer IPs from rippled.cfg.
std::vector<std::string> SNTP_SERVERS; // SNTP servers 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 "beast/modules/beast_core/system/BeforeBoost.h" // must come first
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
// For NodeStore backends // For NodeStore backends
@@ -21,9 +22,6 @@
#include "../ripple_leveldb/ripple_leveldb.h" #include "../ripple_leveldb/ripple_leveldb.h"
#include "../ripple_mdb/ripple_mdb.h" #include "../ripple_mdb/ripple_mdb.h"
// For Validators
//#include "../ripple_net/ripple_net.h"
namespace ripple namespace ripple
{ {
@@ -64,11 +62,13 @@ namespace ripple
# include "validator/ValidatorsUtilities.h" # include "validator/ValidatorsUtilities.h"
#include "validator/ValidatorsUtilities.cpp" #include "validator/ValidatorsUtilities.cpp"
# include "validator/ValidatorSourceStrings.h" # include "validator/ValidatorSourceFile.h"
# include "validator/ValidatorSourceTrustedUri.h" # include "validator/ValidatorSourceStrings.h"
# include "validator/ValidatorsImp.h" // private # include "validator/ValidatorSourceTrustedURL.h"
# include "validator/ValidatorsImp.h"
#include "validator/ValidatorSourceFile.cpp"
#include "validator/ValidatorSourceStrings.cpp" #include "validator/ValidatorSourceStrings.cpp"
#include "validator/ValidatorSourceTrustedUri.cpp" #include "validator/ValidatorSourceTrustedURL.cpp"
#include "validator/Validators.cpp" #include "validator/Validators.cpp"
} }

View File

@@ -7,6 +7,16 @@
#ifndef RIPPLE_CORE_RIPPLEHEADER #ifndef RIPPLE_CORE_RIPPLEHEADER
#define 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_basics/ripple_basics.h"
#include "../ripple_data/ripple_data.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: private:

View File

@@ -8,7 +8,6 @@
#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCESTRINGS_H_INCLUDED #define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCESTRINGS_H_INCLUDED
/** Provides validators from a set of Validator strings. /** Provides validators from a set of Validator strings.
Typically this will come from a local configuration file. Typically this will come from a local configuration file.
*/ */
class ValidatorSourceStrings : public Validators::Source 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 #ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURL_H_INCLUDED
#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURI_H_INCLUDED #define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURL_H_INCLUDED
/** Provides validators from a trusted URI (e.g. HTTPS) /** Provides validators from a trusted URI (e.g. HTTPS)
*/ */
class ValidatorSourceTrustedUri : public Validators::Source class ValidatorSourceTrustedURL : public Validators::Source
{ {
public: public:
static ValidatorSourceTrustedUri* New (String const& uri); static ValidatorSourceTrustedURL* New (UniformResourceLocator const& url);
}; };
#endif #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: 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 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 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 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 - What to do if you're a rippled administrator
- Overview of how ChosenValidators works - Overview of how ChosenValidators works
Goals: Goals:
Make default configuration of rippled secure. Make default configuration of rippled secure.
* Ship with TrustedUriList * Ship with TrustedUriList
@@ -74,59 +69,25 @@ What determines that a validator is good?
* Measurements of constructive/destructive behavior is * Measurements of constructive/destructive behavior is
calculated in units of percentage of ledgers for which calculated in units of percentage of ledgers for which
the behavior is measured. 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 () Validators* Validators::New ()
{ {
return new ValidatorsImp (nullptr); return new ValidatorsImp (nullptr);
@@ -142,6 +103,72 @@ public:
numberOfTestValidators = 1000 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 struct TestSource : Validators::Source
{ {
TestSource (String const& name, uint32 start, uint32 end) 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; Result result;
list.ensureStorageAllocated (numberOfTestValidators);
result.success = true;
result.message = String::empty;
result.list.ensureStorageAllocated (numberOfTestValidators);
for (uint32 i = m_start ; i < m_end; ++i) for (uint32 i = m_start ; i < m_end; ++i)
{ {
Info info; Info info;
info.key = Validators::KeyType::createFromInteger (i); info.key = Validators::KeyType::createFromInteger (i);
list.add (info); result.list.add (info);
} }
return list;
return result;
} }
String m_name; String m_name;
@@ -173,11 +205,15 @@ public:
void addSources (ValidatorsImp::Logic& logic) void addSources (ValidatorsImp::Logic& logic)
{ {
#if 0
logic.addSource (new TestSource ("source 1", 0, 1000)); logic.addSource (new TestSource ("source 1", 0, 1000));
logic.addSource (new TestSource ("source 2", 200, 1500)); logic.addSource (new TestSource ("source 2", 200, 1500));
logic.addSource (new TestSource ("source 3", 500, 2000)); logic.addSource (new TestSource ("source 3", 500, 2000));
logic.addSource (new TestSource ("source 4", 750, 2200)); logic.addSource (new TestSource ("source 4", 750, 2200));
logic.addSource (new TestSource ("source 5", 1500, 3200)); logic.addSource (new TestSource ("source 5", 1500, 3200));
#else
logic.addSource (new TestSource ("source 1", 0, 1));
#endif
} }
void testLogic () void testLogic ()

View File

@@ -50,7 +50,16 @@ public:
returns `true`. returns `true`.
This call will block. 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 () { } virtual ~Validators () { }
/** Add a live source of validators. /** Add a static source of validators from a string array. */
The caller loses ownership of the object. /** @{ */
Thread safety: virtual void addStrings (std::vector <std::string> const& strings) = 0;
Can be called from any thread. virtual void addStrings (StringArray const& stringArray) = 0;
*/ /** @} */
virtual void addSource (Source* source) = 0;
/** Add a static source of validators from a text file. */
virtual void addFile (String const& path) = 0;
/** Add a static source of validators. /** Add a static source of validators.
The Source is called to fetch once and the results are kept The Source is called to fetch once and the results are kept
@@ -85,6 +96,18 @@ public:
*/ */
virtual void addStaticSource (Source* source) = 0; 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 // 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 std::size_t size () const noexcept
@@ -102,7 +105,7 @@ public:
public: public:
// Information associated with each Source // Information associated with each Source
// //
struct SourceInfo struct SourceDesc
{ {
enum enum
{ {
@@ -121,25 +124,24 @@ public:
Time whenToFetch; Time whenToFetch;
int numberOfFailures; int numberOfFailures;
// The result of hte last fetch // The result of the last fetch
Array <Source::Info> list; Source::Result result;
//------------------------------------------------------------------ //------------------------------------------------------------------
SourceInfo () noexcept SourceDesc () noexcept
: status (statusNone) : status (statusNone)
, whenToFetch (Time::getCurrentTime ()) , whenToFetch (Time::getCurrentTime ())
, numberOfFailures (0) , numberOfFailures (0)
{ {
list.ensureStorageAllocated (keysPreallocationSize);
} }
~SourceInfo () ~SourceDesc ()
{ {
} }
}; };
typedef DynamicList <SourceInfo> SourcesType; typedef DynamicList <SourceDesc> SourcesType;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@@ -152,11 +154,11 @@ public:
{ {
} }
KeyType key;
int refCount; 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. // Add a one-time static source.
// Fetch is called right away, this call blocks. // Fetch is called right away, this call blocks.
// //
@@ -181,10 +175,25 @@ public:
ScopedPointer <Source> object (source); ScopedPointer <Source> object (source);
NoOpCancelCallback cancelCallback; NoOpCancelCallback cancelCallback;
Array <Source::Info> 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. // Called when we receive a validation from a peer.
@@ -212,10 +221,11 @@ public:
for (std::size_t i = 0; i < list.size (); ++i) for (std::size_t i = 0; i < list.size (); ++i)
{ {
Source::Info const& info (list.getReference (i)); Source::Info const& info (list.getReference (i));
MapType::Result result (m_map.insert (info.key)); std::pair <MapType::iterator, bool> result (
ValidatorInfo& validatorInfo (result.iter->value ()); m_map.emplace (info.key, ValidatorInfo ()));
ValidatorInfo& validatorInfo (result.first->second);
++validatorInfo.refCount; ++validatorInfo.refCount;
if (result.inserted) if (result.second)
{ {
// This is a new one // This is a new one
markDirtyChosenList (); markDirtyChosenList ();
@@ -233,11 +243,11 @@ public:
Source::Info const& info (list.getReference (i)); Source::Info const& info (list.getReference (i));
MapType::iterator iter (m_map.find (info.key)); MapType::iterator iter (m_map.find (info.key));
bassert (iter != m_map.end ()); bassert (iter != m_map.end ());
ValidatorInfo& validatorInfo (iter->value ()); ValidatorInfo& validatorInfo (iter->second);
if (--validatorInfo.refCount == 0) if (--validatorInfo.refCount == 0)
{ {
// Last reference removed // Last reference removed
m_map.erase (info.key); m_map.erase (iter);
markDirtyChosenList (); markDirtyChosenList ();
} }
} }
@@ -245,26 +255,39 @@ public:
// Fetch one source // 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 ()) if (! callback.shouldCancel ())
{ {
// Reset fetch timer for the source. // Reset fetch timer for the source.
info.whenToFetch = Time::getCurrentTime () + desc.whenToFetch = Time::getCurrentTime () +
RelativeTime (secondsBetweenFetches); RelativeTime (secondsBetweenFetches);
// Add the new source info to the map if (result.success)
addSourceInfo (list); {
// Add the new source info to the map
addSourceInfo (result.list);
// Swap lists // Swap lists
info.list.swapWith (list); desc.result.swapWith (result);
// Remove the old source info from the map // Remove the old source info from the map
removeSourceInfo (list); removeSourceInfo (result.list);
// See if we need to rebuild // See if we need to rebuild
checkDirtyChosenList (); 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 (); for (SourcesType::iterator iter = m_sources.begin ();
! callback.shouldCancel () && iter != m_sources.end (); ++iter) ! callback.shouldCancel () && iter != m_sources.end (); ++iter)
{ {
SourceInfo& info (*iter); SourceDesc& desc (*iter);
if (info.whenToFetch <= currentTime) if (desc.whenToFetch <= currentTime)
fetchSource (info, callback); fetchSource (desc, callback);
} }
} }
@@ -305,14 +328,13 @@ public:
// //
void buildChosenList () void buildChosenList ()
{ {
ChosenList::Ptr list (new ChosenList); ChosenList::Ptr list (new ChosenList (m_map.size ()));
for (MapType::iterator iter = m_map.begin (); for (MapType::iterator iter = m_map.begin ();
iter != m_map.end (); ++iter) iter != m_map.end (); ++iter)
{ {
//ValidatorInfo const& validatorInfo (iter->value ());
ChosenList::Info info; ChosenList::Info info;
list->insert (iter->key (), info); list->insert (iter->first, info);
} }
// This is thread safe // 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) void addSource (Source* source)
{ {
m_thread.call (&Logic::addSource, &m_logic, source); m_thread.call (&Logic::addSource, &m_logic, source);