diff --git a/Builds/VisualStudio2015/RippleD.vcxproj b/Builds/VisualStudio2015/RippleD.vcxproj
index e5fbd1eceb..40b4967b0b 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj
+++ b/Builds/VisualStudio2015/RippleD.vcxproj
@@ -3760,6 +3760,16 @@
+
+ True
+ True
+
+
+ True
+ True
+
+
+
True
True
diff --git a/Builds/VisualStudio2015/RippleD.vcxproj.filters b/Builds/VisualStudio2015/RippleD.vcxproj.filters
index dbe9081d3d..a7d3c809de 100644
--- a/Builds/VisualStudio2015/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2015/RippleD.vcxproj.filters
@@ -421,6 +421,12 @@
{27D70888-7145-691C-0E0A-E511EB3A80A2}
+
+ {94B5035A-6D4A-E4FC-DB50-E7E804DC9F13}
+
+
+ {23DE6C05-81D2-7471-D9BB-3AA1D49DE429}
+
{5DB3CD0B-B361-B301-9562-697CA8A52B68}
@@ -4437,6 +4443,15 @@
ripple\test\jtx
+
+ ripple\test\mao\impl
+
+
+ ripple\test\mao\impl
+
+
+ ripple\test\mao
+
ripple\unity
diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp
index 899a2bd30d..24bf557b7a 100644
--- a/src/ripple/app/main/Application.cpp
+++ b/src/ripple/app/main/Application.cpp
@@ -79,33 +79,6 @@ namespace ripple {
// 204/256 about 80%
static int const MAJORITY_FRACTION (204);
-// This hack lets the s_instance variable remain set during
-// the call to ~Application
-class ApplicationImpBase : public Application
-{
-public:
- ApplicationImpBase ()
- {
- assert (s_instance == nullptr);
- s_instance = this;
- }
-
- ~ApplicationImpBase ()
- {
- s_instance = nullptr;
- }
-
- static Application* s_instance;
-
- static Application& getInstance ()
- {
- bassert (s_instance != nullptr);
- return *s_instance;
- }
-};
-
-Application* ApplicationImpBase::s_instance;
-
//------------------------------------------------------------------------------
namespace detail {
@@ -239,7 +212,7 @@ public:
// VFALCO TODO Move the function definitions into the class declaration
class ApplicationImp
- : public ApplicationImpBase
+ : public Application
, public beast::RootStoppable
, public beast::DeadlineTimer::Listener
, public BasicApp
@@ -523,6 +496,25 @@ public:
//--------------------------------------------------------------------------
+ void setup() override;
+ void run() override;
+ bool isShutdown() override;
+ void signalStop() override;
+
+ //--------------------------------------------------------------------------
+
+ Logs&
+ logs() override
+ {
+ return *logs_;
+ }
+
+ Config const&
+ config() const override
+ {
+ return *config_;
+ }
+
CollectorManager& getCollectorManager () override
{
return *m_collectorManager;
@@ -555,18 +547,6 @@ public:
return *m_networkOPs;
}
- Config const&
- config() const override
- {
- return *config_;
- }
-
- Logs&
- logs() override
- {
- return *logs_;
- }
-
boost::asio::io_service& getIOService () override
{
return get_io_service();
@@ -702,12 +682,6 @@ public:
return *m_overlay;
}
- // VFALCO TODO Move these to the .cpp
- bool running () override
- {
- return mTxnDB != nullptr;
- }
-
DatabaseCon& getTxnDB () override
{
assert (mTxnDB.get() != nullptr);
@@ -724,12 +698,6 @@ public:
return *mWalletDB;
}
- bool isShutdown () override
- {
- // from Stoppable mixin
- return isStopped();
- }
-
bool serverOkay (std::string& reason) override;
beast::Journal journal (std::string const& name) override;
@@ -774,185 +742,6 @@ public:
}
}
- // VFALCO TODO Break this function up into many small initialization segments.
- // Or better yet refactor these initializations into RAII classes
- // which are members of the Application object.
- //
- void setup () override
- {
- // VFALCO NOTE: 0 means use heuristics to determine the thread count.
- m_jobQueue->setThreadCount (0, config_->RUN_STANDALONE);
-
- // We want to intercept and wait for CTRL-C to terminate the process
- m_signals.add (SIGINT);
-
- m_signals.async_wait(std::bind(&ApplicationImp::signalled, this,
- std::placeholders::_1, std::placeholders::_2));
-
- assert (mTxnDB == nullptr);
-
- auto debug_log = config_->getDebugLogFile ();
-
- if (!debug_log.empty ())
- {
- // Let debug messages go to the file but only WARNING or higher to
- // regular output (unless verbose)
-
- if (!logs_->open(debug_log))
- std::cerr << "Can't open log file " << debug_log << '\n';
-
- if (logs_->severity() > beast::Journal::kDebug)
- logs_->severity (beast::Journal::kDebug);
- }
-
- if (!config_->RUN_STANDALONE)
- timeKeeper_->run(config_->SNTP_SERVERS);
-
- if (!initSqliteDbs ())
- {
- m_journal.fatal << "Can not create database connections!";
- exitWithCode(3);
- }
-
- getLedgerDB ().getSession ()
- << boost::str (boost::format ("PRAGMA cache_size=-%d;") %
- (config_->getSize (siLgrDBCache) * 1024));
-
- getTxnDB ().getSession ()
- << boost::str (boost::format ("PRAGMA cache_size=-%d;") %
- (config_->getSize (siTxnDBCache) * 1024));
-
- mTxnDB->setupCheckpointing (m_jobQueue.get(), logs());
- mLedgerDB->setupCheckpointing (m_jobQueue.get(), logs());
-
- if (!config_->RUN_STANDALONE)
- updateTables ();
-
- m_amendmentTable->addInitial (
- config_->section (SECTION_AMENDMENTS));
- initializePathfinding ();
-
- m_ledgerMaster->setMinValidations (
- config_->VALIDATION_QUORUM, config_->LOCK_QUORUM);
-
- auto const startUp = config_->START_UP;
- if (startUp == Config::FRESH)
- {
- m_journal.info << "Starting new Ledger";
-
- startGenesisLedger ();
- }
- else if (startUp == Config::LOAD ||
- startUp == Config::LOAD_FILE ||
- startUp == Config::REPLAY)
- {
- m_journal.info << "Loading specified Ledger";
-
- if (!loadOldLedger (config_->START_LEDGER,
- startUp == Config::REPLAY,
- startUp == Config::LOAD_FILE))
- {
- exitWithCode(-1);
- }
- }
- else if (startUp == Config::NETWORK)
- {
- // This should probably become the default once we have a stable network.
- if (!config_->RUN_STANDALONE)
- m_networkOPs->needNetworkLedger ();
-
- startGenesisLedger ();
- }
- else
- {
- startGenesisLedger ();
- }
-
- m_orderBookDB.setup (getLedgerMaster ().getCurrentLedger ());
-
- // Begin validation and ip maintenance.
- //
- // - LocalCredentials maintains local information: including identity
- // - and network connection persistence information.
- //
- // VFALCO NOTE this starts the UNL
- m_localCredentials.start ();
-
- //
- // Set up UNL.
- //
- if (!config_->RUN_STANDALONE)
- getUNL ().nodeBootstrap ();
-
- mValidations->tune (config_->getSize (siValidationsSize), config_->getSize (siValidationsAge));
- m_nodeStore->tune (config_->getSize (siNodeCacheSize), config_->getSize (siNodeCacheAge));
- m_ledgerMaster->tune (config_->getSize (siLedgerSize), config_->getSize (siLedgerAge));
- family().treecache().setTargetSize (config_->getSize (siTreeCacheSize));
- family().treecache().setTargetAge (config_->getSize (siTreeCacheAge));
-
- //----------------------------------------------------------------------
- //
- // Server
- //
- //----------------------------------------------------------------------
-
- // VFALCO NOTE Unfortunately, in stand-alone mode some code still
- // foolishly calls overlay(). When this is fixed we can
- // move the instantiation inside a conditional:
- //
- // if (!config_.RUN_STANDALONE)
- m_overlay = make_Overlay (*this, setup_Overlay(*config_), *m_jobQueue,
- *serverHandler_, *m_resourceManager, *m_resolver, get_io_service(),
- *config_);
- add (*m_overlay); // add to PropertyStream
-
- m_overlay->setupValidatorKeyManifests (*config_, getWalletDB ());
-
- {
- auto setup = setup_ServerHandler(*config_, std::cerr);
- setup.makeContexts();
- serverHandler_->setup (setup, m_journal);
- }
-
- // Create websocket servers.
- for (auto const& port : serverHandler_->setup().ports)
- {
- if (! port.websockets())
- continue;
- auto server = websocket::makeServer (
- {*this, port, *m_resourceManager, getOPs(), m_journal, *config_,
- *m_collectorManager});
- if (!server)
- {
- m_journal.fatal << "Could not create Websocket for [" <<
- port.name << "]";
- throw std::exception();
- }
- websocketServers_.emplace_back (std::move (server));
- }
-
- //----------------------------------------------------------------------
-
- // Begin connecting to network.
- if (!config_->RUN_STANDALONE)
- {
- // Should this message be here, conceptually? In theory this sort
- // of message, if displayed, should be displayed from PeerFinder.
- if (config_->PEER_PRIVATE && config_->IPS.empty ())
- m_journal.warning << "No outbound peer connections will be made";
-
- // VFALCO NOTE the state timer resets the deadlock detector.
- //
- m_networkOPs->setStateTimer ();
- }
- else
- {
- m_journal.warning << "Running in standalone mode";
-
- m_networkOPs->setStandAlone ();
- }
- }
-
//--------------------------------------------------------------------------
//
// Stoppable
@@ -1018,37 +807,6 @@ public:
//------------------------------------------------------------------------------
- void run () override
- {
- // VFALCO NOTE I put this here in the hopes that when unit tests run (which
- // tragically require an Application object to exist or else they
- // crash), the run() function will not get called and we will
- // avoid doing silly things like contacting the SNTP server, or
- // running the various logic threads like Validators, PeerFinder, etc.
- prepare ();
- start ();
-
-
- {
- if (!config_->RUN_STANDALONE)
- {
- // VFALCO NOTE This seems unnecessary. If we properly refactor the load
- // manager then the deadlock detector can just always be "armed"
- //
- getLoadManager ().activateDeadlockDetector ();
- }
- }
-
- m_stop.wait ();
-
- // Stop the server. When this returns, all
- // Stoppable objects should be stopped.
- m_journal.info << "Received shutdown request";
- stop (m_journal);
- m_journal.info << "Done.";
- StopSustain();
- }
-
void exitWithCode(int code)
{
StopSustain();
@@ -1057,13 +815,6 @@ public:
std::exit(code);
}
- void signalStop () override
- {
- // Unblock the main thread (which is sitting in run()).
- //
- m_stop.signal();
- }
-
void onDeadlineTimer (beast::DeadlineTimer& timer) override
{
if (timer == m_entropyTimer)
@@ -1124,7 +875,236 @@ private:
//------------------------------------------------------------------------------
-void ApplicationImp::startGenesisLedger ()
+// VFALCO TODO Break this function up into many small initialization segments.
+// Or better yet refactor these initializations into RAII classes
+// which are members of the Application object.
+//
+void ApplicationImp::setup()
+{
+ // VFALCO NOTE: 0 means use heuristics to determine the thread count.
+ m_jobQueue->setThreadCount (0, config_->RUN_STANDALONE);
+
+ // We want to intercept and wait for CTRL-C to terminate the process
+ m_signals.add (SIGINT);
+
+ m_signals.async_wait(std::bind(&ApplicationImp::signalled, this,
+ std::placeholders::_1, std::placeholders::_2));
+
+ assert (mTxnDB == nullptr);
+
+ auto debug_log = config_->getDebugLogFile ();
+
+ if (!debug_log.empty ())
+ {
+ // Let debug messages go to the file but only WARNING or higher to
+ // regular output (unless verbose)
+
+ if (!logs_->open(debug_log))
+ std::cerr << "Can't open log file " << debug_log << '\n';
+
+ if (logs_->severity() > beast::Journal::kDebug)
+ logs_->severity (beast::Journal::kDebug);
+ }
+
+ if (!config_->RUN_STANDALONE)
+ timeKeeper_->run(config_->SNTP_SERVERS);
+
+ if (!initSqliteDbs ())
+ {
+ m_journal.fatal << "Can not create database connections!";
+ exitWithCode(3);
+ }
+
+ getLedgerDB ().getSession ()
+ << boost::str (boost::format ("PRAGMA cache_size=-%d;") %
+ (config_->getSize (siLgrDBCache) * 1024));
+
+ getTxnDB ().getSession ()
+ << boost::str (boost::format ("PRAGMA cache_size=-%d;") %
+ (config_->getSize (siTxnDBCache) * 1024));
+
+ mTxnDB->setupCheckpointing (m_jobQueue.get(), logs());
+ mLedgerDB->setupCheckpointing (m_jobQueue.get(), logs());
+
+ if (!config_->RUN_STANDALONE)
+ updateTables ();
+
+ m_amendmentTable->addInitial (
+ config_->section (SECTION_AMENDMENTS));
+ initializePathfinding ();
+
+ m_ledgerMaster->setMinValidations (
+ config_->VALIDATION_QUORUM, config_->LOCK_QUORUM);
+
+ auto const startUp = config_->START_UP;
+ if (startUp == Config::FRESH)
+ {
+ m_journal.info << "Starting new Ledger";
+
+ startGenesisLedger ();
+ }
+ else if (startUp == Config::LOAD ||
+ startUp == Config::LOAD_FILE ||
+ startUp == Config::REPLAY)
+ {
+ m_journal.info << "Loading specified Ledger";
+
+ if (!loadOldLedger (config_->START_LEDGER,
+ startUp == Config::REPLAY,
+ startUp == Config::LOAD_FILE))
+ {
+ exitWithCode(-1);
+ }
+ }
+ else if (startUp == Config::NETWORK)
+ {
+ // This should probably become the default once we have a stable network.
+ if (!config_->RUN_STANDALONE)
+ m_networkOPs->needNetworkLedger ();
+
+ startGenesisLedger ();
+ }
+ else
+ {
+ startGenesisLedger ();
+ }
+
+ m_orderBookDB.setup (getLedgerMaster ().getCurrentLedger ());
+
+ // Begin validation and ip maintenance.
+ //
+ // - LocalCredentials maintains local information: including identity
+ // - and network connection persistence information.
+ //
+ // VFALCO NOTE this starts the UNL
+ m_localCredentials.start ();
+
+ //
+ // Set up UNL.
+ //
+ if (!config_->RUN_STANDALONE)
+ getUNL ().nodeBootstrap ();
+
+ mValidations->tune (config_->getSize (siValidationsSize), config_->getSize (siValidationsAge));
+ m_nodeStore->tune (config_->getSize (siNodeCacheSize), config_->getSize (siNodeCacheAge));
+ m_ledgerMaster->tune (config_->getSize (siLedgerSize), config_->getSize (siLedgerAge));
+ family().treecache().setTargetSize (config_->getSize (siTreeCacheSize));
+ family().treecache().setTargetAge (config_->getSize (siTreeCacheAge));
+
+ //----------------------------------------------------------------------
+ //
+ // Server
+ //
+ //----------------------------------------------------------------------
+
+ // VFALCO NOTE Unfortunately, in stand-alone mode some code still
+ // foolishly calls overlay(). When this is fixed we can
+ // move the instantiation inside a conditional:
+ //
+ // if (!config_.RUN_STANDALONE)
+ m_overlay = make_Overlay (*this, setup_Overlay(*config_), *m_jobQueue,
+ *serverHandler_, *m_resourceManager, *m_resolver, get_io_service(),
+ *config_);
+ add (*m_overlay); // add to PropertyStream
+
+ m_overlay->setupValidatorKeyManifests (*config_, getWalletDB ());
+
+ {
+ auto setup = setup_ServerHandler(*config_, std::cerr);
+ setup.makeContexts();
+ serverHandler_->setup (setup, m_journal);
+ }
+
+ // Create websocket servers.
+ for (auto const& port : serverHandler_->setup().ports)
+ {
+ if (! port.websockets())
+ continue;
+ auto server = websocket::makeServer (
+ {*this, port, *m_resourceManager, getOPs(), m_journal, *config_,
+ *m_collectorManager});
+ if (!server)
+ {
+ m_journal.fatal << "Could not create Websocket for [" <<
+ port.name << "]";
+ throw std::exception();
+ }
+ websocketServers_.emplace_back (std::move (server));
+ }
+
+ //----------------------------------------------------------------------
+
+ // Begin connecting to network.
+ if (!config_->RUN_STANDALONE)
+ {
+ // Should this message be here, conceptually? In theory this sort
+ // of message, if displayed, should be displayed from PeerFinder.
+ if (config_->PEER_PRIVATE && config_->IPS.empty ())
+ m_journal.warning << "No outbound peer connections will be made";
+
+ // VFALCO NOTE the state timer resets the deadlock detector.
+ //
+ m_networkOPs->setStateTimer ();
+ }
+ else
+ {
+ m_journal.warning << "Running in standalone mode";
+
+ m_networkOPs->setStandAlone ();
+ }
+}
+
+void
+ApplicationImp::run()
+{
+ // VFALCO NOTE I put this here in the hopes that when unit tests run (which
+ // tragically require an Application object to exist or else they
+ // crash), the run() function will not get called and we will
+ // avoid doing silly things like contacting the SNTP server, or
+ // running the various logic threads like Validators, PeerFinder, etc.
+ prepare ();
+ start ();
+
+
+ {
+ if (!config_->RUN_STANDALONE)
+ {
+ // VFALCO NOTE This seems unnecessary. If we properly refactor the load
+ // manager then the deadlock detector can just always be "armed"
+ //
+ getLoadManager ().activateDeadlockDetector ();
+ }
+ }
+
+ m_stop.wait ();
+
+ // Stop the server. When this returns, all
+ // Stoppable objects should be stopped.
+ m_journal.info << "Received shutdown request";
+ stop (m_journal);
+ m_journal.info << "Done.";
+ StopSustain();
+}
+
+void
+ApplicationImp::signalStop()
+{
+ // Unblock the main thread (which is sitting in run()).
+ //
+ m_stop.signal();
+}
+
+bool
+ApplicationImp::isShutdown()
+{
+ // from Stoppable mixin
+ return isStopped();
+}
+
+//------------------------------------------------------------------------------
+
+void
+ApplicationImp::startGenesisLedger()
{
std::shared_ptr const genesis =
std::make_shared(
@@ -1485,14 +1465,17 @@ bool ApplicationImp::serverOkay (std::string& reason)
return true;
}
-beast::Journal ApplicationImp::journal (std::string const& name)
+beast::Journal
+ApplicationImp::journal (std::string const& name)
{
return logs_->journal (name);
}
//VFALCO TODO clean this up since it is just a file holding a single member function definition
-static std::vector getSchema (DatabaseCon& dbc, std::string const& dbName)
+static
+std::vector
+getSchema (DatabaseCon& dbc, std::string const& dbName)
{
std::vector schema;
schema.reserve(32);
@@ -1653,6 +1636,8 @@ Application::Application ()
{
}
+//------------------------------------------------------------------------------
+
std::unique_ptr
make_Application (
std::unique_ptr config,
@@ -1662,9 +1647,14 @@ make_Application (
std::move(config), std::move(logs));
}
-Application& getApp ()
+void
+setupConfigForUnitTests (Config& config)
{
- return ApplicationImpBase::getInstance ();
+ config.overwrite (ConfigSection::nodeDatabase (), "type", "memory");
+ config.overwrite (ConfigSection::nodeDatabase (), "path", "main");
+
+ config.deprecatedClearSection (ConfigSection::importNodeDatabase ());
+ config.legacy("database_path", "DummyForUnitTests");
}
}
diff --git a/src/ripple/app/main/Application.h b/src/ripple/app/main/Application.h
index c459a50f78..367ebcdbb4 100644
--- a/src/ripple/app/main/Application.h
+++ b/src/ripple/app/main/Application.h
@@ -90,8 +90,18 @@ public:
Application ();
virtual ~Application () = default;
- virtual Config const& config() const = 0;
+
+ virtual void setup() = 0;
+ virtual void run() = 0;
+ virtual bool isShutdown () = 0;
+ virtual void signalStop () = 0;
+
+ //
+ // ---
+ //
+
virtual Logs& logs() = 0;
+ virtual Config const& config() const = 0;
virtual boost::asio::io_service& getIOService () = 0;
virtual CollectorManager& getCollectorManager () = 0;
virtual Family& family() = 0;
@@ -138,12 +148,6 @@ public:
// NOTE This will be replaced by class Validators
//
virtual DatabaseCon& getWalletDB () = 0;
-
- virtual bool isShutdown () = 0;
- virtual bool running () = 0;
- virtual void setup () = 0;
- virtual void run () = 0;
- virtual void signalStop () = 0;
};
std::unique_ptr
@@ -151,8 +155,9 @@ make_Application(
std::unique_ptr config,
std::unique_ptr logs);
-// DEPRECATED
-extern Application& getApp ();
+extern
+void
+setupConfigForUnitTests (Config& config);
}
diff --git a/src/ripple/app/main/Main.cpp b/src/ripple/app/main/Main.cpp
index fdc0a3d82a..d4b6bfe757 100644
--- a/src/ripple/app/main/Main.cpp
+++ b/src/ripple/app/main/Main.cpp
@@ -162,17 +162,6 @@ void printHelp (const po::options_description& desc)
//------------------------------------------------------------------------------
-static
-void
-setupConfigForUnitTests (Config& config)
-{
- config.overwrite (ConfigSection::nodeDatabase (), "type", "memory");
- config.overwrite (ConfigSection::nodeDatabase (), "path", "main");
-
- config.deprecatedClearSection (ConfigSection::importNodeDatabase ());
- config.legacy("database_path", "DummyForUnitTests");
-}
-
static int runShutdownTests (std::unique_ptr config)
{
// Shutdown tests can not be part of the normal unit tests in 'runUnitTests'
@@ -204,18 +193,10 @@ static int runShutdownTests (std::unique_ptr config)
return EXIT_SUCCESS;
}
-static int runUnitTests (
- std::unique_ptr config,
+static int runUnitTests(
std::string const& pattern,
std::string const& argument)
{
- // Config needs to be set up before creating Application
- setupConfigForUnitTests (*config);
-
- auto app = make_Application (
- std::move(config),
- std::make_unique());
-
using namespace beast::unit_test;
beast::debug_ostream stream;
reporter r (stream);
@@ -363,9 +344,7 @@ int run (int argc, char** argv)
argument = vm["unittest-arg"].as();
return runUnitTests(
- std::make_unique (),
- vm["unittest"].as(),
- argument);
+ vm["unittest"].as(), argument);
}
auto config = std::make_unique();
diff --git a/src/ripple/app/tests/MultiSign.test.cpp b/src/ripple/app/tests/MultiSign.test.cpp
index db01fc9056..d172ea0917 100644
--- a/src/ripple/app/tests/MultiSign.test.cpp
+++ b/src/ripple/app/tests/MultiSign.test.cpp
@@ -142,7 +142,7 @@ public:
env.require (owners (alice, 4));
// This should work.
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
std::uint32_t aliceSeq = env.seq (alice);
env(noop(alice), msig(bogie, demon), fee(3 * baseFee));
env.close();
@@ -232,7 +232,7 @@ public:
// alice multisigns a transaction. Should succeed.
std::uint32_t aliceSeq = env.seq (alice);
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
env(noop(alice), msig(bogie), fee(2 * baseFee));
env.close();
expect (env.seq(alice) == aliceSeq + 1);
@@ -265,7 +265,7 @@ public:
env.require (owners (alice, 10));
// This should work.
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
std::uint32_t aliceSeq = env.seq (alice);
env(noop(alice), msig(bogie), fee(2 * baseFee));
env.close();
@@ -348,7 +348,7 @@ public:
env.require (owners (alice, 4));
// Attempt a multisigned transaction that meets the quorum.
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
aliceSeq = env.seq (alice);
env(noop(alice), msig(cheri), fee(2 * baseFee));
env.close();
@@ -401,7 +401,7 @@ public:
env.close();
// Attempt a multisigned transaction that meets the quorum.
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
std::uint32_t aliceSeq = env.seq (alice);
env(noop(alice), msig(msig::Reg{cheri, cher}), fee(2 * baseFee));
env.close();
@@ -468,7 +468,7 @@ public:
env.require (owners (alice, 6));
// Each type of signer should succeed individually.
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
std::uint32_t aliceSeq = env.seq (alice);
env(noop(alice), msig(becky), fee(2 * baseFee));
env.close();
@@ -592,7 +592,7 @@ public:
env(regkey (alice, disabled), sig(alie));
// L0; A lone signer list cannot be removed.
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
env(signers(alice, jtx::none), msig(bogie),
fee(2 * baseFee), ter(tecNO_ALTERNATIVE_KEY));
@@ -645,7 +645,7 @@ public:
env.require (owners (alice, 4));
// Multisign a ttPAYMENT.
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
std::uint32_t aliceSeq = env.seq (alice);
env(pay(alice, env.master, XRP(1)),
msig(becky, bogie), fee(3 * baseFee));
diff --git a/src/ripple/app/tests/Regression_test.cpp b/src/ripple/app/tests/Regression_test.cpp
index ac82d573c4..eb9042a992 100644
--- a/src/ripple/app/tests/Regression_test.cpp
+++ b/src/ripple/app/tests/Regression_test.cpp
@@ -49,7 +49,7 @@ struct Regression_test : public beast::unit_test::suite
// be reproduced against an open ledger. Make a local
// closed ledger and work with it directly.
auto closed = std::make_shared(
- create_genesis, env.config, env.app().family());
+ create_genesis, env.app().config(), env.app().family());
auto expectedDrops = SYSTEM_CURRENCY_START;
expect(closed->info().drops == expectedDrops);
@@ -67,7 +67,7 @@ struct Regression_test : public beast::unit_test::suite
auto const result = ripple::apply(env.app(),
accum, *jt.stx, tapENABLE_TESTING,
- directSigVerify, env.config,
+ directSigVerify, env.app().config(),
env.journal);
expect(result.first == tesSUCCESS);
expect(result.second);
@@ -95,7 +95,7 @@ struct Regression_test : public beast::unit_test::suite
auto const result = ripple::apply(env.app(),
accum, *jt.stx, tapENABLE_TESTING,
- directSigVerify, env.config,
+ directSigVerify, env.app().config(),
env.journal);
expect(result.first == tecINSUFF_FEE);
expect(result.second);
diff --git a/src/ripple/basics/BasicConfig.h b/src/ripple/basics/BasicConfig.h
index 666475891c..c99668618c 100644
--- a/src/ripple/basics/BasicConfig.h
+++ b/src/ripple/basics/BasicConfig.h
@@ -175,6 +175,9 @@ public:
If the section does not exist, an empty section is returned.
*/
/** @{ */
+ Section&
+ section (std::string const& name);
+
Section const&
section (std::string const& name) const;
@@ -183,6 +186,12 @@ public:
{
return section(name);
}
+
+ Section&
+ operator[] (std::string const& name)
+ {
+ return section(name);
+ }
/** @} */
/** Overwrite a key/value pair with a command line argument
diff --git a/src/ripple/basics/impl/BasicConfig.cpp b/src/ripple/basics/impl/BasicConfig.cpp
index 02ddb0ef31..f0a58d7fe4 100644
--- a/src/ripple/basics/impl/BasicConfig.cpp
+++ b/src/ripple/basics/impl/BasicConfig.cpp
@@ -96,6 +96,12 @@ BasicConfig::exists (std::string const& name) const
return map_.find(name) != map_.end();
}
+Section&
+BasicConfig::section (std::string const& name)
+{
+ return map_[name];
+}
+
Section const&
BasicConfig::section (std::string const& name) const
{
diff --git a/src/ripple/core/Config.h b/src/ripple/core/Config.h
index d97d9828f5..f71868e944 100644
--- a/src/ripple/core/Config.h
+++ b/src/ripple/core/Config.h
@@ -162,9 +162,7 @@ public:
beast::File getModuleDatabasePath () const;
bool doImport = false;
-
bool QUIET = false;
-
bool ELB_SUPPORT = false;
std::string VALIDATORS_SITE; // Where to find validators.txt on the Internet.
diff --git a/src/ripple/test/jtx/Account.h b/src/ripple/test/jtx/Account.h
index 36781e1567..a95d1d43e7 100644
--- a/src/ripple/test/jtx/Account.h
+++ b/src/ripple/test/jtx/Account.h
@@ -47,13 +47,8 @@ public:
Account (Account const&) = default;
Account& operator= (Account const&) = default;
-#ifdef _MSC_VER
- Account (Account&&);
- Account& operator= (Account&&);
-#else
Account (Account&&) = default;
Account& operator= (Account&&) = default;
-#endif
/** Create an account from a key pair. */
Account (std::string name,
diff --git a/src/ripple/test/jtx/Env.h b/src/ripple/test/jtx/Env.h
index c1a38fb774..f8fb3e6467 100644
--- a/src/ripple/test/jtx/Env.h
+++ b/src/ripple/test/jtx/Env.h
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -126,13 +127,21 @@ public:
beast::Journal const journal;
- /** Configuration used. */
- Config const config;
-
/** The master account. */
Account const master;
private:
+ struct AppBundle
+ {
+ Application* app;
+ std::unique_ptr logs;
+ std::unique_ptr owned;
+
+ AppBundle (std::unique_ptr config);
+ AppBundle (Application* app_);
+ };
+
+ AppBundle bundle_;
std::shared_ptr closed_;
CachedSLEs cachedSLEs_;
LogSquelcher logSquelcher_;
@@ -150,7 +159,7 @@ public:
Application&
app()
{
- return getApp();
+ return *bundle_.app;
}
/** Returns the open ledger.
diff --git a/src/ripple/test/jtx/impl/Account.cpp b/src/ripple/test/jtx/impl/Account.cpp
index 6b9eb31a86..6985d4f4ea 100644
--- a/src/ripple/test/jtx/impl/Account.cpp
+++ b/src/ripple/test/jtx/impl/Account.cpp
@@ -26,28 +26,6 @@ namespace ripple {
namespace test {
namespace jtx {
-#ifdef _MSC_VER
-Account::Account (Account&& other)
- : name_(std::move(other.name_))
- , pk_(std::move(other.pk_))
- , sk_(std::move(other.sk_))
- , id_(std::move(other.id_))
- , human_(std::move(other.human_))
-{
-}
-
-Account&
-Account::operator= (Account&& rhs)
-{
- name_ = std::move(rhs.name_);
- pk_ = std::move(rhs.pk_);
- sk_ = std::move(rhs.sk_);
- id_ = std::move(rhs.id_);
- human_ = std::move(rhs.human_);
- return *this;
-}
-#endif
-
Account::Account(std::string name,
std::pair const& keys)
: name_(std::move(name))
@@ -58,16 +36,15 @@ Account::Account(std::string name,
{
}
-Account::Account (std::string name,
- KeyType type)
-#ifndef _MSC_VER
- : Account(name,
-#else
- // Fails on Clang and possibly gcc
- : Account(std::move(name),
-#endif
- generateKeyPair(type, generateSeed(name)))
+Account::Account (std::string name, KeyType type)
+ : name_(std::move(name))
{
+ auto const keys = generateKeyPair(
+ type, generateSeed(name_));
+ pk_ = keys.first;
+ sk_ = keys.second;
+ id_ = calcAccountID(pk_);
+ human_ = toBase58(id_);
}
IOU
diff --git a/src/ripple/test/jtx/impl/Env.cpp b/src/ripple/test/jtx/impl/Env.cpp
index e190427d98..254c7178b8 100644
--- a/src/ripple/test/jtx/impl/Env.cpp
+++ b/src/ripple/test/jtx/impl/Env.cpp
@@ -50,17 +50,41 @@ namespace test {
namespace jtx {
+Env::AppBundle::AppBundle(Application* app_)
+ : app (app_)
+{
+}
+
+Env::AppBundle::AppBundle(std::unique_ptr config)
+{
+ auto logs = std::make_unique();
+ owned = make_Application(
+ std::move(config), std::move(logs));
+ app = owned.get();
+}
+
+//------------------------------------------------------------------------------
+
+static
+std::unique_ptr
+makeConfig()
+{
+ auto p = std::make_unique();
+ setupConfigForUnitTests(*p);
+ return std::unique_ptr(p.release());
+}
+
// VFALCO Could wrap the log in a Journal here
Env::Env (beast::unit_test::suite& test_)
- : test(test_)
- , config()
- , master("master", generateKeyPair(
+ : test (test_)
+ , master ("master", generateKeyPair(
KeyType::secp256k1,
generateSeed("masterpassphrase")))
+ , bundle_ (makeConfig())
, closed_ (std::make_shared(
- create_genesis, config, app().family()))
+ create_genesis, app().config(), app().family()))
, cachedSLEs_ (std::chrono::seconds(5), stopwatch_)
- , openLedger (closed_, config, cachedSLEs_, journal)
+ , openLedger (closed_, app().config(), cachedSLEs_, journal)
{
memoize(master);
initializePathfinding();
@@ -98,7 +122,7 @@ Env::close(NetClock::time_point const& closeTime)
OpenView accum(&*next);
OpenLedger::apply(app(), accum, *closed_,
txs, retries, applyFlags(), *router,
- config, journal);
+ app().config(), journal);
accum.apply(*next);
}
// To ensure that the close time is exact and not rounded, we don't
@@ -254,7 +278,7 @@ Env::submit (JTx const& jt)
{
std::tie(ter_, didApply) = ripple::apply(
app(), view, *stx, applyFlags(),
- directSigVerify, config,
+ directSigVerify, app().config(),
beast::Journal{});
return didApply;
});
diff --git a/src/ripple/test/jtx/impl/Env_test.cpp b/src/ripple/test/jtx/impl/Env_test.cpp
index fa6a42e629..8c8127d308 100644
--- a/src/ripple/test/jtx/impl/Env_test.cpp
+++ b/src/ripple/test/jtx/impl/Env_test.cpp
@@ -360,7 +360,7 @@ public:
{ { "bob", 1 }, { "carol", 2 } }));
env(noop("alice"));
- auto const baseFee = env.config.FEE_DEFAULT;
+ auto const baseFee = env.app().config().FEE_DEFAULT;
env(noop("alice"), msig("bob"), fee(2 * baseFee));
env(noop("alice"), msig("carol"), fee(2 * baseFee));
env(noop("alice"), msig("bob", "carol"), fee(3 * baseFee));
diff --git a/src/ripple/test/mao.h b/src/ripple/test/mao.h
new file mode 100644
index 0000000000..c344baab1d
--- /dev/null
+++ b/src/ripple/test/mao.h
@@ -0,0 +1,27 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_TEST_MAO_H_INCLUDED
+#define RIPPLE_TEST_MAO_H_INCLUDED
+
+// Convenience header that includes everything
+
+#include
+
+#endif
diff --git a/src/ripple/test/mao/Net.h b/src/ripple/test/mao/Net.h
new file mode 100644
index 0000000000..d1406679a3
--- /dev/null
+++ b/src/ripple/test/mao/Net.h
@@ -0,0 +1,39 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef RIPPLE_TEST_MAO_H_INCLUDED
+#define RIPPLE_TEST_MAO_H_INCLUDED
+
+#include
+
+namespace ripple {
+namespace test {
+namespace mao {
+
+class Net
+{
+private:
+public:
+};
+
+} // mao
+} // test
+} // ripple
+
+#endif
diff --git a/src/ripple/test/mao/impl/Net.cpp b/src/ripple/test/mao/impl/Net.cpp
new file mode 100644
index 0000000000..957266ded7
--- /dev/null
+++ b/src/ripple/test/mao/impl/Net.cpp
@@ -0,0 +1,31 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#include
+#include
+
+namespace ripple {
+namespace test {
+namespace mao {
+
+
+
+} // mao
+} // test
+} // ripple
diff --git a/src/ripple/test/mao/impl/Net_test.cpp b/src/ripple/test/mao/impl/Net_test.cpp
new file mode 100644
index 0000000000..ededdaa9a2
--- /dev/null
+++ b/src/ripple/test/mao/impl/Net_test.cpp
@@ -0,0 +1,145 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2012, 2013 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ripple {
+namespace test {
+namespace mao {
+
+struct TestApp
+{
+ TestApp()
+ {
+ auto config = std::make_unique();
+ setupConfigForUnitTests(*config);
+ config->RUN_STANDALONE = true;
+ (*config)["server"].append("port_peer");
+ (*config)["port_peer"].set("ip", "127.0.0.1");
+ (*config)["port_peer"].set("port", "8080");
+ (*config)["port_peer"].set("protocol", "peer");
+ (*config)["server"].append("port_admin");
+ (*config)["port_admin"].set("ip", "127.0.0.1");
+ (*config)["port_admin"].set("port", "8081");
+ (*config)["port_admin"].set("protocol", "http");
+ (*config)["port_admin"].set("admin", "127.0.0.1");
+ // Hack so we dont have to call Config::setup
+ HTTPClient::initializeSSLContext(*config);
+ auto logs = std::make_unique();
+ instance = make_Application(
+ std::move(config), std::move(logs));
+ instance->setup();
+ thread_ = std::thread(
+ [&]() { instance->run(); });
+ }
+
+ ~TestApp()
+ {
+ if (thread_.joinable())
+ {
+ instance->signalStop();
+ thread_.join();
+ }
+ }
+
+ void
+ join()
+ {
+ thread_.join();
+ }
+
+ Application*
+ operator->()
+ {
+ return instance.get();
+ }
+
+ template
+ void
+ rpc (T const& t, Args const&... args)
+ {
+ std::vector v;
+ collect(v, t, args...);
+ RPCCall::fromCommandLine(
+ instance->config(), v,
+ instance->logs());
+ }
+
+private:
+ inline
+ void
+ collect (std::vector& v)
+ {
+ }
+
+ template
+ void
+ collect (std::vector& v,
+ T const& t, Args const&... args)
+ {
+ v.emplace_back(t);
+ collect(v, args...);
+ }
+
+ std::unique_ptr instance;
+ std::thread thread_;
+ std::mutex mutex_;
+};
+
+class Net_test : public beast::unit_test::suite
+{
+public:
+ void
+ testStartStop()
+ {
+ TestApp app;
+ pass();
+ }
+
+ void
+ testRPC()
+ {
+ TestApp app;
+ app.rpc("stop");
+ app.join();
+ pass();
+ }
+
+ void
+ run() override
+ {
+ testStartStop();
+ testRPC();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE_MANUAL(Net,mao,ripple)
+
+} // mao
+} // test
+} // ripple
diff --git a/src/ripple/unity/test.cpp b/src/ripple/unity/test.cpp
index d766d54757..9a53617f41 100644
--- a/src/ripple/unity/test.cpp
+++ b/src/ripple/unity/test.cpp
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -44,4 +45,6 @@
#include
#include
-#include
+#include
+#include
+