diff --git a/Builds/QtCreator/rippled.pro b/Builds/QtCreator/rippled.pro
index 511290eee..3769f4bb1 100644
--- a/Builds/QtCreator/rippled.pro
+++ b/Builds/QtCreator/rippled.pro
@@ -43,7 +43,6 @@ linux-g++:QMAKE_CXXFLAGS += \
-pthread
INCLUDEPATH += \
- "../.." \
"../../src" \
"../../src/leveldb/" \
"../../src/leveldb/port" \
@@ -58,6 +57,9 @@ OTHER_FILES += \
UI_HEADERS_DIR += ../../src/ripple_basics
+# -----
+# Beast
+#
SOURCES += \
../../src/beast/modules/beast_asio/beast_asio.cpp \
../../src/beast/modules/beast_core/beast_core.cpp \
@@ -65,7 +67,12 @@ SOURCES += \
../../src/beast/modules/beast_db/beast_db.cpp \
../../src/beast/modules/beast_extras/beast_extras.cpp \
../../src/beast/modules/beast_sqdb/beast_sqdb.cpp \
- ../../src/beast/modules/beast_sqlite/beast_sqlite.c \
+ ../../src/beast/modules/beast_sqlite/beast_sqlite.c
+
+# ---------
+# Old style
+#
+SOURCES += \
../../src/ripple_app/ripple_app.cpp \
../../src/ripple_app/ripple_app_pt1.cpp \
../../src/ripple_app/ripple_app_pt2.cpp \
@@ -84,6 +91,13 @@ SOURCES += \
../../src/ripple_net/ripple_net.cpp \
../../src/ripple_websocket/ripple_websocket.cpp
+# ---------
+# New style
+#
+SOURCES += \
+ ../../src/ripple/testoverlay/ripple_testoverlay.cpp \
+ ../../src/ripple/validators/ripple_validators.cpp
+
LIBS += \
-lboost_date_time-mt\
-lboost_filesystem-mt \
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj
index b4fe0f11b..386bc106e 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj
+++ b/Builds/VisualStudio2012/RippleD.vcxproj
@@ -26,6 +26,44 @@
+
+ true
+ true
+ true
+ true
+
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
true
true
@@ -784,12 +822,6 @@
true
true
-
- true
- true
- true
- true
-
true
true
@@ -797,36 +829,6 @@
true
-
- true
- true
- true
- true
-
-
- true
- true
- true
- true
-
-
- true
- true
- true
- true
-
-
- true
- true
- true
- true
-
-
- true
- true
- true
- true
-
true
true
@@ -1378,6 +1380,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1520,22 +1539,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters
index 395ecf8e6..955f4b3a5 100644
--- a/Builds/VisualStudio2012/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters
@@ -70,9 +70,6 @@
{571acd5b-065c-4202-8de3-8692735171dc}
-
- {efccddf1-024d-41c4-b7f5-26ce2dd79f21}
-
{cf19fa31-c40b-4203-b497-63a8c3dcb282}
@@ -118,12 +115,6 @@
{1d9bc26d-d76e-4fd4-a737-b968e31e614b}
-
- {129c51dc-e885-4023-999b-e133d800fb80}
-
-
- {c69b07a2-44e5-4b06-99a9-81f5d137ea15}
-
{d1648d3f-7d71-495d-afc9-576ed00d7185}
@@ -157,6 +148,30 @@
{6967f835-a1b0-47e3-9bd9-6fc8bd0f3df7}
+
+ {a2508a4d-acbc-406b-ada6-e66ff66fafc6}
+
+
+ {c69b07a2-44e5-4b06-99a9-81f5d137ea15}
+
+
+ {b6d40ea6-339c-4ae5-9f48-37e235eff2f2}
+
+
+ {ab806f38-36f5-4c76-b83a-72ac8bf54440}
+
+
+ {0e355563-7517-4e4b-ba7c-65eb11942cda}
+
+
+ {de9ef050-2263-4cd3-a563-db81d137cf34}
+
+
+ {35c905cd-afaa-467a-906d-eb2b34a18907}
+
+
+ {e614b68f-21cb-4866-82d1-1ea89ee11906}
+
@@ -831,18 +846,6 @@
[1] Ripple\ripple_core\node
-
- [1] Ripple\ripple_core\validator
-
-
- [1] Ripple\ripple_core\validator
-
-
- [1] Ripple\ripple_core\validator
-
-
- [1] Ripple\ripple_core\validator
-
[1] Ripple
@@ -867,7 +870,6 @@
[0] Libraries\beast
-
[1] Ripple\ripple_core
@@ -877,8 +879,29 @@
[1] Ripple\ripple_core\functional
-
- [1] Ripple\ripple_core\validator
+
+ [2] Ripple %28New%29\testoverlay
+
+
+ [2] Ripple %28New%29\testoverlay\impl
+
+
+ [2] Ripple %28New%29\validators
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\impl
@@ -1680,51 +1703,6 @@
[1] Ripple\ripple_app\misc
-
- [1] Ripple\ripple_core\validator
-
-
- [1] Ripple\ripple_core\validator
-
-
- [1] Ripple\ripple_core\validator
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\test
-
-
- [1] Ripple\ripple_core\validator
-
-
- [1] Ripple\ripple_core\validator
-
[1] Ripple\ripple_core\peerfinder
@@ -1732,8 +1710,56 @@
[1] Ripple\ripple_core\functional
-
- [1] Ripple\ripple_core\validator
+
+ [2] Ripple %28New%29\testoverlay
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\testoverlay\api
+
+
+ [2] Ripple %28New%29\validators
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\impl
+
+
+ [2] Ripple %28New%29\validators\api
@@ -1764,10 +1790,10 @@
%28Notes%29
- [2] doc
+ [3] doc
- [2] doc
+ [3] doc
diff --git a/SConstruct b/SConstruct
index fceaba7ae..442decdaf 100644
--- a/SConstruct
+++ b/SConstruct
@@ -101,41 +101,56 @@ else:
#-------------------------------------------------------------------------------
#
-# VFALCO This is my oasis of sanity. Nothing having to do with directories,
-# source files, or include paths should reside outside the boundaries.
+# VFALCO NOTE Clean area.
+#
+#-------------------------------------------------------------------------------
+#
+# Nothing having to do with directories, source files,
+# or include paths should reside outside the boundaries.
#
# List of includes passed to the C++ compiler.
# These are all relative to the repo dir.
#
INCLUDE_PATHS = [
- '.',
- 'build/proto',
'src',
'src/leveldb',
'src/leveldb/port',
'src/leveldb/include',
'src/beast',
+ 'build/proto'
]
# if BOOST_HOME:
# INCLUDE_PATHS.append(BOOST_HOME)
-if OSX:
- COMPILED_FILES = [
- 'src/beast/modules/beast_core/beast_core.mm'
- ]
-else:
- COMPILED_FILES = [
- 'src/beast/modules/beast_core/beast_core.cpp'
- ]
+#-------------------------------------------------------------------------------
+#
+# Compiled sources
+#
+COMPILED_FILES = []
+
+# -------------------
+# Beast unity sources
+#
COMPILED_FILES.extend([
'src/beast/modules/beast_asio/beast_asio.cpp',
'src/beast/modules/beast_crypto/beast_crypto.cpp',
'src/beast/modules/beast_db/beast_db.cpp',
'src/beast/modules/beast_sqdb/beast_sqdb.cpp',
- 'src/beast/modules/beast_sqlite/beast_sqlite.c',
+ 'src/beast/modules/beast_sqlite/beast_sqlite.c'
+ ])
+if OSX:
+ # OSX: Use the Objective C++ version of beast_core
+ COMPILED_FILES.extend (['src/beast/modules/beast_core/beast_core.mm'])
+else:
+ COMPILED_FILES.extend (['src/beast/modules/beast_core/beast_core.cpp'])
+
+# ------------------------------
+# Old-style Ripple unity sources
+#
+COMPILED_FILES.extend([
'src/ripple_app/ripple_app.cpp',
'src/ripple_app/ripple_app_pt1.cpp',
'src/ripple_app/ripple_app_pt2.cpp',
@@ -155,6 +170,16 @@ COMPILED_FILES.extend([
'src/ripple_websocket/ripple_websocket.cpp'
])
+# ------------------------------
+# New-style Ripple unity sources
+#
+COMPILED_FILES.extend([
+ 'src/ripple/testoverlay/ripple_testoverlay.cpp',
+ 'src/ripple/validators/ripple_validators.cpp'
+ ])
+
+#
+#
#-------------------------------------------------------------------------------
# Map top level source directories to their location in the outputs
diff --git a/doc/todo/VFALCO_TODO.txt b/doc/todo/VFALCO_TODO.txt
index 14e24ff55..5f8f70707 100644
--- a/doc/todo/VFALCO_TODO.txt
+++ b/doc/todo/VFALCO_TODO.txt
@@ -3,6 +3,7 @@ RIPPLE TODO
--------------------------------------------------------------------------------
Vinnie's List: Changes day to day, descending priority
+- Look into using CMake
- Validators should delay the application of newly downloaded lists from
sources, to mitigate the effects of attacks. Unless there's no validators
in the list.
diff --git a/src/ripple_core/test/ConfigType.h b/src/ripple/testoverlay/api/ConfigType.h
similarity index 92%
rename from src/ripple_core/test/ConfigType.h
rename to src/ripple/testoverlay/api/ConfigType.h
index 088e9b232..542378a69 100644
--- a/src/ripple_core/test/ConfigType.h
+++ b/src/ripple/testoverlay/api/ConfigType.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_CONFIGTYPE_H_INCLUDED
-#define RIPPLE_CORE_TEST_CONFIGTYPE_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_CONFIGTYPE_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_CONFIGTYPE_H_INCLUDED
/** A simulated peer to peer network for unit tests. */
namespace TestOverlay
diff --git a/src/ripple_core/test/ConnectionType.h b/src/ripple/testoverlay/api/ConnectionType.h
similarity index 97%
rename from src/ripple_core/test/ConnectionType.h
rename to src/ripple/testoverlay/api/ConnectionType.h
index 1013a6ef7..bbeeb1dda 100644
--- a/src/ripple_core/test/ConnectionType.h
+++ b/src/ripple/testoverlay/api/ConnectionType.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_CONNECTIONTYPE_H_INCLUDED
-#define RIPPLE_CORE_TEST_CONNECTIONTYPE_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_CONNECTIONTYPE_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_CONNECTIONTYPE_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/InitPolicy.h b/src/ripple/testoverlay/api/InitPolicy.h
similarity index 94%
rename from src/ripple_core/test/InitPolicy.h
rename to src/ripple/testoverlay/api/InitPolicy.h
index a57c57ecb..8f383bfc8 100644
--- a/src/ripple_core/test/InitPolicy.h
+++ b/src/ripple/testoverlay/api/InitPolicy.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_INITPOLICY_H_INCLUDED
-#define RIPPLE_CORE_TEST_INITPOLICY_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_INITPOLICY_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_INITPOLICY_H_INCLUDED
/** A simulated peer to peer network for unit tests. */
namespace TestOverlay
diff --git a/src/ripple_core/test/MessageType.h b/src/ripple/testoverlay/api/MessageType.h
similarity index 91%
rename from src/ripple_core/test/MessageType.h
rename to src/ripple/testoverlay/api/MessageType.h
index 61f2ee971..c63a850cd 100644
--- a/src/ripple_core/test/MessageType.h
+++ b/src/ripple/testoverlay/api/MessageType.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_MESSAGETYPE_H_INCLUDED
-#define RIPPLE_CORE_TEST_MESSAGETYPE_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_MESSAGETYPE_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_MESSAGETYPE_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/NetworkType.h b/src/ripple/testoverlay/api/NetworkType.h
similarity index 96%
rename from src/ripple_core/test/NetworkType.h
rename to src/ripple/testoverlay/api/NetworkType.h
index afd6fc06a..4455d08ba 100644
--- a/src/ripple_core/test/NetworkType.h
+++ b/src/ripple/testoverlay/api/NetworkType.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_NETWORKTYPE_H_INCLUDED
-#define RIPPLE_CORE_TEST_NETWORKTYPE_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_NETWORKTYPE_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_NETWORKTYPE_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/PeerLogicBase.h b/src/ripple/testoverlay/api/PeerLogicBase.h
similarity index 92%
rename from src/ripple_core/test/PeerLogicBase.h
rename to src/ripple/testoverlay/api/PeerLogicBase.h
index f56fbe183..51289fb87 100644
--- a/src/ripple_core/test/PeerLogicBase.h
+++ b/src/ripple/testoverlay/api/PeerLogicBase.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_PEERLOGICBASE_H_INCLUDED
-#define RIPPLE_CORE_TEST_PEERLOGICBASE_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_PEERLOGICBASE_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_PEERLOGICBASE_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/PeerType.h b/src/ripple/testoverlay/api/PeerType.h
similarity index 98%
rename from src/ripple_core/test/PeerType.h
rename to src/ripple/testoverlay/api/PeerType.h
index 2e704ce67..fa74c9406 100644
--- a/src/ripple_core/test/PeerType.h
+++ b/src/ripple/testoverlay/api/PeerType.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_PEERTYPE_H_INCLUDED
-#define RIPPLE_CORE_TEST_PEERTYPE_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_PEERTYPE_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_PEERTYPE_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/Results.h b/src/ripple/testoverlay/api/Results.h
similarity index 94%
rename from src/ripple_core/test/Results.h
rename to src/ripple/testoverlay/api/Results.h
index 64b4d429d..509e96542 100644
--- a/src/ripple_core/test/Results.h
+++ b/src/ripple/testoverlay/api/Results.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_RESULTS_H_INCLUDED
-#define RIPPLE_CORE_TEST_RESULTS_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_RESULTS_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_RESULTS_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/SimplePayload.h b/src/ripple/testoverlay/api/SimplePayload.h
similarity index 91%
rename from src/ripple_core/test/SimplePayload.h
rename to src/ripple/testoverlay/api/SimplePayload.h
index e4148349e..f9be4fd4e 100644
--- a/src/ripple_core/test/SimplePayload.h
+++ b/src/ripple/testoverlay/api/SimplePayload.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_SIMPLEPAYLOAD_H_INCLUDED
-#define RIPPLE_CORE_TEST_SIMPLEPAYLOAD_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_SIMPLEPAYLOAD_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_SIMPLEPAYLOAD_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/StateBase.h b/src/ripple/testoverlay/api/StateBase.h
similarity index 90%
rename from src/ripple_core/test/StateBase.h
rename to src/ripple/testoverlay/api/StateBase.h
index 3fec6d9b2..99e143787 100644
--- a/src/ripple_core/test/StateBase.h
+++ b/src/ripple/testoverlay/api/StateBase.h
@@ -4,8 +4,8 @@
*/
//==============================================================================
-#ifndef RIPPLE_CORE_TEST_STATEBASE_H_INCLUDED
-#define RIPPLE_CORE_TEST_STATEBASE_H_INCLUDED
+#ifndef RIPPLE_TESTOVERLAY_STATEBASE_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_STATEBASE_H_INCLUDED
namespace TestOverlay
{
diff --git a/src/ripple_core/test/TestOverlay.cpp b/src/ripple/testoverlay/impl/TestOverlay.cpp
similarity index 100%
rename from src/ripple_core/test/TestOverlay.cpp
rename to src/ripple/testoverlay/impl/TestOverlay.cpp
diff --git a/src/ripple/testoverlay/ripple_testoverlay.cpp b/src/ripple/testoverlay/ripple_testoverlay.cpp
new file mode 100644
index 000000000..e2e1f03f9
--- /dev/null
+++ b/src/ripple/testoverlay/ripple_testoverlay.cpp
@@ -0,0 +1,16 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#include "BeastConfig.h"
+
+#include "ripple_testoverlay.h"
+
+namespace ripple
+{
+
+#include "impl/TestOverlay.cpp"
+
+}
diff --git a/src/ripple/testoverlay/ripple_testoverlay.h b/src/ripple/testoverlay/ripple_testoverlay.h
new file mode 100644
index 000000000..168403d63
--- /dev/null
+++ b/src/ripple/testoverlay/ripple_testoverlay.h
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_TESTOVERLAY_H_INCLUDED
+#define RIPPLE_TESTOVERLAY_H_INCLUDED
+
+#include "beast/modules/beast_core/system/BeforeBoost.h" // must come first
+#include
+
+#include "beast/modules/beast_core/beast_core.h"
+
+/** Provides a template based peer to peer network simulator.
+
+ A TestOverlay::Network simulates an entire peer to peer network.
+ It provides peer connectivity and message passing services, while
+ allowing domain specific customization through user provided types.
+
+ This system is designed to allow business logic to be exercised
+ in unit tests, using a simulated large scale network.
+*/
+
+namespace ripple
+{
+
+using namespace beast;
+
+# include "api/Results.h"
+# include "api/SimplePayload.h"
+# include "api/MessageType.h"
+# include "api/ConnectionType.h"
+# include "api/PeerType.h"
+# include "api/NetworkType.h"
+# include "api/StateBase.h"
+# include "api/PeerLogicBase.h"
+# include "api/InitPolicy.h"
+# include "api/ConfigType.h"
+
+}
+
+#endif
diff --git a/src/ripple/validators/api/Validators.h b/src/ripple/validators/api/Validators.h
new file mode 100644
index 000000000..bb9bcce1c
--- /dev/null
+++ b/src/ripple/validators/api/Validators.h
@@ -0,0 +1,131 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORS_H_INCLUDED
+#define RIPPLE_CORE_VALIDATOR_VALIDATORS_H_INCLUDED
+
+/** Maintains the list of chosen validators.
+
+ The algorithm for acquiring, building, and calculating metadata on
+ the list of chosen validators is critical to the health of the network.
+
+ All operations are performed asynchronously on an internal thread.
+*/
+class Validators : public Uncopyable
+{
+public:
+ typedef RipplePublicKeyHash KeyType;
+
+ //--------------------------------------------------------------------------
+
+ /** A source of validator descriptors. */
+ class Source
+ {
+ public:
+ /** A Source's descriptor for a Validator. */
+ struct Info
+ {
+ /** The unique key for this validator. */
+ KeyType key;
+ };
+
+ /** Destroy the Source.
+ This can be called from any thread. If the Source is busy
+ fetching, the destructor must block until the operation is either
+ canceled or complete.
+ */
+ virtual ~Source () { }
+
+ struct CancelCallback
+ {
+ virtual bool shouldCancel () = 0;
+ };
+
+ /** Fetch the most recent list from the Source.
+ If possible, the Source should periodically poll the
+ CancelCallback, and abort the operation if shouldCancel
+ returns `true`.
+ This call will block.
+ */
+ struct Result
+ {
+ Result ();
+ void swapWith (Result& other);
+
+ bool success;
+ String message;
+ Time expirationTime;
+ Array list;
+ };
+ virtual Result fetch (CancelCallback& callback) = 0;
+ };
+
+ //--------------------------------------------------------------------------
+
+ /** Create a new Validators object.
+ */
+ static Validators* New ();
+
+ /** Destroy the object.
+
+ Any pending source fetch operations are aborted.
+
+ There may be some listener calls made before the
+ destructor returns.
+ */
+ virtual ~Validators () { }
+
+ /** Add a static source of validators from a string array. */
+ /** @{ */
+ virtual void addStrings (std::vector const& strings) = 0;
+ virtual void addStrings (StringArray const& stringArray) = 0;
+ /** @} */
+
+ /** Add a static source of validators from a text file. */
+ virtual void addFile (File const& file) = 0;
+
+ /** Add a static source of validators.
+ The Source is called to fetch once and the results are kept
+ permanently. The fetch is performed asynchronously, this call
+ returns immediately. If the fetch fails, it is not reattempted.
+ The caller loses ownership of the object.
+ Thread safety:
+ Can be called from any thread.
+ */
+ 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 addURL (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
+
+ //virtual bool isPublicKeyTrusted (Validator::PublicKey const&) = 0;
+
+ //--------------------------------------------------------------------------
+
+ struct ReceivedValidation
+ {
+ uint256 ledgerHash;
+ RipplePublicKeyHash signerPublicKeyHash;
+ };
+
+ /** Called when a validation with a proper signature is received.
+ */
+ virtual void receiveValidation (ReceivedValidation const& rv) = 0;
+};
+
+#endif
diff --git a/src/ripple/validators/impl/ValidatorSourceFile.cpp b/src/ripple/validators/impl/ValidatorSourceFile.cpp
new file mode 100644
index 000000000..f937ca887
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorSourceFile.cpp
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+class ValidatorSourceFileImp : public ValidatorSourceFile
+{
+public:
+ ValidatorSourceFileImp (File const& file)
+ : m_file (file)
+ {
+ }
+
+ ~ValidatorSourceFileImp ()
+ {
+ }
+
+ Result fetch (CancelCallback&)
+ {
+ Result result;
+
+ return result;
+ }
+
+private:
+ File m_file;
+};
+
+//------------------------------------------------------------------------------
+
+ValidatorSourceFile* ValidatorSourceFile::New (File const& file)
+{
+ ScopedPointer object (
+ new ValidatorSourceFileImp (file));
+
+ return object.release ();
+}
diff --git a/src/ripple/validators/impl/ValidatorSourceFile.h b/src/ripple/validators/impl/ValidatorSourceFile.h
new file mode 100644
index 000000000..c978b4fe5
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorSourceFile.h
@@ -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 (File const& path);
+};
+
+#endif
diff --git a/src/ripple/validators/impl/ValidatorSourceStrings.cpp b/src/ripple/validators/impl/ValidatorSourceStrings.cpp
new file mode 100644
index 000000000..2ab8d2cc7
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorSourceStrings.cpp
@@ -0,0 +1,47 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+class ValidatorSourceStringsImp : public ValidatorSourceStrings
+{
+public:
+ ValidatorSourceStringsImp (StringArray const& strings)
+ : m_strings (strings)
+ {
+ }
+
+ ~ValidatorSourceStringsImp ()
+ {
+ }
+
+ Result fetch (CancelCallback&)
+ {
+ Result result;
+
+ result.list.ensureStorageAllocated (m_strings.size ());
+
+ for (int i = 0; i < m_strings.size (); ++i)
+ {
+ ValidatorsUtilities::parseResultLine (result, m_strings [i]);
+ }
+
+ result.success = result.list.size () > 0;
+ result.expirationTime = Time::getCurrentTime () + RelativeTime::hours (24);
+ return result;
+ }
+
+private:
+ StringArray m_strings;
+};
+
+//------------------------------------------------------------------------------
+
+ValidatorSourceStrings* ValidatorSourceStrings::New (StringArray const& strings)
+{
+ ScopedPointer object (
+ new ValidatorSourceStringsImp (strings));
+
+ return object.release ();
+}
diff --git a/src/ripple/validators/impl/ValidatorSourceStrings.h b/src/ripple/validators/impl/ValidatorSourceStrings.h
new file mode 100644
index 000000000..9fc1fa427
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorSourceStrings.h
@@ -0,0 +1,19 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCESTRINGS_H_INCLUDED
+#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCESTRINGS_H_INCLUDED
+
+/** Provides validators from a set of Validator strings.
+ Typically this will come from a local configuration file.
+*/
+class ValidatorSourceStrings : public Validators::Source
+{
+public:
+ static ValidatorSourceStrings* New (StringArray const& strings);
+};
+
+#endif
diff --git a/src/ripple/validators/impl/ValidatorSourceURL.cpp b/src/ripple/validators/impl/ValidatorSourceURL.cpp
new file mode 100644
index 000000000..8b18c5d3f
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorSourceURL.cpp
@@ -0,0 +1,48 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+class ValidatorSourceURLImp : public ValidatorSourceURL
+{
+public:
+ explicit ValidatorSourceURLImp (UniformResourceLocator const& url)
+ : m_url (url)
+ {
+ }
+
+ ~ValidatorSourceURLImp ()
+ {
+ }
+
+ Result fetch (CancelCallback&)
+ {
+ Result result;
+
+ ScopedPointer client (HTTPClientBase::New ());
+
+ HTTPClientBase::Result httpResult (client->get (m_url));
+
+ if (httpResult.error == 0)
+ {
+ Logger::outputDebugString (httpResult.response->toString ());
+ }
+
+ return result;
+ }
+
+private:
+ UniformResourceLocator m_url;
+};
+
+//------------------------------------------------------------------------------
+
+ValidatorSourceURL* ValidatorSourceURL::New (
+ UniformResourceLocator const& url)
+{
+ ScopedPointer object (
+ new ValidatorSourceURLImp (url));
+
+ return object.release ();
+}
diff --git a/src/ripple/validators/impl/ValidatorSourceURL.h b/src/ripple/validators/impl/ValidatorSourceURL.h
new file mode 100644
index 000000000..df3c55fa6
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorSourceURL.h
@@ -0,0 +1,18 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURL_H_INCLUDED
+#define RIPPLE_CORE_VALIDATOR_VALIDATORSOURCETRUSTEDURL_H_INCLUDED
+
+/** Provides validators from a trusted URI (e.g. HTTPS)
+*/
+class ValidatorSourceURL : public Validators::Source
+{
+public:
+ static ValidatorSourceURL* New (UniformResourceLocator const& url);
+};
+
+#endif
diff --git a/src/ripple/validators/impl/Validators.cpp b/src/ripple/validators/impl/Validators.cpp
new file mode 100644
index 000000000..ce6a9c9af
--- /dev/null
+++ b/src/ripple/validators/impl/Validators.cpp
@@ -0,0 +1,733 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+/*
+
+Information to track:
+
+- Percentage of validations that the validator has signed
+- Number of validations the validator signed that never got accepted
+
+
+- Target number for Chosen
+- Pseudo-randomly choose a subset from Chosen
+
+
+
+
+
+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.
+
+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?
+
+--------------------------------------------------------------------------------
+ChosenValidators
+--------------------------------------------------------------------------------
+
+David:
+ 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
+ client can ship with that master trust URL and also the list of URI's at the
+ time it's released, in case for some reason it can't pull from OC. That would
+ make the default installation safe even against major changes in the
+ organizations that publish validator lists.
+
+ The difference is that if an organization that provides lists of validators
+ goes rogue, administrators don't have to act.
+
+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.
+ * Ship with TrustedUriList
+ * Also have a preset RankedValidators
+ Eliminate administrative burden of maintaining
+ Produce the ChosenValidators list.
+ Allow quantitative analysis of network health.
+
+What determines that a validator is good?
+ - Are they present (i.e. sending validations)
+ - Are they on the consensus ledger
+ - What percentage of consensus rounds do they participate in
+ - Are they stalling consensus
+ * Measurements of constructive/destructive behavior is
+ calculated in units of percentage of ledgers for which
+ the behavior is measured.
+*/
+
+//------------------------------------------------------------------------------
+
+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);
+}
+
+//------------------------------------------------------------------------------
+
+class ValidatorsImp
+ : public Validators
+ , private ThreadWithCallQueue::EntryPoints
+ , private DeadlineTimer::Listener
+ , LeakChecked
+{
+public:
+ // Tunable constants
+ enum
+ {
+ // We will fetch a source at this interval
+ hoursBetweenFetches = 24
+
+ ,secondsBetweenFetches = hoursBetweenFetches * 60 * 60
+
+ // Wake up every hour to check source times
+ ,secondsPerUpdate = 60 * 60
+
+ // This tunes the preallocated arrays
+ ,expectedNumberOfResults = 1000
+ };
+
+ //--------------------------------------------------------------------------
+
+ // Dummy CancelCallback that does nothing
+ //
+ struct NoOpCancelCallback : Source::CancelCallback
+ {
+ bool shouldCancel ()
+ {
+ return false;
+ }
+
+ };
+
+ //--------------------------------------------------------------------------
+
+ /** Receive event notifications on Validators operations.
+ */
+ class Listener
+ {
+ public:
+ };
+
+ //--------------------------------------------------------------------------
+
+ class ChosenList : public SharedObject
+ {
+ public:
+ typedef SharedPtr Ptr;
+
+ struct Info
+ {
+ Info ()
+ {
+ }
+ };
+
+ //typedef HashMap MapType;
+ typedef boost::unordered_map MapType;
+
+ ChosenList (std::size_t expectedSize = 0)
+ {
+ // Available only in recent boost versions?
+ //m_map.reserve (expectedSize);
+ }
+
+ std::size_t size () const noexcept
+ {
+ return m_map.size ();
+ }
+
+ void insert (KeyType const& key, Info const& info) noexcept
+ {
+ m_map [key] = info;
+ }
+
+ bool contains (KeyType const& key) const noexcept
+ {
+ return m_map.find (key) != m_map.cend ();
+ }
+
+ private:
+ MapType m_map;
+ };
+
+ //--------------------------------------------------------------------------
+
+ // Encapsulates the logic for creating the chosen validators.
+ // This is a separate class to facilitate the unit tests.
+ //
+ class Logic
+ {
+ public:
+ // Information associated with each Source
+ //
+ struct SourceDesc
+ {
+ enum
+ {
+ keysPreallocationSize = 1000
+ };
+
+ enum Status
+ {
+ statusNone,
+ statusFetched,
+ statusFailed
+ };
+
+ ScopedPointer source;
+ Status status;
+ Time whenToFetch;
+ int numberOfFailures;
+
+ // The result of the last fetch
+ Source::Result result;
+
+ //------------------------------------------------------------------
+
+ SourceDesc () noexcept
+ : status (statusNone)
+ , whenToFetch (Time::getCurrentTime ())
+ , numberOfFailures (0)
+ {
+ }
+
+ ~SourceDesc ()
+ {
+ }
+ };
+
+ typedef DynamicList SourcesType;
+
+ //----------------------------------------------------------------------
+
+ // Information associated with each distinguishable validator
+ //
+ struct ValidatorInfo
+ {
+ ValidatorInfo ()
+ : refCount (0)
+ {
+ }
+
+ int refCount;
+ };
+
+ //typedef HashMap MapType;
+ typedef boost::unordered_map MapType;
+
+ //----------------------------------------------------------------------
+
+ Logic ()
+ : m_chosenListNeedsUpdate (false)
+ {
+ }
+
+ // Add a one-time static source.
+ // Fetch is called right away, this call blocks.
+ //
+ void addStaticSource (Source* source)
+ {
+ ScopedPointer object (source);
+
+ NoOpCancelCallback cancelCallback;
+
+ 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.
+ //
+ void receiveValidation (Validators::ReceivedValidation const& rv)
+ {
+ MapType::iterator iter (m_map.find (rv.signerPublicKeyHash));
+ if (iter != m_map.end ())
+ {
+ // Exists
+ //ValidatorInfo& validatorInfo (iter->value ());
+ }
+ else
+ {
+ // New
+ //ValidatorInfo& validatorInfo (m_map.insert (rv.signerPublicKeyHash));
+ }
+ }
+
+ // Add each entry in the list to the map, incrementing the
+ // reference count if it already exists, and updating fields.
+ //
+ void addSourceInfo (Array const& list)
+ {
+ for (std::size_t i = 0; i < list.size (); ++i)
+ {
+ Source::Info const& info (list.getReference (i));
+ std::pair result (
+ m_map.emplace (info.key, ValidatorInfo ()));
+ ValidatorInfo& validatorInfo (result.first->second);
+ ++validatorInfo.refCount;
+ if (result.second)
+ {
+ // This is a new one
+ markDirtyChosenList ();
+ }
+ }
+ }
+
+ // Decrement the reference count of each item in the list
+ // in the map
+ //
+ void removeSourceInfo (Array const& list)
+ {
+ for (std::size_t i = 0; i < list.size (); ++i)
+ {
+ Source::Info const& info (list.getReference (i));
+ MapType::iterator iter (m_map.find (info.key));
+ bassert (iter != m_map.end ());
+ ValidatorInfo& validatorInfo (iter->second);
+ if (--validatorInfo.refCount == 0)
+ {
+ // Last reference removed
+ m_map.erase (iter);
+ markDirtyChosenList ();
+ }
+ }
+ }
+
+ // Fetch one source
+ //
+ void fetchSource (SourceDesc& desc, Source::CancelCallback& callback)
+ {
+ Source::Result result (desc.source->fetch (callback));
+
+ if (! callback.shouldCancel ())
+ {
+ // Reset fetch timer for the source.
+ desc.whenToFetch = Time::getCurrentTime () +
+ RelativeTime (secondsBetweenFetches);
+
+ if (result.success)
+ {
+ // Add the new source info to the map
+ addSourceInfo (result.list);
+
+ // Swap lists
+ desc.result.swapWith (result);
+
+ // Remove the old source info from the map
+ removeSourceInfo (result.list);
+
+ // See if we need to rebuild
+ checkDirtyChosenList ();
+
+ // Reset failure status
+ desc.numberOfFailures = 0;
+ desc.status = SourceDesc::statusFetched;
+ }
+ else
+ {
+ ++desc.numberOfFailures;
+ desc.status = SourceDesc::statusFailed;
+ }
+ }
+ }
+
+ // Check each source to see if it needs fetching.
+ //
+ void checkSources (Source::CancelCallback& callback)
+ {
+ Time const currentTime (Time::getCurrentTime ());
+ for (SourcesType::iterator iter = m_sources.begin ();
+ ! callback.shouldCancel () && iter != m_sources.end (); ++iter)
+ {
+ SourceDesc& desc (*iter);
+ if (desc.whenToFetch <= currentTime)
+ fetchSource (desc, callback);
+ }
+ }
+
+ // Signal that the Chosen List needs to be rebuilt.
+ //
+ void markDirtyChosenList ()
+ {
+ m_chosenListNeedsUpdate = true;
+ }
+
+ // Check the dirty state of the Chosen List, and rebuild it
+ // if necessary.
+ //
+ void checkDirtyChosenList ()
+ {
+ if (m_chosenListNeedsUpdate)
+ {
+ buildChosenList ();
+ m_chosenListNeedsUpdate = false;
+ }
+ }
+
+ // Rebuilds the Chosen List
+ //
+ void buildChosenList ()
+ {
+ ChosenList::Ptr list (new ChosenList (m_map.size ()));
+
+ for (MapType::iterator iter = m_map.begin ();
+ iter != m_map.end (); ++iter)
+ {
+ ChosenList::Info info;
+ list->insert (iter->first, info);
+ }
+
+ // This is thread safe
+ m_chosenList = list;
+ }
+
+ // Get a reference to the chosen list.
+ // This is safe to call from any thread at any time.
+ //
+ ChosenList::Ptr getChosenList ()
+ {
+ return m_chosenList;
+ }
+
+ //----------------------------------------------------------------------
+ //
+ // Ripple interface
+ //
+ // These routines are modeled after UniqueNodeList
+
+ bool isTrustedPublicKeyHash (RipplePublicKeyHash const& key)
+ {
+ return m_chosenList->contains (key);
+ }
+
+ //
+ //
+ //----------------------------------------------------------------------
+
+ private:
+ SourcesType m_sources;
+ MapType m_map;
+ bool m_chosenListNeedsUpdate;
+ ChosenList::Ptr m_chosenList;
+ };
+
+ //--------------------------------------------------------------------------
+
+public:
+ explicit ValidatorsImp (Listener* listener)
+ : m_listener (listener)
+ , m_thread ("Validators")
+ , m_timer (this)
+ {
+ m_thread.start (this);
+ }
+
+ ~ValidatorsImp ()
+ {
+ }
+
+ void addStrings (std::vector 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 (File const& file)
+ {
+ addStaticSource (ValidatorSourceFile::New (file));
+ }
+
+ void addURL (UniformResourceLocator const& url)
+ {
+ addSource (ValidatorSourceURL::New (url));
+ }
+
+ void addSource (Source* source)
+ {
+ m_thread.call (&Logic::addSource, &m_logic, source);
+ }
+
+ void addStaticSource (Source* source)
+ {
+ m_thread.call (&Logic::addStaticSource, &m_logic, source);
+ }
+
+ void receiveValidation (ReceivedValidation const& rv)
+ {
+ m_thread.call (&Logic::receiveValidation, &m_logic, rv);
+ }
+
+ //--------------------------------------------------------------------------
+
+ void onDeadlineTimer (DeadlineTimer&)
+ {
+ // This will make us fall into the idle proc as needed
+ //
+ m_thread.interrupt ();
+ }
+
+ void threadInit ()
+ {
+ m_timer.setRecurringExpiration (secondsPerUpdate);
+ }
+
+ void threadExit ()
+ {
+ }
+
+ bool threadIdle ()
+ {
+ bool interrupted = false;
+
+ struct ThreadCancelCallback : Source::CancelCallback, Uncopyable
+ {
+ explicit ThreadCancelCallback (ThreadWithCallQueue& thread)
+ : m_thread (thread)
+ , m_interrupted (false)
+ {
+ }
+
+ bool shouldCancel ()
+ {
+ if (m_interrupted)
+ return true;
+ return m_interrupted = m_thread.interruptionPoint ();
+ }
+
+ private:
+ ThreadWithCallQueue& m_thread;
+ bool m_interrupted;
+ };
+
+ ThreadCancelCallback cancelCallback (m_thread);
+
+ m_logic.checkSources (cancelCallback);
+
+ return interrupted;
+ }
+
+private:
+ Logic m_logic;
+ Listener* const m_listener;
+ ThreadWithCallQueue m_thread;
+ DeadlineTimer m_timer;
+};
+
+//------------------------------------------------------------------------------
+
+Validators* Validators::New ()
+{
+ return new ValidatorsImp (nullptr);
+}
+
+//------------------------------------------------------------------------------
+
+class ValidatorsTests : public UnitTest
+{
+public:
+ enum
+ {
+ numberOfTestValidators = 1000
+ };
+
+ //--------------------------------------------------------------------------
+
+ struct Payload
+ {
+ Payload ()
+ {
+ }
+ };
+
+ template
+ class PeerLogic : public TestOverlay::PeerLogicBase
+ {
+ public:
+ typedef TestOverlay::PeerLogicBase 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 (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
+ {
+ TestSource (String const& name, uint32 start, uint32 end)
+ : m_name (name)
+ , m_start (start)
+ , m_end (end)
+ {
+ }
+
+ Result fetch (CancelCallback& cancel)
+ {
+ Result result;
+
+ result.success = true;
+ result.message = String::empty;
+ result.list.ensureStorageAllocated (numberOfTestValidators);
+
+ for (uint32 i = m_start ; i < m_end; ++i)
+ {
+ Info info;
+ info.key = Validators::KeyType::createFromInteger (i);
+ result.list.add (info);
+ }
+
+ return result;
+ }
+
+ String m_name;
+ std::size_t m_start;
+ std::size_t m_end;
+ };
+
+ //--------------------------------------------------------------------------
+
+ void addSources (ValidatorsImp::Logic& logic)
+ {
+#if 0
+ logic.addSource (new TestSource ("source 1", 0, 1000));
+ logic.addSource (new TestSource ("source 2", 200, 1500));
+ logic.addSource (new TestSource ("source 3", 500, 2000));
+ logic.addSource (new TestSource ("source 4", 750, 2200));
+ logic.addSource (new TestSource ("source 5", 1500, 3200));
+#else
+ logic.addSource (new TestSource ("source 1", 0, 1));
+#endif
+ }
+
+ void testLogic ()
+ {
+ beginTestCase ("logic");
+
+ ValidatorsImp::Logic logic;
+ addSources (logic);
+
+ ValidatorsImp::NoOpCancelCallback cancelCallback;
+ logic.checkSources (cancelCallback);
+
+ ValidatorsImp::ChosenList::Ptr list (logic.getChosenList ());
+
+ pass ();
+ }
+
+ void runTest ()
+ {
+ testLogic ();
+ }
+
+ ValidatorsTests () : UnitTest ("Validators", "ripple", runManual)
+ {
+ }
+};
+
+static ValidatorsTests validatorsTests;
+
diff --git a/src/ripple/validators/impl/ValidatorsUtilities.cpp b/src/ripple/validators/impl/ValidatorsUtilities.cpp
new file mode 100644
index 000000000..38a02a17c
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorsUtilities.cpp
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+bool ValidatorsUtilities::parseInfoLine (Validators::Source::Info& info, String line)
+{
+ bool success (false);
+
+ return success;
+}
+
+void ValidatorsUtilities::parseResultLine (
+ Validators::Source::Result& result,
+ String line)
+{
+ bool success = false;
+
+ if (! success)
+ {
+ Validators::Source::Info info;
+
+ success = parseInfoLine (info, line);
+ if (success)
+ result.list.add (info);
+ }
+
+
+}
diff --git a/src/ripple/validators/impl/ValidatorsUtilities.h b/src/ripple/validators/impl/ValidatorsUtilities.h
new file mode 100644
index 000000000..e4af59206
--- /dev/null
+++ b/src/ripple/validators/impl/ValidatorsUtilities.h
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_CORE_VALIDATORSUTILITIES_H_INCLUDED
+#define RIPPLE_CORE_VALIDATORSUTILITIES_H_INCLUDED
+
+/** Common code for Validators classes.
+*/
+class ValidatorsUtilities
+{
+public:
+ typedef std::vector Strings;
+
+#if 0
+ /** Parse a ConstBufferSequence of newline delimited text into strings.
+ This works incrementally.
+ */
+ template
+ static void parseLines (Strings& lines, ConstBufferSequence const& buffers)
+ {
+ for (typename ConstBufferSequence::const_iterator iter = buffers.begin ();
+ iter != buffers.end (); ++iter)
+ parserLines (lines, *iter);
+ }
+
+ /** Turn a linear buffer of newline delimited text into strings.
+ This can be called incrementally, i.e. successive calls with
+ multiple buffer segments.
+ */
+ static void parseLines (Strings& lines, char const* buf, std::size_t bytes);
+#endif
+
+ /** Parse a string into the Source::Result.
+ Invalid or comment lines will be skipped.
+ Lines containing validator info will be added to the Result object.
+ Metadata lines will update the corresponding Result fields.
+ */
+ static void parseResultLine (
+ Validators::Source::Result& result,
+ String line);
+
+private:
+ /** Parse a string into a Source::Info.
+ @return `true` on success.
+ */
+ static bool parseInfoLine (Validators::Source::Info& info, String line);
+};
+
+#endif
diff --git a/src/ripple/validators/ripple_validators.cpp b/src/ripple/validators/ripple_validators.cpp
new file mode 100644
index 000000000..cf6180339
--- /dev/null
+++ b/src/ripple/validators/ripple_validators.cpp
@@ -0,0 +1,32 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#include "BeastConfig.h"
+
+#include "ripple_validators.h"
+
+#include "beast/modules/beast_core/system/BeforeBoost.h" // must come first
+//#include
+//#include
+//#include
+#include
+
+#include "../testoverlay/ripple_testoverlay.h" // for unit test
+
+namespace ripple
+{
+
+# include "impl/ValidatorsUtilities.h"
+#include "impl/ValidatorsUtilities.cpp"
+# include "impl/ValidatorSourceFile.h"
+# include "impl/ValidatorSourceStrings.h"
+# include "impl/ValidatorSourceURL.h"
+#include "impl/ValidatorSourceFile.cpp"
+#include "impl/ValidatorSourceStrings.cpp"
+#include "impl/ValidatorSourceURL.cpp"
+#include "impl/Validators.cpp"
+
+}
diff --git a/src/ripple/validators/ripple_validators.h b/src/ripple/validators/ripple_validators.h
new file mode 100644
index 000000000..282e06401
--- /dev/null
+++ b/src/ripple/validators/ripple_validators.h
@@ -0,0 +1,32 @@
+//------------------------------------------------------------------------------
+/*
+ Copyright (c) 2011-2013, OpenCoin, Inc.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_VALIDATORS_H_INCLUDED
+#define RIPPLE_VALIDATORS_H_INCLUDED
+
+// VFALCO TODO Remove buffers/beast_asio dependency
+//
+// 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 required for
+// UniformResourceLocator.
+//
+#include "beast/modules/beast_asio/beast_asio.h"
+
+#include "../ripple_basics/ripple_basics.h"
+#include "../ripple_data/ripple_data.h"
+
+namespace ripple
+{
+
+using namespace beast;
+
+#include "api/Validators.h"
+
+}
+
+#endif
diff --git a/src/ripple_app/ripple_app.cpp b/src/ripple_app/ripple_app.cpp
index 4516a105a..1a6c1c103 100644
--- a/src/ripple_app/ripple_app.cpp
+++ b/src/ripple_app/ripple_app.cpp
@@ -20,6 +20,8 @@
// This .cpp will end up including all of the public header
// material in Ripple since it holds the Application object.
+#include "../ripple/validators/ripple_validators.h"
+
namespace ripple
{
diff --git a/src/ripple_app/ripple_app_pt5.cpp b/src/ripple_app/ripple_app_pt5.cpp
index f8d15c0e4..030765a8f 100644
--- a/src/ripple_app/ripple_app_pt5.cpp
+++ b/src/ripple_app/ripple_app_pt5.cpp
@@ -9,6 +9,8 @@
#include "ripple_app.h"
#include "../ripple_net/ripple_net.h"
+#include "../ripple/validators/ripple_validators.h"
+
namespace ripple
{
diff --git a/src/ripple_core/ripple_core.cpp b/src/ripple_core/ripple_core.cpp
index b1cfefb1e..6fac50548 100644
--- a/src/ripple_core/ripple_core.cpp
+++ b/src/ripple_core/ripple_core.cpp
@@ -51,29 +51,6 @@ namespace ripple
#include "node/NodeStore.cpp"
#include "node/NodeObject.cpp"
-# include "test/Results.h"
-# include "test/SimplePayload.h"
-# include "test/MessageType.h"
-# include "test/ConnectionType.h"
-# include "test/PeerType.h"
-# include "test/NetworkType.h"
-# include "test/StateBase.h"
-# include "test/PeerLogicBase.h"
-# include "test/InitPolicy.h"
-# include "test/ConfigType.h"
-#include "test/TestOverlay.cpp"
-
-# include "validator/ValidatorsUtilities.h"
-#include "validator/ValidatorsUtilities.cpp"
-# include "validator/ValidatorSourceFile.h"
-# include "validator/ValidatorSourceStrings.h"
-# include "validator/ValidatorSourceURL.h"
-# include "validator/ValidatorsImp.h"
-#include "validator/ValidatorSourceFile.cpp"
-#include "validator/ValidatorSourceStrings.cpp"
-#include "validator/ValidatorSourceURL.cpp"
-#include "validator/Validators.cpp"
-
#include "peerfinder/ripple_PeerFinder.cpp"
}
diff --git a/src/ripple_core/ripple_core.h b/src/ripple_core/ripple_core.h
index 897ae538b..305bb7a50 100644
--- a/src/ripple_core/ripple_core.h
+++ b/src/ripple_core/ripple_core.h
@@ -39,7 +39,6 @@ namespace ripple
#include "node/NodeStore.h"
#include "peerfinder/ripple_PeerFinder.h"
-#include "validator/Validators.h"
}