Refactor jtx::Env:

These changes eliminate the Env's OpenLedger member and make
transactions go through the Application associated with each
instance of the Env, making the unit tests follow a code path
closer to the production code path.

* Add Env::open() for open ledger
* Add Env::now()
* Rename to Env::current()

* Inject ManualTimeKeeper in Env Application
* Make Config mutable
* Move setupConfigForUnitTests
* Launch Env Application thread
* Use Application ledgers in Env
* Adjust Application clock on ledger close
* Adjust close time for close resolution
* Scrub obsolete clock types
* Enable features via Env ctor
* Make Env::master Account object global

* Cache SSL context (performance)
* Cache master wallet keys in Ledger ctor (performance)
This commit is contained in:
Vinnie Falco
2015-10-01 09:09:18 -07:00
parent 90466d6cde
commit 1320898fbe
33 changed files with 530 additions and 354 deletions

View File

@@ -3628,6 +3628,10 @@
</ClCompile>
<ClInclude Include="..\..\src\ripple\shamap\TreeNodeCache.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\test\impl\ManualTimeKeeper.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\test\jtx.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\test\jtx\Account.h">
@@ -3794,6 +3798,8 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\test\jtx\utility.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\test\ManualTimeKeeper.h">
</ClInclude>
<ClCompile Include="..\..\src\ripple\test\mao\impl\Net.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>

View File

@@ -412,6 +412,9 @@
<Filter Include="ripple\test">
<UniqueIdentifier>{B25F5854-84AE-1CBD-DFFC-6515DD055652}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\test\impl">
<UniqueIdentifier>{CF7F0C3F-3D61-7764-BA8B-5FF38018425C}</UniqueIdentifier>
</Filter>
<Filter Include="ripple\test\jtx">
<UniqueIdentifier>{A21A3B94-5C44-3746-4F10-6FF8FF990CE3}</UniqueIdentifier>
</Filter>
@@ -4284,6 +4287,9 @@
<ClInclude Include="..\..\src\ripple\shamap\TreeNodeCache.h">
<Filter>ripple\shamap</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\test\impl\ManualTimeKeeper.cpp">
<Filter>ripple\test\impl</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\test\jtx.h">
<Filter>ripple\test</Filter>
</ClInclude>
@@ -4458,6 +4464,9 @@
<ClInclude Include="..\..\src\ripple\test\jtx\utility.h">
<Filter>ripple\test\jtx</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\test\ManualTimeKeeper.h">
<Filter>ripple\test</Filter>
</ClInclude>
<ClCompile Include="..\..\src\ripple\test\mao\impl\Net.cpp">
<Filter>ripple\test\mao\impl</Filter>
</ClCompile>

View File

@@ -5,8 +5,6 @@ VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RippleD", "RippleD.vcxproj", "{26B7D9AC-1A80-8EF8-6703-D061F1BECB75}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CF990ABA-EAE4-47AB-BF5E-0BCBB95CE325}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug.classic|x64 = debug.classic|x64

View File

@@ -179,7 +179,7 @@ Ledger::Ledger (create_genesis_t, Config const& config, Family& family)
info_.seq = 1;
info_.drops = SYSTEM_CURRENCY_START;
info_.closeTimeResolution = ledgerDefaultTimeResolution;
auto const id = calcAccountID(
static auto const id = calcAccountID(
generateKeyPair(KeyType::secp256k1,
generateSeed("masterpassphrase")).first);
auto const sle = std::make_shared<SLE>(keylet::account(id));

View File

@@ -286,13 +286,13 @@ private:
};
public:
std::unique_ptr<Config const> config_;
std::unique_ptr<Config> config_;
std::unique_ptr<Logs> logs_;
std::unique_ptr<TimeKeeper> timeKeeper_;
beast::Journal m_journal;
Application::MutexType m_masterMutex;
std::unique_ptr<TimeKeeper> timeKeeper_;
// Required by the SHAMapStore
TransactionMaster m_txMaster;
@@ -363,18 +363,17 @@ public:
//--------------------------------------------------------------------------
ApplicationImp (
std::unique_ptr<Config const> config,
std::unique_ptr<Logs> logs)
std::unique_ptr<Config> config,
std::unique_ptr<Logs> logs,
std::unique_ptr<TimeKeeper> timeKeeper)
: RootStoppable ("Application")
, BasicApp (numberOfThreads(*config))
, config_ (std::move(config))
, logs_ (std::move(logs))
, timeKeeper_ (std::move(timeKeeper))
, m_journal (logs_->journal("Application"))
, timeKeeper_ (make_TimeKeeper(
logs_->journal("TimeKeeper")))
, m_txMaster (*this)
, m_nodeStoreScheduler (*this)
@@ -518,8 +517,8 @@ public:
return *logs_;
}
Config const&
config() const override
Config&
config() override
{
return *config_;
}
@@ -691,6 +690,12 @@ public:
return *openLedger_;
}
OpenLedger const&
openLedger() const override
{
return *openLedger_;
}
Overlay& overlay () override
{
return *m_overlay;
@@ -1676,21 +1681,13 @@ Application::Application ()
std::unique_ptr<Application>
make_Application (
std::unique_ptr<Config const> config,
std::unique_ptr<Logs> logs)
std::unique_ptr<Config> config,
std::unique_ptr<Logs> logs,
std::unique_ptr<TimeKeeper> timeKeeper)
{
return std::make_unique<ApplicationImp> (
std::move(config), std::move(logs));
}
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");
std::move(config), std::move(logs),
std::move(timeKeeper));
}
}

View File

@@ -103,7 +103,7 @@ public:
//
virtual Logs& logs() = 0;
virtual Config const& config() const = 0;
virtual Config& config() = 0;
virtual boost::asio::io_service& getIOService () = 0;
virtual CollectorManager& getCollectorManager () = 0;
virtual Family& family() = 0;
@@ -136,6 +136,7 @@ public:
virtual PendingSaves& pendingSaves() = 0;
virtual AccountIDCache const& accountIDCache() const = 0;
virtual OpenLedger& openLedger() = 0;
virtual OpenLedger const& openLedger() const = 0;
virtual DatabaseCon& getTxnDB () = 0;
virtual DatabaseCon& getLedgerDB () = 0;
@@ -156,12 +157,9 @@ public:
std::unique_ptr <Application>
make_Application(
std::unique_ptr<Config const> config,
std::unique_ptr<Logs> logs);
extern
void
setupConfigForUnitTests (Config& config);
std::unique_ptr<Config> config,
std::unique_ptr<Logs> logs,
std::unique_ptr<TimeKeeper> timeKeeper);
}

View File

@@ -28,6 +28,7 @@
#include <ripple/basics/ThreadName.h>
#include <ripple/core/Config.h>
#include <ripple/core/ConfigSections.h>
#include <ripple/core/TimeKeeper.h>
#include <ripple/crypto/RandomNumbers.h>
#include <ripple/json/to_string.h>
#include <ripple/net/RPCCall.h>
@@ -162,37 +163,6 @@ void printHelp (const po::options_description& desc)
//------------------------------------------------------------------------------
static int runShutdownTests (std::unique_ptr<Config> config)
{
// Shutdown tests can not be part of the normal unit tests in 'runUnitTests'
// because it needs to create and destroy an application object.
// FIXME: we only loop once, since the Config object will get destroyed
int const numShutdownIterations = 1; //20;
// Give it enough time to sync and run a bit while synced.
std::chrono::seconds const serverUptimePerIteration (4 * 60);
for (int i = 0; i < numShutdownIterations; ++i)
{
std::cerr << "\n\nStarting server. Iteration: " << i << "\n"
<< std::endl;
auto app = make_Application (
std::move(config),
std::make_unique<Logs>());
auto shutdownApp = [&app](std::chrono::seconds sleepTime, int iteration)
{
std::this_thread::sleep_for (sleepTime);
std::cerr << "\n\nStopping server. Iteration: " << iteration << "\n"
<< std::endl;
app->signalStop();
};
std::thread shutdownThread (shutdownApp, serverUptimePerIteration, i);
setupServer(*app);
startServer(*app);
shutdownThread.join();
}
return EXIT_SUCCESS;
}
static int runUnitTests(
std::string const& pattern,
std::string const& argument)
@@ -265,7 +235,6 @@ int run (int argc, char** argv)
("rpc_ip", po::value <std::string> (), "Specify the IP address for RPC command. Format: <ip-address>[':'<port-number>]")
("rpc_port", po::value <std::uint16_t> (), "Specify the port number for RPC command.")
("standalone,a", "Run with no peers.")
("shutdowntest", po::value <std::string> ()->implicit_value (""), "Perform shutdown tests.")
("unittest,u", po::value <std::string> ()->implicit_value (""), "Perform unit tests.")
("unittest-arg", po::value <std::string> ()->implicit_value (""), "Supplies argument to unit tests.")
("parameters", po::value< vector<string> > (), "Specify comma separated parameters.")
@@ -325,7 +294,6 @@ int run (int argc, char** argv)
&& !vm.count ("parameters")
&& !vm.count ("fg")
&& !vm.count ("standalone")
&& !vm.count ("shutdowntest")
&& !vm.count ("unittest"))
{
std::string logMe = DoSustain ();
@@ -471,13 +439,12 @@ int run (int argc, char** argv)
}
}
if (vm.count ("shutdowntest"))
return runShutdownTests (std::move(config));
// No arguments. Run server.
if (!vm.count ("parameters"))
{
auto logs = std::make_unique<Logs>();
auto timeKeeper = make_TimeKeeper(
logs->journal("TimeKeeper"));
if (vm.count ("quiet"))
logs->severity (beast::Journal::kFatal);
@@ -488,7 +455,8 @@ int run (int argc, char** argv)
auto app = make_Application(
std::move(config),
std::move (logs));
std::move(logs),
std::move(timeKeeper));
setupServer (*app);
startServer (*app);
return 0;

View File

@@ -149,8 +149,11 @@ public:
auto const switchoverTime = STAmountCalcSwitchovers::enableUnderflowFixCloseTime ();
for (auto timeDelta : {-10s, 10s}){
NetClock::time_point const closeTime = switchoverTime + timeDelta;
for (auto timeDelta : {
- env.closed()->info().closeTimeResolution,
env.closed()->info().closeTimeResolution} )
{
auto const closeTime = switchoverTime + timeDelta;
STAmountCalcSwitchovers switchover (closeTime);
env.close (closeTime);
// Will fail without the underflow fix

View File

@@ -141,7 +141,7 @@ find_paths(jtx::Env& env,
boost::optional<STAmount> const& saSendMax = boost::none)
{
static int const level = 8;
auto const& view = env.open ();
auto const& view = env.current();
auto cache = std::make_shared<RippleLineCache>(view);
auto currencies = accountSourceCurrencies(src, cache, true);
auto jvSrcCurrencies = Json::Value(Json::arrayValue);

View File

@@ -148,7 +148,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob");
auto const c = cond("receipt");
// syntax
@@ -171,7 +171,7 @@ struct SusPay_test : public beast::unit_test::suite
Env env(*this);
auto const alice = Account("alice");
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), alice, "bob");
auto const c = cond("receipt");
auto const seq = env.seq(alice);
@@ -192,7 +192,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob");
auto const c = cond("receipt");
// VFALCO Should we enforce this?
@@ -224,7 +224,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob");
auto const seq = env.seq("alice");
env(lockup("alice", "alice", XRP(1000), T(S{1})));
@@ -246,7 +246,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
auto const c = cond("receipt");
auto const seq = env.seq("alice");
@@ -272,7 +272,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
auto const c = cond("receipt");
auto const seq = env.seq("alice");
@@ -289,7 +289,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
env.close();
auto const c = cond("receipt");
@@ -308,7 +308,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
auto const c = cond("receipt");
auto const seq = env.seq("alice");
@@ -320,7 +320,7 @@ struct SusPay_test : public beast::unit_test::suite
{
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
auto const p = from_hex_text<uint128>(
"0102030405060708090A0B0C0D0E0F");
@@ -340,7 +340,7 @@ struct SusPay_test : public beast::unit_test::suite
using S = seconds;
Env env(*this);
auto T = [&env](NetClock::duration const& d)
{ return env.clock.now() + d; };
{ return env.now() + d; };
env.fund(XRP(5000), "alice", "bob", "carol");
auto const c = cond("receipt");
env(condpay("alice", "carol", XRP(1000), c.first, T(S{1})));

View File

@@ -42,7 +42,7 @@ class TxQ_test : public TestSuite
std::uint64_t expectedMinFeeLevel,
std::uint64_t expectedMedFeeLevel)
{
auto metrics = env.app().getTxQ().getMetrics(*env.open());
auto metrics = env.app().getTxQ().getMetrics(*env.current());
expect(metrics.referenceFeeLevel == 256, "referenceFeeLevel");
expect(metrics.txCount == expectedCount, "txCount");
expect(metrics.txQMaxSize == expectedMaxCount, "txQMaxSize");
@@ -62,24 +62,10 @@ class TxQ_test : public TestSuite
close(jtx::Env& env, size_t expectedTxSetSize, bool timeLeap = false)
{
{
auto const view = env.open();
auto const view = env.current();
expect(view->txCount() == expectedTxSetSize, "TxSet size mismatch");
// Update fee computations.
// Note implementing this way assumes that everything
// in the open ledger _will_ make it into the closed
// ledger, but for metrics that's probably good enough.
env.app().getTxQ().processValidatedLedger(
env.app(), *view, timeLeap, tapENABLE_TESTING);
}
env.close(
[&](OpenView& view, beast::Journal j)
{
// Stuff the ledger with transactions from the queue.
return env.app().getTxQ().accept(env.app(), view,
tapENABLE_TESTING);
}
);
env.close();
}
void
@@ -92,7 +78,7 @@ class TxQ_test : public TestSuite
bool didApply;
TER ter;
env.openLedger.modify(
env.app().openLedger().modify(
[&](OpenView& view, beast::Journal j)
{
std::tie(ter, didApply) =
@@ -108,7 +94,7 @@ class TxQ_test : public TestSuite
}
static
std::unique_ptr<Config const>
std::unique_ptr<Config>
makeConfig()
{
auto p = std::make_unique<Config>();
@@ -118,7 +104,7 @@ class TxQ_test : public TestSuite
section.set("min_ledgers_to_compute_size_limit", "3");
section.set("max_ledger_counts_to_store", "100");
section.set("retry_sequence_percent", "125");
return std::move(p);
return p;
}
public:
@@ -142,7 +128,7 @@ public:
auto queued = ter(terQUEUED);
expectEquals(env.open()->fees().base, 10);
expectEquals(env.current()->fees().base, 10);
checkMetrics(env, 0, boost::none, 0, 3, 256, 500);
@@ -164,7 +150,7 @@ public:
auto openLedgerFee =
[&]()
{
return fee(txq.openLedgerFee(*env.open()));
return fee(txq.openLedgerFee(*env.current()));
};
// Alice's next transaction -
// fails because the item in the TxQ hasn't applied.
@@ -339,7 +325,7 @@ public:
// we can be sure that there's one in the queue when the
// test ends and the TxQ is destructed.
auto metrics = txq.getMetrics(*env.open());
auto metrics = txq.getMetrics(*env.current());
expect(metrics.txCount == 0, "txCount");
auto txnsNeeded = metrics.txPerLedger - metrics.txInLedger;

View File

@@ -168,8 +168,9 @@ SusPayCreate::doApply()
weeks{1}).time_since_epoch().count();
if (ctx_.tx[~sfDigest])
{
if (! ctx_.tx[~sfCancelAfter] ||
maxExpire <= ctx_.tx[sfCancelAfter])
if (! ctx_.tx[~sfCancelAfter])
return tecNO_PERMISSION;
if (maxExpire <= ctx_.tx[sfCancelAfter])
return tecNO_PERMISSION;
}
else

View File

@@ -55,10 +55,6 @@ public:
static bool const is_steady = false;
};
/** A manual NetClock for unit tests. */
using TestNetClock =
beast::manual_clock<NetClock>;
/** A clock for measuring elapsed time.
The epoch is unspecified.

View File

@@ -514,8 +514,11 @@ initAuthenticated (boost::asio::ssl::context& context,
std::shared_ptr<boost::asio::ssl::context>
make_SSLContext()
{
std::shared_ptr<boost::asio::ssl::context> context =
std::make_shared<boost::asio::ssl::context> (
static auto const context =
[]()
{
auto const context = std::make_shared<
boost::asio::ssl::context>(
boost::asio::ssl::context::sslv23);
// By default, allow anonymous DH.
openssl::detail::initAnonymous(
@@ -524,6 +527,8 @@ make_SSLContext()
// set_verify_mode called, for either setting of WEBSOCKET_SECURE
context->set_verify_mode(boost::asio::ssl::verify_none);
return context;
}();
return context;
}
std::shared_ptr<boost::asio::ssl::context>

View File

@@ -21,6 +21,7 @@
#define RIPPLE_CORE_TIMEKEEPER_H_INCLUDED
#include <beast/chrono/abstract_clock.h>
#include <beast/utility/Journal.h>
#include <ripple/basics/chrono.h>
#include <string>
#include <vector>
@@ -90,7 +91,6 @@ public:
virtual
std::chrono::duration<std::int32_t>
closeOffset() const = 0;
};
extern

View File

@@ -35,26 +35,26 @@ struct BookDirs_test : public beast::unit_test::suite
{
Book book(xrpIssue(), USD.issue());
{
auto d = BookDirs(*env.open(), book);
auto d = BookDirs(*env.current(), book);
expect(std::begin(d) == std::end(d));
expect(std::distance(d.begin(), d.end()) == 0);
}
{
auto d = BookDirs(*env.open(), reversed(book));
auto d = BookDirs(*env.current(), reversed(book));
expect(std::distance(d.begin(), d.end()) == 0);
}
}
{
env(offer("alice", Account("alice")["USD"](50), XRP(10)));
auto d = BookDirs(*env.open(),
auto d = BookDirs(*env.current(),
Book(Account("alice")["USD"].issue(), xrpIssue()));
expect(std::distance(d.begin(), d.end()) == 1);
}
{
env(offer("alice", gw["CNY"](50), XRP(10)));
auto d = BookDirs(*env.open(),
auto d = BookDirs(*env.current(),
Book(gw["CNY"].issue(), xrpIssue()));
expect(std::distance(d.begin(), d.end()) == 1);
}
@@ -63,7 +63,7 @@ struct BookDirs_test : public beast::unit_test::suite
env.trust(Account("bob")["CNY"](10), "alice");
env(pay("bob", "alice", Account("bob")["CNY"](10)));
env(offer("alice", USD(50), Account("bob")["CNY"](10)));
auto d = BookDirs(*env.open(),
auto d = BookDirs(*env.current(),
Book(USD.issue(), Account("bob")["CNY"].issue()));
expect(std::distance(d.begin(), d.end()) == 1);
}
@@ -74,7 +74,7 @@ struct BookDirs_test : public beast::unit_test::suite
for (auto k = 0; k < 80; ++k)
env(offer("alice", AUD(i), XRP(j)));
auto d = BookDirs(*env.open(),
auto d = BookDirs(*env.current(),
Book(AUD.issue(), xrpIssue()));
expect(std::distance(d.begin(), d.end()) == 240);
auto i = 1, j = 3, k = 0;

View File

@@ -32,7 +32,7 @@ struct Directory_test : public beast::unit_test::suite
auto USD = gw["USD"];
{
auto dir = Dir(*env.open(),
auto dir = Dir(*env.current(),
keylet::ownerDir(Account("alice")));
expect(std::begin(dir) == std::end(dir));
expect(std::end(dir) == dir.find(uint256(), uint256()));
@@ -46,13 +46,13 @@ struct Directory_test : public beast::unit_test::suite
env(offer("bob", USD(500), XRP(10)));
{
auto dir = Dir(*env.open(),
auto dir = Dir(*env.current(),
keylet::ownerDir(Account("bob")));
expect(std::begin(dir)->get()->
getFieldAmount(sfTakerPays) == USD(500));
}
auto dir = Dir(*env.open(),
auto dir = Dir(*env.current(),
keylet::ownerDir(Account("alice")));
i = 0;
for (auto const& e : dir)

View File

@@ -34,7 +34,7 @@ isOffer (jtx::Env& env,
STAmount const& takerGets)
{
bool exists = false;
forEachItem (*env.open(), account,
forEachItem (*env.current(), account,
[&](std::shared_ptr<SLE const> const& sle)
{
if (sle->getType () == ltOFFER &&

View File

@@ -120,7 +120,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
STAmount const toDebit (USD_gw1 (20));
{
// accountSend, no deferredCredits
ApplyViewImpl av (&*env.open(), tapNONE);
ApplyViewImpl av (&*env.current(), tapNONE);
auto const iss = USD_gw1.issue ();
auto const startingAmount = accountHolds (
@@ -139,7 +139,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
{
// rippleCredit, no deferredCredits
ApplyViewImpl av (&*env.open(), tapNONE);
ApplyViewImpl av (&*env.current(), tapNONE);
auto const iss = USD_gw1.issue ();
auto const startingAmount = accountHolds (
@@ -158,7 +158,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
{
// accountSend, w/ deferredCredits
ApplyViewImpl av (&*env.open(), tapNONE);
ApplyViewImpl av (&*env.current(), tapNONE);
PaymentSandbox pv (&av);
auto const iss = USD_gw1.issue ();
@@ -178,7 +178,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
{
// rippleCredit, w/ deferredCredits
ApplyViewImpl av (&*env.open(), tapNONE);
ApplyViewImpl av (&*env.current(), tapNONE);
PaymentSandbox pv (&av);
auto const iss = USD_gw1.issue ();
@@ -193,7 +193,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
{
// redeemIOU, w/ deferredCredits
ApplyViewImpl av (&*env.open(), tapNONE);
ApplyViewImpl av (&*env.current(), tapNONE);
PaymentSandbox pv (&av);
auto const iss = USD_gw1.issue ();
@@ -208,7 +208,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
{
// issueIOU, w/ deferredCredits
ApplyViewImpl av (&*env.open(), tapNONE);
ApplyViewImpl av (&*env.current(), tapNONE);
PaymentSandbox pv (&av);
auto const iss = USD_gw1.issue ();
@@ -223,7 +223,7 @@ class PaymentSandbox_test : public beast::unit_test::suite
{
// accountSend, w/ deferredCredits and stacked views
ApplyViewImpl av (&*env.open(), tapNONE);
ApplyViewImpl av (&*env.current(), tapNONE);
PaymentSandbox pv (&av);
auto const iss = USD_gw1.issue ();

View File

@@ -183,8 +183,8 @@ class View_test
{
using namespace jtx;
Env env(*this);
wipe(env.openLedger);
auto const open = env.open();
wipe(env.app().openLedger());
auto const open = env.current();
ApplyViewImpl v(&*open, tapNONE);
succ(v, 0, boost::none);
v.insert(sle(1));
@@ -214,8 +214,8 @@ class View_test
{
using namespace jtx;
Env env(*this);
wipe(env.openLedger);
auto const open = env.open();
wipe(env.app().openLedger());
auto const open = env.current();
ApplyViewImpl v0(&*open, tapNONE);
v0.insert(sle(1));
v0.insert(sle(2));
@@ -278,8 +278,8 @@ class View_test
{
using namespace jtx;
Env env(*this);
wipe(env.openLedger);
auto const open = env.open();
wipe(env.app().openLedger());
auto const open = env.current();
ApplyViewImpl v0 (&*open, tapNONE);
v0.rawInsert(sle(1, 1));
v0.rawInsert(sle(2, 2));
@@ -345,8 +345,8 @@ class View_test
using namespace std::chrono;
{
Env env(*this);
wipe(env.openLedger);
auto const open = env.open();
wipe(env.app().openLedger());
auto const open = env.current();
OpenView v0(open.get());
expect(v0.seq() != 98);
expect(v0.seq() == open->seq());
@@ -556,9 +556,9 @@ class View_test
// Make sure OpenLedger::empty works
{
Env env(*this);
expect(env.openLedger.empty());
expect(env.app().openLedger().empty());
env.fund(XRP(10000), Account("test"));
expect(!env.openLedger.empty());
expect(! env.app().openLedger().empty());
}
}

View File

@@ -1658,7 +1658,7 @@ public:
env(pay(g, env.master, USD(50)));
env.close();
auto const ledger = env.open();
auto const ledger = env.current();
ProcessTransactionFn processTxn = fakeProcessTransaction;

View File

@@ -0,0 +1,69 @@
//------------------------------------------------------------------------------
/*
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_MANUALTIMEKEEPER_H_INCLUDED
#define RIPPLE_TEST_MANUALTIMEKEEPER_H_INCLUDED
#include <ripple/core/TimeKeeper.h>
#include <mutex>
namespace ripple {
namespace test {
class ManualTimeKeeper : public TimeKeeper
{
public:
ManualTimeKeeper();
void
run (std::vector<std::string> const& servers) override;
time_point
now() const override;
time_point
closeTime() const override;
void
adjustCloseTime (std::chrono::duration<std::int32_t> amount) override;
std::chrono::duration<std::int32_t>
nowOffset() const override;
std::chrono::duration<std::int32_t>
closeOffset() const override;
void
set (time_point now);
private:
// Adjust system_clock::time_point for NetClock epoch
static
time_point
adjust (std::chrono::system_clock::time_point when);
std::mutex mutable mutex_;
std::chrono::duration<std::int32_t> closeOffset_;
time_point now_;
};
} // test
} // ripple
#endif

View File

@@ -0,0 +1,104 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-2015 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 <BeastConfig.h>
#include <ripple/test/ManualTimeKeeper.h>
namespace ripple {
namespace test {
using namespace std::chrono_literals;
ManualTimeKeeper::ManualTimeKeeper()
: closeOffset_ {}
, now_ (0s)
{
}
void
ManualTimeKeeper::run (std::vector<std::string> const& servers)
{
}
auto
ManualTimeKeeper::now() const ->
time_point
{
std::lock_guard<std::mutex> lock(mutex_);
return now_;
}
auto
ManualTimeKeeper::closeTime() const ->
time_point
{
std::lock_guard<std::mutex> lock(mutex_);
return now_ + closeOffset_;
}
void
ManualTimeKeeper::adjustCloseTime(
std::chrono::duration<std::int32_t> amount)
{
// Copied from TimeKeeper::adjustCloseTime
using namespace std::chrono;
auto const s = amount.count();
std::lock_guard<std::mutex> lock(mutex_);
// Take large offsets, ignore small offsets,
// push the close time towards our wall time.
if (s > 1)
closeOffset_ += seconds((s + 3) / 4);
else if (s < -1)
closeOffset_ += seconds((s - 3) / 4);
else
closeOffset_ = (closeOffset_ * 3) / 4;
}
std::chrono::duration<std::int32_t>
ManualTimeKeeper::nowOffset() const
{
return {};
}
std::chrono::duration<std::int32_t>
ManualTimeKeeper::closeOffset() const
{
std::lock_guard<std::mutex> lock(mutex_);
return closeOffset_;
}
void
ManualTimeKeeper::set (time_point now)
{
std::lock_guard<std::mutex> lock(mutex_);
now_ = now;
}
auto
ManualTimeKeeper::adjust(
std::chrono::system_clock::time_point when) ->
time_point
{
return time_point(
std::chrono::duration_cast<duration>(
when.time_since_epoch() -
days(10957)));
}
} // test
} // ripple

View File

@@ -23,6 +23,8 @@
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/UintTypes.h>
#include <ripple/crypto/KeyType.h>
#include <beast/hash/uhash.h>
#include <unordered_map>
#include <string>
namespace ripple {
@@ -35,23 +37,18 @@ class IOU;
class Account
{
private:
std::string name_;
PublicKey pk_;
SecretKey sk_;
AccountID id_;
std::string human_; // base58 public key string
// Tag for access to private contr
struct privateCtorTag{};
public:
/** The master account. */
static Account const master;
Account() = default;
Account (Account&&) = default;
Account (Account const&) = default;
Account& operator= (Account const&) = default;
Account (Account&&) = default;
Account& operator= (Account&&) = default;
/** Create an account from a key pair. */
Account (std::string name,
std::pair<PublicKey, SecretKey> const& keys);
/** Create an account from a simple string name. */
/** @{ */
Account (std::string name,
@@ -62,6 +59,13 @@ public:
: Account(std::string(name), type)
{
}
// This constructor needs to be public so `std::pair` can use it when emplacing
// into the cache. However, it is logically `private`. This is enforced with the
// `privateTag` parameter.
Account (std::string name,
std::pair<PublicKey, SecretKey> const& keys, Account::privateCtorTag);
/** @} */
/** Return the name */
@@ -115,6 +119,21 @@ public:
/** Returns an IOU for the specified gateway currency. */
IOU
operator[](std::string const& s) const;
private:
static std::unordered_map<
std::pair<std::string, KeyType>,
Account, beast::uhash<>> cache_;
// Return the account from the cache & add it to the cache if needed
static Account fromCache(std::string name, KeyType type);
std::string name_;
PublicKey pk_;
SecretKey sk_;
AccountID id_;
std::string human_; // base58 public key string
};
inline

View File

@@ -25,9 +25,11 @@
#include <ripple/test/jtx/JTx.h>
#include <ripple/test/jtx/require.h>
#include <ripple/test/jtx/tags.h>
#include <ripple/test/ManualTimeKeeper.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/ledger/Ledger.h>
#include <ripple/app/ledger/OpenLedger.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/basics/chrono.h>
#include <ripple/basics/Log.h>
#include <ripple/core/Config.h>
@@ -49,67 +51,29 @@
namespace ripple {
namespace test {
extern
void
setupConfigForUnitTests (Config& config);
//------------------------------------------------------------------------------
namespace jtx {
namespace detail {
#ifdef _MSC_VER
// Workaround for C2797:
// list initialization inside member initializer
// list or non-static data member initializer is
// not implemented
//
template <std::size_t N>
struct noripple_helper
{
std::array<Account, N> args;
template <class T, class ...Args>
std::array<Account, sizeof...(Args)>
flatten (Args&& ...args)
{
return std::array<T,
sizeof...(Args)> {
std::forward<Args>(args)...};
}
template <class... Args>
explicit
noripple_helper(Args const&... args_)
: args(flatten<Account>(args_...))
{
}
};
#else
template <std::size_t N>
struct noripple_helper
{
std::array<Account, N> args;
template <class... Args>
explicit
noripple_helper(Args const&... args_)
: args { { args_... } }
{
}
};
#endif
} // detail
/** Designate accounts as no-ripple in Env::fund */
template <class... Args>
detail::noripple_helper<1 + sizeof...(Args)>
noripple (Account const& account,
Args const&... args)
std::array<Account, 1 + sizeof...(Args)>
noripple (Account const& account, Args const&... args)
{
return detail::noripple_helper<
1 + sizeof...(Args)>(
account, args...);
return {{account, args...}};
}
/** Activate features in the Env ctor */
template <class... Args>
std::array<uint256, 1 + sizeof...(Args)>
features (uint256 const& key, Args const&... args)
{
return {{key, args...}};
}
//------------------------------------------------------------------------------
@@ -118,16 +82,11 @@ noripple (Account const& account,
class Env
{
public:
using clock_type = TestNetClock;
clock_type clock;
beast::unit_test::suite& test;
beast::Journal const journal;
/** The master account. */
Account const master;
Account const& master = Account::master;
private:
struct AppBundle
@@ -135,27 +94,70 @@ private:
Application* app;
std::unique_ptr<Logs> logs;
std::unique_ptr<Application> owned;
ManualTimeKeeper* timeKeeper;
std::thread thread;
AppBundle (std::unique_ptr<Config const> config);
AppBundle (std::unique_ptr<Config> config);
AppBundle (Application* app_);
~AppBundle();
};
AppBundle bundle_;
std::shared_ptr<Ledger const> closed_;
CachedSLEs cachedSLEs_;
LogSquelcher logSquelcher_;
public:
// Careful with this
OpenLedger openLedger;
inline
void
construct()
{
}
template <class Arg, class... Args>
void
construct (Arg&& arg, Args&&... args)
{
construct_arg(std::forward<Arg>(arg));
construct(std::forward<Args>(args)...);
}
template<std::size_t N>
void
construct_arg (
std::array<uint256, N> const& list)
{
for(auto const& key : list)
app().config().features.insert(key);
}
public:
Env() = delete;
Env (Env const&) = delete;
Env& operator= (Env const&) = delete;
// VFALCO Could wrap the suite::log in a Journal here
template <class... Args>
Env (beast::unit_test::suite& test_,
std::unique_ptr<Config const> config);
Env (beast::unit_test::suite& test_);
std::unique_ptr<Config> config,
Args&&... args)
: test (test_)
, bundle_ (std::move(config))
{
memoize(Account::master);
Pathfinder::initPathTable();
construct(std::forward<Args>(args)...);
}
template <class... Args>
Env (beast::unit_test::suite& test_,
Args&&... args)
: Env(test_, []()
{
auto p = std::make_unique<Config>();
setupConfigForUnitTests(*p);
return p;
}(), std::forward<Args>(args)...)
{
}
Application&
app()
@@ -163,7 +165,24 @@ public:
return *bundle_.app;
}
/** Returns the open ledger.
Application const&
app() const
{
return *bundle_.app;
}
/** Returns the current Ripple Network Time
@note This is manually advanced when ledgers
close or by callers.
*/
NetClock::time_point
now()
{
return app().timeKeeper().now();
}
/** Returns the current ledger.
This is a non-modifiable snapshot of the
open ledger at the moment of the call.
@@ -172,7 +191,10 @@ public:
*/
std::shared_ptr<OpenView const>
open() const;
current() const
{
return app().openLedger().current();
}
/** Returns the last closed ledger.
@@ -182,10 +204,14 @@ public:
and a new open ledger takes its place.
*/
std::shared_ptr<ReadView const>
closed() const;
closed();
/** Close and advance the ledger.
The resulting close time will be different and
greater than the previous close time, and at or
after the passed-in close time.
Effects:
Creates a new closed ledger from the last
@@ -194,11 +220,11 @@ public:
All transactions that made it into the open
ledger are applied to the closed ledger.
The Env clock is set to the new time.
The Application network time is set to
the close time of the resulting ledger.
*/
void
close (NetClock::time_point const& closeTime,
OpenLedger::modify_type const& f = {});
close (NetClock::time_point closeTime);
/** Close and advance the ledger.
@@ -208,11 +234,10 @@ public:
template <class Rep, class Period>
void
close (std::chrono::duration<
Rep, Period> const& elapsed,
OpenLedger::modify_type const& f = {})
Rep, Period> const& elapsed)
{
stopwatch_.advance(elapsed);
close (clock.now() + elapsed, f);
// VFALCO Is this the correct time?
close (now() + elapsed);
}
/** Close and advance the ledger.
@@ -221,9 +246,10 @@ public:
the previous ledger closing time.
*/
void
close(OpenLedger::modify_type const& f = {})
close()
{
close (std::chrono::seconds(5), f);
// VFALCO Is this the correct time?
close (std::chrono::seconds(5));
}
/** Turn on JSON tracing.
@@ -417,9 +443,9 @@ private:
template <std::size_t N>
void
fund_arg (STAmount const& amount,
detail::noripple_helper<N> const& list)
std::array<Account, N> const& list)
{
for (auto const& account : list.args)
for (auto const& account : list)
fund (false, amount, account);
}
public:

View File

@@ -26,8 +26,16 @@ namespace ripple {
namespace test {
namespace jtx {
std::unordered_map<
std::pair<std::string, KeyType>,
Account, beast::uhash<>> Account::cache_;
Account const Account::master("master",
generateKeyPair(KeyType::secp256k1,
generateSeed("masterpassphrase")), Account::privateCtorTag{});
Account::Account(std::string name,
std::pair<PublicKey, SecretKey> const& keys)
std::pair<PublicKey, SecretKey> const& keys, Account::privateCtorTag)
: name_(std::move(name))
, pk_ (keys.first)
, sk_ (keys.second)
@@ -36,15 +44,23 @@ Account::Account(std::string name,
{
}
Account::Account (std::string name, KeyType type)
: name_(std::move(name))
Account Account::fromCache(std::string name, KeyType type)
{
auto const p = std::make_pair (name, type);
auto const iter = cache_.find (p);
if (iter != cache_.end ())
return iter->second;
auto const keys = generateKeyPair (type, generateSeed (name));
auto r = cache_.emplace (std::piecewise_construct,
std::forward_as_tuple (std::move (p)),
std::forward_as_tuple (std::move (name), keys, privateCtorTag{}));
return r.first->second;
}
Account::Account (std::string name, KeyType type)
: Account (fromCache (std::move (name), type))
{
auto const keys = generateKeyPair(
type, generateSeed(name_));
pk_ = keys.first;
sk_ = keys.second;
id_ = calcAccountID(pk_);
human_ = toBase58(id_);
}
IOU

View File

@@ -29,10 +29,12 @@
#include <ripple/test/jtx/sig.h>
#include <ripple/test/jtx/utility.h>
#include <ripple/app/tx/apply.h>
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/ledger/LedgerTiming.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Slice.h>
#include <ripple/core/ConfigSections.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/HashPrefix.h>
@@ -50,6 +52,29 @@
namespace ripple {
namespace test {
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");
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");
}
//------------------------------------------------------------------------------
namespace jtx {
Env::AppBundle::AppBundle(Application* app_)
@@ -57,90 +82,45 @@ Env::AppBundle::AppBundle(Application* app_)
{
}
Env::AppBundle::AppBundle(std::unique_ptr<Config const> config)
Env::AppBundle::AppBundle(std::unique_ptr<Config> config)
{
auto logs = std::make_unique<Logs>();
owned = make_Application(
std::move(config), std::move(logs));
auto timeKeeper_ =
std::make_unique<ManualTimeKeeper>();
timeKeeper = timeKeeper_.get();
owned = make_Application(std::move(config),
std::move(logs), std::move(timeKeeper_));
app = owned.get();
app->setup();
timeKeeper->set(
app->getLedgerMaster().getClosedLedger()->info().closeTime);
thread = std::thread(
[&](){ app->run(); });
}
Env::AppBundle::~AppBundle()
{
app->signalStop();
thread.join();
}
//------------------------------------------------------------------------------
static
std::unique_ptr<Config const>
makeConfig()
{
auto p = std::make_unique<Config>();
setupConfigForUnitTests(*p);
return std::unique_ptr<Config const>(p.release());
}
// VFALCO Could wrap the log in a Journal here
Env::Env(beast::unit_test::suite& test_,
std::unique_ptr<Config const> config)
: test (test_)
, master ("master", generateKeyPair(
KeyType::secp256k1,
generateSeed("masterpassphrase")))
, bundle_ (std::move(config))
, closed_ (std::make_shared<Ledger>(
create_genesis, app().config(), app().family()))
, cachedSLEs_ (std::chrono::seconds(5), stopwatch_)
, openLedger (closed_, cachedSLEs_, journal)
{
memoize(master);
Pathfinder::initPathTable();
}
Env::Env(beast::unit_test::suite& test_)
: Env(test_, makeConfig())
{
}
std::shared_ptr<OpenView const>
Env::open() const
{
return openLedger.current();
}
std::shared_ptr<ReadView const>
Env::closed() const
Env::closed()
{
return closed_;
return app().getLedgerMaster().getClosedLedger();
}
void
Env::close(NetClock::time_point const& closeTime,
OpenLedger::modify_type const& f)
Env::close(NetClock::time_point closeTime)
{
clock.set(closeTime);
// VFALCO TODO Fix the Ledger constructor
auto next = std::make_shared<Ledger>(
open_ledger, *closed_,
app().timeKeeper().closeTime());
next->setClosed();
std::vector<std::shared_ptr<STTx const>> txs;
auto cur = openLedger.current();
for (auto iter = cur->txs.begin();
iter != cur->txs.end(); ++iter)
txs.push_back(iter->first);
OrderedTxs retries(uint256{});
{
OpenView accum(&*next);
OpenLedger::apply(app(), accum, *closed_,
txs, retries, applyFlags(), journal);
accum.apply(*next);
}
// To ensure that the close time is exact and not rounded, we don't
// claim to have reached consensus on what it should be.
next->setAccepted(closeTime, ledgerPossibleTimeResolutions[0],
false, app().config());
OrderedTxs locals({});
openLedger.accept(app(), next->rules(), next,
locals, false, retries, applyFlags(), "", f);
closed_ = next;
cachedSLEs_.expire();
// Round up to next distinguishable value
closeTime += closed()->info().closeTimeResolution - 1s;
bundle_.timeKeeper->set(closeTime);
app().getOPs().acceptLedger();
bundle_.timeKeeper->set(
closed()->info().closeTime);
}
void
@@ -219,7 +199,7 @@ Env::le (Account const& account) const
std::shared_ptr<SLE const>
Env::le (Keylet const& k) const
{
return open()->read(k);
return current()->read(k);
}
void
@@ -232,7 +212,7 @@ Env::fund (bool setDefaultRipple,
{
// VFALCO NOTE Is the fee formula correct?
apply(pay(master, account, amount +
drops(open()->fees().base)),
drops(current()->fees().base)),
jtx::seq(jtx::autofill),
fee(jtx::autofill),
sig(jtx::autofill));
@@ -263,7 +243,7 @@ Env::trust (STAmount const& amount,
fee(jtx::autofill),
sig(jtx::autofill));
apply(pay(master, account,
drops(open()->fees().base)),
drops(current()->fees().base)),
jtx::seq(jtx::autofill),
fee(jtx::autofill),
sig(jtx::autofill));
@@ -277,7 +257,7 @@ Env::submit (JTx const& jt)
if (jt.stx)
{
txid_ = jt.stx->getTransactionID();
openLedger.modify(
app().openLedger().modify(
[&](OpenView& view, beast::Journal j)
{
std::tie(ter_, didApply) = ripple::apply(
@@ -357,9 +337,9 @@ Env::autofill (JTx& jt)
{
auto& jv = jt.jv;
if(jt.fill_fee)
jtx::fill_fee(jv, *open());
jtx::fill_fee(jv, *current());
if(jt.fill_seq)
jtx::fill_seq(jv, *open());
jtx::fill_seq(jv, *current());
// Must come last
try
{

View File

@@ -516,14 +516,14 @@ public:
{
using namespace jtx;
Env env(*this);
auto seq = env.open()->seq();
auto seq = env.current()->seq();
expect(seq == env.closed()->seq() + 1);
env.close();
expect(env.closed()->seq() == seq);
expect(env.open()->seq() == seq + 1);
expect(env.current()->seq() == seq + 1);
env.close();
expect(env.closed()->seq() == seq + 1);
expect(env.open()->seq() == seq + 2);
expect(env.current()->seq() == seq + 2);
}
void
@@ -568,7 +568,7 @@ public:
Env env(*this);
env.fund(XRP(10000), "alice");
auto const baseFee = env.open()->fees().base;
auto const baseFee = env.current()->fees().base;
std::uint32_t const aliceSeq = env.seq ("alice");
// Sign jsonNoop.

View File

@@ -48,7 +48,7 @@ owned_count_helper(Env& env,
std::uint32_t value)
{
env.test.expect(owned_count_of(
*env.open(), id, type) == value);
*env.current(), id, type) == value);
}
} // detail

View File

@@ -37,7 +37,7 @@ paths::operator()(Env& env, JTx& jt) const
auto const amount = amountFromJson(
sfAmount, jv[jss::Amount]);
Pathfinder pf (
std::make_shared<RippleLineCache>(env.open()),
std::make_shared<RippleLineCache>(env.current()),
from, to, in_.currency, in_.account,
amount, boost::none, env.app());
if (! pf.findPaths(depth_))

View File

@@ -52,8 +52,7 @@ sign (Json::Value& jv,
ss.add32 (HashPrefix::txSign);
parse(jv).addWithoutSigningFields(ss);
auto const sig = ripple::sign(
*publicKeyType(account.pk().slice()),
account.sk(), ss.slice());
account.pk(), account.sk(), ss.slice());
jv[jss::TxnSignature] =
strHex(Slice{ sig.data(), sig.size() });
}

View File

@@ -20,6 +20,8 @@
#include <BeastConfig.h>
#include <ripple/basics/Log.h>
#include <ripple/test/mao/Net.h>
#include <ripple/test/jtx.h>
#include <ripple/test/ManualTimeKeeper.h>
#include <ripple/net/HTTPClient.h>
#include <ripple/net/RPCCall.h>
#include <beast/unit_test/suite.h>
@@ -38,21 +40,13 @@ struct TestApp
{
auto config = std::make_unique<Config>();
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<Logs>();
instance = make_Application(
std::move(config), std::move(logs));
auto timeKeeper = std::make_unique<ManualTimeKeeper>();
timeKeeper_ = timeKeeper.get();
instance = make_Application(std::move(config),
std::move(logs), std::move(timeKeeper));
instance->setup();
thread_ = std::thread(
[&]() { instance->run(); });
@@ -106,6 +100,7 @@ private:
collect(v, args...);
}
ManualTimeKeeper* timeKeeper_;
std::unique_ptr<Application> instance;
std::thread thread_;
std::mutex mutex_;

View File

@@ -48,3 +48,4 @@
#include <ripple/test/mao/impl/Net.cpp>
#include <ripple/test/mao/impl/Net_test.cpp>
#include <ripple/test/impl/ManualTimeKeeper.cpp>