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