From 6aca65ff76d41a6fd2480d178febb4e56c539bbe Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 28 Nov 2012 15:27:20 -0800 Subject: [PATCH 1/7] Get the shared pointers out of the scoped lock stuff. We don't need it. --- src/cpp/ripple/Application.h | 2 +- src/cpp/ripple/HashedObject.cpp | 6 +++--- src/cpp/ripple/Ledger.cpp | 2 +- src/cpp/ripple/LedgerConsensus.cpp | 2 +- src/cpp/ripple/NetworkOPs.cpp | 4 ++-- src/cpp/ripple/RPCHandler.cpp | 2 +- src/cpp/ripple/ScopedLock.h | 6 ++++-- src/cpp/ripple/Transaction.cpp | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h index 343d592637..a7518299e4 100644 --- a/src/cpp/ripple/Application.h +++ b/src/cpp/ripple/Application.h @@ -35,7 +35,7 @@ public: DatabaseCon(const std::string& name, const char *initString[], int countInit); ~DatabaseCon(); Database* getDB() { return mDatabase; } - ScopedLock getDBLock() { return ScopedLock(mLock); } + boost::recursive_mutex& getDBLock() { return mLock; } }; class Application diff --git a/src/cpp/ripple/HashedObject.cpp b/src/cpp/ripple/HashedObject.cpp index 7765574ad6..d64e33a644 100644 --- a/src/cpp/ripple/HashedObject.cpp +++ b/src/cpp/ripple/HashedObject.cpp @@ -53,7 +53,7 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index, void HashedObjectStore::waitWrite() { - boost::unique_lock sl(mWriteMutex); + boost::mutex::scoped_lock sl(mWriteMutex); while (mWritePending) mWriteCondition.wait(sl); } @@ -67,7 +67,7 @@ void HashedObjectStore::bulkWrite() set.reserve(128); { - boost::unique_lock sl(mWriteMutex); + boost::mutex::scoped_lock sl(mWriteMutex); mWriteSet.swap(set); assert(mWriteSet.empty()); if (set.empty()) @@ -85,7 +85,7 @@ void HashedObjectStore::bulkWrite() Database* db = theApp->getHashNodeDB()->getDB(); { - ScopedLock sl = theApp->getHashNodeDB()->getDBLock(); + ScopedLock sl( theApp->getHashNodeDB()->getDBLock()); db->executeSQL("BEGIN TRANSACTION;"); diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 334f561549..1f1b2e565b 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -369,7 +369,7 @@ void Ledger::saveAcceptedLedger(bool fromConsensus) SHAMap& txSet = *peekTransactionMap(); Database *db = theApp->getTxnDB()->getDB(); - ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); + ScopedLock dbLock(theApp->getTxnDB()->getDBLock()); db->executeSQL("BEGIN TRANSACTION;"); SHAMapTreeNode::TNType type; for (SHAMapItem::pointer item = txSet.peekFirstItem(type); !!item; diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index ef32c11531..e3e867d90a 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -1251,7 +1251,7 @@ void LedgerConsensus::accept(SHAMap::ref set, LoadEvent::pointer) cLog(lsINFO) << "CNF newLCL " << newLCLHash; Ledger::pointer newOL = boost::make_shared(true, boost::ref(*newLCL)); - ScopedLock sl = theApp->getLedgerMaster().getLock(); + ScopedLock sl( theApp->getLedgerMaster().getLock()); // Apply disputed transactions that didn't get in TransactionEngine engine(newOL); diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 97adc8e9f2..cd2c13af4f 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -888,7 +888,7 @@ std::vector< std::pair > { Database* db = theApp->getTxnDB()->getDB(); - ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); + ScopedLock sl(theApp->getTxnDB()->getDBLock()); SQL_FOREACH(db, sql) { @@ -909,7 +909,7 @@ std::vector RippleAddress acct; { Database* db = theApp->getTxnDB()->getDB(); - ScopedLock dblock = theApp->getTxnDB()->getDBLock(); + ScopedLock sl(theApp->getTxnDB()->getDBLock()); SQL_FOREACH(db, sql) { if (acct.setAccountID(db->getStrBinary("Account"))) diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 1765efcdf2..bed264410f 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1158,7 +1158,7 @@ Json::Value RPCHandler::doTxHistory(const Json::Value& params) { Database* db = theApp->getTxnDB()->getDB(); - ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); + ScopedLock sl (theApp->getTxnDB()->getDBLock()); SQL_FOREACH(db, sql) { diff --git a/src/cpp/ripple/ScopedLock.h b/src/cpp/ripple/ScopedLock.h index 5f85b83ed3..e0859fd774 100644 --- a/src/cpp/ripple/ScopedLock.h +++ b/src/cpp/ripple/ScopedLock.h @@ -6,16 +6,18 @@ #include #include +typedef boost::recursive_mutex::scoped_lock ScopedLock; + // A lock holder that can be returned and copied by value // When the last reference goes away, the lock is released -class ScopedLock +class SharedScopedLock { protected: mutable boost::shared_ptr mHolder; public: - ScopedLock(boost::recursive_mutex& mutex) : + SharedScopedLock(boost::recursive_mutex& mutex) : mHolder(boost::make_shared(boost::ref(mutex))) { ; } void lock() const { mHolder->lock(); } diff --git a/src/cpp/ripple/Transaction.cpp b/src/cpp/ripple/Transaction.cpp index 304494826c..be3c21752d 100644 --- a/src/cpp/ripple/Transaction.cpp +++ b/src/cpp/ripple/Transaction.cpp @@ -150,7 +150,7 @@ bool Transaction::save() % mTransaction->getTransactionID().GetHex()); Database *db = theApp->getTxnDB()->getDB(); - ScopedLock dbLock = theApp->getTxnDB()->getDBLock(); + ScopedLock dbLock(theApp->getTxnDB()->getDBLock()); if (SQL_EXISTS(db, exists)) return false; return db->executeSQL(mTransaction->getSQLInsertHeader() + mTransaction->getSQL(getLedger(), status) + ";"); From bfbf0aa18567c9abf738cc7c00d1c14313a88aa8 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 28 Nov 2012 15:34:47 -0800 Subject: [PATCH 2/7] Eliminate redundant write set waits. You don't need to wait on future write sets. --- src/cpp/ripple/HashedObject.cpp | 8 +++++--- src/cpp/ripple/HashedObject.h | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cpp/ripple/HashedObject.cpp b/src/cpp/ripple/HashedObject.cpp index d64e33a644..fe94aaf045 100644 --- a/src/cpp/ripple/HashedObject.cpp +++ b/src/cpp/ripple/HashedObject.cpp @@ -12,7 +12,7 @@ SETUP_LOG(); DECLARE_INSTANCE(HashedObject); HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) : - mCache("HashedObjectStore", cacheSize, cacheAge), mWritePending(false) + mCache("HashedObjectStore", cacheSize, cacheAge), mWritePending(false), mWriteGeneration(0) { mWriteSet.reserve(128); } @@ -54,7 +54,8 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index, void HashedObjectStore::waitWrite() { boost::mutex::scoped_lock sl(mWriteMutex); - while (mWritePending) + int gen = mWriteGeneration; + while (mWritePending && (mWriteGeneration == gen)) mWriteCondition.wait(sl); } @@ -70,10 +71,11 @@ void HashedObjectStore::bulkWrite() boost::mutex::scoped_lock sl(mWriteMutex); mWriteSet.swap(set); assert(mWriteSet.empty()); + ++mWriteGeneration; + mWriteCondition.notify_all(); if (set.empty()) { mWritePending = false; - mWriteCondition.notify_all(); return; } } diff --git a/src/cpp/ripple/HashedObject.h b/src/cpp/ripple/HashedObject.h index 20a187fb72..69c5e55f79 100644 --- a/src/cpp/ripple/HashedObject.h +++ b/src/cpp/ripple/HashedObject.h @@ -47,8 +47,9 @@ class HashedObjectStore protected: TaggedCache mCache; - boost::mutex mWriteMutex; - boost::condition_variable mWriteCondition; + boost::mutex mWriteMutex; + boost::condition_variable mWriteCondition; + int mWriteGeneration; std::vector< boost::shared_ptr > mWriteSet; bool mWritePending; From 8ba70c73f619efd503104c508dd047a69eb538b6 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 28 Nov 2012 15:35:12 -0800 Subject: [PATCH 3/7] Make some boost::format objects static. --- src/cpp/ripple/Transaction.cpp | 7 ++++--- src/cpp/ripple/utils.h | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cpp/ripple/Transaction.cpp b/src/cpp/ripple/Transaction.cpp index be3c21752d..5305c784f4 100644 --- a/src/cpp/ripple/Transaction.cpp +++ b/src/cpp/ripple/Transaction.cpp @@ -146,12 +146,13 @@ bool Transaction::save() default: status = TXN_SQL_UNKNOWN; } - std::string exists = boost::str(boost::format("SELECT Status FROM Transactions WHERE TransID = '%s';") - % mTransaction->getTransactionID().GetHex()); + static boost::format selStat("SELECT Status FROM Transactions WHERE TransID = '%s';"); + std::string exists = boost::str(selStat % mTransaction->getTransactionID().GetHex()); Database *db = theApp->getTxnDB()->getDB(); ScopedLock dbLock(theApp->getTxnDB()->getDBLock()); - if (SQL_EXISTS(db, exists)) return false; + if (SQL_EXISTS(db, exists)) + return false; return db->executeSQL(mTransaction->getSQLInsertHeader() + mTransaction->getSQL(getLedger(), status) + ";"); } diff --git a/src/cpp/ripple/utils.h b/src/cpp/ripple/utils.h index 7667df578a..c6568d5104 100644 --- a/src/cpp/ripple/utils.h +++ b/src/cpp/ripple/utils.h @@ -154,7 +154,8 @@ inline std::string strHex(const uint64 uiHost) inline static std::string sqlEscape(const std::string& strSrc) { - return str(boost::format("X'%s'") % strHex(strSrc)); + static boost::format f("X'%s'"); + return str(f % strHex(strSrc)); } template From 72777b6b839a66e6c5b8d4cf374ae914a147566c Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 28 Nov 2012 15:53:07 -0800 Subject: [PATCH 4/7] Remove some shared pointers on load monitors. --- src/cpp/ripple/HashedObject.cpp | 2 +- src/cpp/ripple/JobQueue.h | 2 ++ src/cpp/ripple/Ledger.cpp | 8 ++++---- src/cpp/ripple/Ledger.h | 3 ++- src/cpp/ripple/LoadMonitor.h | 3 ++- src/cpp/ripple/NetworkOPs.cpp | 2 +- src/cpp/ripple/Peer.cpp | 2 +- src/cpp/ripple/RPCHandler.cpp | 2 +- src/cpp/ripple/ValidationCollection.cpp | 2 +- 9 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/cpp/ripple/HashedObject.cpp b/src/cpp/ripple/HashedObject.cpp index fe94aaf045..d430272a37 100644 --- a/src/cpp/ripple/HashedObject.cpp +++ b/src/cpp/ripple/HashedObject.cpp @@ -61,7 +61,7 @@ void HashedObjectStore::waitWrite() void HashedObjectStore::bulkWrite() { - LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtDISK); + LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtDISK)); while (1) { std::vector< boost::shared_ptr > set; diff --git a/src/cpp/ripple/JobQueue.h b/src/cpp/ripple/JobQueue.h index ca91a06f19..6dc495da7e 100644 --- a/src/cpp/ripple/JobQueue.h +++ b/src/cpp/ripple/JobQueue.h @@ -104,6 +104,8 @@ public: LoadEvent::pointer getLoadEvent(JobType t) { return boost::make_shared(boost::ref(mJobLoads[t]), true, 1); } + LoadEvent::autoptr getLoadEventAP(JobType t) + { return LoadEvent::autoptr(new LoadEvent(mJobLoads[t], true, 1)); } Json::Value getJson(int c = 0); }; diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 1f1b2e565b..2e9482e0fe 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -339,9 +339,8 @@ uint256 Ledger::getHash() return mHash; } -void Ledger::saveAcceptedLedger(bool fromConsensus) +void Ledger::saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer event) { // can be called in a different thread - LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtDISK); cLog(lsTRACE) << "saveAcceptedLedger " << (fromConsensus ? "fromConsensus " : "fromAcquire ") << getLedgerSeq(); static boost::format ledgerExists("SELECT LedgerSeq FROM Ledgers where LedgerSeq = %d;"); static boost::format deleteLedger("DELETE FROM Ledgers WHERE LedgerSeq = %d;"); @@ -439,7 +438,7 @@ void Ledger::saveAcceptedLedger(bool fromConsensus) } theApp->getLedgerMaster().setFullLedger(shared_from_this()); - event = LoadEvent::pointer(); + event->stop(); theApp->getOPs().pubLedger(shared_from_this()); @@ -1136,7 +1135,8 @@ void Ledger::pendSave(bool fromConsensus) if (!fromConsensus && !theApp->isNewFlag(getHash(), SF_SAVED)) return; - boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, shared_from_this(), fromConsensus)); + boost::thread thread(boost::bind(&Ledger::saveAcceptedLedger, shared_from_this(), + fromConsensus, theApp->getJobQueue().getLoadEvent(jtDISK))); thread.detach(); boost::recursive_mutex::scoped_lock sl(sPendingSaveLock); diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index 64bf9ef4a6..7f9556c3ed 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -19,6 +19,7 @@ #include "BitcoinUtil.h" #include "SHAMap.h" #include "InstanceCounter.h" +#include "LoadMonitor.h" enum LedgerStateParms { @@ -93,7 +94,7 @@ protected: static void incPendingSaves(); static void decPendingSaves(); - void saveAcceptedLedger(bool fromConsensus); + void saveAcceptedLedger(bool fromConsensus, LoadEvent::pointer); public: Ledger(const RippleAddress& masterID, uint64 startAmount); // used for the starting bootstrap ledger diff --git a/src/cpp/ripple/LoadMonitor.h b/src/cpp/ripple/LoadMonitor.h index 992046c178..6eb259a792 100644 --- a/src/cpp/ripple/LoadMonitor.h +++ b/src/cpp/ripple/LoadMonitor.h @@ -36,7 +36,8 @@ public: class LoadEvent { public: - typedef boost::shared_ptr pointer; + typedef boost::shared_ptr pointer; + typedef std::auto_ptr autoptr; protected: LoadMonitor& mMonitor; diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index cd2c13af4f..e67d8eb927 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1002,7 +1002,7 @@ void NetworkOPs::pubLedger(Ledger::ref lpAccepted) if (NetworkOPs::omDISCONNECTED == getOperatingMode()) return; - LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtPUBLEDGER); + LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtPUBLEDGER)); { boost::recursive_mutex::scoped_lock sl(mMonitorLock); diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp index f14b4411ba..f207cba9b1 100644 --- a/src/cpp/ripple/Peer.cpp +++ b/src/cpp/ripple/Peer.cpp @@ -373,7 +373,7 @@ void Peer::processReadBuffer() // std::cerr << "Peer::processReadBuffer: " << mIpPort.first << " " << mIpPort.second << std::endl; - LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtPEER); + LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtPEER)); boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock()); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index bed264410f..2e94baa2a8 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1482,7 +1482,7 @@ Json::Value RPCHandler::doCommand(const std::string& command, Json::Value& param cLog(lsTRACE) << "RPC:" << command; cLog(lsTRACE) << "RPC params:" << params; - LoadEvent::pointer le = theApp->getJobQueue().getLoadEvent(jtRPC); + LoadEvent::autoptr le(theApp->getJobQueue().getLoadEventAP(jtRPC)); mRole = role; diff --git a/src/cpp/ripple/ValidationCollection.cpp b/src/cpp/ripple/ValidationCollection.cpp index cab64a9508..f663b2c2a1 100644 --- a/src/cpp/ripple/ValidationCollection.cpp +++ b/src/cpp/ripple/ValidationCollection.cpp @@ -289,7 +289,7 @@ void ValidationCollection::condWrite() void ValidationCollection::doWrite() { - LoadEvent::pointer event = theApp->getJobQueue().getLoadEvent(jtDISK); + LoadEvent::autoptr event(theApp->getJobQueue().getLoadEventAP(jtDISK)); static boost::format insVal("INSERT INTO LedgerValidations " "(LedgerHash,NodePubKey,Flags,SignTime,Signature) VALUES ('%s','%s','%u','%u',%s);"); From 5cf15b3f4e4b027827f5faf7348864247bd4c91b Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 28 Nov 2012 20:49:07 -0800 Subject: [PATCH 5/7] Shutdown cleanly on control-C. --- src/cpp/ripple/Application.cpp | 16 ++++++++++++++++ src/cpp/ripple/LedgerConsensus.cpp | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 7a4bfadef1..61b6005a2d 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -71,8 +71,24 @@ static void InitDB(DatabaseCon** dbCon, const char *fileName, const char *dbInit *dbCon = new DatabaseCon(fileName, dbInit, dbCount); } +volatile bool doShutdown = false; + +#ifdef SIGINT +void sigIntHandler(int) +{ + doShutdown = true; +} +#endif + void Application::run() { +#ifdef SIGINT + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sigIntHandler; + sigaction(SIGINT, &sa, NULL); +#endif + assert(mTxnDB == NULL); if (!theConfig.DEBUG_LOGFILE.empty()) { // Let DEBUG messages go to the file but only WARNING or higher to regular output (unless verbose) diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index e3e867d90a..7401461e86 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -644,8 +644,16 @@ void LedgerConsensus::stateAccepted() endConsensus(); } +extern volatile bool doShutdown; + void LedgerConsensus::timerEntry() { + if (doShutdown) + { + cLog(lsFATAL) << "Shutdown requested"; + theApp->stop(); + } + if ((mState != lcsFINISHED) && (mState != lcsACCEPTED)) checkLCL(); From 2664229017735a8aa4362e8c56ead7270ed3783b Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 29 Nov 2012 09:00:05 -0800 Subject: [PATCH 6/7] Fix a compiler warning. --- src/cpp/ripple/HashedObject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/ripple/HashedObject.cpp b/src/cpp/ripple/HashedObject.cpp index d430272a37..f59a186fe1 100644 --- a/src/cpp/ripple/HashedObject.cpp +++ b/src/cpp/ripple/HashedObject.cpp @@ -12,7 +12,7 @@ SETUP_LOG(); DECLARE_INSTANCE(HashedObject); HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) : - mCache("HashedObjectStore", cacheSize, cacheAge), mWritePending(false), mWriteGeneration(0) + mCache("HashedObjectStore", cacheSize, cacheAge), mWriteGeneration(0), mWritePending(false) { mWriteSet.reserve(128); } From 377747fb2cd325e4d5afd384e32819630281b4f0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 29 Nov 2012 09:00:16 -0800 Subject: [PATCH 7/7] Helper function. --- src/cpp/ripple/Ledger.cpp | 23 +++++++++++++++++++++++ src/cpp/ripple/Ledger.h | 3 +++ 2 files changed, 26 insertions(+) diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 2e9482e0fe..fc6567d3bf 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -299,6 +299,29 @@ SerializedTransaction::pointer Ledger::getSTransaction(SHAMapItem::ref item, SHA return SerializedTransaction::pointer(); } +SerializedTransaction::pointer Ledger::getSMTransaction(SHAMapItem::ref item, SHAMapTreeNode::TNType type, + TransactionMetaSet::pointer& txMeta) +{ + SerializerIterator sit(item->peekSerializer()); + + if (type == SHAMapTreeNode::tnTRANSACTION_NM) + { + txMeta.reset(); + return boost::make_shared(boost::ref(sit)); + } + else if (type == SHAMapTreeNode::tnTRANSACTION_MD) + { + Serializer sTxn(sit.getVL()); + SerializerIterator tSit(sTxn); + + txMeta = boost::make_shared(item->getTag(), mLedgerSeq, sit.getVL()); + return boost::make_shared(boost::ref(tSit)); + } + + txMeta.reset(); + return SerializedTransaction::pointer(); +} + bool Ledger::getTransaction(const uint256& txID, Transaction::pointer& txn, TransactionMetaSet::pointer& meta) { SHAMapTreeNode::TNType type; diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index 7f9556c3ed..d9ddc14cb4 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -161,7 +161,10 @@ public: bool hasTransaction(const uint256& TransID) const { return mTransactionMap->hasItem(TransID); } Transaction::pointer getTransaction(const uint256& transID) const; bool getTransaction(const uint256& transID, Transaction::pointer& txn, TransactionMetaSet::pointer& txMeta); + static SerializedTransaction::pointer getSTransaction(SHAMapItem::ref, SHAMapTreeNode::TNType); + SerializedTransaction::pointer getSMTransaction(SHAMapItem::ref, SHAMapTreeNode::TNType, + TransactionMetaSet::pointer& txMeta); // high-level functions AccountState::pointer getAccountState(const RippleAddress& acctID);