From 4ea9b43799fcb14124df023348a42ac551e625c6 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 8 Mar 2013 13:07:15 -0800 Subject: [PATCH 01/10] Cosmetic. --- .gitignore | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index f3cda28c5..41a4891b8 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,9 @@ *.o build tags +bin/rippled +Debug/*.* +Release/*.* # Ignore locally installed node_modules node_modules @@ -30,11 +33,6 @@ tmp db/*.db db/*.db-* -# Ignore obj files -bin/rippled -Debug/*.* -Release/*.* - # Ignore customized configs rippled.cfg validators.txt From fa895e0d92743fd125f0ceb4f4e391d3f86a9b20 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 8 Mar 2013 13:37:46 -0800 Subject: [PATCH 02/10] Improve WAL logging. --- src/cpp/database/SqliteDatabase.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cpp/database/SqliteDatabase.cpp b/src/cpp/database/SqliteDatabase.cpp index 7db0a623f..aa3195daf 100644 --- a/src/cpp/database/SqliteDatabase.cpp +++ b/src/cpp/database/SqliteDatabase.cpp @@ -239,25 +239,25 @@ void SqliteDatabase::runWal() { { boost::mutex::scoped_lock sl(walMutex); - walDBs.swap(walSet); - if (walSet.empty()) + if (walDBs.empty()) { walRunning = false; return; } + walDBs.swap(walSet); } BOOST_FOREACH(const std::string& db, walSet) { - int log, ckpt; + int log = 0, ckpt = 0; int ret = sqlite3_wal_checkpoint_v2(mConnection, db.c_str(), SQLITE_CHECKPOINT_PASSIVE, &log, &ckpt); if (ret != SQLITE_OK) { - cLog((ret == SQLITE_LOCKED) ? lsTRACE : lsWARNING) << "WAL " << mHost << ":" + cLog((ret == SQLITE_LOCKED) ? lsTRACE : lsWARNING) << "WAL " << name << ":" << db << " error " << ret; } else - cLog(lsTRACE) << "WAL(" << mHost << "): pass=" << pass << ", frames=" << log << ", written=" << ckpt; + cLog(lsTRACE) << "WAL(" << name << "): pass=" << pass << ", frames=" << log << ", written=" << ckpt; } walSet.clear(); ++pass; From 51aa48d622d790899164b0cbc9475d9815d4e2c4 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 8 Mar 2013 13:37:54 -0800 Subject: [PATCH 03/10] Lok TOO_BUSY errors. --- src/cpp/ripple/RPCHandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 76d135017..03106fcc7 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1163,6 +1163,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest, int& cost) if (theApp->getJobQueue().getJobCountGE(jtCLIENT) > 200) { + cLog(lsDEBUG) << "Too busy for RPF"; jvResult = rpcError(rpcTOO_BUSY); } else if (!jvRequest.isMember("source_account")) @@ -2892,7 +2893,10 @@ Json::Value RPCHandler::doCommand(const Json::Value& jvRequest, int iRole, int & if (cost == 0) cost = rpcCOST_DEFAULT; if ((iRole != ADMIN) && (theApp->getJobQueue().getJobCountGE(jtCLIENT) > 500)) + { + cLog(lsDEBUG) << "Too busy for command"; return rpcError(rpcTOO_BUSY); + } if (!jvRequest.isMember("command")) return rpcError(rpcCOMMAND_MISSING); From b71f16b8b81f76c996929a9ce9d9165ddd04f32f Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 8 Mar 2013 13:44:12 -0800 Subject: [PATCH 04/10] Better logging of rpcTOO_BUSY returns. --- src/cpp/ripple/RPCHandler.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 03106fcc7..6277a8893 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1152,6 +1152,13 @@ Json::Value RPCHandler::doRandom(Json::Value jvRequest, int& cost) // - From a trusted server, allows clients to use path without manipulation. Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest, int& cost) { + int jc = theApp->getJobQueue().getJobCountGE(jtCLIENT); + if (jc > 200) + { + cLog(lsDEBUG) << "Too busy for RPF: " << jc; + return rpcError(rpcTOO_BUSY); + } + RippleAddress raSrc; RippleAddress raDst; STAmount saDstAmount; @@ -1161,12 +1168,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest, int& cost) if (!lpLedger) return jvResult; - if (theApp->getJobQueue().getJobCountGE(jtCLIENT) > 200) - { - cLog(lsDEBUG) << "Too busy for RPF"; - jvResult = rpcError(rpcTOO_BUSY); - } - else if (!jvRequest.isMember("source_account")) + if (!jvRequest.isMember("source_account")) { jvResult = rpcError(rpcSRC_ACT_MISSING); } @@ -2892,10 +2894,14 @@ Json::Value RPCHandler::doCommand(const Json::Value& jvRequest, int iRole, int & { if (cost == 0) cost = rpcCOST_DEFAULT; - if ((iRole != ADMIN) && (theApp->getJobQueue().getJobCountGE(jtCLIENT) > 500)) + if (iRole != ADMIN) { - cLog(lsDEBUG) << "Too busy for command"; - return rpcError(rpcTOO_BUSY); + int jc = theApp->getJobQueue().getJobCountGE(jtCLIENT); + if (jc > 500) + { + cLog(lsDEBUG) << "Too busy for command: " << jc; + return rpcError(rpcTOO_BUSY); + } } if (!jvRequest.isMember("command")) From b10a2c7a180ea12c45172826bdda5ce477e54211 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 8 Mar 2013 13:45:43 -0800 Subject: [PATCH 05/10] Distinguish between excess server load and excessive connection work. --- src/cpp/ripple/RPCErr.cpp | 1 + src/cpp/ripple/RPCErr.h | 1 + src/cpp/ripple/WSConnection.h | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/RPCErr.cpp b/src/cpp/ripple/RPCErr.cpp index 469630060..de0216f2c 100644 --- a/src/cpp/ripple/RPCErr.cpp +++ b/src/cpp/ripple/RPCErr.cpp @@ -72,6 +72,7 @@ Json::Value rpcError(int iError, Json::Value jvResult) { rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown method." }, { rpcWRONG_SEED, "wrongSeed", "The regular key does not point as the master key." }, { rpcTOO_BUSY, "tooBusy", "The server is too busy to help you now." }, + { rpcSLOW_DOWN, "slowDown", "You are placing too much load on the server." }, }; int i; diff --git a/src/cpp/ripple/RPCErr.h b/src/cpp/ripple/RPCErr.h index 0da8f82be..67ad2de4a 100644 --- a/src/cpp/ripple/RPCErr.h +++ b/src/cpp/ripple/RPCErr.h @@ -18,6 +18,7 @@ enum { rpcNO_EVENTS, rpcNOT_STANDALONE, rpcTOO_BUSY, + rpcSLOW_DOWN, // Networking rpcNO_CLOSED, diff --git a/src/cpp/ripple/WSConnection.h b/src/cpp/ripple/WSConnection.h index 25a7fcfe3..10b8be406 100644 --- a/src/cpp/ripple/WSConnection.h +++ b/src/cpp/ripple/WSConnection.h @@ -93,7 +93,7 @@ public: connection_ptr ptr = mConnection.lock(); if (ptr) ptr->close(websocketpp::close::status::PROTOCOL_ERROR, "overload"); - return rpcError(rpcTOO_BUSY); + return rpcError(rpcSLOW_DOWN); } if (!jvRequest.isMember("command")) From a3ee8b0ed15dfb8f960e037eb388fac23969931d Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 8 Mar 2013 13:53:00 -0800 Subject: [PATCH 06/10] Cosmetic. --- src/cpp/ripple/PaymentTransactor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/PaymentTransactor.cpp b/src/cpp/ripple/PaymentTransactor.cpp index ed46b8253..707b0ecf0 100644 --- a/src/cpp/ripple/PaymentTransactor.cpp +++ b/src/cpp/ripple/PaymentTransactor.cpp @@ -21,8 +21,8 @@ TER PaymentTransactor::doApply() const STAmount saMaxAmount = bMax ? mTxn.getFieldAmount(sfSendMax) : saDstAmount.isNative() - ? saDstAmount - : STAmount(saDstAmount.getCurrency(), mTxnAccountID, saDstAmount.getMantissa(), saDstAmount.getExponent(), saDstAmount.isNegative()); + ? saDstAmount + : STAmount(saDstAmount.getCurrency(), mTxnAccountID, saDstAmount.getMantissa(), saDstAmount.getExponent(), saDstAmount.isNegative()); const uint160 uSrcCurrency = saMaxAmount.getCurrency(); const uint160 uDstCurrency = saDstAmount.getCurrency(); const bool bXRPDirect = uSrcCurrency.isZero() && uDstCurrency.isZero(); From 446120c45633be1fe65481915a6671273d124ac9 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 8 Mar 2013 13:56:33 -0800 Subject: [PATCH 07/10] UT: add test showing sending IOUs with source as issuer is broken. --- test/send-test.js | 154 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/test/send-test.js b/test/send-test.js index c3055f708..b02dd5ce2 100644 --- a/test/send-test.js +++ b/test/send-test.js @@ -493,8 +493,8 @@ buster.testCase("Sending future", { }); buster.testCase("Gateway", { - // 'setUp' : testutils.build_setup({ verbose: true }), - 'setUp' : testutils.build_setup(), + // 'setUp' : testutils.build_setup(), + 'setUp' : testutils.build_setup({ verbose: true }), 'tearDown' : testutils.build_teardown(), "customer to customer with and without transfer fee" : @@ -603,6 +603,156 @@ buster.testCase("Gateway", { }); }, + "customer to customer, transfer fee, default path with and without specific issuer for Amount and SendMax" : + function (done) { + var self = this; + + // self.remote.set_trace(); + + async.waterfall([ + function (callback) { + self.what = "Create accounts."; + + testutils.create_accounts(self.remote, "root", "10000.0", ["alice", "bob", "mtgox"], callback); + }, + function (callback) { + self.what = "Set transfer rate."; + + self.remote.transaction() + .account_set("mtgox") + .transfer_rate(1e9*1.1) + .once('proposed', function (m) { + // console.log("proposed: %s", JSON.stringify(m)); + callback(m.result !== 'tesSUCCESS'); + }) + .submit(); + }, + function (callback) { + self.what = "Set credit limits."; + + testutils.credit_limits(self.remote, + { + "alice" : "100/AUD/mtgox", + "bob" : "100/AUD/mtgox", + }, + callback); + }, + function (callback) { + self.what = "Distribute funds."; + + testutils.payments(self.remote, + { + "mtgox" : [ "4.4/AUD/alice" ], + }, + callback); + }, + function (callback) { + self.what = "Verify balances."; + + testutils.verify_balances(self.remote, + { + "alice" : "4.4/AUD/mtgox", + }, + callback); + }, + function (callback) { + self.what = "Alice sends 1.1/AUD/mtgox Bob 1/AUD/mtgox"; + + self.remote.transaction() + .payment("alice", "bob", "1/AUD/mtgox") + .send_max("1.1/AUD/mtgox") + .on('proposed', function (m) { + // console.log("proposed: %s", JSON.stringify(m)); + + callback(m.result !== 'tesSUCCESS'); + }) + .submit(); + }, + function (callback) { + self.what = "Verify balances 2."; + + testutils.verify_balances(self.remote, + { + "alice" : "3.3/AUD/mtgox", + "bob" : "1/AUD/mtgox", + }, + callback); + }, + function (callback) { + self.what = "Alice sends 1.1/AUD/mtgox Bob 1/AUD/bob"; + + self.remote.transaction() + .payment("alice", "bob", "1/AUD/bob") + .send_max("1.1/AUD/mtgox") + .on('proposed', function (m) { + // console.log("proposed: %s", JSON.stringify(m)); + + callback(m.result !== 'tesSUCCESS'); + }) + .submit(); + }, + function (callback) { + self.what = "Verify balances 3."; + + testutils.verify_balances(self.remote, + { + "alice" : "2.2/AUD/mtgox", + "bob" : "2/AUD/mtgox", + }, + callback); + }, + function (callback) { + self.what = "Alice sends 1.1/AUD/alice Bob 1/AUD/mtgox"; + + self.remote.transaction() + .payment("alice", "bob", "1/AUD/mtgox") + .send_max("1.1/AUD/alice") + .on('proposed', function (m) { + // console.log("proposed: %s", JSON.stringify(m)); + + callback(m.result !== 'tesSUCCESS'); + }) + .submit(); + }, + function (callback) { + self.what = "Verify balances 4."; + + testutils.verify_balances(self.remote, + { + "alice" : "1.1/AUD/mtgox", + "bob" : "3/AUD/mtgox", + }, + callback); + }, + function (callback) { + self.what = "Alice sends 1.1/AUD/alice Bob 1/AUD/bob"; + + self.remote.transaction() + .payment("alice", "bob", "1/AUD/bob") + .send_max("1.1/AUD/alice") + .on('proposed', function (m) { + // console.log("proposed: %s", JSON.stringify(m)); + + callback(m.result !== 'tesSUCCESS'); + }) + .submit(); + }, + function (callback) { + self.what = "Verify balances 5."; + + testutils.verify_balances(self.remote, + { + "alice" : "0/AUD/mtgox", + "bob" : "4/AUD/mtgox", + }, + callback); + }, + ], function (error) { + buster.refute(error, self.what); + done(); + }); + }, + "subscribe test: customer to customer with and without transfer fee" : function (done) { var self = this; From 81264b17b4d318f94319268bc71420d11a7d1ec7 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 8 Mar 2013 14:47:20 -0800 Subject: [PATCH 08/10] Fix -a --load (again). --- src/cpp/ripple/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index f0c360265..a9ff4ce79 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -26,7 +26,7 @@ Application* theApp = NULL; DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount) { - boost::filesystem::path pPath = (theConfig.RUN_STANDALONE && (!theConfig.START_UP != Config::LOAD)) + boost::filesystem::path pPath = (theConfig.RUN_STANDALONE && (theConfig.START_UP != Config::LOAD)) ? "" // Use temporary files. : (theConfig.DATA_DIR / strName); // Use regular db files. From 2cc201824092685871ae8d32d44b15379cb8e911 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 8 Mar 2013 15:54:24 -0800 Subject: [PATCH 09/10] UT: Fix unit tests fro default paths. --- test/send-test.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/send-test.js b/test/send-test.js index b02dd5ce2..e80964fc2 100644 --- a/test/send-test.js +++ b/test/send-test.js @@ -493,8 +493,8 @@ buster.testCase("Sending future", { }); buster.testCase("Gateway", { - // 'setUp' : testutils.build_setup(), - 'setUp' : testutils.build_setup({ verbose: true }), + 'setUp' : testutils.build_setup(), + // 'setUp' : testutils.build_setup({ verbose: true }), 'tearDown' : testutils.build_teardown(), "customer to customer with and without transfer fee" : @@ -725,6 +725,7 @@ buster.testCase("Gateway", { callback); }, function (callback) { + // Must fail, doesn't know to use the mtgox self.what = "Alice sends 1.1/AUD/alice Bob 1/AUD/bob"; self.remote.transaction() @@ -733,7 +734,7 @@ buster.testCase("Gateway", { .on('proposed', function (m) { // console.log("proposed: %s", JSON.stringify(m)); - callback(m.result !== 'tesSUCCESS'); + callback(m.result !== 'terNO_LINE'); }) .submit(); }, @@ -742,8 +743,8 @@ buster.testCase("Gateway", { testutils.verify_balances(self.remote, { - "alice" : "0/AUD/mtgox", - "bob" : "4/AUD/mtgox", + "alice" : "1.1/AUD/mtgox", + "bob" : "3/AUD/mtgox", }, callback); }, From 0a7c67be2915ac082dae96e9fbb656e3eb5e1b3c Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 8 Mar 2013 16:11:40 -0800 Subject: [PATCH 10/10] Add a warning. --- src/cpp/ripple/AcceptedLedger.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/AcceptedLedger.h b/src/cpp/ripple/AcceptedLedger.h index e3237cd23..4b6297e55 100644 --- a/src/cpp/ripple/AcceptedLedger.h +++ b/src/cpp/ripple/AcceptedLedger.h @@ -40,7 +40,7 @@ class AcceptedLedger public: typedef boost::shared_ptr pointer; typedef const pointer& ret; - typedef std::map map_t; + typedef std::map map_t; // Must be an ordered map! typedef map_t::value_type value_type; typedef map_t::const_iterator const_iterator;