#ifndef __PEER__ #define __PEER__ #include #include #include #include #include #include #include "ripple.pb.h" #include "PackedMessage.h" #include "Ledger.h" #include "Transaction.h" #include "InstanceCounter.h" #include "JobQueue.h" #include "ProofOfWork.h" #include "LoadManager.h" typedef std::pair ipPort; DEFINE_INSTANCE(Peer); class Peer : public boost::enable_shared_from_this, public IS_INSTANCE(Peer) { public: typedef boost::shared_ptr pointer; typedef const boost::shared_ptr& ref; static const int psbGotHello = 0, psbSentHello = 1, psbInMap = 2, psbTrusted = 3; static const int psbNoLedgers = 4, psbNoTransactions = 5, psbDownLevel = 6; void handleConnect(const boost::system::error_code& error, boost::asio::ip::tcp::resolver::iterator it); private: bool mInbound; // Connection is inbound bool mClientConnect; // In process of connecting as client. bool mHelloed; // True, if hello accepted. bool mDetaching; // True, if detaching. int mActive; // 0=idle, 1=pingsent, 2=active bool mCluster; // Node in our cluster RippleAddress mNodePublic; // Node public key of peer. std::string mNodeName; ipPort mIpPort; ipPort mIpPortConnect; uint256 mCookieHash; uint64 mPeerId; bool mPrivate; // Keep peer IP private. LoadSource mLoad; uint32 mMinLedger, mMaxLedger; uint256 mClosedLedgerHash; uint256 mPreviousLedgerHash; std::list mRecentLedgers; std::list mRecentTxSets; boost::asio::ssl::stream mSocketSsl; boost::asio::deadline_timer mActivityTimer; void handleStart(const boost::system::error_code& ecResult); void handleVerifyTimer(const boost::system::error_code& ecResult); void handlePingTimer(const boost::system::error_code& ecResult); protected: boost::asio::io_service::strand mIOStrand; std::vector mReadbuf; std::list mSendQ; PackedMessage::pointer mSendingPacket; ripple::TMStatusChange mLastStatus; ripple::TMHello mHello; Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx, uint64 peerId, bool inbound); void handleShutdown(const boost::system::error_code& error) { ; } void handleWrite(const boost::system::error_code& error, size_t bytes_transferred); void handleReadHeader(const boost::system::error_code& error); void handleReadBody(const boost::system::error_code& error); void processReadBuffer(); void startReadHeader(); void startReadBody(unsigned msg_len); void sendPacketForce(const PackedMessage::pointer& packet); void sendHello(); void recvHello(ripple::TMHello& packet); void recvTransaction(ripple::TMTransaction& packet); void recvValidation(const boost::shared_ptr& packet); void recvGetValidation(ripple::TMGetValidations& packet); void recvContact(ripple::TMContact& packet); void recvGetContacts(ripple::TMGetContacts& packet); void recvGetPeers(ripple::TMGetPeers& packet); void recvPeers(ripple::TMPeers& packet); void recvGetObjectByHash(const boost::shared_ptr& packet); void recvPing(ripple::TMPing& packet); void recvErrorMessage(ripple::TMErrorMsg& packet); void recvSearchTransaction(ripple::TMSearchTransaction& packet); void recvGetAccount(ripple::TMGetAccount& packet); void recvAccount(ripple::TMAccount& packet); void recvGetLedger(ripple::TMGetLedger& packet, ScopedLock& MasterLockHolder); void recvLedger(const boost::shared_ptr& packet); void recvStatus(ripple::TMStatusChange& packet); void recvPropose(const boost::shared_ptr& packet); void recvHaveTxSet(ripple::TMHaveTransactionSet& packet); void recvProofWork(ripple::TMProofWork& packet); void getSessionCookie(std::string& strDst); void addLedger(const uint256& ledger); void addTxSet(const uint256& TxSet); void doFetchPack(const boost::shared_ptr& packet); static void doProofOfWork(Job&, boost::weak_ptr, ProofOfWork::pointer); public: //bool operator == (const Peer& other); std::string& getIP() { return mIpPort.first; } std::string getDisplayName() { return mCluster ? mNodeName : mIpPort.first; } int getPort() { return mIpPort.second; } void setIpPort(const std::string& strIP, int iPort); static pointer create(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx, uint64 id, bool inbound) { return pointer(new Peer(io_service, ctx, id, inbound)); } boost::asio::ssl::stream::lowest_layer_type& getSocket() { return mSocketSsl.lowest_layer(); } void connect(const std::string& strIp, int iPort); void connected(const boost::system::error_code& error); void detach(const char *, bool onIOStrand); bool samePeer(Peer::ref p) { return samePeer(*p); } bool samePeer(const Peer& p) { return this == &p; } void sendPacket(const PackedMessage::pointer& packet, bool onStrand); void sendLedgerProposal(Ledger::ref ledger); void sendFullLedger(Ledger::ref ledger); void sendGetFullLedger(uint256& hash); void sendGetPeers(); void punishPeer(LoadType); static void punishPeer(const boost::weak_ptr&, LoadType); Json::Value getJson(); bool isConnected() const { return mHelloed && !mDetaching; } bool isInbound() const { return mInbound; } bool isOutbound() const { return !mInbound; } const uint256& getClosedLedgerHash() const { return mClosedLedgerHash; } bool hasLedger(const uint256& hash, uint32 seq) const; bool hasTxSet(const uint256& hash) const; uint64 getPeerId() const { return mPeerId; } const RippleAddress& getNodePublic() const { return mNodePublic; } void cycleStatus() { mPreviousLedgerHash = mClosedLedgerHash; mClosedLedgerHash.zero(); } bool hasProto(int version); bool hasRange(uint32 uMin, uint32 uMax) { return (uMin >= mMinLedger) && (uMax <= mMaxLedger); } }; #endif // vim:ts=4