Add ChosenValidators logic

This commit is contained in:
Vinnie Falco
2013-07-11 15:36:38 -07:00
parent 1c1d9a9926
commit 3ef8796940
17 changed files with 561 additions and 19 deletions

View File

@@ -355,12 +355,36 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\ripple_core\ripple_core.cpp" /> <ClCompile Include="..\..\modules\ripple_core\ripple_core.cpp" />
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_ChosenValidators.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\ripple_StringsValidatorSource.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\ripple_TrustedUriValidatorSource.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\ripple_Validator.cpp"> <ClCompile Include="..\..\modules\ripple_core\validator\ripple_Validator.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\ripple_ValidatorList.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\ripple_Validators.cpp"> <ClCompile Include="..\..\modules\ripple_core\validator\ripple_Validators.cpp">
<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>
@@ -1428,7 +1452,11 @@
<ClInclude Include="..\..\modules\ripple_core\functional\ripple_LoadFeeTrack.h" /> <ClInclude Include="..\..\modules\ripple_core\functional\ripple_LoadFeeTrack.h" />
<ClInclude Include="..\..\modules\ripple_core\functional\ripple_LoadMonitor.h" /> <ClInclude Include="..\..\modules\ripple_core\functional\ripple_LoadMonitor.h" />
<ClInclude Include="..\..\modules\ripple_core\ripple_core.h" /> <ClInclude Include="..\..\modules\ripple_core\ripple_core.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ChosenValidators.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_StringsValidatorSource.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_TrustedUriValidatorSource.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validator.h" /> <ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validator.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorList.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validators.h" /> <ClInclude Include="..\..\modules\ripple_core\validator\ripple_Validators.h" />
<ClInclude Include="..\..\modules\ripple_data\crypto\ripple_Base58.h" /> <ClInclude Include="..\..\modules\ripple_data\crypto\ripple_Base58.h" />
<ClInclude Include="..\..\modules\ripple_data\crypto\ripple_Base58Data.h" /> <ClInclude Include="..\..\modules\ripple_data\crypto\ripple_Base58Data.h" />

View File

@@ -885,6 +885,18 @@
<ClCompile Include="..\..\modules\ripple_app\ledger\SerializedValidation.cpp"> <ClCompile Include="..\..\modules\ripple_app\ledger\SerializedValidation.cpp">
<Filter>[1] Ripple\ripple_app\ledger</Filter> <Filter>[1] Ripple\ripple_app\ledger</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_ValidatorList.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_ChosenValidators.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_TrustedUriValidatorSource.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
<ClCompile Include="..\..\modules\ripple_core\validator\ripple_StringsValidatorSource.cpp">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\Subtrees\sqlite\sqlite3.h"> <ClInclude Include="..\..\Subtrees\sqlite\sqlite3.h">
@@ -1647,6 +1659,18 @@
<ClInclude Include="..\..\src\cpp\ripple\ripple_Application.h"> <ClInclude Include="..\..\src\cpp\ripple\ripple_Application.h">
<Filter>[1] Ripple\ripple_app\_main</Filter> <Filter>[1] Ripple\ripple_app\_main</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorList.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ChosenValidators.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_TrustedUriValidatorSource.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_StringsValidatorSource.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\..\src\cpp\ripple\ripple.proto" /> <CustomBuild Include="..\..\src\cpp\ripple\ripple.proto" />

View File

@@ -2,6 +2,14 @@
RIPPLE TODO RIPPLE TODO
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
- Unit Test attention
- NodeStore backend unit test
- Validations unit test
--------------------------------------------------------------------------------
- Rename RPCHandler to CallHandler - Rename RPCHandler to CallHandler
- Move everything in src/cpp/ripple into ripple_app and sort them into - Move everything in src/cpp/ripple into ripple_app and sort them into
@@ -227,7 +235,7 @@ Interfaces
boost boost
Unclear from the class declaration what style of shared object management Unclear from the class declaration what style of shared object management
is used. Prefer to derive from a ReferenceCountedObject class so that the is used. Prefer to derive from a SharedObject class so that the
behavior is explicit. Furthermore the use of intrusive containers is behavior is explicit. Furthermore the use of intrusive containers is
preferred over the alternative. preferred over the alternative.
@@ -302,6 +310,17 @@ What we want from the unique node list:
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
ChosenValidators
--------------------------------------------------------------------------------
TODO:
Write up from end-user perspective on the deployment and administration
of this feature, on the wiki. "DRAFT" or "PROPOSE" to mark it as provisional.
Template: https://ripple.com/wiki/Federation_protocol
- What to do if you're a publisher of ValidatorList
- What to do if you're a rippled administrator
- Overview of how ChosenValidators works
Goals: Goals:
Make default configuration of rippled secure. Make default configuration of rippled secure.

View File

@@ -31,8 +31,12 @@ namespace ripple
#include "functional/ripple_LoadEvent.cpp" #include "functional/ripple_LoadEvent.cpp"
#include "functional/ripple_LoadMonitor.cpp" #include "functional/ripple_LoadMonitor.cpp"
#include "validator/ripple_ChosenValidators.cpp"
#include "validator/ripple_Validator.cpp" #include "validator/ripple_Validator.cpp"
#include "validator/ripple_ValidatorList.cpp"
#include "validator/ripple_Validators.cpp" #include "validator/ripple_Validators.cpp"
#include "validator/ripple_StringsValidatorSource.cpp"
#include "validator/ripple_TrustedUriValidatorSource.cpp"
} }

View File

@@ -38,7 +38,11 @@ namespace ripple
/**/#include "functional/ripple_JobQueue.h" /**/#include "functional/ripple_JobQueue.h"
#include "validator/ripple_Validator.h" #include "validator/ripple_Validator.h"
#include "validator/ripple_ValidatorList.h"
#include "validator/ripple_ChosenValidators.h"
#include "validator/ripple_Validators.h" #include "validator/ripple_Validators.h"
#include "validator/ripple_StringsValidatorSource.h"
#include "validator/ripple_TrustedUriValidatorSource.h"
} }

View File

@@ -0,0 +1,27 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
ChosenValidators::ChosenValidators (ValidatorList::Ptr chosenValidators,
ValidatorList::Ptr wellKnownValidators)
: m_list (chosenValidators)
, m_wellKnownList (wellKnownValidators)
{
}
ChosenValidators::~ChosenValidators ()
{
}
ValidatorList::Ptr ChosenValidators::getList ()
{
return m_list;
}
ValidatorList::Ptr ChosenValidators::getWellKnownList ()
{
return m_wellKnownList;
}

View File

@@ -0,0 +1,41 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_CHOSENVALIDATORS_H_INCLUDED
#define RIPPLE_CHOSENVALIDATORS_H_INCLUDED
/** A subset of validators chosen from a list of well known validators.
@see Validators
*/
class ChosenValidators : public SharedObject
{
public:
typedef SharedObjectPtr <ChosenValidators> Ptr;
ChosenValidators (ValidatorList::Ptr chosenValidators,
ValidatorList::Ptr wellKnownValidators);
~ChosenValidators ();
/** Retrieve the list of chosen validators.
This is the subset of validators that we care about.
*/
ValidatorList::Ptr getList ();
/** Retrieve the list of well known validators.
This is the set from which the chosen validators were chosen.
*/
ValidatorList::Ptr getWellKnownList ();
private:
ValidatorList::Ptr m_list;
ValidatorList::Ptr m_wellKnownList;
};
#endif

View File

@@ -0,0 +1,31 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
class StringsValidatorSourceImp : public StringsValidatorSource
{
public:
StringsValidatorSourceImp (StringArray const& strings)
{
}
~StringsValidatorSourceImp ()
{
}
ValidatorList::Ptr fetch ()
{
ValidatorList::Ptr list = new ValidatorList;
return list;
}
private:
};
StringsValidatorSource* StringsValidatorSource::New (StringArray const& strings)
{
return new StringsValidatorSourceImp (strings);
}

View File

@@ -0,0 +1,20 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_STRINGSVALIDATORSOURCE_H_INCLUDED
#define RIPPLE_STRINGSVALIDATORSOURCE_H_INCLUDED
/** Provides validators from a set of Validator strings.
Typically this will come from a local configuration file.
*/
class StringsValidatorSource : public Validators::Source
{
public:
static StringsValidatorSource* New (StringArray const& strings);
};
#endif

View File

@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
class TrustedUriValidatorSourceImp : public TrustedUriValidatorSource
{
public:
TrustedUriValidatorSourceImp (String const url)
: m_url (url)
{
}
~TrustedUriValidatorSourceImp ()
{
}
ValidatorList::Ptr fetch ()
{
ValidatorList::Ptr list = new ValidatorList;
return list;
}
private:
String const m_url;
};
TrustedUriValidatorSource* TrustedUriValidatorSource::New (String url)
{
return new TrustedUriValidatorSourceImp (url);
}

View File

@@ -0,0 +1,18 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_TRUSTEDURIVALIDATORSOURCE_H_INCLUDED
#define RIPPLE_TRUSTEDURIVALIDATORSOURCE_H_INCLUDED
/** Provides validators from a trusted URI (e.g. HTTPS)
*/
class TrustedUriValidatorSource : public Validators::Source
{
public:
static TrustedUriValidatorSource* New (String url);
};
#endif

View File

@@ -4,6 +4,7 @@
*/ */
//============================================================================== //==============================================================================
Validator::Validator () Validator::Validator (PublicKey const& publicKey)
: m_publicKey (publicKey)
{ {
} }

View File

@@ -16,10 +16,18 @@ class Validator
public: public:
typedef RippleAddress PublicKey; typedef RippleAddress PublicKey;
Validator (); explicit Validator (PublicKey const& publicKey);
//Validator (Validator const&);
PublicKey const& getPublicKey () const { return m_publicKey; }
// not thread safe
void incrementWeight () { ++m_weight; }
private: private:
PublicKey m_publicKey; PublicKey m_publicKey;
int m_weight;
}; };
#endif #endif

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
ValidatorList::ValidatorList ()
: m_isSigned (false)
{
}
ValidatorList::~ValidatorList ()
{
}
int ValidatorList::size () const
{
return m_list.size ();
}
Validator& ValidatorList::operator [] (int index)
{
return m_list.getReference (index);
}
bool ValidatorList::isSigned () const
{
return m_isSigned;
}
void ValidatorList::add (Validator const& validator)
{
m_list.add (validator);
}

View File

@@ -0,0 +1,44 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_VALIDATORLIST_H_INCLUDED
#define RIPPLE_VALIDATORLIST_H_INCLUDED
/** A list of Validator that comes from a source of validators.
Sources include trusted URIs, or a local file.
The list may be signed.
*/
class ValidatorList : public SharedObject
{
public:
typedef SharedObjectPtr <ValidatorList> Ptr;
/** Create an empty list.
*/
ValidatorList ();
~ValidatorList ();
/** Retrieve the number of items.
*/
int size () const;
Validator& operator[] (int index);
bool isSigned () const;
/** Add a validator to the list.
*/
void add (Validator const& validator);
private:
bool m_isSigned;
Array <Validator> m_list;
};
#endif

View File

@@ -4,40 +4,214 @@
*/ */
//============================================================================== //==============================================================================
/*
Two important questions:
- Are there any validators in my ChosenValidators that I dont want
* For example, they have dropped off all the trusted lists
- Do I have enough?
*/
class ValidatorsImp class ValidatorsImp
: public Validators : public Validators
, private InterruptibleThread::EntryPoint , private ThreadWithCallQueue::EntryPoints
, private DeadlineTimer::Listener
{ {
public: public:
explicit ValidatorsImp (Listener* listener) // Tunable constants
enum
{
hoursBetweenFetches = 24,
secondsBetweenFetches = hoursBetweenFetches * 60 * 60,
timerGranularity = 60 * 60 // Wake up every hour
};
//--------------------------------------------------------------------------
struct SourceInfo
{
enum Status
{
statusNone,
statusFetched,
statusFailed,
};
explicit SourceInfo (Source* source_)
: source (source_)
, status (statusNone)
{
}
Source* source;
Status status;
Time lastFetch;
ValidatorList::Ptr list;
};
//--------------------------------------------------------------------------
public:
explicit ValidatorsImp (Validators::Listener* listener)
: m_thread ("Validators") : m_thread ("Validators")
, m_timer (this)
, m_listener (listener) , m_listener (listener)
{ {
m_thread.start (this);
} }
~ValidatorsImp () ~ValidatorsImp ()
{ {
} }
void addTrustedUri (String uri) void addSource (Source* source)
{ {
m_trustedUris.add (uri); m_thread.call (&ValidatorsImp::doAddSource, this, source);
} }
void start () void doAddSource (Source* source)
{ {
m_thread.start (this); m_sources.add (source);
m_info.add (SourceInfo (source));
} }
void threadRun () void onDeadlineTimer (DeadlineTimer&)
{ {
// process the trustedUri list and blah blah // This will make us fall into the idle proc as needed
//
m_thread.interrupt ();
}
void mergeValidators (ValidatorList::Ptr dest, ValidatorList::Ptr source)
{
}
// Construct the list of well known validators
ValidatorList::Ptr buildWellKnownValidators ()
{
ValidatorList::Ptr list = new ValidatorList;
// Go through each source and merge its list
for (int i = 0; i < m_info.size (); ++i)
{
SourceInfo const& info (m_info.getReference (i));
if (info.status == SourceInfo::statusFetched)
{
mergeValidators (list, info.list);
}
}
return list;
}
// Choose a subset of validators from the well known list
//
ValidatorList::Ptr chooseSubset (ValidatorList::Ptr list)
{
ValidatorList::Ptr result = new ValidatorList;
return result;
}
// Create a composite object representing the chosen validators.
//
ChosenValidators::Ptr createChosenValidators ()
{
ValidatorList::Ptr wellKnownValidators = buildWellKnownValidators ();
ValidatorList::Ptr validatorSubset = chooseSubset (wellKnownValidators);
ChosenValidators::Ptr chosenValidators = new ChosenValidators (
validatorSubset,
wellKnownValidators);
return chosenValidators;
}
// Create a fresh chosen validators from our source information
// and broadcast it.
//
void updateChosenValidators ()
{
ChosenValidators::Ptr chosenValidators = createChosenValidators ();
m_listener->onValidatorsChosen (chosenValidators);
}
// Goes through all the sources and refreshes them as needed
//
bool scanSources ()
{
bool interrupted = false;
Time currentTime = Time::getCurrentTime ();
// Find a source that needs to be processed
//
for (int i = 0; i < m_info.size (); ++i)
{
SourceInfo& info (m_info.getReference (i));
// See if we need to refresh its list
//
if ((currentTime - info.lastFetch).inSeconds () > secondsBetweenFetches)
{
ValidatorList::Ptr list = info.source->fetch ();
currentTime = Time::getCurrentTime ();
if (list != nullptr)
{
info.status = SourceInfo::statusFetched;
info.lastFetch = currentTime;
info.list = list;
updateChosenValidators ();
}
}
interrupted = m_thread.interruptionPoint ();
if (interrupted)
break;
}
return interrupted;
}
void threadInit ()
{
m_timer.setRecurringExpiration (timerGranularity);
}
void threadExit ()
{
}
bool threadIdle ()
{
bool interrupted = false;
interrupted = scanSources ();
return interrupted;
} }
private: private:
InterruptibleThread m_thread; ThreadWithCallQueue m_thread;
Listener* const m_listener; DeadlineTimer m_timer;
StringArray m_trustedUris; Validators::Listener* const m_listener;
OwnedArray <Source> m_sources;
Array <SourceInfo> m_info;
ValidatorList::Ptr m_chosenValidators;
}; };
Validators* Validators::New (Listener* listener) Validators* Validators::New (Listener* listener)

View File

@@ -17,20 +17,51 @@
class Validators : Uncopyable class Validators : Uncopyable
{ {
public: public:
class Listener /** Provides a ValidatorList.
*/
class Source
{ {
public: public:
//virtual void onValidatorsChosen (ValidatorList validators) { } /** Destroy the source.
If a fetch is active, it will be aborted before the
destructor returns.
*/
virtual ~Source () { }
/** Fetch the validator list from this source.
This call blocks.
*/
virtual ValidatorList::Ptr fetch () = 0;
}; };
public: public:
/** Receive event notifications on Validators operations.
*/
class Listener
{
public:
virtual void onValidatorsChosen (ChosenValidators::Ptr list) { }
};
public:
/** Create a new Validators object.
*/
static Validators* New (Listener* listener); static Validators* New (Listener* listener);
/** Destroy the object.
Any pending source fetch operations are aborted.
There may be some listener calls made before the
destructor returns.
*/
virtual ~Validators () { } virtual ~Validators () { }
virtual void addTrustedUri (String uri) = 0; /** Add a source of validators.
*/
virtual void start () = 0; virtual void addSource (Source* source) = 0;
}; };
#endif #endif