From 5f7d655d7d04e144c5410787753bd889b80c9a18 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 2 Dec 2012 15:52:09 -0800 Subject: [PATCH] Structures to track state of features. --- src/cpp/ripple/FeatureTable.cpp | 61 ++++++++++++++++++++++++++++++ src/cpp/ripple/FeatureTable.h | 67 +++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 src/cpp/ripple/FeatureTable.cpp create mode 100644 src/cpp/ripple/FeatureTable.h diff --git a/src/cpp/ripple/FeatureTable.cpp b/src/cpp/ripple/FeatureTable.cpp new file mode 100644 index 0000000000..ebf4d268b5 --- /dev/null +++ b/src/cpp/ripple/FeatureTable.cpp @@ -0,0 +1,61 @@ +#include "FeatureTable.h" + +FeatureTable::FeatureState* FeatureTable::getCreateFeature(const uint256& feature, bool create) +{ // call with the mutex held + featureMap_t::iterator it = mFeatureMap.find(feature); + if (it == mFeatureMap.end()) + { + if (!create) + return NULL; + return &(mFeatureMap[feature]); + } + return &(it->second); +} + +bool FeatureTable::vetoFeature(const uint256& feature) +{ + boost::mutex::scoped_lock sl(mMutex); + FeatureState *s = getCreateFeature(feature, true); + if (s->mVetoed) + return false; + s->mVetoed = true; + return true; +} + +bool FeatureTable::unVetoFeature(const uint256& feature) +{ + boost::mutex::scoped_lock sl(mMutex); + FeatureState *s = getCreateFeature(feature, false); + if (!s || !s->mVetoed) + return false; + s->mVetoed = false; + return true; +} + +bool FeatureTable::enableFeature(const uint256& feature) +{ + boost::mutex::scoped_lock sl(mMutex); + FeatureState *s = getCreateFeature(feature, true); + if (s->mEnabled) + return false; + s->mEnabled = true; + return true; +} + +bool FeatureTable::disableFeature(const uint256& feature) +{ + boost::mutex::scoped_lock sl(mMutex); + FeatureState *s = getCreateFeature(feature, false); + if (!s || !s->mEnabled) + return false; + s->mEnabled = false; + return true; +} + +bool FeatureTable::isFeatureEnabled(const uint256& feature) +{ + boost::mutex::scoped_lock sl(mMutex); + FeatureState *s = getCreateFeature(feature, false); + return s && s->mEnabled; +} + diff --git a/src/cpp/ripple/FeatureTable.h b/src/cpp/ripple/FeatureTable.h new file mode 100644 index 0000000000..fa268700a7 --- /dev/null +++ b/src/cpp/ripple/FeatureTable.h @@ -0,0 +1,67 @@ +#ifndef FEATURETABLE__H +#define FEATURETABLE__H + +#include +#include +#include + +#include "uint256.h" + +struct FeatureSet +{ // the status of all features requested in a given window + uint32 mLedgerSequence; + uint32 mCloseTime; + int mTrustedValidations; // number of trusted validations + + boost::unordered_map mVotes; // yes votes by feature +}; + +class FeatureTable +{ +protected: + + class FeatureState + { + public: + bool mVetoed; // We don't want this feature enabled + bool mEnabled; + + int mEnableVotes; // Trusted votes to enable this feature + int mDisableVotes; // Trusted votes to disable this feature + uint32 mFirstMajority; // First time we saw a majority (ledger sequence) + uint32 mLastMajority; // Most recent time we saw a majority + + FeatureState() : mVetoed(false), mEnabled(false), mEnableVotes(0), mDisableVotes(0), + mFirstMajority(0), mLastMajority(0) { ; } + }; + + typedef boost::unordered_map featureMap_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% + + FeatureState* getCreateFeature(const uint256& feature, bool create); + +public: + + FeatureTable(uint32 majorityTime, int mMajorityFraction) : mMajorityTime(majorityTime) { ; } + + 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); + + featureList_t getVetoedFeatures(); + featureList_t getEnabledFeatures(); + featureList_t getFeaturesToEnable(uint32 sequence); // gets features we would vote to enable + + void reportValidations(const FeatureSet&); +}; + +#endif