#ifndef __NETWORK_OPS__ #define __NETWORK_OPS__ #include #include #include #include #include "AccountState.h" #include "LedgerMaster.h" #include "NicknameState.h" #include "RippleState.h" #include "SerializedValidation.h" #include "LedgerAcquire.h" #include "LedgerProposal.h" // Operations that clients may wish to perform against the network // Master operational handler, server sequencer, network tracker class Peer; class LedgerConsensus; class InfoSub { public: virtual ~InfoSub() { ; } virtual void send(const Json::Value& jvObj) = 0; }; class NetworkOPs { public: enum Fault { // exceptions these functions can throw IO_ERROR = 1, NO_NETWORK = 2, }; enum OperatingMode { // how we process transactions or account balance requests omDISCONNECTED = 0, // not ready to process requests omCONNECTED = 1, // convinced we are talking to the network omTRACKING = 2, // convinced we agree with the network omFULL = 3 // we have the ledger and can even validate }; protected: typedef boost::unordered_map > subInfoMapType; typedef boost::unordered_map >::value_type subInfoMapValue; typedef boost::unordered_map >::iterator subInfoMapIterator; OperatingMode mMode; boost::posix_time::ptime mConnectTime; boost::asio::deadline_timer mNetTimer; boost::shared_ptr mConsensus; boost::unordered_map > mDeferredProposals; LedgerMaster* mLedgerMaster; LedgerAcquire::pointer mAcquiringLedger; int mCloseTimeOffset; // last ledger close int mLastCloseProposers, mLastCloseConvergeTime; uint256 mLastCloseHash; uint32 mLastCloseTime; uint32 mLastValidationTime; // XXX Split into more locks. boost::interprocess::interprocess_upgradable_mutex mMonitorLock; subInfoMapType mBootAccountInfo; subInfoMapType mSubAccountInfo; subInfoMapType mSubAccountTransaction; boost::unordered_set mSubLedger; // ledger accepteds boost::unordered_set mSubLedgerAccounts; // ledger accepteds + affected accounts boost::unordered_set mSubTransaction; // all transactions // subInfoMapType mSubTransactionAccounts; void setMode(OperatingMode); Json::Value transJson(const SerializedTransaction& stTxn, TER terResult, const std::string& strStatus, int iSeq, const std::string& strType); void pubTransactionAll(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState); void pubTransactionAccounts(Ledger::ref lpCurrent, const SerializedTransaction& stTxn, TER terResult, const char* pState); Json::Value pubBootstrapAccountInfo(Ledger::ref lpAccepted, const NewcoinAddress& naAccountID); public: NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster); // network information uint32 getNetworkTimeNC(); uint32 getCloseTimeNC(); uint32 getValidationTimeNC(); void closeTimeOffset(int); boost::posix_time::ptime getNetworkTimePT(); uint32 getCurrentLedgerID(); OperatingMode getOperatingMode() { return mMode; } inline bool available() { // XXX Later this can be relaxed to omCONNECTED return mMode >= omTRACKING; } uint256 getClosedLedger() { return mLedgerMaster->getClosedLedger()->getHash(); } // FIXME: This function is basically useless since the hash is constantly changing and the ledger // is ephemeral and mutable. uint256 getCurrentLedger() { return mLedgerMaster->getCurrentLedger()->getHash(); } // // Transaction operations // Transaction::pointer submitTransaction(const Transaction::pointer& tpTrans); Transaction::pointer processTransaction(Transaction::pointer transaction, Peer* source = NULL); Transaction::pointer findTransactionByID(const uint256& transactionID); int findTransactionsBySource(const uint256& uLedger, std::list&, const NewcoinAddress& sourceAccount, uint32 minSeq, uint32 maxSeq); int findTransactionsByDestination(std::list&, const NewcoinAddress& destinationAccount, uint32 startLedgerSeq, uint32 endLedgerSeq, int maxTransactions); // // Account functions // AccountState::pointer getAccountState(const uint256& uLedger, const NewcoinAddress& accountID); SLE::pointer getGenerator(const uint256& uLedger, const uint160& uGeneratorID); // // Directory functions // STVector256 getDirNodeInfo(const uint256& uLedger, const uint256& uRootIndex, uint64& uNodePrevious, uint64& uNodeNext); // // Nickname functions // NicknameState::pointer getNicknameState(const uint256& uLedger, const std::string& strNickname); // // Owner functions // Json::Value getOwnerInfo(const uint256& uLedger, const NewcoinAddress& naAccount); Json::Value getOwnerInfo(Ledger::pointer lpLedger, const NewcoinAddress& naAccount); // raw object operations bool findRawLedger(const uint256& ledgerHash, std::vector& rawLedger); bool findRawTransaction(const uint256& transactionHash, std::vector& rawTransaction); bool findAccountNode(const uint256& nodeHash, std::vector& rawAccountNode); bool findTransactionNode(const uint256& nodeHash, std::vector& rawTransactionNode); // tree synchronization operations bool getTransactionTreeNodes(uint32 ledgerSeq, const uint256& myNodeID, const std::vector& myNode, std::list< std::vector >& newNodes); bool getAccountStateNodes(uint32 ledgerSeq, const uint256& myNodeId, const std::vector& myNode, std::list< std::vector >& newNodes); // ledger proposal/close functions bool recvPropose(uint32 proposeSeq, const uint256& proposeHash, const uint256& prevLedger, uint32 closeTime, const std::string& pubKey, const std::string& signature, const NewcoinAddress& nodePublic); bool gotTXData(const boost::shared_ptr& peer, const uint256& hash, const std::list& nodeIDs, const std::list< std::vector >& nodeData); bool recvValidation(const SerializedValidation::pointer& val); SHAMap::pointer getTXMap(const uint256& hash); bool hasTXSet(const boost::shared_ptr& peer, const uint256& set, newcoin::TxSetStatus status); void mapComplete(const uint256& hash, SHAMap::ref map); // network state machine void checkState(const boost::system::error_code& result); void switchLastClosedLedger(Ledger::pointer newLedger, bool duringConsensus); // Used for the "jump" case bool checkLastClosedLedger(const std::vector&, uint256& networkClosed); int beginConsensus(const uint256& networkClosed, Ledger::pointer closingLedger); void endConsensus(bool correctLCL); void setStandAlone() { setMode(omFULL); } void setStateTimer(); void newLCL(int proposers, int convergeTime, const uint256& ledgerHash); void consensusViewChange(); int getPreviousProposers() { return mLastCloseProposers; } int getPreviousConvergeTime() { return mLastCloseConvergeTime; } uint32 getLastCloseTime() { return mLastCloseTime; } void setLastCloseTime(uint32 t) { mLastCloseTime = t; } Json::Value getServerInfo(); // client information retrieval functions std::vector< std::pair > getAffectedAccounts(const NewcoinAddress& account, uint32 minLedger, uint32 maxLedger); std::vector getLedgerAffectedAccounts(uint32 ledgerSeq); std::vector getLedgerTransactions(uint32 ledgerSeq); // // Monitoring: publisher side // void pubAccountInfo(const NewcoinAddress& naAccountID, const Json::Value& jvObj); void pubLedger(Ledger::ref lpAccepted); void pubTransaction(Ledger::ref lpLedger, const SerializedTransaction& stTxn, TER terResult); // // Monitoring: subscriber side // // --> vnaAddress: empty = all void subAccountInfo(InfoSub* ispListener, const boost::unordered_set& vnaAccountIDs); void unsubAccountInfo(InfoSub* ispListener, const boost::unordered_set& vnaAccountIDs); void subAccountTransaction(InfoSub* ispListener, const boost::unordered_set& vnaAccountIDs); void unsubAccountTransaction(InfoSub* ispListener, const boost::unordered_set& vnaAccountIDs); // void subAccountChanges(InfoSub* ispListener, const uint256 uLedgerHash); // void unsubAccountChanges(InfoSub* ispListener); bool subLedger(InfoSub* ispListener); bool unsubLedger(InfoSub* ispListener); bool subLedgerAccounts(InfoSub* ispListener); bool unsubLedgerAccounts(InfoSub* ispListener); bool subTransaction(InfoSub* ispListener); bool unsubTransaction(InfoSub* ispListener); }; #endif // vim:ts=4