diff --git a/SConstruct b/SConstruct index 6028302ff..1985cb8e1 100644 --- a/SConstruct +++ b/SConstruct @@ -47,7 +47,7 @@ else: # # Put objects files in their own directory. # -for dir in ['ripple', 'database', 'json', 'leveldb/db', 'leveldb/port', 'leveldb/include', 'leveldb/table', 'leveldb/util', 'websocketpp']: +for dir in ['.', 'ripple', 'database', 'json', 'leveldb/db', 'leveldb/port', 'leveldb/include', 'leveldb/table', 'leveldb/util', 'websocketpp']: VariantDir('build/obj/'+dir, 'src/cpp/'+dir, duplicate=0) # Use openssl @@ -118,19 +118,9 @@ if OSX: env.Append(CXXFLAGS = ['-I/usr/local/opt/openssl/include']) if LevelDB: - env.Append(CXXFLAGS = [ '-Isrc/cpp/leveldb', '-Isrc/cpp/leveldb/port', '-Isrc/cpp/leveldb/include', '-DUSE_LEVELDB', '-DLEVELDB_PLATFORM_POSIX']) + env.Append(CXXFLAGS = [ '-Isrc/cpp/leveldb', '-Isrc/cpp/leveldb/port', '-Isrc/cpp/leveldb/include', '-DUSE_LEVELDB']) - LEVELDB_PREFIX = 'src/cpp/leveldb' - PORTABLE_FILES = commands.getoutput('find ' - + LEVELDB_PREFIX + '/db ' - + LEVELDB_PREFIX + '/util ' - + LEVELDB_PREFIX + '/table ' - + ' -name *test*.cc -prune' - + ' -o -name *_bench.cc -prune' - + ' -o -name leveldb_main.cc -prune' - + ' -o -name "*.cc" -print | sort | tr "\n" " "').rstrip() - LEVELDB_SRCS = re.split(' ', PORTABLE_FILES) - LEVELDB_SRCS.append(LEVELDB_PREFIX + '/port/port_posix.cc') + LEVELDB_SRCS = [ 'src/cpp/leveldb_core.cpp' ] DB_SRCS = glob.glob('src/cpp/database/*.c') + glob.glob('src/cpp/database/*.cpp') JSON_SRCS = glob.glob('src/cpp/json/*.cpp') @@ -149,8 +139,9 @@ WEBSOCKETPP_SRCS = [ RIPPLE_SRCS = glob.glob('src/cpp/ripple/*.cpp') PROTO_SRCS = env.Protoc([], 'src/cpp/ripple/ripple.proto', PROTOCOUTDIR='build/proto', PROTOCPYTHONOUTDIR=None) env.Append(CXXFLAGS = ['-Ibuild/proto']) - env.Clean(PROTO_SRCS, 'site_scons/site_tools/protoc.pyc') +# PROTO_SRCS = [ 'src/cpp/protobuf_core.cpp' ] +# env.Append(CXXFLAGS = ['-Ibuild/proto', '-Isrc/cpp/protobuf/src', '-Isrc/cpp/protobuf/vsprojects' ]) # Remove unused source files. UNUSED_SRCS = [] diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 8bb7709e2..33344bcfd 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -256,6 +256,7 @@ bool Ledger::addTransaction(const uint256& txID, const Serializer& txn) cLog(lsWARNING) << "Attempt to add transaction to ledger that already had it"; return false; } + mValidHash = false; return true; } @@ -270,6 +271,7 @@ bool Ledger::addTransaction(const uint256& txID, const Serializer& txn, const Se cLog(lsFATAL) << "Attempt to add transaction+MD to ledger that already had it"; return false; } + mValidHash = false; return true; } diff --git a/src/cpp/ripple/LedgerMaster.cpp b/src/cpp/ripple/LedgerMaster.cpp index dd93c393e..56a28a802 100644 --- a/src/cpp/ripple/LedgerMaster.cpp +++ b/src/cpp/ripple/LedgerMaster.cpp @@ -18,6 +18,14 @@ uint32 LedgerMaster::getCurrentLedgerIndex() return mCurrentLedger->getLedgerSeq(); } +Ledger::ref LedgerMaster::getCurrentSnapshot() +{ + if (!mCurrentSnapshot || (mCurrentSnapshot->getHash() != mCurrentLedger->getHash())) + mCurrentSnapshot = boost::make_shared(boost::ref(*mCurrentLedger), false); + assert(mCurrentSnapshot->isImmutable()); + return mCurrentSnapshot; +} + void LedgerMaster::addHeldTransaction(Transaction::ref transaction) { // returns true if transaction was added boost::recursive_mutex::scoped_lock ml(mLock); diff --git a/src/cpp/ripple/LedgerMaster.h b/src/cpp/ripple/LedgerMaster.h index 2d872bbdc..dddffaa42 100644 --- a/src/cpp/ripple/LedgerMaster.h +++ b/src/cpp/ripple/LedgerMaster.h @@ -26,6 +26,7 @@ protected: TransactionEngine mEngine; Ledger::pointer mCurrentLedger; // The ledger we are currently processiong + Ledger::pointer mCurrentSnapshot; // Snapshot of the current ledger Ledger::pointer mFinalizedLedger; // The ledger that most recently closed Ledger::pointer mValidLedger; // The highest-sequence ledger we have fully accepted Ledger::pointer mPubLedger; // The last ledger we have published @@ -74,6 +75,9 @@ public: // The current ledger is the ledger we believe new transactions should go in Ledger::ref getCurrentLedger() { return mCurrentLedger; } + // An immutable snapshot of the current ledger + Ledger::ref getCurrentSnapshot(); + // The finalized ledger is the last closed/accepted ledger Ledger::ref getClosedLedger() { return mFinalizedLedger; } diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index c18f8b55c..94c522d50 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -183,6 +183,7 @@ public: Ledger::ref getClosedLedger() { return mLedgerMaster->getClosedLedger(); } Ledger::ref getValidatedLedger() { return mLedgerMaster->getValidatedLedger(); } Ledger::ref getCurrentLedger() { return mLedgerMaster->getCurrentLedger(); } + Ledger::ref getCurrentSnapshot() { return mLedgerMaster->getCurrentSnapshot(); } Ledger::pointer getLedgerByHash(const uint256& hash) { return mLedgerMaster->getLedgerByHash(hash); } Ledger::pointer getLedgerBySeq(const uint32 seq); void missingNodeInLedger(const uint32 seq); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index de444d4da..37ca82103 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -177,8 +177,7 @@ Json::Value RPCHandler::transactionSign(Json::Value jvRequest, bool bSubmit) return rpcError(rpcINVALID_PARAMS); } - Ledger::pointer lSnapshot = boost::make_shared( - boost::ref(*mNetOps->getCurrentLedger()), false); + Ledger::pointer lSnapshot = mNetOps->getCurrentSnapshot(); { ScopedUnlock su(theApp->getMasterLock()); bool bValid; @@ -1031,6 +1030,9 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL if (!lpLedger) return jvResult; + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); + if (!jvRequest.isMember("account")) return rpcError(rpcINVALID_PARAMS); @@ -1065,9 +1067,6 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL AccountState::pointer as = mNetOps->getAccountState(lpLedger, raAccount); - if (lpLedger->isImmutable()) - MasterLockHolder.unlock(); - if (as) { jvResult["account"] = raAccount.humanAccountID(); @@ -1124,6 +1123,9 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost, Scoped if (!lpLedger) return jvResult; + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); + if (!jvRequest.isMember("account")) return rpcError(rpcINVALID_PARAMS); @@ -1860,6 +1862,9 @@ Json::Value RPCHandler::doLedger(Json::Value jvRequest, int& cost, ScopedLock& M if (!lpLedger) return jvResult; + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); + bool bFull = jvRequest.isMember("full") && jvRequest["full"].asBool(); bool bTransactions = jvRequest.isMember("transactions") && jvRequest["transactions"].asBool(); bool bAccounts = jvRequest.isMember("accounts") && jvRequest["accounts"].asBool(); @@ -1869,15 +1874,6 @@ Json::Value RPCHandler::doLedger(Json::Value jvRequest, int& cost, ScopedLock& M | (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0) | (bAccounts ? LEDGER_JSON_DUMP_STATE : 0); - if ((bFull || bAccounts) && !lpLedger->isImmutable()) - { // For full or accounts, it's cheaper to snapshot - lpLedger = boost::make_shared(*lpLedger, false); - assert(lpLedger->isImmutable()); - } - - if (lpLedger->isImmutable()) - MasterLockHolder.unlock(); - Json::Value ret(Json::objectValue); lpLedger->addJson(ret, iOptions); @@ -2620,7 +2616,7 @@ Json::Value RPCHandler::lookupLedger(Json::Value jvRequest, Ledger::pointer& lpL switch (iLedgerIndex) { case LEDGER_CURRENT: - lpLedger = mNetOps->getCurrentLedger(); + lpLedger = mNetOps->getCurrentSnapshot(); iLedgerIndex = lpLedger->getLedgerSeq(); break;