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

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