diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index e2147e19b6..ab65409358 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj
+++ b/Builds/VisualStudio2012/RippleD.vcxproj
@@ -355,12 +355,36 @@
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
true
true
true
+
+ true
+ true
+ true
+ true
+
true
true
@@ -1428,7 +1452,11 @@
+
+
+
+
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters
index bc7add8bd0..e5431a02ad 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters
@@ -885,6 +885,18 @@
[1] Ripple\ripple_app\ledger
+
+ [1] Ripple\ripple_core\validator
+
+
+ [1] Ripple\ripple_core\validator
+
+
+ [1] Ripple\ripple_core\validator
+
+
+ [1] Ripple\ripple_core\validator
+
@@ -1647,6 +1659,18 @@
[1] Ripple\ripple_app\_main
+
+ [1] Ripple\ripple_core\validator
+
+
+ [1] Ripple\ripple_core\validator
+
+
+ [1] Ripple\ripple_core\validator
+
+
+ [1] Ripple\ripple_core\validator
+
diff --git a/TODO.txt b/TODO.txt
index 12723e289a..781a5d056d 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -2,6 +2,14 @@
RIPPLE TODO
--------------------------------------------------------------------------------
+- Unit Test attention
+
+- NodeStore backend unit test
+
+- Validations unit test
+
+--------------------------------------------------------------------------------
+
- Rename RPCHandler to CallHandler
- Move everything in src/cpp/ripple into ripple_app and sort them into
@@ -227,7 +235,7 @@ Interfaces
boost
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
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:
Make default configuration of rippled secure.
diff --git a/modules/ripple_core/ripple_core.cpp b/modules/ripple_core/ripple_core.cpp
index 421fff750c..00345c1f67 100644
--- a/modules/ripple_core/ripple_core.cpp
+++ b/modules/ripple_core/ripple_core.cpp
@@ -31,8 +31,12 @@ 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_Validators.cpp"
+#include "validator/ripple_StringsValidatorSource.cpp"
+#include "validator/ripple_TrustedUriValidatorSource.cpp"
}
diff --git a/modules/ripple_core/ripple_core.h b/modules/ripple_core/ripple_core.h
index 91575ec8c9..cc8a8d56c9 100644
--- a/modules/ripple_core/ripple_core.h
+++ b/modules/ripple_core/ripple_core.h
@@ -38,7 +38,11 @@ namespace ripple
/**/#include "functional/ripple_JobQueue.h"
#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"
}
diff --git a/modules/ripple_core/validator/ripple_ChosenValidators.cpp b/modules/ripple_core/validator/ripple_ChosenValidators.cpp
new file mode 100644
index 0000000000..9b4b2d9bc1
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_ChosenValidators.cpp
@@ -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;
+}
+
diff --git a/modules/ripple_core/validator/ripple_ChosenValidators.h b/modules/ripple_core/validator/ripple_ChosenValidators.h
new file mode 100644
index 0000000000..96833bdfdb
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_ChosenValidators.h
@@ -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 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
diff --git a/modules/ripple_core/validator/ripple_StringsValidatorSource.cpp b/modules/ripple_core/validator/ripple_StringsValidatorSource.cpp
new file mode 100644
index 0000000000..9bf67bfb3c
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_StringsValidatorSource.cpp
@@ -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);
+}
diff --git a/modules/ripple_core/validator/ripple_StringsValidatorSource.h b/modules/ripple_core/validator/ripple_StringsValidatorSource.h
new file mode 100644
index 0000000000..d7991a7d4f
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_StringsValidatorSource.h
@@ -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
diff --git a/modules/ripple_core/validator/ripple_TrustedUriValidatorSource.cpp b/modules/ripple_core/validator/ripple_TrustedUriValidatorSource.cpp
new file mode 100644
index 0000000000..4d54117ca0
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_TrustedUriValidatorSource.cpp
@@ -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);
+}
diff --git a/modules/ripple_core/validator/ripple_TrustedUriValidatorSource.h b/modules/ripple_core/validator/ripple_TrustedUriValidatorSource.h
new file mode 100644
index 0000000000..5a32f2a211
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_TrustedUriValidatorSource.h
@@ -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
diff --git a/modules/ripple_core/validator/ripple_Validator.cpp b/modules/ripple_core/validator/ripple_Validator.cpp
index a4cd57cff3..0766d0c7f3 100644
--- a/modules/ripple_core/validator/ripple_Validator.cpp
+++ b/modules/ripple_core/validator/ripple_Validator.cpp
@@ -4,6 +4,7 @@
*/
//==============================================================================
-Validator::Validator ()
+Validator::Validator (PublicKey const& publicKey)
+ : m_publicKey (publicKey)
{
}
diff --git a/modules/ripple_core/validator/ripple_Validator.h b/modules/ripple_core/validator/ripple_Validator.h
index 310b2c6552..de3a9c39c9 100644
--- a/modules/ripple_core/validator/ripple_Validator.h
+++ b/modules/ripple_core/validator/ripple_Validator.h
@@ -16,10 +16,18 @@ class Validator
public:
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:
PublicKey m_publicKey;
+ int m_weight;
};
#endif
diff --git a/modules/ripple_core/validator/ripple_ValidatorList.cpp b/modules/ripple_core/validator/ripple_ValidatorList.cpp
new file mode 100644
index 0000000000..2b927d1f5d
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_ValidatorList.cpp
@@ -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);
+}
+
diff --git a/modules/ripple_core/validator/ripple_ValidatorList.h b/modules/ripple_core/validator/ripple_ValidatorList.h
new file mode 100644
index 0000000000..ad0eed1c85
--- /dev/null
+++ b/modules/ripple_core/validator/ripple_ValidatorList.h
@@ -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 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 m_list;
+};
+
+#endif
diff --git a/modules/ripple_core/validator/ripple_Validators.cpp b/modules/ripple_core/validator/ripple_Validators.cpp
index 360d8fba0f..14d9d600d8 100644
--- a/modules/ripple_core/validator/ripple_Validators.cpp
+++ b/modules/ripple_core/validator/ripple_Validators.cpp
@@ -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
: public Validators
- , private InterruptibleThread::EntryPoint
+ , private ThreadWithCallQueue::EntryPoints
+ , private DeadlineTimer::Listener
{
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_timer (this)
, m_listener (listener)
{
+ m_thread.start (this);
}
~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:
- InterruptibleThread m_thread;
- Listener* const m_listener;
- StringArray m_trustedUris;
+ ThreadWithCallQueue m_thread;
+ DeadlineTimer m_timer;
+ Validators::Listener* const m_listener;
+ OwnedArray m_sources;
+ Array m_info;
+ ValidatorList::Ptr m_chosenValidators;
};
Validators* Validators::New (Listener* listener)
diff --git a/modules/ripple_core/validator/ripple_Validators.h b/modules/ripple_core/validator/ripple_Validators.h
index a025840157..922c0ee605 100644
--- a/modules/ripple_core/validator/ripple_Validators.h
+++ b/modules/ripple_core/validator/ripple_Validators.h
@@ -17,20 +17,51 @@
class Validators : Uncopyable
{
public:
- class Listener
+ /** Provides a ValidatorList.
+ */
+ class Source
{
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:
+ /** 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);
+ /** Destroy the object.
+
+ Any pending source fetch operations are aborted.
+
+ There may be some listener calls made before the
+ destructor returns.
+ */
virtual ~Validators () { }
- virtual void addTrustedUri (String uri) = 0;
-
- virtual void start () = 0;
+ /** Add a source of validators.
+ */
+ virtual void addSource (Source* source) = 0;
};
#endif