From 47ffc5ff1299234c9fd3086e896ae63cc3f1b4cc Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 16 Mar 2013 16:41:13 -0700 Subject: [PATCH 01/16] Some extra debug logging. --- src/cpp/ripple/Ledger.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 2d689156e0..ddb4bc441b 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -421,7 +421,13 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus) assert(false); } - assert (getAccountHash() == mAccountStateMap->getHash()); + if (getAccountHash() != mAccountStateMap->getHash()) + { + cLog(lsFATAL) << "sAL: " << getAccountHash() << " != " << mAccountStateMap->getHash(); + cLog(lsFATAL) << "saveAcceptedLedger: seq=" << mLedgerSeq << ", fromcons=" << fromConsensus; + assert(false); + } + assert (getTransHash() == mTransactionMap->getHash()); // Save the ledger header in the hashed object store From a12c72f4226f8695f1c8165eeb01ec17ee6a0d46 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 16 Mar 2013 18:22:35 -0700 Subject: [PATCH 02/16] Be more careful not to tamper with an acquired ledger/map after it has completed. --- src/cpp/ripple/LedgerAcquire.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index e6da90f82b..f91c4952bf 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -270,6 +270,7 @@ void LedgerAcquire::done() else theApp->getMasterLedgerAcquire().logFailure(mHash); + // FIXME: We hold the PeerSet lock for (unsigned int i = 0; i < triggers.size(); ++i) triggers[i](shared_from_this()); } @@ -591,7 +592,7 @@ bool LedgerAcquire::takeBase(const std::string& data) // data must not have hash cLog(lsTRACE) << "got base acquiring ledger " << mHash; #endif boost::recursive_mutex::scoped_lock sl(mLock); - if (mHaveBase) + if (mComplete || mFailed || mHaveBase) return true; mLedger = boost::make_shared(data, false); if (mLedger->getHash() != mHash) @@ -626,7 +627,7 @@ bool LedgerAcquire::takeTxNode(const std::list& nodeIDs, boost::recursive_mutex::scoped_lock sl(mLock); if (!mHaveBase) return false; - if (mHaveTransactions) + if (mHaveTransactions || mFailed) return true; std::list::const_iterator nodeIDit = nodeIDs.begin(); @@ -673,7 +674,7 @@ bool LedgerAcquire::takeAsNode(const std::list& nodeIDs, cLog(lsWARNING) << "Don't have ledger base"; return false; } - if (mHaveState) + if (mHaveState || mFailed) return true; std::list::const_iterator nodeIDit = nodeIDs.begin(); @@ -714,6 +715,8 @@ bool LedgerAcquire::takeAsNode(const std::list& nodeIDs, bool LedgerAcquire::takeAsRootNode(const std::vector& data, SMAddNode& san) { boost::recursive_mutex::scoped_lock sl(mLock); + if (mFailed || mHaveState) + return true; if (!mHaveBase) return false; AccountStateSF tFilter(mLedger->getLedgerSeq()); @@ -724,6 +727,8 @@ bool LedgerAcquire::takeAsRootNode(const std::vector& data, SMAdd bool LedgerAcquire::takeTxRootNode(const std::vector& data, SMAddNode& san) { boost::recursive_mutex::scoped_lock sl(mLock); + if (mFailed || mHaveState) + return true; if (!mHaveBase) return false; TransactionStateSF tFilter(mLedger->getLedgerSeq()); From 74bf47c73d60cedb1c4830e017f4e45f711fd896 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sat, 16 Mar 2013 18:30:26 -0700 Subject: [PATCH 03/16] Defer acquire timeouts if ledger data is backing up. --- src/cpp/ripple/LedgerAcquire.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index f91c4952bf..e4d735ca8a 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -73,13 +73,21 @@ void PeerSet::TimerEntry(boost::weak_ptr wptr, const boost::system::err return; boost::shared_ptr ptr = wptr.lock(); if (ptr) - theApp->getJobQueue().addJob(jtLEDGER_DATA, "timerEntry", + { + int jc = theApp->getJobQueue().getJobCountTotal(jtLEDGER_DATA); + if (jc > 4) + { + cLog(lsDEBUG) << "Deferring PeerSet timer due to load"; + ptr->setTimer(); + } + else theApp->getJobQueue().addJob(jtLEDGER_DATA, "timerEntry", BIND_TYPE(&PeerSet::TimerJobEntry, P_1, ptr)); + } } void PeerSet::TimerJobEntry(Job&, boost::shared_ptr ptr) { - ptr->invokeOnTimer(); + ptr->invokeOnTimer(); } bool PeerSet::isActive() From 39c63550ee042ea27be62053c2c7114e3ae0869a Mon Sep 17 00:00:00 2001 From: Stefan Thomas Date: Sun, 17 Mar 2013 20:08:42 +0100 Subject: [PATCH 04/16] JS: Expose Meta class. --- src/js/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/index.js b/src/js/index.js index 175c277500..139c71cb1f 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -4,6 +4,7 @@ exports.Currency = require('./currency').Currency; exports.UInt160 = require('./amount').UInt160; exports.Seed = require('./amount').Seed; exports.Transaction = require('./transaction').Transaction; +exports.Meta = require('./meta').Meta; exports.utils = require('./utils'); From 1994ed96dd93a2f53c4bd487e2bf7e2991c920af Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 17 Mar 2013 16:51:44 -0700 Subject: [PATCH 05/16] Try to catch the acquire ledger bug earlier. --- src/cpp/ripple/LedgerHistory.cpp | 1 + src/cpp/ripple/LedgerMaster.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/cpp/ripple/LedgerHistory.cpp b/src/cpp/ripple/LedgerHistory.cpp index 420b442558..0fe513bd64 100644 --- a/src/cpp/ripple/LedgerHistory.cpp +++ b/src/cpp/ripple/LedgerHistory.cpp @@ -31,6 +31,7 @@ void LedgerHistory::addLedger(Ledger::pointer ledger) void LedgerHistory::addAcceptedLedger(Ledger::pointer ledger, bool fromConsensus) { assert(ledger && ledger->isAccepted() && ledger->isImmutable()); + assert(ledger->peekAccountStateMap()->getHash().isNonZero()); uint256 h(ledger->getHash()); boost::recursive_mutex::scoped_lock sl(mLedgersByHash.peekMutex()); mLedgersByHash.canonicalize(h, ledger, true); diff --git a/src/cpp/ripple/LedgerMaster.cpp b/src/cpp/ripple/LedgerMaster.cpp index 6aa52fa9be..fad0466db5 100644 --- a/src/cpp/ripple/LedgerMaster.cpp +++ b/src/cpp/ripple/LedgerMaster.cpp @@ -353,6 +353,7 @@ void LedgerMaster::fixMismatch(Ledger::ref ledger) void LedgerMaster::setFullLedger(Ledger::pointer ledger) { // A new ledger has been accepted as part of the trusted chain cLog(lsDEBUG) << "Ledger " << ledger->getLedgerSeq() << " accepted :" << ledger->getHash(); + assert(ledger->peekAccountStateMap()->getHash().isNonZero()); boost::recursive_mutex::scoped_lock ml(mLock); From 6bc474c4610851cd2374857afe4925e2134c662b Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 17 Mar 2013 17:30:35 -0700 Subject: [PATCH 06/16] tryLocal should only check the hash database. --- src/cpp/ripple/LedgerAcquire.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index e4d735ca8a..7d0d20ae2c 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -113,14 +113,9 @@ bool LedgerAcquire::tryLocal() { HashedObject::pointer node = theApp->getHashedObjectStore().retrieve(mHash); if (!node) - { - mLedger = theApp->getLedgerMaster().getLedgerByHash(mHash); - if (!mLedger) - return false; - } - else - mLedger = boost::make_shared(strCopy(node->getData()), true); + return false; + mLedger = boost::make_shared(strCopy(node->getData()), true); if (mLedger->getHash() != mHash) { // We know for a fact the ledger can never be acquired cLog(lsWARNING) << mHash << " cannot be a ledger"; From 9edfd514309579326095466139a78aadb574f82b Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 17 Mar 2013 21:24:56 -0700 Subject: [PATCH 07/16] Reduce some log severities. --- src/cpp/ripple/LedgerAcquire.cpp | 2 +- src/cpp/ripple/LedgerMaster.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index 7d0d20ae2c..9e9e307e7d 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -863,7 +863,7 @@ void LedgerAcquireMaster::gotLedgerData(Job&, boost::shared_ptrpunishPeer(LT_InvalidRequest); return; } diff --git a/src/cpp/ripple/LedgerMaster.cpp b/src/cpp/ripple/LedgerMaster.cpp index fad0466db5..50e96b3470 100644 --- a/src/cpp/ripple/LedgerMaster.cpp +++ b/src/cpp/ripple/LedgerMaster.cpp @@ -316,7 +316,7 @@ void LedgerMaster::resumeAcquiring() else { mCompleteLedgers.clearValue(prevMissing); - cLog(lsWARNING) << "We have a gap at: " << prevMissing + 1; + cLog(lsINFO) << "We have a gap at: " << prevMissing + 1; } } } From 00913f838fb6e6cf9b9d8716333192bb993946c0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 17 Mar 2013 22:04:34 -0700 Subject: [PATCH 08/16] Fix the 'getAccountHash() == mAccountStateMap->getHash()' bug. 'getNeededHashes' can do the wrong thing (report no needed hashes when we need them all) if we have a ledger's root node but not the root node of the tree we're querying. --- src/cpp/ripple/Ledger.cpp | 26 ++++++++++++++++++++++++++ src/cpp/ripple/Ledger.h | 3 +++ src/cpp/ripple/LedgerAcquire.cpp | 11 +++++++---- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index ddb4bc441b..d9fdab4ca5 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -1614,6 +1614,32 @@ uint64 Ledger::scaleFeeLoad(uint64 fee) return theApp->getFeeTrack().scaleFeeLoad(fee, mBaseFee, mReferenceFeeUnits); } +std::vector Ledger::getNeededTransactionHashes(int max) +{ + std::vector ret; + if (mTransHash.isNonZero()) + { + if (mTransactionMap->getHash().isZero()) + ret.push_back(mTransHash); + else + ret = mTransactionMap->getNeededHashes(max); + } + return ret; +} + +std::vector Ledger::getNeededAccountStateHashes(int max) +{ + std::vector ret; + if (mAccountHash.isNonZero()) + { + if (mAccountStateMap->getHash().isZero()) + ret.push_back(mAccountHash); + else + ret = mAccountStateMap->getNeededHashes(max); + } + return ret; +} + BOOST_AUTO_TEST_SUITE(quality) BOOST_AUTO_TEST_CASE( getquality ) diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index c260a0443c..5dda848805 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -222,6 +222,9 @@ public: static uint256 getLedgerFeatureIndex(); static uint256 getLedgerFeeIndex(); + std::vector getNeededTransactionHashes(int max); + std::vector getNeededAccountStateHashes(int max); + // index calculation functions static uint256 getAccountRootIndex(const uint160& uAccountID); diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index 9e9e307e7d..e345dc18ca 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -139,7 +139,7 @@ bool LedgerAcquire::tryLocal() { mLedger->peekTransactionMap()->fetchRoot(mLedger->getTransHash()); cLog(lsDEBUG) << "Got root txn map locally"; - std::vector h = mLedger->peekTransactionMap()->getNeededHashes(1); + std::vector h = mLedger->getNeededTransactionHashes(1); if (h.empty()) { cLog(lsDEBUG) << "Had full txn map locally"; @@ -155,14 +155,17 @@ bool LedgerAcquire::tryLocal() if (!mHaveState) { if (mLedger->getAccountHash().isZero()) + { + cLog(lsFATAL) << "We are acquiring a ledger with a zero account hash"; mHaveState = true; + } else { try { mLedger->peekAccountStateMap()->fetchRoot(mLedger->getAccountHash()); cLog(lsDEBUG) << "Got root AS map locally"; - std::vector h = mLedger->peekAccountStateMap()->getNeededHashes(1); + std::vector h = mLedger->getNeededAccountStateHashes(1); if (h.empty()) { cLog(lsDEBUG) << "Had full AS map locally"; @@ -783,13 +786,13 @@ std::vector LedgerAcquire::getNeededHashes() } if (!mHaveState) { - std::vector v = mLedger->peekAccountStateMap()->getNeededHashes(16); + std::vector v = mLedger->getNeededAccountStateHashes(16); BOOST_FOREACH(const uint256& h, v) ret.push_back(std::make_pair(ripple::TMGetObjectByHash::otSTATE_NODE, h)); } if (!mHaveTransactions) { - std::vector v = mLedger->peekTransactionMap()->getNeededHashes(16); + std::vector v = mLedger->getNeededAccountStateHashes(16); BOOST_FOREACH(const uint256& h, v) ret.push_back(std::make_pair(ripple::TMGetObjectByHash::otTRANSACTION_NODE, h)); } From 125c5273a68c16dfd5ce41efec56b81e4d86aa2a Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 18 Mar 2013 03:10:20 -0700 Subject: [PATCH 09/16] Dispatch transaction from job queue, not I/O service. Mark a FIXME where we don't do this. --- src/cpp/ripple/NetworkOPs.cpp | 1 + src/cpp/ripple/Peer.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 67c2a8908e..db8a28c0d5 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -210,6 +210,7 @@ void NetworkOPs::submitTransaction(Job&, SerializedTransaction::pointer iTrans, } } + // FIXME: Should submit to job queue theApp->getIOService().post(boost::bind(&NetworkOPs::processTransaction, this, boost::make_shared(trans, false), callback)); } diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp index 752b9c0e13..e4a418f0f7 100644 --- a/src/cpp/ripple/Peer.cpp +++ b/src/cpp/ripple/Peer.cpp @@ -830,7 +830,7 @@ static void checkTransaction(Job&, int flags, SerializedTransaction::pointer stx else tx = boost::make_shared(stx, false); - theApp->getIOService().post(boost::bind(&NetworkOPs::processTransaction, &theApp->getOPs(), tx)); + theApp->getOPs().processTransaction(tx); #ifndef TRUST_NETWORK } From 7a6a199df42ee63c68cce64c860fa7b1d4cbcdbf Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 18 Mar 2013 03:10:54 -0700 Subject: [PATCH 10/16] Take advantage of perfect forwarding in a few more places. --- src/cpp/ripple/CallRPC.cpp | 16 +++++++++------- src/cpp/ripple/CallRPC.h | 2 +- src/cpp/ripple/HttpsClient.cpp | 17 ++++++++--------- src/cpp/ripple/HttpsClient.h | 20 ++++++++++---------- src/cpp/ripple/NetworkOPs.h | 2 +- src/cpp/ripple/UniqueNodeList.cpp | 6 +++--- 6 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 96d350140c..1d0f009105 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -785,7 +785,7 @@ int commandLineRPC(const std::vector& vCmd) : vCmd[0], jvParams, // Parsed, execute. false, - boost::bind(callRPCHandler, &jvOutput, _1)); + BIND_TYPE(callRPCHandler, &jvOutput, P_1)); isService.run(); // This blocks until there is no more outstanding async calls. @@ -848,7 +848,7 @@ int commandLineRPC(const std::vector& vCmd) #define RPC_NOTIFY_SECONDS 10 bool responseRPC( - boost::function callbackFuncP, + FUNCTION_TYPE callbackFuncP, const boost::system::error_code& ecResult, int iStatus, const std::string& strData) { if (callbackFuncP) @@ -886,7 +886,9 @@ bool responseRPC( } // Build the request. -void requestRPC(const std::string& strMethod, const Json::Value& jvParams, const std::map& mHeaders, const std::string& strPath, boost::asio::streambuf& sb, const std::string& strHost) +void requestRPC(const std::string& strMethod, const Json::Value& jvParams, + const std::map& mHeaders, const std::string& strPath, + boost::asio::streambuf& sb, const std::string& strHost) { cLog(lsDEBUG) << "requestRPC: strPath='" << strPath << "'"; @@ -906,7 +908,7 @@ void callRPC( const std::string& strUsername, const std::string& strPassword, const std::string& strPath, const std::string& strMethod, const Json::Value& jvParams, const bool bSSL, - boost::function callbackFuncP) + FUNCTION_TYPE callbackFuncP) { // Connect to localhost if (!theConfig.QUIET) @@ -933,15 +935,15 @@ void callRPC( io_service, strIp, iPort, - boost::bind( + BIND_TYPE( &requestRPC, strMethod, jvParams, mapRequestHeaders, - strPath, _1, _2), + strPath, P_1, P_2), RPC_REPLY_MAX_BYTES, boost::posix_time::seconds(RPC_NOTIFY_SECONDS), - boost::bind(&responseRPC, callbackFuncP, _1, _2, _3)); + BIND_TYPE(&responseRPC, callbackFuncP, P_1, P_2, P_3)); } // vim:ts=4 diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index adde89f708..5d9a0377fc 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -56,7 +56,7 @@ extern void callRPC( const std::string& strUsername, const std::string& strPassword, const std::string& strPath, const std::string& strMethod, const Json::Value& jvParams, const bool bSSL, - boost::function callbackFuncP = 0); + FUNCTION_TYPE callbackFuncP = 0); #endif // vim:ts=4 diff --git a/src/cpp/ripple/HttpsClient.cpp b/src/cpp/ripple/HttpsClient.cpp index 1ae01e19f2..1144d98596 100644 --- a/src/cpp/ripple/HttpsClient.cpp +++ b/src/cpp/ripple/HttpsClient.cpp @@ -6,7 +6,6 @@ #include "utils.h" #include -#include #include #include #include @@ -52,9 +51,9 @@ void HttpsClient::makeGet(const std::string& strPath, boost::asio::streambuf& sb void HttpsClient::httpsRequest( bool bSSL, std::deque deqSites, - boost::function build, + FUNCTION_TYPE build, boost::posix_time::time_duration timeout, - boost::function complete) + FUNCTION_TYPE complete) { mSSL = bSSL; mDeqSites = deqSites; @@ -70,7 +69,7 @@ void HttpsClient::httpsGet( std::deque deqSites, const std::string& strPath, boost::posix_time::time_duration timeout, - boost::function complete) { + FUNCTION_TYPE complete) { mComplete = complete; mTimeout = timeout; @@ -78,7 +77,7 @@ void HttpsClient::httpsGet( httpsRequest( bSSL, deqSites, - boost::bind(&HttpsClient::makeGet, shared_from_this(), strPath, _1, _2), + BIND_TYPE(&HttpsClient::makeGet, shared_from_this(), strPath, P_1, P_2), timeout, complete); } @@ -403,7 +402,7 @@ void HttpsClient::httpsGet( const std::string& strPath, std::size_t responseMax, boost::posix_time::time_duration timeout, - boost::function complete) { + FUNCTION_TYPE complete) { boost::shared_ptr client(new HttpsClient(io_service, port, responseMax)); @@ -418,7 +417,7 @@ void HttpsClient::httpsGet( const std::string& strPath, std::size_t responseMax, boost::posix_time::time_duration timeout, - boost::function complete) { + FUNCTION_TYPE complete) { std::deque deqSites(1, strSite); @@ -432,10 +431,10 @@ void HttpsClient::httpsRequest( boost::asio::io_service& io_service, std::string strSite, const unsigned short port, - boost::function setRequest, + FUNCTION_TYPE setRequest, std::size_t responseMax, boost::posix_time::time_duration timeout, - boost::function complete) { + FUNCTION_TYPE complete) { std::deque deqSites(1, strSite); diff --git a/src/cpp/ripple/HttpsClient.h b/src/cpp/ripple/HttpsClient.h index d4e89df6c8..909594efe1 100644 --- a/src/cpp/ripple/HttpsClient.h +++ b/src/cpp/ripple/HttpsClient.h @@ -8,10 +8,10 @@ #include #include #include -#include #include #include "AutoSocket.h" +#include "utils.h" // // Async https client. @@ -33,8 +33,8 @@ private: const unsigned short mPort; int mResponseMax; int mStatus; - boost::function mBuild; - boost::function mComplete; + FUNCTION_TYPE mBuild; + FUNCTION_TYPE mComplete; boost::asio::deadline_timer mDeadline; @@ -76,16 +76,16 @@ public: void httpsRequest( bool bSSL, std::deque deqSites, - boost::function build, + FUNCTION_TYPE build, boost::posix_time::time_duration timeout, - boost::function complete); + FUNCTION_TYPE complete); void httpsGet( bool bSSL, std::deque deqSites, const std::string& strPath, boost::posix_time::time_duration timeout, - boost::function complete); + FUNCTION_TYPE complete); static void httpsGet( bool bSSL, @@ -95,7 +95,7 @@ public: const std::string& strPath, std::size_t responseMax, boost::posix_time::time_duration timeout, - boost::function complete); + FUNCTION_TYPE complete); static void httpsGet( bool bSSL, @@ -105,17 +105,17 @@ public: const std::string& strPath, std::size_t responseMax, boost::posix_time::time_duration timeout, - boost::function complete); + FUNCTION_TYPE complete); static void httpsRequest( bool bSSL, boost::asio::io_service& io_service, std::string strSite, const unsigned short port, - boost::function build, + FUNCTION_TYPE build, std::size_t responseMax, boost::posix_time::time_duration timeout, - boost::function complete); + FUNCTION_TYPE complete); }; #endif // vim:ts=4 diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index 1fa99064b2..99daf9483d 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -185,7 +185,7 @@ public: // // Transaction operations // - typedef boost::function stCallback; // must complete immediately + typedef FUNCTION_TYPE stCallback; // must complete immediately void submitTransaction(Job&, SerializedTransaction::pointer, stCallback callback = stCallback()); Transaction::pointer submitTransactionSync(Transaction::ref tpTrans, bool bSubmit=true); diff --git a/src/cpp/ripple/UniqueNodeList.cpp b/src/cpp/ripple/UniqueNodeList.cpp index 5928fb5a9a..04917f2b88 100644 --- a/src/cpp/ripple/UniqueNodeList.cpp +++ b/src/cpp/ripple/UniqueNodeList.cpp @@ -885,7 +885,7 @@ void UniqueNodeList::getValidatorsUrl(const RippleAddress& naNodePublic, section strPath, NODE_FILE_BYTES_MAX, boost::posix_time::seconds(NODE_FETCH_SECONDS), - boost::bind(&UniqueNodeList::responseValidators, this, strValidatorsUrl, naNodePublic, secSite, strDomain, _1, _2, _3)); + BIND_TYPE(&UniqueNodeList::responseValidators, this, strValidatorsUrl, naNodePublic, secSite, strDomain, P_1, P_2, P_3)); } else { @@ -1063,7 +1063,7 @@ void UniqueNodeList::fetchProcess(std::string strDomain) NODE_FILE_PATH, NODE_FILE_BYTES_MAX, boost::posix_time::seconds(NODE_FETCH_SECONDS), - boost::bind(&UniqueNodeList::responseFetch, this, strDomain, _1, _2, _3)); + BIND_TYPE(&UniqueNodeList::responseFetch, this, strDomain, P_1, P_2, P_3)); } void UniqueNodeList::fetchTimerHandler(const boost::system::error_code& err) @@ -1610,7 +1610,7 @@ void UniqueNodeList::nodeNetwork() theConfig.VALIDATORS_URI, VALIDATORS_FILE_BYTES_MAX, boost::posix_time::seconds(VALIDATORS_FETCH_SECONDS), - boost::bind(&UniqueNodeList::validatorsResponse, this, _1, _2, _3)); + BIND_TYPE(&UniqueNodeList::validatorsResponse, this, P_1, P_2, P_3)); } } From f30624bb3dd514ee0093a5d06597e07d1f0fc438 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Mon, 18 Mar 2013 17:20:16 -0700 Subject: [PATCH 11/16] Work on browser.js. --- bin/browser.js | 298 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 197 insertions(+), 101 deletions(-) diff --git a/bin/browser.js b/bin/browser.js index ab33850d05..311d249544 100755 --- a/bin/browser.js +++ b/bin/browser.js @@ -1,9 +1,9 @@ #!/usr/bin/node // -// ledger_header?l=L +// ledger?l=L // transaction?h=H // ledger_entry?l=L&h=H -// account_root?l=L&a=A +// account?l=L&a=A // directory?l=L&dir_root=H&i=I // directory?l=L&o=A&i=I // owner directory // offer?l=L&offer=H @@ -26,22 +26,50 @@ var Remote = require("../src/js/remote.js").Remote; var program = process.argv[1]; +var httpd_response = function (res, opts) { + var self=this; + + res.statusCode = opts.statusCode; + res.end( + "" + + "Title" + + "" + + "State:" + self.state + + "" + + (opts.body || '') + + '
'
+      + (opts.url || '')
+      + '
' + + "" + + "" + ); +}; + +var html_link = function (generic) { + return '' + generic + ''; +}; + // Build a link to a type. var build_uri = function (params, opts) { var c; - if (params.type === 'account_root') { + if (params.type === 'account') { c = { - pathname: 'account_root', + pathname: 'account', query: { l: params.ledger, a: params.account, }, }; - } else if (params.type === 'ledger_header') { + } else if (params.type === 'ledger') { c = { - pathname: 'ledger_header', + pathname: 'ledger', query: { l: params.ledger, }, @@ -58,9 +86,11 @@ var build_uri = function (params, opts) { c = {}; } + opts = opts || {}; + c.protocol = "http"; - c.hostname = opts.hostname; - c.port = opts.port; + c.hostname = opts.hostname || self.base.hostname; + c.port = opts.port || self.base.port; return url.format(c); }; @@ -70,31 +100,109 @@ console.log(link); return "" + item + ""; }; -var rewrite_object = function (obj, opts) { - var out = extend({}, obj); +var rewrite_type = function (type, obj, opts) { + if ('amount' === type) { + if ('string' === typeof obj) { + // XRP. + return '' + obj + ''; - if ('ledger_index' in obj) { - out.ledger_index = - build_link( - obj.ledger_index, - build_uri({ - type: 'ledger_header', - ledger: obj.ledger_index, - }, opts) + } else { + obj.issuer = rewrite_type('address', obj.issuer, opts); + + return obj; + } + return build_link( + obj, + build_uri({ + type: 'account', + account: obj + }, opts) + ); + } + if ('address' === type) { + return build_link( + obj, + build_uri({ + type: 'account', + account: obj + }, opts) + ); + } + else if ('ledger' === type) { + return build_link( + obj, + build_uri({ + type: 'ledger', + ledger: obj, + }, opts) + ); + } + else if ('transaction' === type) { + return build_link( + obj, + build_uri({ + type: 'transaction', + hash: obj + }, opts) ); } - if ('node' in obj) { + return 'ERROR: ' + type; +}; + +var rewrite_object = function (obj, opts) { + var out = extend({}, obj); + + if ('TransactionType' in obj) { + // It's a transaction. + out.TransactionType = '' + obj.TransactionType + ''; + + if ('TakerGets' in obj) + out.TakerGets = rewrite_type('amount', obj.TakerGets, opts); + + if ('TakerPays' in obj) + out.TakerPays = rewrite_type('amount', obj.TakerPays, opts); + } + + if ('Account' in obj) { + out.Account = rewrite_type('address', obj.Account, opts); + } + + if ('parent_hash' in obj) { + out.parent_hash = rewrite_type('ledger', out.parent_hash, opts); + } + if ('ledger_index' in obj) { + out.ledger_index = rewrite_type('ledger', out.ledger_index, opts); + } + if ('ledger_current_index' in obj) { + out.ledger_current_index = rewrite_type('ledger', out.ledger_current_index, opts); + } + if ('ledger_hash' in obj) { + out.ledger_hash = rewrite_type('ledger', out.ledger_hash, opts); + } + + if ('ledger' in obj) { + // It's a ledger header. + out.ledger = rewrite_object(out.ledger, opts); + + if ('ledger_hash' in out.ledger) + out.ledger.ledger_hash = '' + out.ledger.ledger_hash + ''; + + delete out.ledger.hash; + delete out.ledger.totalCoins; + } + + if ('node' in obj && 'LedgerEntryType' in obj.node) { + // Its a ledger entry. + if (obj.node.LedgerEntryType === 'AccountRoot') { - out.node.PreviousTxnID = - build_link( - obj.node.PreviousTxnID, - build_uri({ - type: 'transaction', - hash: obj.node.PreviousTxnID, - }, opts) - ); + out.node.Account = rewrite_type('address', obj.node.Account, opts); +// out.node.hash = rewrite_type('transaction', obj.node.hash, opts); + out.node.PreviousTxnID = out.node.PreviousTxnID = rewrite_type('transaction', obj.node.PreviousTxnID, opts); + out.node.PreviousTxnLgrSeq = rewrite_type('ledger', out.node.PreviousTxnLgrSeq, opts); } + + out.node.LedgerEntryType = '' + out.node.LedgerEntryType + ''; } return out; @@ -149,7 +257,8 @@ console.log("SERVE"); var _parsed = url.parse(req.url, true); var _url = JSON.stringify(_parsed, undefined, 2); - if (_parsed.pathname === "/account_root") { + console.log("HEADERS: %s", JSON.stringify(_parsed, undefined, 2)); + if (_parsed.pathname === "/account") { var request = remote .request_ledger_entry('account_root') .ledger_index(-1) @@ -157,99 +266,86 @@ console.log("SERVE"); .on('success', function (m) { console.log("account_root: %s", JSON.stringify(m, undefined, 2)); - res.statusCode = 200; - res.end( - "" - + "Title" - + "" - + "State: " + self.state - + "" - + "
"
-                        + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
-                        + "
" - + "" - + "" - ); + httpd_response(res, + { + statusCode: 200, + url: _url, + body: "
"
+                            + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
+                            + "
" + }); }) .request(); - } else if (_parsed.pathname === "/ledger_header") { - var request = remote - .request_ledger_header() - .ledger_index(-1) - .on('success', function (m) { - console.log("Ledger: %s", JSON.stringify(m, undefined, 2)); + } else if (_parsed.pathname === "/ledger") { + var request = remote + .request_ledger_header() + .on('success', function (m) { + console.log("Ledger: %s", JSON.stringify(m, undefined, 2)); - res.statusCode = 200; - res.end( - "" - + "Title" - + "" - + "State: " + self.state - + "" - + "
"
-                        + JSON.stringify(m, undefined, 2)
-                        + "
" - + "" - + "" - ); - }) - .request(); + httpd_response(res, + { + statusCode: 200, + url: _url, + body: "
"
+                          + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
+                          +"
" + }); + }) + + if (_parsed.query.l && _parsed.query.l.length === 64) { + request.ledger_hash(_parsed.query.l); + } + else if (_parsed.query.l) { + request.ledger_index(_parsed.query.l); + } + else { + request.ledger_index(-1); + } + + request.request(); } else if (_parsed.pathname === "/transaction") { var request = remote - .request_transaction_entry(_parsed.query.h) + .request_tx(_parsed.query.h) +// .request_transaction_entry(_parsed.query.h) // .ledger_select(_parsed.query.l) .on('success', function (m) { console.log("transaction: %s", JSON.stringify(m, undefined, 2)); - res.statusCode = 200; - res.end( - "" - + "Title" - + "" - + "State: " + self.state - + "" - + "
"
-                        + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
-                        + "
" - + "" - + "" - ); + httpd_response(res, + { + statusCode: 200, + url: _url, + body: "
"
+                            + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
+                            +"
" + }); + }) + .on('error', function (m) { + httpd_response(res, + { + statusCode: 200, + url: _url, + body: "
"
+                            + 'ERROR: ' + JSON.stringify(m, undefined, 2)
+                            +"
" + }); }) .request(); } else { var test = build_uri({ - type: 'account_root', + type: 'account', ledger: 'closed', account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', }, self.base); - res.statusCode = req.url === "/" ? 200 : 404; - res.end( - "" - + "Title" - + "" - + "State: " + self.state - + "" - + "
"+_url+"
" - + "" - + "" - ); + httpd_response(res, + { + statusCode: req.url === "/" ? 200 : 404, + url: _url, + }); } }); }); From 42c7ec79650e9899b498fa760e0218cba32f4c56 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 18 Mar 2013 18:07:03 -0700 Subject: [PATCH 12/16] Make sure we maintain cluster connections. --- src/cpp/ripple/ConnectionPool.cpp | 24 ++++++++++++++++++++++-- src/cpp/ripple/ConnectionPool.h | 5 ++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/cpp/ripple/ConnectionPool.cpp b/src/cpp/ripple/ConnectionPool.cpp index 89f0d55489..d17f38885e 100644 --- a/src/cpp/ripple/ConnectionPool.cpp +++ b/src/cpp/ripple/ConnectionPool.cpp @@ -209,6 +209,12 @@ void ConnectionPool::policyEnforce() // Enforce policies. policyLowWater(); + if (((++mPhase) % 12) == 0) + { + cLog(lsTRACE) << "Making configured connections"; + makeConfigured(); + } + // Schedule next enforcement. mPolicyTimer.expires_at(boost::posix_time::second_clock::universal_time()+boost::posix_time::seconds(POLICY_INTERVAL_SECONDS)); mPolicyTimer.async_wait(boost::bind(&ConnectionPool::policyHandler, this, _1)); @@ -313,11 +319,11 @@ Peer::pointer ConnectionPool::peerConnect(const std::string& strIp, int iPort) if (ppResult) { ppResult->connect(strIp, iPort); - //cLog(lsINFO) << "Pool: Connecting: " << ADDRESS_SHARED(ppResult) << ": " << strIp << " " << iPort; + cLog(lsTRACE) << "Pool: Connecting: " << ADDRESS_SHARED(ppResult) << ": " << strIp << " " << iPort; } else { - //cLog(lsINFO) << "Pool: Already connected: " << strIp << " " << iPort; + cLog(lsTRACE) << "Pool: Already connected: " << strIp << " " << iPort; } return ppResult; @@ -623,6 +629,20 @@ void ConnectionPool::scanHandler(const boost::system::error_code& ecResult) } } +void ConnectionPool::makeConfigured() +{ + if (theConfig.RUN_STANDALONE) + return; + + BOOST_FOREACH(const std::string& strPeer, theConfig.IPS) + { + std::string strIP; + int iPort; + if (parseIpPort(strPeer, strIP, iPort)) + peerConnect(strIP, iPort); + } +} + // Scan ips as per db entries. void ConnectionPool::scanRefresh() { diff --git a/src/cpp/ripple/ConnectionPool.h b/src/cpp/ripple/ConnectionPool.h index 3d1e3d3a4d..45ba2b6e95 100644 --- a/src/cpp/ripple/ConnectionPool.h +++ b/src/cpp/ripple/ConnectionPool.h @@ -18,6 +18,7 @@ class ConnectionPool private: boost::recursive_mutex mPeerLock; uint64 mLastPeer; + int mPhase; typedef std::pair naPeer; typedef std::pair pipPeer; @@ -59,7 +60,7 @@ private: public: ConnectionPool(boost::asio::io_service& io_service) : - mLastPeer(0), mScanTimer(io_service), mPolicyTimer(io_service) + mLastPeer(0), mPhase(0), mScanTimer(io_service), mPolicyTimer(io_service) { ; } // Begin enforcing connection policy. @@ -114,6 +115,8 @@ public: void policyLowWater(); void policyEnforce(); + // configured connections + void makeConfigured(); }; extern void splitIpPort(const std::string& strIpPort, std::string& strIp, int& iPort); From 1fdf27ca7220d0cf774c8d179f759116281ddf18 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 18 Mar 2013 21:18:07 -0700 Subject: [PATCH 13/16] Fix bug that causes ledger synching take much more CPU and memory than it should. --- src/cpp/ripple/SHAMapSync.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/ripple/SHAMapSync.cpp b/src/cpp/ripple/SHAMapSync.cpp index a06f3a4716..8d36c8f347 100644 --- a/src/cpp/ripple/SHAMapSync.cpp +++ b/src/cpp/ripple/SHAMapSync.cpp @@ -41,7 +41,7 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vector SHAMap::getNeededHashes(int max) stack.pop(); int base = rand() % 256; - bool have_all = false; + bool have_all = true; for (int ii = 0; ii < 16; ++ii) { // traverse in semi-random order int branch = (base + ii) % 16; From 5bc7e36df5d7a67ef8b403880f4061101706c513 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Mon, 18 Mar 2013 21:22:54 -0700 Subject: [PATCH 14/16] Fix the fix. --- src/cpp/ripple/SHAMapSync.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cpp/ripple/SHAMapSync.cpp b/src/cpp/ripple/SHAMapSync.cpp index 8d36c8f347..13c482f21e 100644 --- a/src/cpp/ripple/SHAMapSync.cpp +++ b/src/cpp/ripple/SHAMapSync.cpp @@ -72,14 +72,17 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vectorisInner() && !d->isFullBelow()) // we might need children of this node + { + have_all = false; stack.push(d); + } } } if (have_all) @@ -124,7 +127,10 @@ std::vector SHAMap::getNeededHashes(int max) SHAMapTreeNode* d = getNodePointer(childID, childHash); assert(d); if (d->isInner() && !d->isFullBelow()) + { + have_all = false; stack.push(d); + } } catch (SHAMapMissingNode&) { // node is not in the map From 05e8caa50a8f409760588a6b0ab793b4c3d319ac Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 19 Mar 2013 01:58:32 -0700 Subject: [PATCH 15/16] More work on browser.js. --- bin/browser.js | 106 +++++++++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/bin/browser.js b/bin/browser.js index 311d249544..30e83c3c36 100755 --- a/bin/browser.js +++ b/bin/browser.js @@ -100,6 +100,12 @@ console.log(link); return "" + item + ""; }; +var rewrite_field = function (type, obj, field, opts) { + if (field in obj) { + obj[field] = rewrite_type(type, obj[field], opts); + } +}; + var rewrite_type = function (type, obj, opts) { if ('amount' === type) { if ('string' === typeof obj) { @@ -107,7 +113,7 @@ var rewrite_type = function (type, obj, opts) { return '' + obj + ''; } else { - obj.issuer = rewrite_type('address', obj.issuer, opts); + rewrite_field('address', obj, 'issuer', opts); return obj; } @@ -137,7 +143,27 @@ var rewrite_type = function (type, obj, opts) { }, opts) ); } + else if ('node' === type) { + // A node + if ('PreviousTxnID' in obj) + obj.PreviousTxnID = rewrite_type('transaction', obj.PreviousTxnID, opts); + + if ('Offer' === obj.LedgerEntryType) { + if ('NewFields' in obj) { + if ('TakerGets' in obj.NewFields) + obj.NewFields.TakerGets = rewrite_type('amount', obj.NewFields.TakerGets, opts); + + if ('TakerPays' in obj.NewFields) + obj.NewFields.TakerPays = rewrite_type('amount', obj.NewFields.TakerPays, opts); + } + } + + obj.LedgerEntryType = '' + obj.LedgerEntryType + ''; + + return obj; + } else if ('transaction' === type) { + // Reference to a transaction. return build_link( obj, build_uri({ @@ -153,33 +179,12 @@ var rewrite_type = function (type, obj, opts) { var rewrite_object = function (obj, opts) { var out = extend({}, obj); - if ('TransactionType' in obj) { - // It's a transaction. - out.TransactionType = '' + obj.TransactionType + ''; + rewrite_field('address', out, 'Account', opts); - if ('TakerGets' in obj) - out.TakerGets = rewrite_type('amount', obj.TakerGets, opts); - - if ('TakerPays' in obj) - out.TakerPays = rewrite_type('amount', obj.TakerPays, opts); - } - - if ('Account' in obj) { - out.Account = rewrite_type('address', obj.Account, opts); - } - - if ('parent_hash' in obj) { - out.parent_hash = rewrite_type('ledger', out.parent_hash, opts); - } - if ('ledger_index' in obj) { - out.ledger_index = rewrite_type('ledger', out.ledger_index, opts); - } - if ('ledger_current_index' in obj) { - out.ledger_current_index = rewrite_type('ledger', out.ledger_current_index, opts); - } - if ('ledger_hash' in obj) { - out.ledger_hash = rewrite_type('ledger', out.ledger_hash, opts); - } + rewrite_field('ledger', out, 'parent_hash', opts); + rewrite_field('ledger', out, 'ledger_index', opts); + rewrite_field('ledger', out, 'ledger_current_index', opts); + rewrite_field('ledger', out, 'ledger_hash', opts); if ('ledger' in obj) { // It's a ledger header. @@ -192,13 +197,36 @@ var rewrite_object = function (obj, opts) { delete out.ledger.totalCoins; } - if ('node' in obj && 'LedgerEntryType' in obj.node) { + if ('TransactionType' in obj) { + // It's a transaction. + out.TransactionType = '' + obj.TransactionType + ''; + + rewrite_field('amount', out, 'TakerGets', opts); + rewrite_field('amount', out, 'TakerPays', opts); + rewrite_field('ledger', out, 'inLedger', opts); + + out.meta.AffectedNodes = out.meta.AffectedNodes.map(function (node) { + var kind = 'CreatedNode' in node + ? 'CreatedNode' + : 'ModifiedNode' in node + ? 'ModifiedNode' + : 'DeletedNode' in node + ? 'DeletedNode' + : undefined; + + if (kind) { + node[kind] = rewrite_type('node', node[kind], opts); + } + return node; + }); + } + else if ('node' in obj && 'LedgerEntryType' in obj.node) { // Its a ledger entry. if (obj.node.LedgerEntryType === 'AccountRoot') { out.node.Account = rewrite_type('address', obj.node.Account, opts); // out.node.hash = rewrite_type('transaction', obj.node.hash, opts); - out.node.PreviousTxnID = out.node.PreviousTxnID = rewrite_type('transaction', obj.node.PreviousTxnID, opts); + out.node.PreviousTxnID = rewrite_type('transaction', out.node.PreviousTxnID, opts); out.node.PreviousTxnLgrSeq = rewrite_type('ledger', out.node.PreviousTxnLgrSeq, opts); } @@ -217,7 +245,7 @@ else { var ip = process.argv.length > 4 ? process.argv[4] : "127.0.0.1"; var port = process.argv.length > 5 ? process.argv[5] : "8080"; -console.log("START"); +// console.log("START"); var self = this; self.base = { @@ -228,7 +256,7 @@ console.log("START"); var remote = (new Remote({ websocket_ip: ws_ip, websocket_port: ws_port, - trace: true +// trace: true })) .on('state', function (m) { console.log("STATE: %s", m); @@ -239,7 +267,7 @@ console.log("START"); .connect() ; -console.log("SERVE"); +// console.log("SERVE"); var server = http.createServer(function (req, res) { var input = ""; @@ -251,20 +279,20 @@ console.log("SERVE"); }); req.on('end', function () { - console.log("URL: %s", req.url); + // console.log("URL: %s", req.url); // console.log("HEADERS: %s", JSON.stringify(req.headers, undefined, 2)); var _parsed = url.parse(req.url, true); var _url = JSON.stringify(_parsed, undefined, 2); - console.log("HEADERS: %s", JSON.stringify(_parsed, undefined, 2)); + // console.log("HEADERS: %s", JSON.stringify(_parsed, undefined, 2)); if (_parsed.pathname === "/account") { var request = remote .request_ledger_entry('account_root') .ledger_index(-1) .account_root(_parsed.query.a) .on('success', function (m) { - console.log("account_root: %s", JSON.stringify(m, undefined, 2)); + // console.log("account_root: %s", JSON.stringify(m, undefined, 2)); httpd_response(res, { @@ -279,9 +307,9 @@ console.log("SERVE"); } else if (_parsed.pathname === "/ledger") { var request = remote - .request_ledger_header() + .request_ledger(undefined, { expand: true, transactions: true }) .on('success', function (m) { - console.log("Ledger: %s", JSON.stringify(m, undefined, 2)); + // console.log("Ledger: %s", JSON.stringify(m, undefined, 2)); httpd_response(res, { @@ -297,7 +325,7 @@ console.log("SERVE"); request.ledger_hash(_parsed.query.l); } else if (_parsed.query.l) { - request.ledger_index(_parsed.query.l); + request.ledger_index(Number(_parsed.query.l)); } else { request.ledger_index(-1); @@ -311,7 +339,7 @@ console.log("SERVE"); // .request_transaction_entry(_parsed.query.h) // .ledger_select(_parsed.query.l) .on('success', function (m) { - console.log("transaction: %s", JSON.stringify(m, undefined, 2)); + // console.log("transaction: %s", JSON.stringify(m, undefined, 2)); httpd_response(res, { From 9a7cbe0ce73a5af8f4e023349ba0be518edbfb35 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 19 Mar 2013 02:34:22 -0700 Subject: [PATCH 16/16] Only use c++11 for gcc 4.7 or later. --- SConstruct | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index f944d7799c..83dd04ef4e 100644 --- a/SConstruct +++ b/SConstruct @@ -4,6 +4,8 @@ import glob import platform +import commands +import re OSX = bool(platform.mac_ver()[0]) FreeBSD = bool('FreeBSD' == platform.system()) @@ -23,6 +25,8 @@ env = Environment( tools = ['default', 'protoc'] ) +GCC_VERSION = re.split('\.', commands.getoutput(env['CXX'] + ' -dumpversion')) + # Use clang #env.Replace(CC = 'clang') #env.Replace(CXX = 'clang++') @@ -100,7 +104,10 @@ BOOSTFLAGS = ['-DBOOST_TEST_DYN_LINK', '-DBOOST_FILESYSTEM_NO_DEPRECATED'] env.Append(LINKFLAGS = ['-rdynamic', '-pthread']) env.Append(CCFLAGS = ['-pthread', '-Wall', '-Wno-sign-compare', '-Wno-char-subscripts', '-DSQLITE_THREADSAFE=1']) -env.Append(CXXFLAGS = ['-O0', '-std=c++11', '-pthread', '-Wno-invalid-offsetof', '-Wformat']+BOOSTFLAGS+DEBUGFLAGS) +env.Append(CXXFLAGS = ['-O0', '-pthread', '-Wno-invalid-offsetof', '-Wformat']+BOOSTFLAGS+DEBUGFLAGS) + +if (GCC_VERSION[0] > 4 or (GCC_VERSION[0] == 4 and GCC_VERSION[1] >= 7)): + env.Append(CXXFLAGS = ['-std=c++11']) if OSX: env.Append(LINKFLAGS = ['-L/usr/local/opt/openssl/lib'])