From e3d844de8faf08ffe35baccf01043657a9c75ea7 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Tue, 11 Jun 2013 06:29:43 -0700 Subject: [PATCH] Add IApplication interface and hide the implementation --- modules/ripple_client/ripple_client.cpp | 72 +++-- modules/ripple_data/ripple_data.h | 9 + modules/ripple_main/ripple_main.cpp | 17 +- newcoin.vcxproj | 10 +- newcoin.vcxproj.filters | 15 +- src/cpp/ripple/Application.h | 133 --------- src/cpp/ripple/UpdateTables.cpp | 136 --------- src/cpp/ripple/main.cpp | 4 +- ...Application.cpp => ripple_Application.cpp} | 269 ++++++++++++++++-- src/cpp/ripple/ripple_HashedObjectStore.h | 1 + src/cpp/ripple/ripple_IApplication.h | 111 ++++++++ 11 files changed, 423 insertions(+), 354 deletions(-) delete mode 100644 src/cpp/ripple/Application.h delete mode 100644 src/cpp/ripple/UpdateTables.cpp rename src/cpp/ripple/{Application.cpp => ripple_Application.cpp} (65%) create mode 100644 src/cpp/ripple/ripple_IApplication.h diff --git a/modules/ripple_client/ripple_client.cpp b/modules/ripple_client/ripple_client.cpp index 7a8a285ef0..de2e1db2e7 100644 --- a/modules/ripple_client/ripple_client.cpp +++ b/modules/ripple_client/ripple_client.cpp @@ -26,49 +26,45 @@ #include #include -#if 0 - #include "ripple_client.h" #include "../ripple_basics/ripple_basics.h" #include "../ripple_data/ripple_data.h" +#include "src/cpp/ripple/ripple_InfoSub.h" + // Order and indentation reflect the hierarchy of dependencies - #include "src/cpp/ripple/ripple_HashedObject.h" - #include "src/cpp/ripple/ripple_SHAMapItem.h" - #include "src/cpp/ripple/ripple_SHAMapNode.h" - #include "src/cpp/ripple/ripple_SHAMapAddNode.h" - #include "src/cpp/ripple/ripple_SHAMapMissingNode.h" - #include "src/cpp/ripple/ripple_SHAMapTreeNode.h" - #include "src/cpp/ripple/ripple_SHAMapSyncFilter.h" - #include "src/cpp/ripple/ripple_SHAMap.h" - #include "src/cpp/ripple/ripple_SerializedTransaction.h" - #include "src/cpp/ripple/ripple_SerializedLedger.h" - #include "src/cpp/ripple/TransactionMeta.h" - #include "src/cpp/ripple/Transaction.h" - #include "src/cpp/ripple/AccountState.h" - #include "src/cpp/ripple/NicknameState.h" - #include "src/cpp/ripple/Ledger.h" - #include "src/cpp/ripple/LedgerEntrySet.h" - #include "src/cpp/ripple/TransactionEngine.h" - #include "src/cpp/ripple/LoadManager.h" - #include "src/cpp/ripple/ripple_Peer.h" - #include "src/cpp/ripple/ripple_PeerSet.h" - #include "src/cpp/ripple/ripple_LedgerAcquire.h" - #include "src/cpp/ripple/ripple_LedgerHistory.h" - #include "src/cpp/ripple/ripple_CanonicalTXSet.h" - #include "src/cpp/ripple/LedgerMaster.h" - #include "src/cpp/ripple/ripple_InfoSub.h" - #include "src/cpp/ripple/SerializedValidation.h" - #include "src/cpp/ripple/LedgerProposal.h" - #include "src/cpp/ripple/ripple_AcceptedLedgerTx.h" -#include "src/cpp/ripple/NetworkOPs.h" + #include "src/cpp/ripple/ripple_HashedObject.h" + #include "src/cpp/ripple/ripple_SHAMapItem.h" + #include "src/cpp/ripple/ripple_SHAMapNode.h" + #include "src/cpp/ripple/ripple_SHAMapAddNode.h" + #include "src/cpp/ripple/ripple_SHAMapMissingNode.h" + #include "src/cpp/ripple/ripple_SHAMapTreeNode.h" + #include "src/cpp/ripple/ripple_SHAMapSyncFilter.h" + #include "src/cpp/ripple/ripple_SHAMap.h" + #include "src/cpp/ripple/ripple_SerializedTransaction.h" + #include "src/cpp/ripple/ripple_SerializedLedger.h" + #include "src/cpp/ripple/TransactionMeta.h" + #include "src/cpp/ripple/Transaction.h" + #include "src/cpp/ripple/AccountState.h" + #include "src/cpp/ripple/NicknameState.h" + #include "src/cpp/ripple/Ledger.h" + #include "src/cpp/ripple/LedgerEntrySet.h" + #include "src/cpp/ripple/TransactionEngine.h" + #include "src/cpp/ripple/LoadManager.h" + #include "src/cpp/ripple/ripple_Peer.h" + #include "src/cpp/ripple/ripple_PeerSet.h" + #include "src/cpp/ripple/ripple_LedgerAcquire.h" + #include "src/cpp/ripple/ripple_LedgerHistory.h" + #include "src/cpp/ripple/ripple_CanonicalTXSet.h" + #include "src/cpp/ripple/LedgerMaster.h" + #include "src/cpp/ripple/ripple_InfoSub.h" + #include "src/cpp/ripple/SerializedValidation.h" + #include "src/cpp/ripple/LedgerProposal.h" + #include "src/cpp/ripple/ripple_AcceptedLedgerTx.h" + #include "src/cpp/ripple/NetworkOPs.h" + #include "src/cpp/ripple/ripple_IApplication.h" - -// Application.h needs too much stuff. - - #include "src/cpp/ripple/Application.h" -#include "src/cpp/ripple/ripple_InfoSub.cpp" - -#endif +#include "src/cpp/ripple/ripple_InfoSub.cpp" +//#include "src/cpp/ripple/NetworkOPs.cpp" diff --git a/modules/ripple_data/ripple_data.h b/modules/ripple_data/ripple_data.h index 14b687c4c0..cb899428ee 100644 --- a/modules/ripple_data/ripple_data.h +++ b/modules/ripple_data/ripple_data.h @@ -57,6 +57,15 @@ // VFALCO TODO try to reduce these dependencies #include "../ripple_basics/ripple_basics.h" +//------------------------------------------------------------------------------ + +// VFALCO TODO prepare a unity header for LevelDB +// VFALCO TODO don't expose leveldb throughout the headers +#include "leveldb/cache.h" +#include "leveldb/filter_policy.h" +#include "leveldb/db.h" +#include "leveldb/write_batch.h" + // VFALCO TODO figure out a good place for this file, perhaps give it some // additional hierarchy via directories. #include "ripple.pb.h" diff --git a/modules/ripple_main/ripple_main.cpp b/modules/ripple_main/ripple_main.cpp index 1687d36a90..0f72e445a1 100644 --- a/modules/ripple_main/ripple_main.cpp +++ b/modules/ripple_main/ripple_main.cpp @@ -40,6 +40,8 @@ #include #include +// VFALCO NOTE Holy smokes...that's a lot of boost!!! + #include #include #include @@ -81,14 +83,6 @@ //------------------------------------------------------------------------------ -// VFALCO TODO prepare a unity header for LevelDB -#include "leveldb/cache.h" -#include "leveldb/filter_policy.h" -#include "leveldb/db.h" -#include "leveldb/write_batch.h" - -//------------------------------------------------------------------------------ - // VFALCO TODO fix these warnings! #ifdef _MSC_VER //#pragma warning (push) // Causes spurious C4503 "decorated name exceeds maximum length" @@ -210,7 +204,7 @@ #include "src/cpp/ripple/OrderBookDB.h" #include "src/cpp/ripple/ripple_DatabaseCon.h" -#include "src/cpp/ripple/Application.h" +#include "src/cpp/ripple/ripple_IApplication.h" #include "src/cpp/ripple/AutoSocket.h" #include "src/cpp/ripple/CallRPC.h" #include "src/cpp/ripple/ChangeTransactor.h" @@ -276,7 +270,6 @@ static DH* handleTmpDh(SSL* ssl, int is_export, int iKeyLength) #include "src/cpp/ripple/AccountItems.cpp" // no log #include "src/cpp/ripple/AccountSetTransactor.cpp" #include "src/cpp/ripple/AccountState.cpp" // no log -#include "src/cpp/ripple/Application.cpp" #include "src/cpp/ripple/CallRPC.cpp" #include "src/cpp/ripple/ripple_CanonicalTXSet.cpp" #include "src/cpp/ripple/ChangeTransactor.cpp" // no log @@ -327,7 +320,6 @@ static DH* handleTmpDh(SSL* ssl, int is_export, int iKeyLength) #include "src/cpp/ripple/TransactionQueue.cpp" // no log #include "src/cpp/ripple/Transactor.cpp" #include "src/cpp/ripple/TrustSetTransactor.cpp" -#include "src/cpp/ripple/UpdateTables.cpp" #include "src/cpp/ripple/Wallet.cpp" #include "src/cpp/ripple/WalletAddTransactor.cpp" #include "src/cpp/ripple/WSDoor.cpp" // uses logging in WSConnection.h @@ -344,13 +336,14 @@ static DH* handleTmpDh(SSL* ssl, int is_export, int iKeyLength) #include "src/cpp/ripple/ripple_AcceptedLedgerTx.cpp" #include "src/cpp/ripple/ripple_AcceptedLedger.cpp" +#include "src/cpp/ripple/ripple_Application.cpp" #include "src/cpp/ripple/ripple_Config.cpp" #include "src/cpp/ripple/ripple_DatabaseCon.cpp" #include "src/cpp/ripple/ripple_Features.cpp" #include "src/cpp/ripple/ripple_FeeVote.cpp" #include "src/cpp/ripple/ripple_HashedObjectStore.cpp" #include "src/cpp/ripple/ripple_HashRouter.cpp" -#include "src/cpp/ripple/ripple_InfoSub.cpp" +//#include "src/cpp/ripple/ripple_InfoSub.cpp" #include "src/cpp/ripple/ripple_Job.cpp" #include "src/cpp/ripple/ripple_JobQueue.cpp" #include "src/cpp/ripple/ripple_LedgerAcquire.cpp" diff --git a/newcoin.vcxproj b/newcoin.vcxproj index 3cdc157df2..bd058cc8bd 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -734,7 +734,7 @@ true true - + true true true @@ -1264,12 +1264,6 @@ true true - - true - true - true - true - true true @@ -1702,7 +1696,7 @@ - + diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index 9eac0f386b..a3f77cb535 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -579,18 +579,12 @@ 1. Modules\ripple_data\protobuf - - 1. Modules\ripple_main\_unfactored\main - 1. Modules\ripple_main\_unfactored\main 1. Modules\ripple_main\_unfactored\main - - 1. Modules\ripple_main\_unfactored\main - 1. Modules\ripple_main\_unfactored\network @@ -840,6 +834,9 @@ 1. Modules\ripple_main\_unfactored\ledger + + 1. Modules\ripple_main\_unfactored\main + @@ -1316,9 +1313,6 @@ 1. Modules\ripple_data\protobuf - - 1. Modules\ripple_main\_unfactored\main - 1. Modules\ripple_main\_unfactored\main @@ -1583,6 +1577,9 @@ 1. Modules\ripple_main\_unfactored\ledger + + 1. Modules\ripple_main\_unfactored\main + diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h deleted file mode 100644 index 0e8080ad8e..0000000000 --- a/src/cpp/ripple/Application.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef RIPPLE_APPLICATION_H -#define RIPPLE_APPLICATION_H - -// VFALCO TODO Fix forward declares required for header dependency loops -class IFeatures; -class IFeeVote; -class IHashRouter; -class ILoadFeeTrack; -class IValidations; -class IUniqueNodeList; -class IProofOfWorkFactory; -class IPeers; - -class RPCDoor; -class PeerDoor; - -typedef TaggedCache NodeCache; -typedef TaggedCache SLECache; - -class Application -{ -public: - Application(); - ~Application(); - - Wallet& getWallet() { return mWallet ; } - NetworkOPs& getOPs() { return mNetOps; } - - boost::asio::io_service& getIOService() { return mIOService; } - boost::asio::io_service& getAuxService() { return mAuxService; } - - LedgerMaster& getLedgerMaster() { return mLedgerMaster; } - LedgerAcquireMaster& getMasterLedgerAcquire() { return mMasterLedgerAcquire; } - TransactionMaster& getMasterTransaction() { return mMasterTransaction; } - NodeCache& getTempNodeCache() { return mTempNodeCache; } - HashedObjectStore& getHashedObjectStore() { return mHashedObjectStore; } - JobQueue& getJobQueue() { return mJobQueue; } - boost::recursive_mutex& getMasterLock() { return mMasterLock; } - LoadManager& getLoadManager() { return mLoadMgr; } - TXQueue& getTxnQueue() { return mTxnQueue; } - PeerDoor& getPeerDoor() { return *mPeerDoor; } - OrderBookDB& getOrderBookDB() { return mOrderBookDB; } - SLECache& getSLECache() { return mSLECache; } - - IFeatures& getFeatureTable() { return *mFeatures; } - ILoadFeeTrack& getFeeTrack() { return *mFeeTrack; } - IFeeVote& getFeeVote() { return *mFeeVote; } - IHashRouter& getHashRouter() { return *mHashRouter; } - IValidations& getValidations() { return *mValidations; } - IUniqueNodeList& getUNL() { return *mUNL; } - IProofOfWorkFactory& getProofOfWorkFactory() { return *mProofOfWorkFactory; } - IPeers& getPeers () { return *mPeers; } - - // VFALCO TODO Move these to the .cpp - bool running() { return mTxnDB != NULL; } // VFALCO TODO replace with nullptr when beast is available - bool getSystemTimeOffset(int& offset) { return mSNTPClient.getOffset(offset); } - - DatabaseCon* getRpcDB() { return mRpcDB; } - DatabaseCon* getTxnDB() { return mTxnDB; } - DatabaseCon* getLedgerDB() { return mLedgerDB; } - DatabaseCon* getWalletDB() { return mWalletDB; } - DatabaseCon* getNetNodeDB() { return mNetNodeDB; } - DatabaseCon* getPathFindDB() { return mPathFindDB; } - DatabaseCon* getHashNodeDB() { return mHashNodeDB; } - - leveldb::DB* getHashNodeLDB() { return mHashNodeLDB; } - leveldb::DB* getEphemeralLDB() { return mEphemeralLDB; } - - bool isShutdown() { return mShutdown; } - void setup(); - void run(); - void stop(); - void sweep(); - -private: - void updateTables (bool); - void startNewLedger (); - bool loadOldLedger (const std::string&); - - boost::asio::io_service mIOService; - boost::asio::io_service mAuxService; - boost::asio::io_service::work mIOWork; - boost::asio::io_service::work mAuxWork; - - boost::recursive_mutex mMasterLock; - - Wallet mWallet; - LedgerMaster mLedgerMaster; - LedgerAcquireMaster mMasterLedgerAcquire; - TransactionMaster mMasterTransaction; - NetworkOPs mNetOps; - NodeCache mTempNodeCache; - HashedObjectStore mHashedObjectStore; - SLECache mSLECache; - SNTPClient mSNTPClient; - JobQueue mJobQueue; - LoadManager mLoadMgr; - TXQueue mTxnQueue; - OrderBookDB mOrderBookDB; - - // VFALCO Clean stuff - beast::ScopedPointer mFeatures; - beast::ScopedPointer mFeeVote; - beast::ScopedPointer mFeeTrack; - beast::ScopedPointer mHashRouter; - beast::ScopedPointer mValidations; - beast::ScopedPointer mUNL; - beast::ScopedPointer mProofOfWorkFactory; - beast::ScopedPointer mPeers; - // VFALCO End Clean stuff - - DatabaseCon *mRpcDB, *mTxnDB, *mLedgerDB, *mWalletDB, *mNetNodeDB, *mPathFindDB, *mHashNodeDB; - - leveldb::DB *mHashNodeLDB; - leveldb::DB *mEphemeralLDB; - - PeerDoor* mPeerDoor; - RPCDoor* mRPCDoor; - WSDoor* mWSPublicDoor; - WSDoor* mWSPrivateDoor; - - boost::asio::deadline_timer mSweepTimer; - - std::map mPeerMap; - boost::recursive_mutex mPeerMapLock; - - volatile bool mShutdown; -}; - -extern Application* theApp; - -#endif -// vim:ts=4 diff --git a/src/cpp/ripple/UpdateTables.cpp b/src/cpp/ripple/UpdateTables.cpp deleted file mode 100644 index d9ce1c989b..0000000000 --- a/src/cpp/ripple/UpdateTables.cpp +++ /dev/null @@ -1,136 +0,0 @@ - -//VFALCO TODO clean this up since it is just a file holding a single member function definition - -static std::vector getSchema(DatabaseCon* dbc, const std::string& dbName) -{ - std::vector schema; - - std::string sql = "SELECT sql FROM sqlite_master WHERE tbl_name='"; - sql += dbName; - sql += "';"; - - SQL_FOREACH(dbc->getDB(), sql) - { - dbc->getDB()->getStr("sql", sql); - schema.push_back(sql); - } - - return schema; -} - -static bool schemaHas(DatabaseCon* dbc, const std::string& dbName, int line, const std::string& content) -{ - std::vector schema = getSchema(dbc, dbName); - if (static_cast(schema.size()) <= line) - { - Log(lsFATAL) << "Schema for " << dbName << " has too few lines"; - throw std::runtime_error("bad schema"); - } - return schema[line].find(content) != std::string::npos; -} - -static void addTxnSeqField() -{ - if (schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "TxnSeq")) - return; - Log(lsWARNING) << "Transaction sequence field is missing"; - - Database* db = theApp->getTxnDB()->getDB(); - - std::vector< std::pair > txIDs; - txIDs.reserve(300000); - - Log(lsINFO) << "Parsing transactions"; - int i = 0; - uint256 transID; - SQL_FOREACH(db, "SELECT TransID,TxnMeta FROM Transactions;") - { - Blob rawMeta; - int metaSize = 2048; - rawMeta.resize(metaSize); - metaSize = db->getBinary("TxnMeta", &*rawMeta.begin(), rawMeta.size()); - if (metaSize > static_cast(rawMeta.size())) - { - rawMeta.resize(metaSize); - db->getBinary("TxnMeta", &*rawMeta.begin(), rawMeta.size()); - } - else rawMeta.resize(metaSize); - - std::string tid; - db->getStr("TransID", tid); - transID.SetHex(tid, true); - - if (rawMeta.size() == 0) - { - txIDs.push_back(std::make_pair(transID, -1)); - Log(lsINFO) << "No metadata for " << transID; - } - else - { - TransactionMetaSet m(transID, 0, rawMeta); - txIDs.push_back(std::make_pair(transID, m.getIndex())); - } - - if ((++i % 1000) == 0) - Log(lsINFO) << i << " transactions read"; - } - - Log(lsINFO) << "All " << i << " transactions read"; - - db->executeSQL("BEGIN TRANSACTION;"); - - Log(lsINFO) << "Dropping old index"; - db->executeSQL("DROP INDEX AcctTxIndex;"); - - Log(lsINFO) << "Altering table"; - db->executeSQL("ALTER TABLE AccountTransactions ADD COLUMN TxnSeq INTEGER;"); - - typedef std::pair u256_int_pair_t; - boost::format fmt("UPDATE AccountTransactions SET TxnSeq = %d WHERE TransID = '%s';"); - i = 0; - BOOST_FOREACH(u256_int_pair_t& t, txIDs) - { - db->executeSQL(boost::str(fmt % t.second % t.first.GetHex())); - if ((++i % 1000) == 0) - Log(lsINFO) << i << " transactions updated"; - } - - Log(lsINFO) << "Building new index"; - db->executeSQL("CREATE INDEX AcctTxIndex ON AccountTransactions(Account, LedgerSeq, TxnSeq, TransID);"); - db->executeSQL("END TRANSACTION;"); -} - -void Application::updateTables(bool ldbImport) -{ // perform any needed table updates - assert(schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "TransID")); - assert(!schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "foobar")); - addTxnSeqField(); - - if (schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "PRIMARY")) - { - Log(lsFATAL) << "AccountTransactions database should not have a primary key"; - StopSustain(); - exit(1); - } - - if (theApp->getHashedObjectStore().isLevelDB()) - { - boost::filesystem::path hashPath = theConfig.DATA_DIR / "hashnode.db"; - if (boost::filesystem::exists(hashPath)) - { - if (theConfig.LDB_IMPORT) - { - Log(lsWARNING) << "Importing SQLite -> LevelDB"; - theApp->getHashedObjectStore().import(hashPath.string()); - Log(lsWARNING) << "Remove or remname the hashnode.db file"; - } - else - { - Log(lsWARNING) << "SQLite hashnode database exists. Please either remove or import"; - Log(lsWARNING) << "To import, start with the '--import' option. Otherwise, remove hashnode.db"; - StopSustain(); - exit(1); - } - } - } -} diff --git a/src/cpp/ripple/main.cpp b/src/cpp/ripple/main.cpp index fd6d197866..de7c50bc37 100644 --- a/src/cpp/ripple/main.cpp +++ b/src/cpp/ripple/main.cpp @@ -10,7 +10,7 @@ using namespace boost::unit_test; void setupServer() { - theApp = new Application(); + theApp = IApplication::New (); theApp->setup(); } @@ -43,7 +43,7 @@ void startServer() bool init_unit_test() { - theApp = new Application(); + theApp = IApplication::New (); return true; } diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/ripple_Application.cpp similarity index 65% rename from src/cpp/ripple/Application.cpp rename to src/cpp/ripple/ripple_Application.cpp index 803d304c25..40d98ebcdb 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/ripple_Application.cpp @@ -1,27 +1,125 @@ -// VFALCO TODO Replace these with beast "unsigned long long" generators -#define SYSTEM_CURRENCY_GIFT 1000ull -#define SYSTEM_CURRENCY_USERS 100000000ull -#define SYSTEM_CURRENCY_PARTS 1000000ull // 10^SYSTEM_CURRENCY_PRECISION -#define SYSTEM_CURRENCY_START (SYSTEM_CURRENCY_GIFT*SYSTEM_CURRENCY_USERS*SYSTEM_CURRENCY_PARTS) -/* VFALCO NOTE +IApplication* theApp = NULL; - The master lock protects: - - The open ledger - - Server global state - * What the last closed ledger is - * State of the consensus engine - - other things -*/ +class Application; SETUP_LOG (Application) // VFALCO TODO fix/clean this, it might have broken with the Log changes LogPartition AutoSocketPartition("AutoSocket"); -Application* theApp = NULL; + +// VFALCO TODO Move the function definitions into the class declaration +class Application : public IApplication +{ +public: + Application(); + ~Application(); + + Wallet& getWallet() { return mWallet ; } + NetworkOPs& getOPs() { return mNetOps; } + + boost::asio::io_service& getIOService() { return mIOService; } + boost::asio::io_service& getAuxService() { return mAuxService; } + + LedgerMaster& getLedgerMaster() { return mLedgerMaster; } + LedgerAcquireMaster& getMasterLedgerAcquire() { return mMasterLedgerAcquire; } + TransactionMaster& getMasterTransaction() { return mMasterTransaction; } + NodeCache& getTempNodeCache() { return mTempNodeCache; } + HashedObjectStore& getHashedObjectStore() { return mHashedObjectStore; } + JobQueue& getJobQueue() { return mJobQueue; } + boost::recursive_mutex& getMasterLock() { return mMasterLock; } + LoadManager& getLoadManager() { return mLoadMgr; } + TXQueue& getTxnQueue() { return mTxnQueue; } + PeerDoor& getPeerDoor() { return *mPeerDoor; } + OrderBookDB& getOrderBookDB() { return mOrderBookDB; } + SLECache& getSLECache() { return mSLECache; } + + IFeatures& getFeatureTable() { return *mFeatures; } + ILoadFeeTrack& getFeeTrack() { return *mFeeTrack; } + IFeeVote& getFeeVote() { return *mFeeVote; } + IHashRouter& getHashRouter() { return *mHashRouter; } + IValidations& getValidations() { return *mValidations; } + IUniqueNodeList& getUNL() { return *mUNL; } + IProofOfWorkFactory& getProofOfWorkFactory() { return *mProofOfWorkFactory; } + IPeers& getPeers () { return *mPeers; } + + // VFALCO TODO Move these to the .cpp + bool running() { return mTxnDB != NULL; } // VFALCO TODO replace with nullptr when beast is available + bool getSystemTimeOffset(int& offset) { return mSNTPClient.getOffset(offset); } + + DatabaseCon* getRpcDB() { return mRpcDB; } + DatabaseCon* getTxnDB() { return mTxnDB; } + DatabaseCon* getLedgerDB() { return mLedgerDB; } + DatabaseCon* getWalletDB() { return mWalletDB; } + DatabaseCon* getNetNodeDB() { return mNetNodeDB; } + DatabaseCon* getPathFindDB() { return mPathFindDB; } + DatabaseCon* getHashNodeDB() { return mHashNodeDB; } + + leveldb::DB* getHashNodeLDB() { return mHashNodeLDB; } + leveldb::DB* getEphemeralLDB() { return mEphemeralLDB; } + + bool isShutdown() { return mShutdown; } + void setup(); + void run(); + void stop(); + void sweep(); + +private: + void updateTables (bool); + void startNewLedger (); + bool loadOldLedger (const std::string&); + + boost::asio::io_service mIOService; + boost::asio::io_service mAuxService; + boost::asio::io_service::work mIOWork; + boost::asio::io_service::work mAuxWork; + + boost::recursive_mutex mMasterLock; + + Wallet mWallet; + LedgerMaster mLedgerMaster; + LedgerAcquireMaster mMasterLedgerAcquire; + TransactionMaster mMasterTransaction; + NetworkOPs mNetOps; + NodeCache mTempNodeCache; + HashedObjectStore mHashedObjectStore; + SLECache mSLECache; + SNTPClient mSNTPClient; + JobQueue mJobQueue; + LoadManager mLoadMgr; + TXQueue mTxnQueue; + OrderBookDB mOrderBookDB; + + // VFALCO Clean stuff + beast::ScopedPointer mFeatures; + beast::ScopedPointer mFeeVote; + beast::ScopedPointer mFeeTrack; + beast::ScopedPointer mHashRouter; + beast::ScopedPointer mValidations; + beast::ScopedPointer mUNL; + beast::ScopedPointer mProofOfWorkFactory; + beast::ScopedPointer mPeers; + // VFALCO End Clean stuff + + DatabaseCon *mRpcDB, *mTxnDB, *mLedgerDB, *mWalletDB, *mNetNodeDB, *mPathFindDB, *mHashNodeDB; + + leveldb::DB *mHashNodeLDB; + leveldb::DB *mEphemeralLDB; + + PeerDoor* mPeerDoor; + RPCDoor* mRPCDoor; + WSDoor* mWSPublicDoor; + WSDoor* mWSPrivateDoor; + + boost::asio::deadline_timer mSweepTimer; + + std::map mPeerMap; + boost::recursive_mutex mPeerMapLock; + + volatile bool mShutdown; +}; Application::Application () : mIOService ((theConfig.NODE_SIZE >= 2) ? 2 : 1) @@ -568,4 +666,143 @@ bool serverOkay(std::string& reason) return true; } -// vim:ts=4 +//VFALCO TODO clean this up since it is just a file holding a single member function definition + +static std::vector getSchema(DatabaseCon* dbc, const std::string& dbName) +{ + std::vector schema; + + std::string sql = "SELECT sql FROM sqlite_master WHERE tbl_name='"; + sql += dbName; + sql += "';"; + + SQL_FOREACH(dbc->getDB(), sql) + { + dbc->getDB()->getStr("sql", sql); + schema.push_back(sql); + } + + return schema; +} + +static bool schemaHas(DatabaseCon* dbc, const std::string& dbName, int line, const std::string& content) +{ + std::vector schema = getSchema(dbc, dbName); + if (static_cast(schema.size()) <= line) + { + Log(lsFATAL) << "Schema for " << dbName << " has too few lines"; + throw std::runtime_error("bad schema"); + } + return schema[line].find(content) != std::string::npos; +} + +static void addTxnSeqField() +{ + if (schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "TxnSeq")) + return; + Log(lsWARNING) << "Transaction sequence field is missing"; + + Database* db = theApp->getTxnDB()->getDB(); + + std::vector< std::pair > txIDs; + txIDs.reserve(300000); + + Log(lsINFO) << "Parsing transactions"; + int i = 0; + uint256 transID; + SQL_FOREACH(db, "SELECT TransID,TxnMeta FROM Transactions;") + { + Blob rawMeta; + int metaSize = 2048; + rawMeta.resize(metaSize); + metaSize = db->getBinary("TxnMeta", &*rawMeta.begin(), rawMeta.size()); + if (metaSize > static_cast(rawMeta.size())) + { + rawMeta.resize(metaSize); + db->getBinary("TxnMeta", &*rawMeta.begin(), rawMeta.size()); + } + else rawMeta.resize(metaSize); + + std::string tid; + db->getStr("TransID", tid); + transID.SetHex(tid, true); + + if (rawMeta.size() == 0) + { + txIDs.push_back(std::make_pair(transID, -1)); + Log(lsINFO) << "No metadata for " << transID; + } + else + { + TransactionMetaSet m(transID, 0, rawMeta); + txIDs.push_back(std::make_pair(transID, m.getIndex())); + } + + if ((++i % 1000) == 0) + Log(lsINFO) << i << " transactions read"; + } + + Log(lsINFO) << "All " << i << " transactions read"; + + db->executeSQL("BEGIN TRANSACTION;"); + + Log(lsINFO) << "Dropping old index"; + db->executeSQL("DROP INDEX AcctTxIndex;"); + + Log(lsINFO) << "Altering table"; + db->executeSQL("ALTER TABLE AccountTransactions ADD COLUMN TxnSeq INTEGER;"); + + typedef std::pair u256_int_pair_t; + boost::format fmt("UPDATE AccountTransactions SET TxnSeq = %d WHERE TransID = '%s';"); + i = 0; + BOOST_FOREACH(u256_int_pair_t& t, txIDs) + { + db->executeSQL(boost::str(fmt % t.second % t.first.GetHex())); + if ((++i % 1000) == 0) + Log(lsINFO) << i << " transactions updated"; + } + + Log(lsINFO) << "Building new index"; + db->executeSQL("CREATE INDEX AcctTxIndex ON AccountTransactions(Account, LedgerSeq, TxnSeq, TransID);"); + db->executeSQL("END TRANSACTION;"); +} + +void Application::updateTables(bool ldbImport) +{ // perform any needed table updates + assert(schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "TransID")); + assert(!schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "foobar")); + addTxnSeqField(); + + if (schemaHas(theApp->getTxnDB(), "AccountTransactions", 0, "PRIMARY")) + { + Log(lsFATAL) << "AccountTransactions database should not have a primary key"; + StopSustain(); + exit(1); + } + + if (theApp->getHashedObjectStore().isLevelDB()) + { + boost::filesystem::path hashPath = theConfig.DATA_DIR / "hashnode.db"; + if (boost::filesystem::exists(hashPath)) + { + if (theConfig.LDB_IMPORT) + { + Log(lsWARNING) << "Importing SQLite -> LevelDB"; + theApp->getHashedObjectStore().import(hashPath.string()); + Log(lsWARNING) << "Remove or remname the hashnode.db file"; + } + else + { + Log(lsWARNING) << "SQLite hashnode database exists. Please either remove or import"; + Log(lsWARNING) << "To import, start with the '--import' option. Otherwise, remove hashnode.db"; + StopSustain(); + exit(1); + } + } + } +} + +IApplication* IApplication::New () +{ + return new Application; +} diff --git a/src/cpp/ripple/ripple_HashedObjectStore.h b/src/cpp/ripple/ripple_HashedObjectStore.h index 06244f2220..279e121547 100644 --- a/src/cpp/ripple/ripple_HashedObjectStore.h +++ b/src/cpp/ripple/ripple_HashedObjectStore.h @@ -3,6 +3,7 @@ /** Persistency layer for hashed objects. */ +// VFALCO TODO Move all definitions to the .cpp class HashedObjectStore { public: diff --git a/src/cpp/ripple/ripple_IApplication.h b/src/cpp/ripple/ripple_IApplication.h new file mode 100644 index 0000000000..f745244cbd --- /dev/null +++ b/src/cpp/ripple/ripple_IApplication.h @@ -0,0 +1,111 @@ +#ifndef RIPPLE_IAPPLICATION_H +#define RIPPLE_IAPPLICATION_H + +// VFALCO TODO Replace these with beast "unsigned long long" generators +// VFALCO NOTE Apparently these are used elsewhere. Make them constants in the config +// or in the IApplication +// +#define SYSTEM_CURRENCY_GIFT 1000ull +#define SYSTEM_CURRENCY_USERS 100000000ull +#define SYSTEM_CURRENCY_PARTS 1000000ull // 10^SYSTEM_CURRENCY_PRECISION +#define SYSTEM_CURRENCY_START (SYSTEM_CURRENCY_GIFT*SYSTEM_CURRENCY_USERS*SYSTEM_CURRENCY_PARTS) + +// VFALCO TODO Fix forward declares required for header dependency loops +class IFeatures; +class IFeeVote; +class IHashRouter; +class ILoadFeeTrack; +class IPeers; +class IProofOfWorkFactory; +class IUniqueNodeList; +class IValidations; + +class HashedObjectStore; +class JobQueue; +class LedgerAcquireMaster; +class LedgerMaster; +class LoadManager; +class NetworkOPs; +class OrderBookDB; +class PeerDoor; +class SerializedLedgerEntry; +class TransactionMaster; +class TXQueue; +class Wallet; + +class DatabaseCon; + +typedef TaggedCache NodeCache; +typedef TaggedCache SLECache; + +class IApplication +{ +public: + static IApplication* New (); + + virtual ~IApplication () { } + + /* VFALCO NOTE + + The master lock protects: + + - The open ledger + - Server global state + * What the last closed ledger is + * State of the consensus engine + + other things + */ + virtual boost::recursive_mutex& getMasterLock () = 0; + + virtual boost::asio::io_service& getIOService () = 0; + virtual boost::asio::io_service& getAuxService () = 0; + + virtual NodeCache& getTempNodeCache () = 0; + virtual SLECache& getSLECache () = 0; + + virtual IFeatures& getFeatureTable () = 0; + virtual IFeeVote& getFeeVote () = 0; + virtual IHashRouter& getHashRouter () = 0; + virtual ILoadFeeTrack& getFeeTrack () = 0; + virtual IPeers& getPeers () = 0; + virtual IProofOfWorkFactory& getProofOfWorkFactory () = 0; + virtual IUniqueNodeList& getUNL () = 0; + virtual IValidations& getValidations () = 0; + + virtual HashedObjectStore& getHashedObjectStore () = 0; + virtual JobQueue& getJobQueue () = 0; + virtual LedgerAcquireMaster& getMasterLedgerAcquire () = 0; + virtual LedgerMaster& getLedgerMaster () = 0; + virtual LoadManager& getLoadManager () = 0; + virtual NetworkOPs& getOPs () = 0; + virtual OrderBookDB& getOrderBookDB () = 0; + virtual PeerDoor& getPeerDoor () = 0; + virtual TransactionMaster& getMasterTransaction () = 0; + virtual TXQueue& getTxnQueue () = 0; + virtual Wallet& getWallet () = 0; + + virtual DatabaseCon* getRpcDB () = 0; + virtual DatabaseCon* getTxnDB () = 0; + virtual DatabaseCon* getLedgerDB () = 0; + virtual DatabaseCon* getWalletDB () = 0; + virtual DatabaseCon* getNetNodeDB () = 0; + virtual DatabaseCon* getPathFindDB () = 0; + virtual DatabaseCon* getHashNodeDB () = 0; + + virtual leveldb::DB* getHashNodeLDB () = 0; + virtual leveldb::DB* getEphemeralLDB () = 0; + + virtual bool getSystemTimeOffset (int& offset) = 0; + virtual bool isShutdown () = 0; + virtual bool running () = 0; + virtual void setup () = 0; + virtual void run () = 0; + virtual void stop () = 0; + virtual void sweep () = 0; +}; + +extern IApplication* theApp; + +#endif +// vim:ts=4