mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Refactor FeatureTable into IFeatures
Conflicts: src/cpp/ripple/FeatureTable.h src/cpp/ripple/ripple_Features.cpp
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 <IFeatures> mFeatures;
|
||||
beast::ScopedPointer <IFeeVote> mFeeVote;
|
||||
beast::ScopedPointer <ILoadFeeTrack> mFeeTrack;
|
||||
beast::ScopedPointer <IHashRouter> mHashRouter;
|
||||
@@ -69,8 +69,6 @@ class Application
|
||||
beast::ScopedPointer <IUniqueNodeList> 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; }
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
#ifndef FEATURETABLE__H
|
||||
#define FEATURETABLE__H
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#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<uint256, int> 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<uint256, FeatureState> featureMap_t;
|
||||
typedef std::pair<const uint256, FeatureState> featureIt_t;
|
||||
typedef boost::unordered_set<uint256> 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<uint256>& features);
|
||||
void setSupportedFeatures(const std::vector<uint256>& 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
|
||||
@@ -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
|
||||
|
||||
@@ -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<uint256, FeatureState> featureMap_t;
|
||||
typedef std::pair<const uint256, FeatureState> featureIt_t;
|
||||
typedef boost::unordered_set<uint256> 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<uint256>& features);
|
||||
void setSupportedFeatures(const std::vector<uint256>& 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<uint256>& features)
|
||||
void Features::setEnabledFeatures(const std::vector<uint256>& features)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mMutex);
|
||||
BOOST_FOREACH(featureIt_t& it, mFeatureMap)
|
||||
@@ -269,7 +328,7 @@ void FeatureTable::setEnabledFeatures(const std::vector<uint256>& features)
|
||||
}
|
||||
}
|
||||
|
||||
void FeatureTable::setSupportedFeatures(const std::vector<uint256>& features)
|
||||
void Features::setSupportedFeatures(const std::vector<uint256>& features)
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mMutex);
|
||||
BOOST_FOREACH(featureIt_t& it, mFeatureMap)
|
||||
@@ -282,7 +341,7 @@ void FeatureTable::setSupportedFeatures(const std::vector<uint256>& 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<SHAMapItem>(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<typename INT> class VotableInteger
|
||||
{
|
||||
protected:
|
||||
INT mCurrent; // The current setting
|
||||
INT mTarget; // The setting we want
|
||||
std::map<INT, int> 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<INT, int> mVoteMap;
|
||||
};
|
||||
|
||||
IFeatures* IFeatures::New (uint32 majorityTime, int majorityFraction)
|
||||
{
|
||||
return new Features (majorityTime, majorityFraction);
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
@@ -1,10 +1,61 @@
|
||||
|
||||
class FeatureTable;
|
||||
class Features;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class FeeVote : public IFeeVote
|
||||
{
|
||||
private:
|
||||
// VFALCO: TODO, rename template parameter (wtf, looks like a macro)
|
||||
template <typename INT>
|
||||
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<INT, int>::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<INT, int> 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<SHAMapItem>(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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<uint256, int> 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<uint256>& features) = 0;
|
||||
virtual void setSupportedFeatures(const std::vector<uint256>& 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
|
||||
|
||||
Reference in New Issue
Block a user