From eafa6f960f47d75778b815cd6b1c637357f642ef Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Wed, 19 Nov 2014 14:04:36 -0500 Subject: [PATCH] API for improved Unit Testing (RIPD-432): * Added new test APIs allowing easy ways to create ledgers, apply transactions to them, close and advance them. * Moved Ledger tests from Ledger.cpp to Ledger.test.cpp. * Changed several TransactionEngine log priorities from lsINFO to lsDEBUG to reduce unnecessary verbosity in the log messages while running these tests. * Moved LedgerConsensus:applyTransactions from a private member function to a free function so that it could be accessed externally, and without having to reference a LedgerConsensus object. This was done to facilitate the new testing API. --- Builds/VisualStudio2013/RippleD.vcxproj | 3 + .../VisualStudio2013/RippleD.vcxproj.filters | 3 + src/ripple/app/consensus/LedgerConsensus.cpp | 337 +++++++++--------- src/ripple/app/consensus/LedgerConsensus.h | 6 + src/ripple/app/ledger/Ledger.cpp | 37 -- src/ripple/app/ledger/Ledger.test.cpp | 318 +++++++++++++++++ src/ripple/app/tx/TransactionEngine.cpp | 10 +- src/ripple/unity/app3.cpp | 1 + 8 files changed, 505 insertions(+), 210 deletions(-) create mode 100644 src/ripple/app/ledger/Ledger.test.cpp diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index 5a8bd7980..5a479f379 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -1730,6 +1730,9 @@ + + True + True diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index 9a9a59cb1..bb96d05e1 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -2586,6 +2586,9 @@ ripple\app\ledger + + ripple\app\ledger + ripple\app\ledger diff --git a/src/ripple/app/consensus/LedgerConsensus.cpp b/src/ripple/app/consensus/LedgerConsensus.cpp index 46e35c756..83e1dadb4 100644 --- a/src/ripple/app/consensus/LedgerConsensus.cpp +++ b/src/ripple/app/consensus/LedgerConsensus.cpp @@ -1452,174 +1452,6 @@ private: msg, protocol::mtHAVE_SET))); } - /** Apply a set of transactions to a ledger - - @param set The set of transactions to apply - @param applyLedger The ledger to which the transactions should - be applied. - @param checkLedger A reference ledger for determining error - messages (typically new last closed ledger). - @param retriableTransactions collect failed transactions in this set - @param openLgr true if applyLedger is open, else false. - */ - void applyTransactions (SHAMap::ref set, Ledger::ref applyLedger, - Ledger::ref checkLedger, CanonicalTXSet& retriableTransactions, - bool openLgr) - { - TransactionEngine engine (applyLedger); - - if (set) - { - for (SHAMapItem::pointer item = set->peekFirstItem (); !!item; - item = set->peekNextItem (item->getTag ())) - { - // If the checkLedger doesn't have the transaction - if (!checkLedger->hasTransaction (item->getTag ())) - { - // Then try to apply the transaction to applyLedger - WriteLog (lsINFO, LedgerConsensus) << - "Processing candidate transaction: " << item->getTag (); - try - { - SerializerIterator sit (item->peekSerializer ()); - STTx::pointer txn - = std::make_shared(sit); - if (applyTransaction (engine, txn, - openLgr, true) == resultRetry) - { - // On failure, stash the failed transaction for - // later retry. - retriableTransactions.push_back (txn); - } - } - catch (...) - { - WriteLog (lsWARNING, LedgerConsensus) << " Throws"; - } - } - } - } - - int changes; - bool certainRetry = true; - // Attempt to apply all of the retriable transactions - for (int pass = 0; pass < LEDGER_TOTAL_PASSES; ++pass) - { - WriteLog (lsDEBUG, LedgerConsensus) << "Pass: " << pass << " Txns: " - << retriableTransactions.size () - << (certainRetry ? " retriable" : " final"); - changes = 0; - - auto it = retriableTransactions.begin (); - - while (it != retriableTransactions.end ()) - { - try - { - switch (applyTransaction (engine, it->second, - openLgr, certainRetry)) - { - case resultSuccess: - it = retriableTransactions.erase (it); - ++changes; - break; - - case resultFail: - it = retriableTransactions.erase (it); - break; - - case resultRetry: - ++it; - } - } - catch (...) - { - WriteLog (lsWARNING, LedgerConsensus) - << "Transaction throws"; - it = retriableTransactions.erase (it); - } - } - - WriteLog (lsDEBUG, LedgerConsensus) << "Pass: " - << pass << " finished " << changes << " changes"; - - // A non-retry pass made no changes - if (!changes && !certainRetry) - return; - - // Stop retriable passes - if ((!changes) || (pass >= LEDGER_RETRY_PASSES)) - certainRetry = false; - } - - // If there are any transactions left, we must have - // tried them in at least one final pass - assert (retriableTransactions.empty() || !certainRetry); - } - - /** Apply a transaction to a ledger - - @param engine The transaction engine containing the ledger. - @param txn The transaction to be applied to ledger. - @param openLedger true if ledger is open - @param retryAssured true if the transaction should be retried on failure. - @return One of resultSuccess, resultFail or resultRetry. - */ - int applyTransaction (TransactionEngine& engine - , STTx::ref txn, bool openLedger, bool retryAssured) - { - // Returns false if the transaction has need not be retried. - TransactionEngineParams parms = openLedger ? tapOPEN_LEDGER : tapNONE; - - if (retryAssured) - { - parms = static_cast (parms | tapRETRY); - } - - if (getApp().getHashRouter ().setFlag (txn->getTransactionID () - , SF_SIGGOOD)) - { - parms = static_cast - (parms | tapNO_CHECK_SIGN); - } - WriteLog (lsDEBUG, LedgerConsensus) << "TXN " - << txn->getTransactionID () - << (openLedger ? " open" : " closed") - << (retryAssured ? "/retry" : "/final"); - WriteLog (lsTRACE, LedgerConsensus) << txn->getJson (0); - - try - { - bool didApply; - TER result = engine.applyTransaction (*txn, parms, didApply); - - if (didApply) - { - WriteLog (lsDEBUG, LedgerConsensus) - << "Transaction success: " << transHuman (result); - return resultSuccess; - } - - if (isTefFailure (result) || isTemMalformed (result) || - isTelLocal (result)) - { - // failure - WriteLog (lsDEBUG, LedgerConsensus) - << "Transaction failure: " << transHuman (result); - return resultFail; - } - - WriteLog (lsDEBUG, LedgerConsensus) - << "Transaction retry: " << transHuman (result); - return resultRetry; - } - catch (...) - { - WriteLog (lsWARNING, LedgerConsensus) << "Throws"; - return resultFail; - } - } - /** Round the close time to the close time resolution. @@ -2164,4 +1996,173 @@ make_LedgerConsensus (LedgerConsensus::clock_type& clock, LocalTxs& localtx, prevLCLHash, previousLedger, closeTime, feeVote); } +/** Apply a transaction to a ledger + + @param engine The transaction engine containing the ledger. + @param txn The transaction to be applied to ledger. + @param openLedger true if ledger is open + @param retryAssured true if the transaction should be retried on failure. + @return One of resultSuccess, resultFail or resultRetry. +*/ +static +int applyTransaction (TransactionEngine& engine + , STTx::ref txn, bool openLedger, bool retryAssured) +{ + // Returns false if the transaction has need not be retried. + TransactionEngineParams parms = openLedger ? tapOPEN_LEDGER : tapNONE; + + if (retryAssured) + { + parms = static_cast (parms | tapRETRY); + } + + if (getApp().getHashRouter ().setFlag (txn->getTransactionID () + , SF_SIGGOOD)) + { + parms = static_cast + (parms | tapNO_CHECK_SIGN); + } + WriteLog (lsDEBUG, LedgerConsensus) << "TXN " + << txn->getTransactionID () + << (openLedger ? " open" : " closed") + << (retryAssured ? "/retry" : "/final"); + WriteLog (lsTRACE, LedgerConsensus) << txn->getJson (0); + + try + { + bool didApply; + TER result = engine.applyTransaction (*txn, parms, didApply); + + if (didApply) + { + WriteLog (lsDEBUG, LedgerConsensus) + << "Transaction success: " << transHuman (result); + return LedgerConsensusImp::resultSuccess; + } + + if (isTefFailure (result) || isTemMalformed (result) || + isTelLocal (result)) + { + // failure + WriteLog (lsDEBUG, LedgerConsensus) + << "Transaction failure: " << transHuman (result); + return LedgerConsensusImp::resultFail; + } + + WriteLog (lsDEBUG, LedgerConsensus) + << "Transaction retry: " << transHuman (result); + return LedgerConsensusImp::resultRetry; + } + catch (...) + { + WriteLog (lsWARNING, LedgerConsensus) << "Throws"; + return LedgerConsensusImp::resultFail; + } +} + +/** Apply a set of transactions to a ledger + + @param set The set of transactions to apply + @param applyLedger The ledger to which the transactions should + be applied. + @param checkLedger A reference ledger for determining error + messages (typically new last closed ledger). + @param retriableTransactions collect failed transactions in this set + @param openLgr true if applyLedger is open, else false. +*/ +void applyTransactions (SHAMap::ref set, Ledger::ref applyLedger, + Ledger::ref checkLedger, CanonicalTXSet& retriableTransactions, + bool openLgr) +{ + TransactionEngine engine (applyLedger); + + if (set) + { + for (SHAMapItem::pointer item = set->peekFirstItem (); !!item; + item = set->peekNextItem (item->getTag ())) + { + // If the checkLedger doesn't have the transaction + if (!checkLedger->hasTransaction (item->getTag ())) + { + // Then try to apply the transaction to applyLedger + WriteLog (lsINFO, LedgerConsensus) << + "Processing candidate transaction: " << item->getTag (); + try + { + SerializerIterator sit (item->peekSerializer ()); + STTx::pointer txn + = std::make_shared(sit); + if (applyTransaction (engine, txn, + openLgr, true) == LedgerConsensusImp::resultRetry) + { + // On failure, stash the failed transaction for + // later retry. + retriableTransactions.push_back (txn); + } + } + catch (...) + { + WriteLog (lsWARNING, LedgerConsensus) << " Throws"; + } + } + } + } + + int changes; + bool certainRetry = true; + // Attempt to apply all of the retriable transactions + for (int pass = 0; pass < LEDGER_TOTAL_PASSES; ++pass) + { + WriteLog (lsDEBUG, LedgerConsensus) << "Pass: " << pass << " Txns: " + << retriableTransactions.size () + << (certainRetry ? " retriable" : " final"); + changes = 0; + + auto it = retriableTransactions.begin (); + + while (it != retriableTransactions.end ()) + { + try + { + switch (applyTransaction (engine, it->second, + openLgr, certainRetry)) + { + case LedgerConsensusImp::resultSuccess: + it = retriableTransactions.erase (it); + ++changes; + break; + + case LedgerConsensusImp::resultFail: + it = retriableTransactions.erase (it); + break; + + case LedgerConsensusImp::resultRetry: + ++it; + } + } + catch (...) + { + WriteLog (lsWARNING, LedgerConsensus) + << "Transaction throws"; + it = retriableTransactions.erase (it); + } + } + + WriteLog (lsDEBUG, LedgerConsensus) << "Pass: " + << pass << " finished " << changes << " changes"; + + // A non-retry pass made no changes + if (!changes && !certainRetry) + return; + + // Stop retriable passes + if ((!changes) || (pass >= LEDGER_RETRY_PASSES)) + certainRetry = false; + } + + // If there are any transactions left, we must have + // tried them in at least one final pass + assert (retriableTransactions.empty() || !certainRetry); +} + } // ripple diff --git a/src/ripple/app/consensus/LedgerConsensus.h b/src/ripple/app/consensus/LedgerConsensus.h index 100e72e3e..b009bac7b 100644 --- a/src/ripple/app/consensus/LedgerConsensus.h +++ b/src/ripple/app/consensus/LedgerConsensus.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -95,6 +96,11 @@ make_LedgerConsensus (LedgerConsensus::clock_type& clock, LocalTxs& localtx, LedgerHash const & prevLCLHash, Ledger::ref previousLedger, std::uint32_t closeTime, FeeVote& feeVote); +void +applyTransactions(SHAMap::ref set, Ledger::ref applyLedger, + Ledger::ref checkLedger, + CanonicalTXSet& retriableTransactions, bool openLgr); + } // ripple #endif diff --git a/src/ripple/app/ledger/Ledger.cpp b/src/ripple/app/ledger/Ledger.cpp index 13bb0d325..f6b91cbb2 100644 --- a/src/ripple/app/ledger/Ledger.cpp +++ b/src/ripple/app/ledger/Ledger.cpp @@ -1899,43 +1899,6 @@ std::vector Ledger::getNeededAccountStateHashes ( return ret; } -//------------------------------------------------------------------------------ - -class Ledger_test : public beast::unit_test::suite -{ - void test_genesis_ledger () - { - RippleAddress rootSeedMaster - = RippleAddress::createSeedGeneric ("masterpassphrase"); - RippleAddress rootGeneratorMaster - = RippleAddress::createGeneratorPublic (rootSeedMaster); - RippleAddress rootAddress - = RippleAddress::createAccountPublic (rootGeneratorMaster, 0); - std::uint64_t startAmount (100000); - Ledger::pointer ledger (std::make_shared ( - rootAddress, startAmount)); - ledger->updateHash(); - expect(ledger->assertSane()); - } - - void test_getQuality () - { - uint256 uBig ( - "D2DC44E5DC189318DB36EF87D2104CDF0A0FE3A4B698BEEE55038D7EA4C68000"); - - // VFALCO NOTE This fails in the original version as well. - expect (6125895493223874560 == getQuality (uBig)); - } -public: - void run () - { - test_genesis_ledger (); - test_getQuality (); - } -}; - -BEAST_DEFINE_TESTSUITE(Ledger,ripple_app,ripple); - Ledger::StaticLockType Ledger::sPendingSaveLock; std::set Ledger::sPendingSaves; diff --git a/src/ripple/app/ledger/Ledger.test.cpp b/src/ripple/app/ledger/Ledger.test.cpp new file mode 100644 index 000000000..06a76b1e3 --- /dev/null +++ b/src/ripple/app/ledger/Ledger.test.cpp @@ -0,0 +1,318 @@ +//------------------------------------------------------------------------------ +/* + 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 + +namespace ripple { + +class Ledger_test : public beast::unit_test::suite +{ + using TestAccount = std::pair; + + struct Amount + { + double value; + std::string currency; + TestAccount issuer; + + Json::Value + getJson() const + { + Json::Value tx_json; + tx_json["currency"] = currency; + tx_json["issuer"] = issuer.first.humanAccountID(); + tx_json["value"] = std::to_string(value); + return tx_json; + } + }; + + // Helper function to parse a transaction in Json, sign it with account, + // and return it as a STTx + STTx + parseTransaction(TestAccount& account, Json::Value const& tx_json) + { + STParsedJSONObject parsed("tx_json", tx_json); + std::unique_ptr sopTrans = std::move(parsed.object); + expect(sopTrans != nullptr); + sopTrans->setFieldVL(sfSigningPubKey, account.first.getAccountPublic()); + return STTx{*sopTrans}; + } + + // Helper function to apply a transaction to a ledger + void + applyTransaction(Ledger::pointer const& ledger, STTx const& tx) + { + TransactionEngine engine(ledger); + bool didApply = false; + auto r = engine.applyTransaction(tx, tapOPEN_LEDGER | tapNO_CHECK_SIGN, + didApply); + expect(r == tesSUCCESS); + expect(didApply); + } + + // Create genesis ledger from a start amount in drops, and the public + // master RippleAddress + Ledger::pointer + createGenesisLedger(std::uint64_t start_amount_drops, TestAccount const& master) + { + Ledger::pointer ledger = std::make_shared(master.first, + start_amount_drops); + ledger->updateHash(); + ledger->setClosed(); + expect(ledger->assertSane()); + return ledger; + } + + // Create an account represented by public RippleAddress and private + // RippleAddress + TestAccount + createAccount() + { + static RippleAddress const seed + = RippleAddress::createSeedGeneric ("masterpassphrase"); + static RippleAddress const generator + = RippleAddress::createGeneratorPublic (seed); + static int iSeq = -1; + ++iSeq; + return std::make_pair(RippleAddress::createAccountPublic(generator, iSeq), + std::uint64_t(0)); + } + + void + freezeAccount(TestAccount& account, Ledger::pointer const& ledger) + { + Json::Value tx_json; + tx_json["TransactionType"] = "AccountSet"; + tx_json["Fee"] = std::to_string(10); + tx_json["Account"] = account.first.humanAccountID(); + tx_json["SetFlag"] = asfGlobalFreeze; + tx_json["Sequence"] = ++account.second; + STTx tx = parseTransaction(account, tx_json); + applyTransaction(ledger, tx); + } + + void + unfreezeAccount(TestAccount& account, Ledger::pointer const& ledger) + { + Json::Value tx_json; + tx_json["TransactionType"] = "AccountSet"; + tx_json["Fee"] = std::to_string(10); + tx_json["Account"] = account.first.humanAccountID(); + tx_json["ClearFlag"] = asfGlobalFreeze; + tx_json["Sequence"] = ++account.second; + STTx tx = parseTransaction(account, tx_json); + applyTransaction(ledger, tx); + } + + void + makePayment(TestAccount& from, TestAccount const& to, + std::uint64_t amountDrops, + Ledger::pointer const& ledger) + { + Json::Value tx_json; + tx_json["Account"] = from.first.humanAccountID(); + tx_json["Amount"] = std::to_string(amountDrops); + tx_json["Destination"] = to.first.humanAccountID(); + tx_json["TransactionType"] = "Payment"; + tx_json["Fee"] = std::to_string(10); + tx_json["Sequence"] = ++from.second; + tx_json["Flags"] = tfUniversal; + STTx tx = parseTransaction(from, tx_json); + applyTransaction(ledger, tx); + } + + void + makePayment(TestAccount& from, TestAccount const& to, + std::string const& currency, std::string const& amount, + Ledger::pointer const& ledger) + { + Json::Value tx_json; + tx_json["Account"] = from.first.humanAccountID(); + tx_json["Amount"] = Amount{std::stod(amount), currency, to}.getJson(); + tx_json["Destination"] = to.first.humanAccountID(); + tx_json["TransactionType"] = "Payment"; + tx_json["Fee"] = std::to_string(10); + tx_json["Sequence"] = ++from.second; + tx_json["Flags"] = tfUniversal; + STTx tx = parseTransaction(from, tx_json); + applyTransaction(ledger, tx); + } + + void + createOffer(TestAccount& from, Amount const& in, Amount const& out, + Ledger::pointer ledger) + { + Json::Value tx_json; + tx_json["TransactionType"] = "OfferCreate"; + tx_json["Fee"] = std::to_string(10); + tx_json["Account"] = from.first.humanAccountID(); + tx_json["TakerPays"] = in.getJson(); + tx_json["TakerGets"] = out.getJson(); + tx_json["Sequence"] = ++from.second; + STTx tx = parseTransaction(from, tx_json); + applyTransaction(ledger, tx); + } + + // As currently implemented, this will cancel only the last offer made + // from this account. + void + cancelOffer(TestAccount& from, Ledger::pointer ledger) + { + Json::Value tx_json; + tx_json["TransactionType"] = "OfferCancel"; + tx_json["Fee"] = std::to_string(10); + tx_json["Account"] = from.first.humanAccountID(); + tx_json["OfferSequence"] = from.second; + tx_json["Sequence"] = ++from.second; + STTx tx = parseTransaction(from, tx_json); + applyTransaction(ledger, tx); + } + + void + makeTrustSet(TestAccount& from, TestAccount const& issuer, + std::string const& currency, double amount, + Ledger::pointer const& ledger) + { + Json::Value tx_json; + tx_json["Account"] = from.first.humanAccountID(); + Json::Value& limitAmount = tx_json["LimitAmount"]; + limitAmount["currency"] = currency; + limitAmount["issuer"] = issuer.first.humanAccountID(); + limitAmount["value"] = std::to_string(amount); + tx_json["TransactionType"] = "TrustSet"; + tx_json["Fee"] = std::to_string(10); + tx_json["Sequence"] = ++from.second; + tx_json["Flags"] = tfClearNoRipple; + STTx tx = parseTransaction(from, tx_json); + applyTransaction(ledger, tx); + } + + Ledger::pointer + close_and_advance(Ledger::pointer ledger, Ledger::pointer LCL) + { + SHAMap::pointer set = ledger->peekTransactionMap(); + CanonicalTXSet retriableTransactions{set->getHash()}; + Ledger::pointer newLCL = std::make_shared(false, *LCL); + // Set up to write SHAMap changes to our database, + // perform updates, extract changes + applyTransactions(set, newLCL, newLCL, retriableTransactions, false); + newLCL->updateSkipList(); + newLCL->setClosed(); + int asf = newLCL->peekAccountStateMap()->flushDirty(hotACCOUNT_NODE, + newLCL->getLedgerSeq()); + int tmf = newLCL->peekTransactionMap()->flushDirty(hotTRANSACTION_NODE, + newLCL->getLedgerSeq()); + using namespace std::chrono; + auto const epoch_offset = days{10957}; // 2000-01-01 + std::uint32_t closeTime = time_point_cast // now + (system_clock::now()-epoch_offset). + time_since_epoch().count(); + int CloseResolution = seconds{LEDGER_TIME_ACCURACY}.count(); + bool closeTimeCorrect = true; + newLCL->setAccepted(closeTime, CloseResolution, closeTimeCorrect); + return newLCL; + } + + void test_genesisLedger () + { + std::uint64_t const xrp = std::mega::num; + + // Create master account + auto master = createAccount(); + + // Create genesis ledger + Ledger::pointer LCL = createGenesisLedger(100000*xrp, master); + + // Create open scratch ledger + Ledger::pointer ledger = std::make_shared(false, *LCL); + + // Create user accounts + auto gw1 = createAccount(); + auto gw2 = createAccount(); + auto gw3 = createAccount(); + auto alice = createAccount(); + auto mark = createAccount(); + + // Fund gw1, gw2, gw3, alice, mark from master + makePayment(master, gw1, 5000*xrp, ledger); + makePayment(master, gw2, 4000*xrp, ledger); + makePayment(master, gw3, 3000*xrp, ledger); + makePayment(master, alice, 2000*xrp, ledger); + makePayment(master, mark, 1000*xrp, ledger); + + LCL = close_and_advance(ledger, LCL); + ledger = std::make_shared(false, *LCL); + + // alice trusts FOO/gw1 + makeTrustSet(alice, gw1, "FOO", 1, ledger); + + // mark trusts FOO/gw2 + makeTrustSet(mark, gw2, "FOO", 1, ledger); + + // mark trusts FOO/gw3 + makeTrustSet(mark, gw3, "FOO", 1, ledger); + + // gw2 pays mark with FOO + makePayment(gw2, mark, "FOO", ".1", ledger); + + // gw3 pays mark with FOO + makePayment(gw3, mark, "FOO", ".2", ledger); + + // gw1 pays alice with FOO + makePayment(gw1, alice, "FOO", ".3", ledger); + + LCL = close_and_advance(ledger, LCL); + ledger = std::make_shared(false, *LCL); + + createOffer(mark, Amount{1, "FOO", gw1}, Amount{1, "FOO", gw2}, ledger); + createOffer(mark, Amount{1, "FOO", gw2}, Amount{1, "FOO", gw3}, ledger); + cancelOffer(mark, ledger); + freezeAccount(alice, ledger); + + LCL = close_and_advance(ledger, LCL); + ledger = std::make_shared(false, *LCL); + + makePayment(alice, mark, 1*xrp, ledger); + + LCL = close_and_advance(ledger, LCL); + ledger = std::make_shared(false, *LCL); + } + + void test_getQuality () + { + uint256 uBig ( + "D2DC44E5DC189318DB36EF87D2104CDF0A0FE3A4B698BEEE55038D7EA4C68000"); + expect (6125895493223874560 == getQuality (uBig)); + } +public: + void run () + { + test_genesisLedger (); + test_getQuality (); + } +}; + +BEAST_DEFINE_TESTSUITE(Ledger,ripple_app,ripple); + +} // ripple diff --git a/src/ripple/app/tx/TransactionEngine.cpp b/src/ripple/app/tx/TransactionEngine.cpp index b76b91fc4..326dcba11 100644 --- a/src/ripple/app/tx/TransactionEngine.cpp +++ b/src/ripple/app/tx/TransactionEngine.cpp @@ -42,7 +42,7 @@ void TransactionEngine::txnWrite () case taaCREATE: { - WriteLog (lsINFO, TransactionEngine) << "applyTransaction: taaCREATE: " << sleEntry->getText (); + WriteLog (lsDEBUG, TransactionEngine) << "applyTransaction: taaCREATE: " << sleEntry->getText (); if (mLedger->writeBack (lepCREATE, sleEntry) & lepERROR) assert (false); @@ -51,7 +51,7 @@ void TransactionEngine::txnWrite () case taaMODIFY: { - WriteLog (lsINFO, TransactionEngine) << "applyTransaction: taaMODIFY: " << sleEntry->getText (); + WriteLog (lsDEBUG, TransactionEngine) << "applyTransaction: taaMODIFY: " << sleEntry->getText (); if (mLedger->writeBack (lepNONE, sleEntry) & lepERROR) assert (false); @@ -60,7 +60,7 @@ void TransactionEngine::txnWrite () case taaDELETE: { - WriteLog (lsINFO, TransactionEngine) << "applyTransaction: taaDELETE: " << sleEntry->getText (); + WriteLog (lsDEBUG, TransactionEngine) << "applyTransaction: taaDELETE: " << sleEntry->getText (); if (!mLedger->peekAccountStateMap ()->delItem (it.first)) assert (false); @@ -117,14 +117,14 @@ TER TransactionEngine::applyTransaction ( return temUNKNOWN; } - if (ShouldLog (lsINFO, TransactionEngine)) + if (ShouldLog (lsDEBUG, TransactionEngine)) { std::string strToken; std::string strHuman; transResultInfo (terResult, strToken, strHuman); - WriteLog (lsINFO, TransactionEngine) << + WriteLog (lsDEBUG, TransactionEngine) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman; diff --git a/src/ripple/unity/app3.cpp b/src/ripple/unity/app3.cpp index aa5a3b5f8..ffe265f14 100644 --- a/src/ripple/unity/app3.cpp +++ b/src/ripple/unity/app3.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include