diff --git a/modules/ripple_main/ripple_main.cpp b/modules/ripple_main/ripple_main.cpp index 0af0736d4..3eec9a1f0 100644 --- a/modules/ripple_main/ripple_main.cpp +++ b/modules/ripple_main/ripple_main.cpp @@ -138,7 +138,6 @@ #include "src/cpp/ripple/ripple_ILoadFeeTrack.h" #include "src/cpp/ripple/ripple_IValidations.h" #include "src/cpp/ripple/ripple_IUniqueNodeList.h" -#include "src/cpp/ripple/FeatureTable.h" // ?? //------------------------------------------------------------------------------ @@ -178,7 +177,6 @@ static DH* handleTmpDh(SSL* ssl, int is_export, int iKeyLength) #include "src/cpp/ripple/AcceptedLedger.cpp" // no log #include "src/cpp/ripple/AccountItems.cpp" // no log #include "src/cpp/ripple/AccountState.cpp" // no log -#include "src/cpp/ripple/FeatureTable.cpp" #include "src/cpp/ripple/Ledger.cpp" #include "src/cpp/ripple/LedgerAcquire.cpp" #include "src/cpp/ripple/LedgerConsensus.cpp" @@ -270,6 +268,7 @@ static DH* handleTmpDh(SSL* ssl, int is_export, int iKeyLength) // Implementation of interfaces +#include "src/cpp/ripple/ripple_Features.cpp" #include "src/cpp/ripple/ripple_FeeVote.cpp" #include "src/cpp/ripple/ripple_HashRouter.cpp" #include "src/cpp/ripple/ripple_LoadFeeTrack.cpp" diff --git a/newcoin.vcxproj b/newcoin.vcxproj index a0efa77db..d620ca2d8 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -744,12 +744,6 @@ true true - - true - true - true - true - true true @@ -974,6 +968,12 @@ true true + + true + true + true + true + true true @@ -1614,7 +1614,6 @@ - diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index 16a6233f5..8bd4c5151 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -519,9 +519,6 @@ 1. Modules\ripple_main\processing - - 1. Modules\ripple_main\processing - 1. Modules\ripple_main\processing @@ -801,6 +798,9 @@ 1. Modules\ripple_main\sockets + + 1. Modules\ripple_main\processing + @@ -1169,9 +1169,6 @@ 1. Modules\ripple_main\processing - - 1. Modules\ripple_main\processing - 1. Modules\ripple_main\processing diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index b37446d21..b4b58ceba 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -34,13 +34,13 @@ Application::Application () , mSNTPClient (mAuxService) , mJobQueue (mIOService) // VFALCO: New stuff + , mFeatures (IFeatures::New (2 * 7 * 24 * 60 * 60, 200)) // two weeks, 200/256 , mFeeVote (IFeeVote::New (10, 50 * SYSTEM_CURRENCY_PARTS, 12.5 * SYSTEM_CURRENCY_PARTS)) , mFeeTrack (ILoadFeeTrack::New ()) , mHashRouter (IHashRouter::New (IHashRouter::getDefaultHoldTime ())) , mValidations (IValidations::New ()) , mUNL (IUniqueNodeList::New (mIOService)) // VFALCO: End new stuff - , mFeatureTable (2 * 7 * 24 * 60 * 60, 200) // two weeks, 200/256 // VFALCO: TODO replace all NULL with nullptr , mRpcDB (NULL) , mTxnDB (NULL) @@ -230,7 +230,7 @@ void Application::setup() if (!theConfig.RUN_STANDALONE) updateTables(theConfig.LDB_IMPORT); - mFeatureTable.addInitialFeatures(); + mFeatures->addInitialFeatures(); if (theConfig.START_UP == Config::FRESH) { diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h index 60b2204a9..3d1121e21 100644 --- a/src/cpp/ripple/Application.h +++ b/src/cpp/ripple/Application.h @@ -9,7 +9,6 @@ #include "LedgerMaster.h" #include "ConnectionPool.h" -#include "FeatureTable.h" #include "LedgerAcquire.h" #include "TransactionMaster.h" #include "Wallet.h" @@ -27,7 +26,7 @@ #include "ripple_DatabaseCon.h" // VFALCO: TODO, Fix forward declares required for header dependency loops -class IFeatureTable; +class IFeatures; class IFeeVote; class IHashRouter; class ILoadFeeTrack; @@ -62,6 +61,7 @@ class Application OrderBookDB mOrderBookDB; // VFALCO: Clean stuff + beast::ScopedPointer mFeatures; beast::ScopedPointer mFeeVote; beast::ScopedPointer mFeeTrack; beast::ScopedPointer mHashRouter; @@ -69,8 +69,6 @@ class Application beast::ScopedPointer mUNL; // VFALCO: End Clean stuff - FeatureTable mFeatureTable; - DatabaseCon *mRpcDB, *mTxnDB, *mLedgerDB, *mWalletDB, *mNetNodeDB, *mPathFindDB, *mHashNodeDB; leveldb::DB *mHashNodeLDB; @@ -124,7 +122,7 @@ public: PeerDoor& getPeerDoor() { return *mPeerDoor; } OrderBookDB& getOrderBookDB() { return mOrderBookDB; } SLECache& getSLECache() { return mSLECache; } - FeatureTable& getFeatureTable() { return mFeatureTable; } + IFeatures& getFeatureTable() { return *mFeatures; } IFeeVote& getFeeVote() { return *mFeeVote; } ILoadFeeTrack& getFeeTrack() { return *mFeeTrack; } diff --git a/src/cpp/ripple/FeatureTable.h b/src/cpp/ripple/FeatureTable.h deleted file mode 100644 index b55a98b55..000000000 --- a/src/cpp/ripple/FeatureTable.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef FEATURETABLE__H -#define FEATURETABLE__H - -#include -#include -#include - -#include "Ledger.h" - -class FeatureSet -{ // the status of all features requested in a given window -public: - uint32 mCloseTime; - int mTrustedValidations; // number of trusted validations - boost::unordered_map mVotes; // yes votes by feature - - FeatureSet(uint32 ct, int tv) : mCloseTime(ct), mTrustedValidations(tv) { ; } - void addVote(const uint256& feature) { ++mVotes[feature]; } -}; - -class FeatureState -{ -public: - bool mVetoed; // We don't want this feature enabled - bool mEnabled; - bool mSupported; - bool mDefault; // Include in genesis ledger - - uint32 mFirstMajority; // First time we saw a majority (close time) - uint32 mLastMajority; // Most recent time we saw a majority (close time) - - std::string mFriendlyName; - - FeatureState() - : mVetoed(false), mEnabled(false), mSupported(false), mDefault(false), - mFirstMajority(0), mLastMajority(0) { ; } - - void setVeto() { mVetoed = true; } - void setDefault() { mDefault = true; } - bool isDefault() { return mDefault; } - bool isSupported() { return mSupported; } - bool isVetoed() { return mVetoed; } - bool isEnabled() { return mEnabled; } - const std::string& getFiendlyName() { return mFriendlyName; } - void setFriendlyName(const std::string& n) { mFriendlyName = n; } -}; - -class FeatureTable -{ -protected: - - typedef boost::unordered_map featureMap_t; - typedef std::pair featureIt_t; - typedef boost::unordered_set featureList_t; - - boost::mutex mMutex; - featureMap_t mFeatureMap; - int mMajorityTime; // Seconds a feature must hold a majority - int mMajorityFraction; // 256 = 100% - uint32 mFirstReport; // close time of first majority report - uint32 mLastReport; // close time of most recent majority report - - FeatureState* getCreateFeature(const uint256& feature, bool create); - bool shouldEnable (uint32 closeTime, const FeatureState& fs); - void setJson(Json::Value& v, const FeatureState&); - -public: - - FeatureTable(uint32 majorityTime, int majorityFraction) - : mMajorityTime(majorityTime), mMajorityFraction(majorityFraction), mFirstReport(0), mLastReport(0) - { ; } - - void addInitialFeatures(); - - FeatureState* addKnownFeature(const char *featureID, const char *friendlyName, bool veto); - uint256 getFeature(const std::string& name); - - bool vetoFeature(const uint256& feature); - bool unVetoFeature(const uint256& feature); - - bool enableFeature(const uint256& feature); - bool disableFeature(const uint256& feature); - - bool isFeatureEnabled(const uint256& feature); - bool isFeatureSupported(const uint256& feature); - - void setEnabledFeatures(const std::vector& features); - void setSupportedFeatures(const std::vector& features); - - featureList_t getVetoedFeatures(); - featureList_t getEnabledFeatures(); - featureList_t getFeaturesToEnable(uint32 closeTime); // gets features we would vote to enable - featureList_t getDesiredFeatures(); // features we support, do not veto, are not enabled - - void reportValidations(const FeatureSet&); - - Json::Value getJson(int); - Json::Value getJson(const uint256&); - - void doValidation(Ledger::ref lastClosedLedger, STObject& baseValidation); - void doVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition); -}; - -#endif diff --git a/src/cpp/ripple/LedgerConsensus.cpp b/src/cpp/ripple/LedgerConsensus.cpp index eebec8c7b..2c33046d3 100644 --- a/src/cpp/ripple/LedgerConsensus.cpp +++ b/src/cpp/ripple/LedgerConsensus.cpp @@ -314,8 +314,8 @@ void LedgerConsensus::takeInitialPosition(Ledger& initialLedger) && ((mPreviousLedger->getLedgerSeq() % 256) == 0)) { // previous ledger was flag ledger SHAMap::pointer preSet = initialLedger.peekTransactionMap()->snapShot(true); - theApp->getFeeVote().doVoting(mPreviousLedger, preSet); - theApp->getFeatureTable().doVoting(mPreviousLedger, preSet); + theApp->getFeeVote().doVoting (mPreviousLedger, preSet); + theApp->getFeatureTable().doVoting (mPreviousLedger, preSet); initialSet = preSet->snapShot(false); } else diff --git a/src/cpp/ripple/FeatureTable.cpp b/src/cpp/ripple/ripple_Features.cpp similarity index 67% rename from src/cpp/ripple/FeatureTable.cpp rename to src/cpp/ripple/ripple_Features.cpp index 1d953c95c..b59d44870 100644 --- a/src/cpp/ripple/FeatureTable.cpp +++ b/src/cpp/ripple/ripple_Features.cpp @@ -1,9 +1,68 @@ -SETUP_LOG (FeatureTable) +class Features; + +SETUP_LOG (Features) FeatureState* testFeature = NULL; -void FeatureTable::addInitialFeatures() +// VFALCO: TODO Rename this to Features +class Features : public IFeatures +{ +protected: + + typedef boost::unordered_map featureMap_t; + typedef std::pair featureIt_t; + typedef boost::unordered_set featureList_t; + + boost::mutex mMutex; + featureMap_t mFeatureMap; + int mMajorityTime; // Seconds a feature must hold a majority + int mMajorityFraction; // 256 = 100% + uint32 mFirstReport; // close time of first majority report + uint32 mLastReport; // close time of most recent majority report + + FeatureState* getCreateFeature(const uint256& feature, bool create); + bool shouldEnable (uint32 closeTime, const FeatureState& fs); + void setJson(Json::Value& v, const FeatureState&); + +public: + + Features(uint32 majorityTime, int majorityFraction) + : mMajorityTime(majorityTime), mMajorityFraction(majorityFraction), mFirstReport(0), mLastReport(0) + { ; } + + void addInitialFeatures(); + + FeatureState* addKnownFeature(const char *featureID, const char *friendlyName, bool veto); + uint256 getFeature(const std::string& name); + + bool vetoFeature(const uint256& feature); + bool unVetoFeature(const uint256& feature); + + bool enableFeature(const uint256& feature); + bool disableFeature(const uint256& feature); + + bool isFeatureEnabled(const uint256& feature); + bool isFeatureSupported(const uint256& feature); + + void setEnabledFeatures(const std::vector& features); + void setSupportedFeatures(const std::vector& features); + + featureList_t getVetoedFeatures(); + featureList_t getEnabledFeatures(); + featureList_t getFeaturesToEnable(uint32 closeTime); // gets features we would vote to enable + featureList_t getDesiredFeatures(); // features we support, do not veto, are not enabled + + void reportValidations(const FeatureSet&); + + Json::Value getJson(int); + Json::Value getJson(const uint256&); + + void doValidation(Ledger::ref lastClosedLedger, STObject& baseValidation); + void doVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition); +}; + +void Features::addInitialFeatures() { // For each feature this version supports, construct the FeatureState object by calling // getCreateFeature. Set any vetoes or defaults. A pointer to the FeatureState can be stashed @@ -11,7 +70,7 @@ void FeatureTable::addInitialFeatures() testFeature = addKnownFeature("1234", "testFeature", false); } -FeatureState* FeatureTable::getCreateFeature(const uint256& featureHash, bool create) +FeatureState* Features::getCreateFeature(const uint256& featureHash, bool create) { // call with the mutex held featureMap_t::iterator it = mFeatureMap.find(featureHash); if (it == mFeatureMap.end()) @@ -40,7 +99,7 @@ FeatureState* FeatureTable::getCreateFeature(const uint256& featureHash, bool cr return &(it->second); } -uint256 FeatureTable::getFeature(const std::string& name) +uint256 Features::getFeature(const std::string& name) { if (!name.empty()) { @@ -53,7 +112,7 @@ uint256 FeatureTable::getFeature(const std::string& name) return uint256(); } -FeatureState* FeatureTable::addKnownFeature(const char *featureID, const char *friendlyName, bool veto) +FeatureState* Features::addKnownFeature(const char *featureID, const char *friendlyName, bool veto) { uint256 hash; hash.SetHex(featureID); @@ -73,7 +132,7 @@ FeatureState* FeatureTable::addKnownFeature(const char *featureID, const char *f return f; } -bool FeatureTable::vetoFeature(const uint256& feature) +bool Features::vetoFeature(const uint256& feature) { boost::mutex::scoped_lock sl(mMutex); FeatureState *s = getCreateFeature(feature, true); @@ -83,7 +142,7 @@ bool FeatureTable::vetoFeature(const uint256& feature) return true; } -bool FeatureTable::unVetoFeature(const uint256& feature) +bool Features::unVetoFeature(const uint256& feature) { boost::mutex::scoped_lock sl(mMutex); FeatureState *s = getCreateFeature(feature, false); @@ -93,7 +152,7 @@ bool FeatureTable::unVetoFeature(const uint256& feature) return true; } -bool FeatureTable::enableFeature(const uint256& feature) +bool Features::enableFeature(const uint256& feature) { boost::mutex::scoped_lock sl(mMutex); FeatureState *s = getCreateFeature(feature, true); @@ -103,7 +162,7 @@ bool FeatureTable::enableFeature(const uint256& feature) return true; } -bool FeatureTable::disableFeature(const uint256& feature) +bool Features::disableFeature(const uint256& feature) { boost::mutex::scoped_lock sl(mMutex); FeatureState *s = getCreateFeature(feature, false); @@ -113,21 +172,21 @@ bool FeatureTable::disableFeature(const uint256& feature) return true; } -bool FeatureTable::isFeatureEnabled(const uint256& feature) +bool Features::isFeatureEnabled(const uint256& feature) { boost::mutex::scoped_lock sl(mMutex); FeatureState *s = getCreateFeature(feature, false); return s && s->mEnabled; } -bool FeatureTable::isFeatureSupported(const uint256& feature) +bool Features::isFeatureSupported(const uint256& feature) { boost::mutex::scoped_lock sl(mMutex); FeatureState *s = getCreateFeature(feature, false); return s && s->mSupported; } -FeatureTable::featureList_t FeatureTable::getVetoedFeatures() +Features::featureList_t Features::getVetoedFeatures() { featureList_t ret; boost::mutex::scoped_lock sl(mMutex); @@ -139,7 +198,7 @@ FeatureTable::featureList_t FeatureTable::getVetoedFeatures() return ret; } -FeatureTable::featureList_t FeatureTable::getEnabledFeatures() +Features::featureList_t Features::getEnabledFeatures() { featureList_t ret; boost::mutex::scoped_lock sl(mMutex); @@ -151,7 +210,7 @@ FeatureTable::featureList_t FeatureTable::getEnabledFeatures() return ret; } -bool FeatureTable::shouldEnable(uint32 closeTime, const FeatureState& fs) +bool Features::shouldEnable(uint32 closeTime, const FeatureState& fs) { if (fs.mVetoed || fs.mEnabled || !fs.mSupported || (fs.mLastMajority != mLastReport)) return false; @@ -165,7 +224,7 @@ bool FeatureTable::shouldEnable(uint32 closeTime, const FeatureState& fs) } -FeatureTable::featureList_t FeatureTable::getFeaturesToEnable(uint32 closeTime) +Features::featureList_t Features::getFeaturesToEnable(uint32 closeTime) { featureList_t ret; boost::mutex::scoped_lock sl(mMutex); @@ -180,7 +239,7 @@ FeatureTable::featureList_t FeatureTable::getFeaturesToEnable(uint32 closeTime) return ret; } -FeatureTable::featureList_t FeatureTable::getDesiredFeatures() +Features::featureList_t Features::getDesiredFeatures() { featureList_t ret; boost::mutex::scoped_lock sl(mMutex); @@ -192,7 +251,7 @@ FeatureTable::featureList_t FeatureTable::getDesiredFeatures() return ret; } -void FeatureTable::reportValidations(const FeatureSet& set) +void Features::reportValidations(const FeatureSet& set) { if (set.mTrustedValidations == 0) return; @@ -211,13 +270,13 @@ void FeatureTable::reportValidations(const FeatureSet& set) BOOST_FOREACH(const u256_int_pair& it, set.mVotes) { FeatureState& state = mFeatureMap[it.first]; - WriteLog (lsDEBUG, FeatureTable) << "Feature " << it.first.GetHex() << " has " << it.second << " votes, needs " << threshold; + WriteLog (lsDEBUG, Features) << "Feature " << it.first.GetHex() << " has " << it.second << " votes, needs " << threshold; if (it.second >= threshold) { // we have a majority state.mLastMajority = set.mCloseTime; if (state.mFirstMajority == 0) { - WriteLog (lsWARNING, FeatureTable) << "Feature " << it.first << " attains a majority vote"; + WriteLog (lsWARNING, Features) << "Feature " << it.first << " attains a majority vote"; state.mFirstMajority = set.mCloseTime; changedFeatures.push_back(it.first); } @@ -226,7 +285,7 @@ void FeatureTable::reportValidations(const FeatureSet& set) { if (state.mFirstMajority != 0) { - WriteLog (lsWARNING, FeatureTable) << "Feature " << it.first << " loses majority vote"; + WriteLog (lsWARNING, Features) << "Feature " << it.first << " loses majority vote"; state.mFirstMajority = 0; state.mLastMajority = 0; changedFeatures.push_back(it.first); @@ -256,7 +315,7 @@ void FeatureTable::reportValidations(const FeatureSet& set) } } -void FeatureTable::setEnabledFeatures(const std::vector& features) +void Features::setEnabledFeatures(const std::vector& features) { boost::mutex::scoped_lock sl(mMutex); BOOST_FOREACH(featureIt_t& it, mFeatureMap) @@ -269,7 +328,7 @@ void FeatureTable::setEnabledFeatures(const std::vector& features) } } -void FeatureTable::setSupportedFeatures(const std::vector& features) +void Features::setSupportedFeatures(const std::vector& features) { boost::mutex::scoped_lock sl(mMutex); BOOST_FOREACH(featureIt_t& it, mFeatureMap) @@ -282,7 +341,7 @@ void FeatureTable::setSupportedFeatures(const std::vector& features) } } -void FeatureTable::doValidation(Ledger::ref lastClosedLedger, STObject& baseValidation) +void Features::doValidation(Ledger::ref lastClosedLedger, STObject& baseValidation) { featureList_t lFeatures = getDesiredFeatures(); if (lFeatures.empty()) @@ -297,7 +356,7 @@ void FeatureTable::doValidation(Ledger::ref lastClosedLedger, STObject& baseVali baseValidation.setFieldV256(sfFeatures, vFeatures); } -void FeatureTable::doVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) +void Features::doVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) { featureList_t lFeatures = getFeaturesToEnable(lastClosedLedger->getCloseTimeNC()); if (lFeatures.empty()) @@ -305,12 +364,12 @@ void FeatureTable::doVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPos BOOST_FOREACH(const uint256& uFeature, lFeatures) { - WriteLog (lsWARNING, FeatureTable) << "Voting for feature: " << uFeature; + WriteLog (lsWARNING, Features) << "Voting for feature: " << uFeature; SerializedTransaction trans(ttFEATURE); trans.setFieldAccount(sfAccount, uint160()); trans.setFieldH256(sfFeature, uFeature); uint256 txID = trans.getTransactionID(); - WriteLog (lsWARNING, FeatureTable) << "Vote ID: " << txID; + WriteLog (lsWARNING, Features) << "Vote ID: " << txID; Serializer s; trans.add(s, true); @@ -318,12 +377,12 @@ void FeatureTable::doVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPos SHAMapItem::pointer tItem = boost::make_shared(txID, s.peekData()); if (!initialPosition->addGiveItem(tItem, true, false)) { - WriteLog (lsWARNING, FeatureTable) << "Ledger already had feature transaction"; + WriteLog (lsWARNING, Features) << "Ledger already had feature transaction"; } } } -Json::Value FeatureTable::getJson(int) +Json::Value Features::getJson(int) { Json::Value ret(Json::objectValue); { @@ -336,7 +395,7 @@ Json::Value FeatureTable::getJson(int) return ret; } -void FeatureTable::setJson(Json::Value& v, const FeatureState& fs) +void Features::setJson(Json::Value& v, const FeatureState& fs) { if (!fs.mFriendlyName.empty()) v["name"] = fs.mFriendlyName; @@ -379,7 +438,7 @@ void FeatureTable::setJson(Json::Value& v, const FeatureState& fs) v["veto"] = true; } -Json::Value FeatureTable::getJson(const uint256& feature) +Json::Value Features::getJson(const uint256& feature) { Json::Value ret = Json::objectValue; boost::mutex::scoped_lock sl(mMutex); @@ -389,6 +448,11 @@ Json::Value FeatureTable::getJson(const uint256& feature) template class VotableInteger { +protected: + INT mCurrent; // The current setting + INT mTarget; // The setting we want + std::map mVoteMap; + public: VotableInteger(INT current, INT target) : mCurrent(current), mTarget(target) { @@ -430,11 +494,11 @@ public: return ourVote; } - -private: - INT mCurrent; // The current setting - INT mTarget; // The setting we want - std::map mVoteMap; }; +IFeatures* IFeatures::New (uint32 majorityTime, int majorityFraction) +{ + return new Features (majorityTime, majorityFraction); +} + // vim:ts=4 diff --git a/src/cpp/ripple/ripple_FeeVote.cpp b/src/cpp/ripple/ripple_FeeVote.cpp index 5a5c9b6c3..5bf47cf2d 100644 --- a/src/cpp/ripple/ripple_FeeVote.cpp +++ b/src/cpp/ripple/ripple_FeeVote.cpp @@ -1,10 +1,61 @@ -class FeatureTable; +class Features; //------------------------------------------------------------------------------ class FeeVote : public IFeeVote { +private: + // VFALCO: TODO, rename template parameter (wtf, looks like a macro) + template + class VotableInteger + { + public: + VotableInteger(INT current, INT target) : mCurrent(current), mTarget(target) + { + ++mVoteMap[mTarget]; // Add our vote + } + + bool mayVote() + { + return mCurrent != mTarget; // If we love the current setting, we will not vote + } + + void addVote(INT vote) + { + ++mVoteMap[vote]; + } + + void noVote() + { + addVote(mCurrent); + } + + INT getVotes() + { + INT ourVote = mCurrent; + int weight = 0; + + typedef typename std::map::value_type mapVType; + BOOST_FOREACH(const mapVType& value, mVoteMap) + { // Take most voted value between current and target, inclusive + if ((value.first <= std::max(mTarget, mCurrent)) && + (value.first >= std::min(mTarget, mCurrent)) && + (value.second > weight)) + { + ourVote = value.first; + weight = value.second; + } + } + + return ourVote; + } + + private: + INT mCurrent; // The current setting + INT mTarget; // The setting we want + std::map mVoteMap; + }; public: FeeVote (uint64 targetBaseFee, uint32 targetReserveBase, uint32 targetReserveIncrement) : mTargetBaseFee (targetBaseFee) @@ -19,19 +70,19 @@ public: { if (lastClosedLedger->getBaseFee() != mTargetBaseFee) { - WriteLog (lsINFO, FeatureTable) << "Voting for base fee of " << mTargetBaseFee; + WriteLog (lsINFO, Features) << "Voting for base fee of " << mTargetBaseFee; baseValidation.setFieldU64(sfBaseFee, mTargetBaseFee); } if (lastClosedLedger->getReserve(0) != mTargetReserveBase) { - WriteLog (lsINFO, FeatureTable) << "Voting for base resrve of " << mTargetReserveBase; + WriteLog (lsINFO, Features) << "Voting for base resrve of " << mTargetReserveBase; baseValidation.setFieldU32(sfReserveBase, mTargetReserveBase); } if (lastClosedLedger->getReserveInc() != mTargetReserveIncrement) { - WriteLog (lsINFO, FeatureTable) << "Voting for reserve increment of " << mTargetReserveIncrement; + WriteLog (lsINFO, Features) << "Voting for reserve increment of " << mTargetReserveIncrement; baseValidation.setFieldU32(sfReserveIncrement, mTargetReserveIncrement); } } @@ -94,7 +145,7 @@ public: (baseReserve != lastClosedLedger->getReserve(0)) || (incReserve != lastClosedLedger->getReserveInc())) { - WriteLog (lsWARNING, FeatureTable) << "We are voting for a fee change: " << baseFee << "/" << baseReserve << "/" << incReserve; + WriteLog (lsWARNING, Features) << "We are voting for a fee change: " << baseFee << "/" << baseReserve << "/" << incReserve; SerializedTransaction trans(ttFEE); trans.setFieldAccount(sfAccount, uint160()); @@ -105,7 +156,7 @@ public: uint256 txID = trans.getTransactionID(); - WriteLog (lsWARNING, FeatureTable) << "Vote: " << txID; + WriteLog (lsWARNING, Features) << "Vote: " << txID; Serializer s; trans.add(s, true); @@ -113,7 +164,7 @@ public: SHAMapItem::pointer tItem = boost::make_shared(txID, s.peekData()); if (!initialPosition->addGiveItem(tItem, true, false)) { - WriteLog (lsWARNING, FeatureTable) << "Ledger already had fee change"; + WriteLog (lsWARNING, Features) << "Ledger already had fee change"; } } } diff --git a/src/cpp/ripple/ripple_IFeatures.h b/src/cpp/ripple/ripple_IFeatures.h index a8d41ea07..99e686207 100644 --- a/src/cpp/ripple/ripple_IFeatures.h +++ b/src/cpp/ripple/ripple_IFeatures.h @@ -1,21 +1,90 @@ #ifndef RIPPLE_IFEATURES_H #define RIPPLE_IFEATURES_H +class FeatureSet +{ // the status of all features requested in a given window +public: + uint32 mCloseTime; + int mTrustedValidations; // number of trusted validations + boost::unordered_map mVotes; // yes votes by feature + + FeatureSet(uint32 ct, int tv) : mCloseTime(ct), mTrustedValidations(tv) { ; } + void addVote(const uint256& feature) { ++mVotes[feature]; } +}; + +class FeatureState +{ +public: + bool mVetoed; // We don't want this feature enabled + bool mEnabled; + bool mSupported; + bool mDefault; // Include in genesis ledger + + uint32 mFirstMajority; // First time we saw a majority (close time) + uint32 mLastMajority; // Most recent time we saw a majority (close time) + + std::string mFriendlyName; + + FeatureState() + : mVetoed(false), mEnabled(false), mSupported(false), mDefault(false), + mFirstMajority(0), mLastMajority(0) { ; } + + void setVeto() { mVetoed = true; } + void setDefault() { mDefault = true; } + bool isDefault() { return mDefault; } + bool isSupported() { return mSupported; } + bool isVetoed() { return mVetoed; } + bool isEnabled() { return mEnabled; } + const std::string& getFiendlyName() { return mFriendlyName; } + void setFriendlyName(const std::string& n) { mFriendlyName = n; } +}; + /** Feature table interface. The feature table stores the list of enabled and potential features. Individuals features are voted on by validators during the consensus process. */ -class IFeatureTable +class IFeatures { public: - static IFeatureTable* New (uint32 majorityTime, int majorityFraction); + static IFeatures* New (uint32 majorityTime, int majorityFraction); - virtual ~IFeatureTable () { } + virtual ~IFeatures () { } + + virtual void addInitialFeatures() = 0; + + virtual FeatureState* addKnownFeature(const char *featureID, const char *friendlyName, bool veto) = 0; + virtual uint256 getFeature(const std::string& name) = 0; + + virtual bool vetoFeature(const uint256& feature) = 0; + virtual bool unVetoFeature(const uint256& feature) = 0; + + virtual bool enableFeature(const uint256& feature) = 0; + virtual bool disableFeature(const uint256& feature) = 0; + + virtual bool isFeatureEnabled(const uint256& feature) = 0; + virtual bool isFeatureSupported(const uint256& feature) = 0; + + virtual void setEnabledFeatures(const std::vector& features) = 0; + virtual void setSupportedFeatures(const std::vector& features) = 0; + + // VFALCO: NOTE these can't possibly be used since featureList_t was/is private. + /* + featureList_t getVetoedFeatures() = 0; + featureList_t getEnabledFeatures() = 0; + featureList_t getFeaturesToEnable(uint32 closeTime) = 0; // gets features we would vote to enable + featureList_t getDesiredFeatures() = 0; // features we support, do not veto, are not enabled + */ + + virtual void reportValidations(const FeatureSet&) = 0; + + virtual Json::Value getJson(int) = 0; + virtual Json::Value getJson(const uint256&) = 0; + + virtual void doValidation(Ledger::ref lastClosedLedger, STObject& baseValidation) = 0; + virtual void doVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) = 0; - virtual void doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation) = 0; - virtual void doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) = 0; }; #endif