diff --git a/modules/ripple_core/functional/ripple_ILoadFeeTrack.h b/modules/ripple_core/functional/ripple_ILoadFeeTrack.h index 95a9bcfe2..914381693 100644 --- a/modules/ripple_core/functional/ripple_ILoadFeeTrack.h +++ b/modules/ripple_core/functional/ripple_ILoadFeeTrack.h @@ -43,9 +43,12 @@ public: virtual Json::Value getJson (uint64 baseFee, uint32 referenceFeeUnits) = 0; + virtual void setClusterFee (uint32) = 0; + virtual uint32 getClusterFee () = 0; virtual bool raiseLocalFee () = 0; virtual bool lowerLocalFee () = 0; - virtual bool isLoaded () = 0; + virtual bool isLoadedLocal () = 0; + virtual bool isLoadedCluster () = 0; }; #endif diff --git a/modules/ripple_core/functional/ripple_LoadFeeTrack.h b/modules/ripple_core/functional/ripple_LoadFeeTrack.h index ef5c27283..c74e16e5c 100644 --- a/modules/ripple_core/functional/ripple_LoadFeeTrack.h +++ b/modules/ripple_core/functional/ripple_LoadFeeTrack.h @@ -80,7 +80,19 @@ public: return std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee); } - bool isLoaded () + void setClusterFee (uint32 fee) + { + boost::mutex::scoped_lock sl (mLock); + mClusterTxnLoadFee = fee; + } + + uint32 getClusterFee () + { + boost::mutex::scoped_lock sl (mLock); + return mClusterTxnLoadFee; + } + + bool isLoadedLocal () { // VFALCO TODO This could be replaced with a SharedData and // using a read/write lock instead of a critical section. @@ -92,6 +104,18 @@ public: return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee); } + bool isLoadedCluster () + { + // VFALCO TODO This could be replaced with a SharedData and + // using a read/write lock instead of a critical section. + // + // NOTE This applies to all the locking in this class. + // + // + boost::mutex::scoped_lock sl (mLock); + return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee) || (mClusterTxnLoadFee != lftNormalFee); + } + void setRemoteFee (uint32 f) { boost::mutex::scoped_lock sl (mLock); @@ -181,6 +205,7 @@ private: uint32 mLocalTxnLoadFee; // Scale factor, lftNormalFee = normal fee uint32 mRemoteTxnLoadFee; // Scale factor, lftNormalFee = normal fee + uint32 mClusterTxnLoadFee; // Scale factor, lftNormalFee = normal fee int raiseCount; boost::mutex mLock; diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 4cbb7dc46..3c3208e4a 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -2183,7 +2183,7 @@ void NetworkOPs::makeFetchPack (Job&, boost::weak_ptr wPeer, return; } - if (getApp().getFeeTrack ().isLoaded ()) + if (getApp().getFeeTrack ().isLoadedLocal ()) { WriteLog (lsINFO, NetworkOPs) << "Too busy to make fetch pack"; return; diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 4900ea564..482f4e367 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -60,7 +60,7 @@ RPCHandler::RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub) : mNetOps Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool bFailHard, ScopedLock& mlh) { - if (getApp().getFeeTrack().isLoaded() && (mRole != ADMIN)) + if (getApp().getFeeTrack().isLoadedCluster() && (mRole != ADMIN)) return rpcError(rpcTOO_BUSY); Json::Value jvResult; diff --git a/src/cpp/ripple/ripple.proto b/src/cpp/ripple/ripple.proto index 920654c39..01f56b2ee 100644 --- a/src/cpp/ripple/ripple.proto +++ b/src/cpp/ripple/ripple.proto @@ -7,6 +7,7 @@ enum MessageType mtERROR_MSG = 2; mtPING = 3; mtPROOFOFWORK = 4; + mtCLUSTER = 5; // network presence detection mtGET_CONTACTS = 10; @@ -76,6 +77,21 @@ message TMHello optional bool testNet = 13; // Running as testnet. } +// The status of a node in our cluster +message TMClusterNode +{ + required bytes publicKey = 1; + optional string nodeName = 2; + optional uint32 nodeLoad = 3; + optional uint32 lastHeard = 4; +} + +// The status of all nodes in the cluster +message TMCluster +{ + repeated TMClusterNode clusterNodes = 1; +} + // A transaction can have only one input and one output. // If you want to send an amount that is greater than any single address of yours diff --git a/src/cpp/ripple/ripple_Application.cpp b/src/cpp/ripple/ripple_Application.cpp index 6103e84e8..58d0dd105 100644 --- a/src/cpp/ripple/ripple_Application.cpp +++ b/src/cpp/ripple/ripple_Application.cpp @@ -867,7 +867,7 @@ bool serverOkay (std::string& reason) if (!getApp().getLedgerMaster().isCaughtUp(reason)) return false; - if (getApp().getFeeTrack ().isLoaded ()) + if (getApp().getFeeTrack ().isLoadedLocal ()) { reason = "Too much load"; return false; diff --git a/src/cpp/ripple/ripple_Peer.cpp b/src/cpp/ripple/ripple_Peer.cpp index ded0d0f4f..b80c437ba 100644 --- a/src/cpp/ripple/ripple_Peer.cpp +++ b/src/cpp/ripple/ripple_Peer.cpp @@ -1274,7 +1274,7 @@ void PeerImp::recvPropose (const boost::shared_ptr& pack } bool isTrusted = getApp().getUNL ().nodeInUNL (signerPublic); - if (!isTrusted && getApp().getFeeTrack ().isLoaded ()) + if (!isTrusted && getApp().getFeeTrack ().isLoadedLocal ()) { WriteLog (lsDEBUG, Peer) << "Dropping untrusted proposal due to load"; return; @@ -1388,7 +1388,7 @@ void PeerImp::recvValidation (const boost::shared_ptr& p } bool isTrusted = getApp().getUNL ().nodeInUNL (val->getSignerPublic ()); - if (isTrusted || !getApp().getFeeTrack ().isLoaded ()) + if (isTrusted || !getApp().getFeeTrack ().isLoadedLocal ()) getApp().getJobQueue ().addJob (isTrusted ? jtVALIDATION_t : jtVALIDATION_ut, "recvValidation->checkValidation", BIND_TYPE (&checkValidation, P_1, val, signingHash, isTrusted, mCluster, packet, boost::weak_ptr (shared_from_this ()))); @@ -2286,7 +2286,7 @@ void PeerImp::doProofOfWork (Job&, boost::weak_ptr peer, ProofOfWork::poi void PeerImp::doFetchPack (const boost::shared_ptr& packet) { // VFALCO TODO Invert this dependency using an observer and shared state object. - if (getApp().getFeeTrack ().isLoaded ()) + if (getApp().getFeeTrack ().isLoadedLocal ()) { WriteLog (lsINFO, Peer) << "Too busy to make fetch pack"; return;