Rename to SharedObjectArray

Conflicts:
	Builds/VisualStudio2012/RippleD.vcxproj.filters
This commit is contained in:
Vinnie Falco
2013-07-14 17:41:02 -07:00
parent 6d1a76b320
commit 166e2b69cb
26 changed files with 344 additions and 305 deletions

View File

@@ -355,12 +355,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<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>
@@ -379,12 +373,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</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">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
@@ -1453,11 +1441,11 @@
<ClInclude Include="..\..\modules\ripple_core\functional\ripple_LoadFeeTrack.h" />
<ClInclude Include="..\..\modules\ripple_core\functional\ripple_LoadMonitor.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_ValidatorList.h" />
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorListImp.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_Base58Data.h" />

View File

@@ -885,12 +885,6 @@
<ClCompile Include="..\..\modules\ripple_app\ledger\SerializedValidation.cpp">
<Filter>[1] Ripple\ripple_app\ledger</Filter>
</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>
@@ -1665,15 +1659,15 @@
<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>
<ClInclude Include="..\..\modules\ripple_core\validator\ripple_ValidatorListImp.h">
<Filter>[1] Ripple\ripple_core\validator</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\cpp\ripple\ripple.proto" />

View File

@@ -120,7 +120,7 @@
<ClInclude Include="..\..\modules\beast_core\containers\beast_NamedValueSet.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_OwnedArray.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_PropertySet.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_ReferenceCountedArray.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_SharedObjectArray.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_ScopedValueSetter.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_SharedTable.h" />
<ClInclude Include="..\..\modules\beast_core\containers\beast_SortedLookupTable.h" />

View File

@@ -160,9 +160,6 @@
<ClInclude Include="..\..\modules\beast_core\containers\beast_PropertySet.h">
<Filter>beast_core\containers</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\containers\beast_ReferenceCountedArray.h">
<Filter>beast_core\containers</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\containers\beast_ScopedValueSetter.h">
<Filter>beast_core\containers</Filter>
</ClInclude>
@@ -623,6 +620,9 @@
<ClInclude Include="..\..\modules\beast_crypto\beast_crypto.h">
<Filter>beast_crypto</Filter>
</ClInclude>
<ClInclude Include="..\..\modules\beast_core\containers\beast_SharedObjectArray.h">
<Filter>beast_core\containers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">

View File

@@ -239,7 +239,7 @@ namespace beast
#include "containers/beast_NamedValueSet.h"
#include "containers/beast_OwnedArray.h"
#include "containers/beast_PropertySet.h"
#include "containers/beast_ReferenceCountedArray.h"
#include "containers/beast_SharedObjectArray.h"
#include "containers/beast_ScopedValueSetter.h"
#include "containers/beast_SharedTable.h"
#include "containers/beast_SortedLookupTable.h"

View File

@@ -43,7 +43,7 @@
You can of course have an array of pointers to any kind of object, e.g. Array <MyClass*>, but if
you do this, the array doesn't take any ownership of the objects - see the OwnedArray class or the
ReferenceCountedArray class for more powerful ways of holding lists of objects.
SharedObjectArray class for more powerful ways of holding lists of objects.
For holding lists of strings, you can use Array\<String\>, but it's usually better to use the
specialised class StringArray, which provides more useful functions.
@@ -51,7 +51,7 @@
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
@see OwnedArray, ReferenceCountedArray, StringArray, CriticalSection
@see OwnedArray, SharedObjectArray, StringArray, CriticalSection
*/
template <typename ElementType,
typename TypeOfCriticalSectionToUse = DummyCriticalSection,

View File

@@ -37,7 +37,7 @@
It inherits from a critical section class to allow the arrays to use
the "empty base class optimisation" pattern to reduce their footprint.
@see Array, OwnedArray, ReferenceCountedArray
@see Array, OwnedArray, SharedObjectArray
*/
template <class ElementType, class TypeOfCriticalSectionToUse>
class ArrayAllocationBase

View File

@@ -41,7 +41,7 @@
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
@see Array, ReferenceCountedArray, StringArray, CriticalSection
@see Array, SharedObjectArray, StringArray, CriticalSection
*/
template <class ObjectClass,
class TypeOfCriticalSectionToUse = DummyCriticalSection>

View File

@@ -34,7 +34,7 @@
/**
Holds a list of objects derived from SharedObject.
A ReferenceCountedArray holds objects derived from SharedObject,
A SharedObjectArray holds objects derived from SharedObject,
and takes care of incrementing and decrementing their ref counts when they
are added and removed from the array.
@@ -44,7 +44,7 @@
@see Array, OwnedArray, StringArray
*/
template <class ObjectClass, class TypeOfCriticalSectionToUse = DummyCriticalSection>
class ReferenceCountedArray
class SharedObjectArray
{
public:
typedef SharedObjectPtr<ObjectClass> ObjectClassPtr;
@@ -53,13 +53,13 @@ public:
/** Creates an empty array.
@see SharedObject, Array, OwnedArray
*/
ReferenceCountedArray() noexcept
SharedObjectArray() noexcept
: numUsed (0)
{
}
/** Creates a copy of another array */
ReferenceCountedArray (const ReferenceCountedArray& other) noexcept
SharedObjectArray (const SharedObjectArray& other) noexcept
{
const ScopedLockType lock (other.getLock());
numUsed = other.size();
@@ -73,9 +73,9 @@ public:
/** Creates a copy of another array */
template <class OtherObjectClass, class OtherCriticalSection>
ReferenceCountedArray (const ReferenceCountedArray<OtherObjectClass, OtherCriticalSection>& other) noexcept
SharedObjectArray (const SharedObjectArray<OtherObjectClass, OtherCriticalSection>& other) noexcept
{
const typename ReferenceCountedArray<OtherObjectClass, OtherCriticalSection>::ScopedLockType lock (other.getLock());
const typename SharedObjectArray<OtherObjectClass, OtherCriticalSection>::ScopedLockType lock (other.getLock());
numUsed = other.size();
data.setAllocatedSize (numUsed);
memcpy (data.elements, other.getRawDataPointer(), numUsed * sizeof (ObjectClass*));
@@ -88,9 +88,9 @@ public:
/** Copies another array into this one.
Any existing objects in this array will first be released.
*/
ReferenceCountedArray& operator= (const ReferenceCountedArray& other) noexcept
SharedObjectArray& operator= (const SharedObjectArray& other) noexcept
{
ReferenceCountedArray otherCopy (other);
SharedObjectArray otherCopy (other);
swapWithArray (otherCopy);
return *this;
}
@@ -99,9 +99,9 @@ public:
Any existing objects in this array will first be released.
*/
template <class OtherObjectClass>
ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& operator= (const ReferenceCountedArray<OtherObjectClass, TypeOfCriticalSectionToUse>& other) noexcept
SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse>& operator= (const SharedObjectArray<OtherObjectClass, TypeOfCriticalSectionToUse>& other) noexcept
{
ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other);
SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other);
swapWithArray (otherCopy);
return *this;
}
@@ -109,7 +109,7 @@ public:
/** Destructor.
Any objects in the array will be released, and may be deleted if not referenced from elsewhere.
*/
~ReferenceCountedArray()
~SharedObjectArray()
{
clear();
}
@@ -409,7 +409,7 @@ public:
all available elements will be copied.
@see add
*/
void addArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& arrayToAddFrom,
void addArray (const SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse>& arrayToAddFrom,
int startIndex = 0,
int numElementsToAdd = -1) noexcept
{
@@ -740,7 +740,7 @@ public:
If you need to exchange two arrays, this is vastly quicker than using copy-by-value
because it just swaps their internal pointers.
*/
void swapWithArray (ReferenceCountedArray& otherArray) noexcept
void swapWithArray (SharedObjectArray& otherArray) noexcept
{
const ScopedLockType lock1 (getLock());
const ScopedLockType lock2 (otherArray.getLock());
@@ -754,7 +754,7 @@ public:
@returns true only if the other array contains the same objects in the same order
*/
bool operator== (const ReferenceCountedArray& other) const noexcept
bool operator== (const SharedObjectArray& other) const noexcept
{
const ScopedLockType lock2 (other.getLock());
const ScopedLockType lock1 (getLock());
@@ -773,7 +773,7 @@ public:
@see operator==
*/
bool operator!= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const noexcept
bool operator!= (const SharedObjectArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const noexcept
{
return ! operator== (other);
}

View File

@@ -53,7 +53,7 @@
To make all the set's methods thread-safe, pass in "CriticalSection" as the templated
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
@see Array, OwnedArray, ReferenceCountedArray, StringArray, CriticalSection
@see Array, OwnedArray, SharedObjectArray, StringArray, CriticalSection
*/
template <class ElementType, class TypeOfCriticalSectionToUse = DummyCriticalSection>
class SortedSet

View File

@@ -57,7 +57,7 @@
the pointers can be passed between threads safely. For a faster but non-thread-safe
version, use SingleThreadedSharedObject instead.
@see SharedObjectPtr, ReferenceCountedArray, SingleThreadedSharedObject
@see SharedObjectPtr, SharedObjectArray, SingleThreadedSharedObject
*/
class BEAST_API SharedObject : Uncopyable
{
@@ -126,7 +126,7 @@ private:
efficient).
For more details on how to use it, see the SharedObject class notes.
@see SharedObject, SharedObjectPtr, ReferenceCountedArray
@see SharedObject, SharedObjectPtr, SharedObjectArray
*/
class BEAST_API SingleThreadedSharedObject : public Uncopyable
{

View File

@@ -122,7 +122,7 @@ private:
This is currently used by some templated classes, and most compilers should
manage to optimise it out of existence.
@see CriticalSection, Array, OwnedArray, ReferenceCountedArray
@see CriticalSection, Array, OwnedArray, SharedObjectArray
*/
class BEAST_API DummyCriticalSection : Uncopyable
{

View File

@@ -12,6 +12,10 @@ RIPPLE TODO
--------------------------------------------------------------------------------
- Replace endian conversion calls with beast calls:
htobe32, be32toh, ntohl, etc...
Start by removing the system headers which provide these routines, if possible
- Rename RPCHandler to CallHandler
- Move everything in src/cpp/ripple into ripple_app and sort them into
@@ -405,14 +409,6 @@ ChosenValidators
* "local health" percentage is the percent of validations from this list that
you've seen recently. And have they been behaving.
Process:
Algorithm
For each TrustedUri:
Perform HTTPS request to retrieve a KnownValidators list
Create the union of all unique KnownValidator, keyed by public key
- Calculate the number of appearances to determine the "weight"
Algorithm:
ChosenValidators chooseRandomSubset (RankedKnownValidators)
When updating a source

View File

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

View File

@@ -39,7 +39,6 @@ namespace ripple
#include "validator/ripple_Validator.h"
#include "validator/ripple_ValidatorList.h"
#include "validator/ripple_ChosenValidators.h"
#include "validator/ripple_Validators.h"
#include "validator/ripple_StringsValidatorSource.h"
#include "validator/ripple_TrustedUriValidatorSource.h"

View File

@@ -1,27 +0,0 @@
//------------------------------------------------------------------------------
/*
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

@@ -1,41 +0,0 @@
//------------------------------------------------------------------------------
/*
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

@@ -15,11 +15,8 @@ public:
{
}
ValidatorList::Ptr fetch ()
void fetch (Array <ValidatorInfo>& results)
{
ValidatorList::Ptr list = new ValidatorList;
return list;
}
private:

View File

@@ -16,11 +16,8 @@ public:
{
}
ValidatorList::Ptr fetch ()
void fetch (Array <ValidatorInfo>& results)
{
ValidatorList::Ptr list = new ValidatorList;
return list;
}
private:

View File

@@ -7,18 +7,33 @@
#ifndef RIPPLE_VALIDATOR_H_INCLUDED
#define RIPPLE_VALIDATOR_H_INCLUDED
/** Identifies a validator.
A validator signs ledgers and participates in the consensus process.
/** Fixed information on a validator.
*/
class Validator
struct ValidatorInfo
{
public:
// VFALCO TODO magic number argh!!!
// This type should be located elsewhere.
//
typedef UnsignedInteger <33> PublicKey;
PublicKey publicKey;
String friendlyName;
String organizationType;
String jurisdicton;
};
/** Identifies a validator.
A validator signs ledgers and participates in the consensus process.
*/
class Validator : public SharedObject
{
public:
typedef SharedObjectPtr <Validator> Ptr;
typedef ValidatorInfo::PublicKey PublicKey;
public:
explicit Validator (PublicKey const& publicKey);
//Validator (Validator const&);
@@ -29,6 +44,7 @@ public:
void incrementWeight () { ++m_weight; }
private:
ValidatorInfo m_info;
PublicKey m_publicKey;
int m_weight;
};

View File

@@ -1,35 +0,0 @@
//------------------------------------------------------------------------------
/*
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

@@ -18,27 +18,17 @@ class ValidatorList : public SharedObject
public:
typedef SharedObjectPtr <ValidatorList> Ptr;
/** Create an empty list.
*/
ValidatorList ();
~ValidatorList ();
virtual ~ValidatorList () { }
/** Retrieve the number of items.
*/
int size () const;
virtual int size () const noexcept = 0;
Validator& operator[] (int index);
bool isSigned () const;
virtual Validator::Ptr operator[] (int index) = 0;
/** Add a validator to the list.
*/
void add (Validator const& validator);
private:
bool m_isSigned;
Array <Validator> m_list;
virtual void add (Validator::Ptr validator) = 0;
};
#endif

View File

@@ -0,0 +1,44 @@
//------------------------------------------------------------------------------
/*
Copyright (c) 2011-2013, OpenCoin, Inc.
*/
//==============================================================================
#ifndef RIPPLE_VALIDATORLISTIMP_H_INCLUDED
#define RIPPLE_VALIDATORLISTIMP_H_INCLUDED
// This is a private header
/** Private implementation of ValidatorList.
*/
class ValidatorListImp : public ValidatorList
{
public:
ValidatorListImp ()
{
}
~ValidatorListImp ()
{
}
int size () const
{
return m_list.size ();
}
Validator::Ptr operator[] (int index)
{
return m_list.getObjectPointer (index);
}
void add (Validator::Ptr validator)
{
m_list.add (validator);
}
private:
SharedObjectArray <Validator> m_list;
};
#endif

View File

@@ -15,7 +15,6 @@ Two important questions:
*/
class ValidatorsImp
: public Validators
, private ThreadWithCallQueue::EntryPoints
@@ -25,15 +24,37 @@ public:
// Tunable constants
enum
{
hoursBetweenFetches = 24,
// We will fetch a source at this interval
hoursBetweenFetches = 24
secondsBetweenFetches = hoursBetweenFetches * 60 * 60,
,secondsBetweenFetches = hoursBetweenFetches * 60 * 60
timerGranularity = 60 * 60 // Wake up every hour
// Wake up every hour to check source times
,timerGranularity = 60 * 60
// This tunes the preallocated arrays
,expectedNumberOfResults = 1000
};
//--------------------------------------------------------------------------
struct ValidatorInfoCompare
{
static int compareElements (ValidatorInfo const& lhs, ValidatorInfo const& rhs)
{
int result;
if (lhs.publicKey < rhs.publicKey)
result = -1;
else if (lhs.publicKey > rhs.publicKey)
result = 1;
else
result = 0;
return result;
}
};
struct SourceInfo
{
enum Status
@@ -46,22 +67,122 @@ public:
explicit SourceInfo (Source* source_)
: source (source_)
, status (statusNone)
, numberOfFailures (0)
{
}
Source* source;
Status status;
Time lastFetch;
ValidatorList::Ptr list;
Time whenToFetch;
/** The number of times a fetch has failed.
*/
int numberOfFailures;
};
// This is what comes back from a source
typedef Array <SourceInfo> SourceInfoArray;
typedef Array <ValidatorInfo> ValidatorInfoArray;
// The result of performing a fetch
struct FetchResult
{
// This is what comes back from the fetch
ValidatorInfoArray updatedList;
// The original list before the fetch
SharedObjectArray <Validator> oldList;
// The new list after the fetch
SharedObjectArray <Validator> newList;
// The list of validators that were added
SharedObjectArray <Validator> addedList;
// The list of validators that were removed
SharedObjectArray <Validator> removedList;
FetchResult ()
{
updatedList.ensureStorageAllocated (expectedNumberOfResults);
oldList.ensureStorageAllocated (expectedNumberOfResults);
newList.ensureStorageAllocated (expectedNumberOfResults);
addedList.ensureStorageAllocated (expectedNumberOfResults);
removedList.ensureStorageAllocated (expectedNumberOfResults);
}
void clear ()
{
updatedList.clearQuick ();
oldList.clear ();
newList.clear ();
addedList.clear ();
removedList.clear ();
}
};
//--------------------------------------------------------------------------
// Encapsulates the logic for creating the chosen validators.
// This is a separate class to facilitate the unit tests.
//
class Logic
{
public:
Logic ()
: m_knownValidators (new ValidatorListImp)
, m_chosenValidators (new ValidatorListImp)
{
}
void addSource (Source* source)
{
m_sources.add (source);
m_sourceInfo.add (SourceInfo (source));
}
SourceInfoArray& getSources ()
{
return m_sourceInfo;
}
void processValidatorInfo (ValidatorInfoArray& fetchResults)
{
}
void sortValidatorInfo (ValidatorInfoArray& arrayToSort)
{
ValidatorInfoArray sorted;
sorted.ensureStorageAllocated (arrayToSort.size ());
for (int i = 0; i < arrayToSort.size (); ++i)
sorted.addSorted (ValidatorInfoCompare(), arrayToSort [i]);
arrayToSort.swapWithArray (sorted);
}
void fetchSource (SourceInfo& sourceInfo)
{
}
private:
OwnedArray <Source> m_sources;
SourceInfoArray m_sourceInfo;
ValidatorList::Ptr m_knownValidators;
ValidatorList::Ptr m_chosenValidators;
};
//--------------------------------------------------------------------------
public:
explicit ValidatorsImp (Validators::Listener* listener)
: m_thread ("Validators")
: m_listener (listener)
, m_thread ("Validators")
, m_timer (this)
, m_listener (listener)
{
m_thread.start (this);
}
@@ -77,9 +198,7 @@ public:
void doAddSource (Source* source)
{
m_sources.add (source);
m_info.add (SourceInfo (source));
m_logic.addSource (source);
}
void onDeadlineTimer (DeadlineTimer&)
@@ -89,63 +208,6 @@ public:
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 ()
@@ -154,28 +216,43 @@ public:
Time currentTime = Time::getCurrentTime ();
ValidatorInfoArray fetchResults;
fetchResults.ensureStorageAllocated (1000);
SourceInfoArray sourceInfoArray (m_logic.getSources ());
// Find a source that needs to be processed
//
for (int i = 0; i < m_info.size (); ++i)
for (int i = 0; i < sourceInfoArray.size (); ++i)
{
SourceInfo& info (m_info.getReference (i));
SourceInfo& sourceInfo (sourceInfoArray.getReference (i));
// See if we need to refresh its list
//
if ((currentTime - info.lastFetch).inSeconds () > secondsBetweenFetches)
if (currentTime <= sourceInfo.whenToFetch)
{
ValidatorList::Ptr list = info.source->fetch ();
sourceInfo.source->fetch (fetchResults);
currentTime = Time::getCurrentTime ();
if (list != nullptr)
if (fetchResults.size () != 0)
{
info.status = SourceInfo::statusFetched;
info.lastFetch = currentTime;
info.list = list;
sourceInfo.status = SourceInfo::statusFetched;
sourceInfo.whenToFetch = currentTime + RelativeTime (hoursBetweenFetches * 60.0 * 60.0);
updateChosenValidators ();
m_logic.processValidatorInfo (fetchResults);
//m_listener->onValidatorsChosen (chosenValidators);
}
else
{
// Failed to fetch
// Don't update fetch time
sourceInfo.status = SourceInfo::statusFailed;
sourceInfo.numberOfFailures++;
}
fetchResults.clearQuick ();
}
interrupted = m_thread.interruptionPoint ();
@@ -206,12 +283,10 @@ public:
}
private:
Logic m_logic;
Validators::Listener* const m_listener;
ThreadWithCallQueue m_thread;
DeadlineTimer m_timer;
Validators::Listener* const m_listener;
OwnedArray <Source> m_sources;
Array <SourceInfo> m_info;
ValidatorList::Ptr m_chosenValidators;
};
Validators* Validators::New (Listener* listener)
@@ -221,36 +296,28 @@ Validators* Validators::New (Listener* listener)
//------------------------------------------------------------------------------
/** Produces validators for unit tests.
*/
// Produces validators for unit tests.
class TestValidatorSource : public Validators::Source
{
public:
static Validator createValidator (unsigned int publicKeyIndex)
{
Validator validator (Validator::PublicKey::createFromInteger (publicKeyIndex));
return validator;
}
TestValidatorSource (unsigned startIndex, int numEntries)
TestValidatorSource (unsigned int startIndex, int numEntries)
: m_startIndex (startIndex)
, m_numEntries (numEntries)
{
}
ValidatorList::Ptr fetch ()
void fetch (Array <ValidatorInfo>& results)
{
ValidatorList::Ptr list = new ValidatorList;
for (unsigned int publicKeyIndex = m_startIndex;
publicKeyIndex < m_startIndex + m_numEntries;
++publicKeyIndex)
{
list->add (createValidator (publicKeyIndex));
}
ValidatorInfo info;
return list;
info.publicKey = Validator::PublicKey::createFromInteger (publicKeyIndex);
results.add (info);
}
}
private:
@@ -267,10 +334,60 @@ public:
{
}
void publicKeyTest ()
{
beginTest ("compare");
ValidatorInfo::PublicKey one (ValidatorInfo::PublicKey::createFromInteger (1U));
ValidatorInfo::PublicKey two (ValidatorInfo::PublicKey::createFromInteger (2U));
expect (one < two, "should be less");
expect (two > one, "should be greater");
}
void fetchTest ()
{
beginTest ("fetch");
TestValidatorSource source (0, 32);
ValidatorsImp::ValidatorInfoArray results;
source.fetch (results);
expect (results.size () == 32, "size should be 32");
}
void runTest ()
{
beginTest ("ValidatorList");
publicKeyTest ();
fetchTest ();
}
};
template class UnitTestType <ValidatorListTests>;
/*
Goal:
Provide the listener with a ValidatorList.
- This forms the UNL
Task:
fetch ValidatorInfo array from a source
- We have the old one and the new one, compute the following:
* unchanged validators list
* new validators list
* removed validators list
- From the unchanged / new / removed, figure out what to do.
*/

View File

@@ -33,7 +33,7 @@ public:
This call blocks.
*/
virtual ValidatorList::Ptr fetch () = 0;
virtual void fetch (Array <ValidatorInfo>& results) = 0;
};
public:
@@ -42,7 +42,7 @@ public:
class Listener
{
public:
virtual void onValidatorsChosen (ChosenValidators::Ptr list) { }
virtual void onValidatorsChosen (ValidatorList::Ptr list) { }
};
public:

View File

@@ -343,12 +343,17 @@ private:
bool volatile mShutdown;
};
// VFALCO TODO Why do we even have this function?
// It could just be handled in the destructor.
//
void ApplicationImp::stop ()
{
WriteLog (lsINFO, Application) << "Received shutdown request";
StopSustain ();
mShutdown = true;
mIOService.stop ();
// VFALCO TODO We shouldn't have to explicitly call this function.
// The NodeStore destructor should take care of it.
m_nodeStore.waitWrite ();
mValidations->flush ();
mAuxService.stop ();