diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index f766f0458d..e4b1595182 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -1072,7 +1072,7 @@ true true - + true true true @@ -2952,7 +2952,7 @@ - + @@ -3247,6 +3247,7 @@ + diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index c83f24187e..386063c6f0 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -1716,10 +1716,10 @@ [2] Old Ripple\ripple_rpc\impl - + [2] Old Ripple\ripple_app\misc - + [2] Old Ripple\ripple_app\misc @@ -3342,7 +3342,7 @@ [2] Old Ripple\ripple_app\misc - + [2] Old Ripple\ripple_app\misc @@ -3473,8 +3473,9 @@ [2] Old Ripple\ripple_core\nodestore - - + + [2] Old Ripple\ripple_app\misc + [1] Ripple\proto diff --git a/src/BeastConfig.h b/src/BeastConfig.h index 57f9a66e34..db29563077 100644 --- a/src/BeastConfig.h +++ b/src/BeastConfig.h @@ -211,8 +211,8 @@ correctly to find the boost headers. /** Config: RIPPLE_PROPOSE_FEATURES This determines whether to add any features to the proposed transaction set. */ -#ifndef RIPPLE_PROPOSE_FEATURES -#define RIPPLE_PROPOSE_FEATURES 0 +#ifndef RIPPLE_PROPOSE_AMENDMENTS +#define RIPPLE_PROPOSE_AMENDMENTS 0 #endif #endif diff --git a/src/ripple_app/consensus/LedgerConsensus.cpp b/src/ripple_app/consensus/LedgerConsensus.cpp index 79d5aa5fde..0350ee50ee 100644 --- a/src/ripple_app/consensus/LedgerConsensus.cpp +++ b/src/ripple_app/consensus/LedgerConsensus.cpp @@ -961,7 +961,7 @@ private: // next ledger is flag ledger { m_feeVote.doValidation (newLCL, *v); - getApp().getFeatureTable ().doValidation (newLCL, *v); + getApp().getAmendmentTable ().doValidation (newLCL, *v); } v->sign (signingHash, mValPrivate); @@ -1491,7 +1491,7 @@ private: SHAMap::pointer preSet = initialLedger.peekTransactionMap ()->snapShot (true); m_feeVote.doVoting (mPreviousLedger, preSet); - getApp().getFeatureTable ().doVoting (mPreviousLedger, preSet); + getApp().getAmendmentTable ().doVoting (mPreviousLedger, preSet); initialSet = preSet->snapShot (false); } else diff --git a/src/ripple_app/ledger/Ledger.cpp b/src/ripple_app/ledger/Ledger.cpp index dd5f26451d..8ea4bd60a6 100644 --- a/src/ripple_app/ledger/Ledger.cpp +++ b/src/ripple_app/ledger/Ledger.cpp @@ -1504,11 +1504,11 @@ uint256 Ledger::getLedgerFeeIndex () return s.getSHA512Half (); } -uint256 Ledger::getLedgerFeatureIndex () +uint256 Ledger::getLedgerAmendmentIndex () { - // get the index of the node that holds the enabled features + // get the index of the node that holds the enabled amendments Serializer s (2); - s.add16 (spaceFeature); + s.add16 (spaceAmendment); return s.getSHA512Half (); } @@ -1616,15 +1616,15 @@ std::vector< std::pair > Ledger::getLedgerHashes () return ret; } -std::vector Ledger::getLedgerFeatures () +std::vector Ledger::getLedgerAmendments () { - std::vector usFeatures; - SLE::pointer sleFeatures = getSLEi (getLedgerFeatureIndex ()); + std::vector usAmendments; + SLE::pointer sleAmendments = getSLEi (getLedgerAmendmentIndex ()); - if (sleFeatures) - usFeatures = sleFeatures->getFieldV256 (sfFeatures).peekValue (); + if (sleAmendments) + usAmendments = sleAmendments->getFieldV256 (sfAmendments).peekValue (); - return usFeatures; + return usAmendments; } // XRP to XRP not allowed. diff --git a/src/ripple_app/ledger/Ledger.h b/src/ripple_app/ledger/Ledger.h index 0922e128e1..86f3d52ebb 100644 --- a/src/ripple_app/ledger/Ledger.h +++ b/src/ripple_app/ledger/Ledger.h @@ -300,9 +300,9 @@ public: uint256 getLedgerHash (std::uint32_t ledgerIndex); std::vector< std::pair > getLedgerHashes (); - static uint256 getLedgerFeatureIndex (); + static uint256 getLedgerAmendmentIndex (); static uint256 getLedgerFeeIndex (); - std::vector getLedgerFeatures (); + std::vector getLedgerAmendments (); std::vector getNeededTransactionHashes (int max, SHAMapSyncFilter * filter); std::vector getNeededAccountStateHashes (int max, SHAMapSyncFilter * filter); diff --git a/src/ripple_app/ledger/SerializedValidation.cpp b/src/ripple_app/ledger/SerializedValidation.cpp index aa198a4e47..99eb39710d 100644 --- a/src/ripple_app/ledger/SerializedValidation.cpp +++ b/src/ripple_app/ledger/SerializedValidation.cpp @@ -146,7 +146,7 @@ SOTemplate const& SerializedValidation::getFormat () format.push_back (SOElement (sfLedgerSequence, SOE_OPTIONAL)); format.push_back (SOElement (sfCloseTime, SOE_OPTIONAL)); format.push_back (SOElement (sfLoadFee, SOE_OPTIONAL)); - format.push_back (SOElement (sfFeatures, SOE_OPTIONAL)); + format.push_back (SOElement (sfAmendments, SOE_OPTIONAL)); format.push_back (SOElement (sfBaseFee, SOE_OPTIONAL)); format.push_back (SOElement (sfReserveBase, SOE_OPTIONAL)); format.push_back (SOElement (sfReserveIncrement, SOE_OPTIONAL)); diff --git a/src/ripple_app/main/Application.cpp b/src/ripple_app/main/Application.cpp index d10af444b7..13dbc3862a 100644 --- a/src/ripple_app/main/Application.cpp +++ b/src/ripple_app/main/Application.cpp @@ -28,7 +28,7 @@ namespace ripple { // VFALCO TODO Clean this global up static bool volatile doShutdown = false; -static int const MAJORITY_FRACTION (200); +static int const MAJORITY_FRACTION (204); //------------------------------------------------------------------------------ // @@ -59,8 +59,8 @@ class PathRequestLog; template <> char const* LogPartition::getPartitionName () { return "PathRequest"; } class RPCManagerLog; template <> char const* LogPartition::getPartitionName () { return "RPCManager"; } -class FeaturesLog; -template <> char const* LogPartition::getPartitionName () { return "FeatureTable"; } +class AmendmentTableLog; +template <> char const* LogPartition::getPartitionName () { return "AmendmentTable"; } template <> char const* LogPartition::getPartitionName () { return "Collector"; } @@ -141,7 +141,7 @@ public: std::unique_ptr m_sntpClient; std::unique_ptr m_txQueue; std::unique_ptr m_validators; - std::unique_ptr m_featureTable; + std::unique_ptr m_amendmentTable; std::unique_ptr mFeeTrack; std::unique_ptr mHashRouter; std::unique_ptr mValidations; @@ -296,8 +296,8 @@ public: getConfig ().getModuleDatabasePath (), LogPartition::getJournal ()))) - , m_featureTable (make_FeatureTable (weeks(2), MAJORITY_FRACTION, // 200/256 - LogPartition::getJournal ())) + , m_amendmentTable (make_AmendmentTable (weeks(2), MAJORITY_FRACTION, // 204/256 about 80% + LogPartition::getJournal ())) , mFeeTrack (LoadFeeTrack::New (LogPartition::getJournal ())) @@ -450,9 +450,9 @@ public: return *m_validators; } - FeatureTable& getFeatureTable () + AmendmentTable& getAmendmentTable() { - return *m_featureTable; + return *m_amendmentTable; } LoadFeeTrack& getFeeTrack () @@ -609,7 +609,7 @@ public: if (!getConfig ().RUN_STANDALONE) updateTables (); - m_featureTable->addInitial (); + m_amendmentTable->addInitial(); Pathfinder::initPathTable (); m_ledgerMaster->setMinValidations (getConfig ().VALIDATION_QUORUM); @@ -1069,7 +1069,7 @@ void ApplicationImp::startNewLedger () { Ledger::pointer firstLedger = boost::make_shared (rootAddress, SYSTEM_CURRENCY_START); assert (!!firstLedger->getAccountState (rootAddress)); - // WRITEME: Add any default features + // WRITEME: Add any default amendments // WRITEME: Set default fee/reserve firstLedger->updateHash (); firstLedger->setClosed (); @@ -1215,7 +1215,7 @@ bool serverOkay (std::string& reason) return false; } - if (getApp().getOPs ().isFeatureBlocked ()) + if (getApp().getOPs ().isAmendmentBlocked ()) { reason = "Server version too old"; return false; diff --git a/src/ripple_app/main/Application.h b/src/ripple_app/main/Application.h index 2d0752e708..99bea55b18 100644 --- a/src/ripple_app/main/Application.h +++ b/src/ripple_app/main/Application.h @@ -32,7 +32,7 @@ namespace RPC { class Manager; } // VFALCO TODO Fix forward declares required for header dependency loops class CollectorManager; -class FeatureTable; +class AmendmentTable; class IHashRouter; class LoadFeeTrack; class Overlay; @@ -88,7 +88,7 @@ public: virtual NodeCache& getTempNodeCache () = 0; virtual SLECache& getSLECache () = 0; virtual Validators::Manager& getValidators () = 0; - virtual FeatureTable& getFeatureTable () = 0; + virtual AmendmentTable& getAmendmentTable() = 0; virtual IHashRouter& getHashRouter () = 0; virtual LoadFeeTrack& getFeeTrack () = 0; virtual LoadManager& getLoadManager () = 0; diff --git a/src/ripple_app/misc/FeatureTable.h b/src/ripple_app/misc/AmendmentTable.h similarity index 64% rename from src/ripple_app/misc/FeatureTable.h rename to src/ripple_app/misc/AmendmentTable.h index bda42fb6bf..e90cd0372b 100644 --- a/src/ripple_app/misc/FeatureTable.h +++ b/src/ripple_app/misc/AmendmentTable.h @@ -17,22 +17,22 @@ */ //============================================================================== -#ifndef RIPPLE_FEATURES_H -#define RIPPLE_FEATURES_H +#ifndef RIPPLE_AMENDMENT_TABLE_H +#define RIPPLE_AMENDMENT_TABLE_H #include "../book/Types.h" namespace ripple { -class FeatureSet +/** The status of all amendments requested in a given window. */ +class AmendmentSet { - // the status of all features requested in a given window public: std::uint32_t mCloseTime; int mTrustedValidations; // number of trusted validations - ripple::unordered_map mVotes; // yes votes by feature + ripple::unordered_map mVotes; // yes votes by amendment - FeatureSet (std::uint32_t ct) : mCloseTime (ct), mTrustedValidations (0) + AmendmentSet (std::uint32_t ct) : mCloseTime (ct), mTrustedValidations (0) { ; } @@ -40,16 +40,20 @@ public: { ++mTrustedValidations; } - void addVote (uint256 const& feature) + void addVote (uint256 const& amendment) { - ++mVotes[feature]; + ++mVotes[amendment]; } }; -class FeatureState +/** Current state of an amendment. + Tells if a amendment is supported, enabled or vetoed. A vetoed amendment + means the node will never announce its support. +*/ +class AmendmentState { public: - bool mVetoed; // We don't want this feature enabled + bool mVetoed; // We don't want this amendment enabled bool mEnabled; bool mSupported; bool mDefault; // Include in genesis ledger @@ -59,7 +63,7 @@ public: std::string mFriendlyName; - FeatureState () + AmendmentState () : mVetoed (false), mEnabled (false), mSupported (false), mDefault (false), m_firstMajority (0), m_lastMajority (0) { @@ -100,46 +104,44 @@ public: } }; -/** Feature table interface. - - The feature table stores the list of enabled and potential features. - Individuals features are voted on by validators during the consensus +/** The amendment table stores the list of enabled and potential amendments. + Individuals amendments are voted on by validators during the consensus process. */ -class FeatureTable +class AmendmentTable { public: - /** Create a new FeatureTable. + /** Create a new AmendmentTable. - @param majorityTime the number of seconds a feature must hold a majority + @param majorityTime the number of seconds an amendment must hold a majority before we're willing to vote yes on it. @param majorityFraction ratio, out of 256, of servers that must say - they want a feature before we consider it to + they want an amendment before we consider it to have a majority. @param journal */ - virtual ~FeatureTable() { } + virtual ~AmendmentTable() { } virtual void addInitial () = 0; - virtual FeatureState* addKnown (const char* featureID, + virtual AmendmentState* addKnown (const char* amendmentID, const char* friendlyName, bool veto) = 0; virtual uint256 get (const std::string& name) = 0; - virtual bool veto (uint256 const& feature) = 0; - virtual bool unVeto (uint256 const& feature) = 0; + virtual bool veto (uint256 const& amendment) = 0; + virtual bool unVeto (uint256 const& amendment) = 0; - virtual bool enable (uint256 const& feature) = 0; - virtual bool disable (uint256 const& feature) = 0; + virtual bool enable (uint256 const& amendment) = 0; + virtual bool disable (uint256 const& amendment) = 0; - virtual bool isEnabled (uint256 const& feature) = 0; - virtual bool isSupported (uint256 const& feature) = 0; + virtual bool isEnabled (uint256 const& amendment) = 0; + virtual bool isSupported (uint256 const& amendment) = 0; - virtual void setEnabled (const std::vector& features) = 0; - virtual void setSupported (const std::vector& features) = 0; + virtual void setEnabled (const std::vector& amendments) = 0; + virtual void setSupported (const std::vector& amendments) = 0; - virtual void reportValidations (const FeatureSet&) = 0; + virtual void reportValidations (const AmendmentSet&) = 0; virtual Json::Value getJson (int) = 0; virtual Json::Value getJson (uint256 const& ) = 0; @@ -150,8 +152,8 @@ public: doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) = 0; }; -std::unique_ptr -make_FeatureTable (std::chrono::seconds majorityTime, int majorityFraction, +std::unique_ptr +make_AmendmentTable (std::chrono::seconds majorityTime, int majorityFraction, beast::Journal journal); } // ripple diff --git a/src/ripple_app/misc/FeaturesImpl.cpp b/src/ripple_app/misc/AmendmentTableImpl.cpp similarity index 58% rename from src/ripple_app/misc/FeaturesImpl.cpp rename to src/ripple_app/misc/AmendmentTableImpl.cpp index cfb8747dcd..fd1e1b6069 100644 --- a/src/ripple_app/misc/FeaturesImpl.cpp +++ b/src/ripple_app/misc/AmendmentTableImpl.cpp @@ -19,38 +19,38 @@ namespace ripple { -/** Track the list of "features" +/** Track the list of "amendments" - A "feature" is an option that can affect transaction processing - rules that is identified by a 256-bit feature identifier + An "amendment" is an option that can affect transaction processing + rules that is identified by a 256-bit amendment identifier and adopted, or rejected, by the network. */ -class FeaturesImpl : public FeatureTable + class AmendmentTableImpl : public AmendmentTable { protected: - typedef ripple::unordered_map featureMap_t; - typedef std::pair featureIt_t; - typedef boost::unordered_set featureList_t; + typedef ripple::unordered_map amendmentMap_t; + typedef std::pair amendmentIt_t; + typedef boost::unordered_set amendmentList_t; typedef RippleMutex LockType; typedef std::lock_guard ScopedLockType; LockType mLock; - featureMap_t mFeatureMap; - std::chrono::seconds m_majorityTime; // Seconds a feature must hold a majority + amendmentMap_t m_amendmentMap; + std::chrono::seconds m_majorityTime; // Seconds an amendment must hold a majority int mMajorityFraction; // 256 = 100% core::Clock::time_point m_firstReport; // close time of first majority report core::Clock::time_point m_lastReport; // close time of most recent majority report beast::Journal m_journal; - FeatureState* getCreate (uint256 const& feature, bool create); - bool shouldEnable (std::uint32_t closeTime, const FeatureState& fs); - void setJson (Json::Value& v, const FeatureState&); + AmendmentState* getCreate (uint256 const& amendment, bool create); + bool shouldEnable (std::uint32_t closeTime, const AmendmentState& fs); + void setJson (Json::Value& v, const AmendmentState&); public: - FeaturesImpl (std::chrono::seconds majorityTime, int majorityFraction, + AmendmentTableImpl (std::chrono::seconds majorityTime, int majorityFraction, beast::Journal journal) : m_majorityTime (majorityTime) , mMajorityFraction (majorityFraction) @@ -62,23 +62,23 @@ public: void addInitial () override; - FeatureState* addKnown (const char* featureID, const char* friendlyName, + AmendmentState* addKnown (const char* amendmentID, const char* friendlyName, bool veto) override; uint256 get (const std::string& name) override; - bool veto (uint256 const& feature) override; - bool unVeto (uint256 const& feature) override; + bool veto (uint256 const& amendment) override; + bool unVeto (uint256 const& amendment) override; - bool enable (uint256 const& feature) override; - bool disable (uint256 const& feature) override; + bool enable (uint256 const& amendment) override; + bool disable (uint256 const& amendment) override; - bool isEnabled (uint256 const& feature) override; - bool isSupported (uint256 const& feature) override; + bool isEnabled (uint256 const& amendment) override; + bool isSupported (uint256 const& amendment) override; - void setEnabled (const std::vector& features) override; - void setSupported (const std::vector& features) override; + void setEnabled (const std::vector& amendments) override; + void setSupported (const std::vector& amendments) override; - void reportValidations (const FeatureSet&) override; + void reportValidations (const AmendmentSet&) override; Json::Value getJson (int) override; Json::Value getJson (uint256 const&) override; @@ -86,35 +86,35 @@ public: void doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation) override; void doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) override; - featureList_t getVetoed (); - featureList_t getEnabled (); - featureList_t getToEnable (core::Clock::time_point closeTime); // gets features we would vote to enable - featureList_t getDesired (); // features we support, do not veto, are not enabled + amendmentList_t getVetoed(); + amendmentList_t getEnabled(); + amendmentList_t getToEnable(core::Clock::time_point closeTime); // gets amendments we would vote to enable + amendmentList_t getDesired(); // amendments we support, do not veto, are not enabled }; void -FeaturesImpl::addInitial () +AmendmentTableImpl::addInitial () { - // For each feature this version supports, construct the FeatureState object by calling - // addKnown. Set any vetoes or defaults. A pointer to the FeatureState can be stashed + // For each amendment this version supports, construct the AmendmentState object by calling + // addKnown. Set any vetoes or defaults. A pointer to the AmendmentState can be stashed } -FeatureState* -FeaturesImpl::getCreate (uint256 const& featureHash, bool create) +AmendmentState* +AmendmentTableImpl::getCreate (uint256 const& amendmentHash, bool create) { // call with the mutex held - auto iter (mFeatureMap.find (featureHash)); + auto iter (m_amendmentMap.find (amendmentHash)); - if (iter == mFeatureMap.end ()) + if (iter == m_amendmentMap.end()) { if (!create) return nullptr; - FeatureState* feature = & (mFeatureMap[featureHash]); + AmendmentState* amendment = & (m_amendmentMap[amendmentHash]); { std::string query = "SELECT FirstMajority,LastMajority FROM Features WHERE hash='"; - query.append (featureHash.GetHex ()); + query.append (amendmentHash.GetHex ()); query.append ("';"); DeprecatedScopedLock sl (getApp().getWalletDB ()->getDBLock ()); @@ -122,22 +122,22 @@ FeaturesImpl::getCreate (uint256 const& featureHash, bool create) if (db->executeSQL (query) && db->startIterRows ()) { - feature->m_firstMajority = db->getBigInt("FirstMajority"); - feature->m_lastMajority = db->getBigInt("LastMajority"); + amendment->m_firstMajority = db->getBigInt("FirstMajority"); + amendment->m_lastMajority = db->getBigInt("LastMajority"); db->endIterRows (); } } - return feature; + return amendment; } return & (iter->second); } uint256 -FeaturesImpl::get (const std::string& name) +AmendmentTableImpl::get (const std::string& name) { - for (auto const& e : mFeatureMap) + for (auto const& e : m_amendmentMap) { if (name == e.second.mFriendlyName) return e.first; @@ -146,12 +146,12 @@ FeaturesImpl::get (const std::string& name) return uint256 (); } -FeatureState* -FeaturesImpl::addKnown (const char* featureID, const char* friendlyName, +AmendmentState* +AmendmentTableImpl::addKnown (const char* amendmentID, const char* friendlyName, bool veto) { uint256 hash; - hash.SetHex (featureID); + hash.SetHex (amendmentID); if (hash.isZero ()) { @@ -159,7 +159,7 @@ FeaturesImpl::addKnown (const char* featureID, const char* friendlyName, return nullptr; } - FeatureState* f = getCreate (hash, true); + AmendmentState* f = getCreate (hash, true); if (friendlyName != nullptr) f->setFriendlyName (friendlyName); @@ -171,10 +171,10 @@ FeaturesImpl::addKnown (const char* featureID, const char* friendlyName, } bool -FeaturesImpl::veto (uint256 const& feature) +AmendmentTableImpl::veto (uint256 const& amendment) { ScopedLockType sl (mLock); - FeatureState* s = getCreate (feature, true); + AmendmentState* s = getCreate (amendment, true); if (s->mVetoed) return false; @@ -184,10 +184,10 @@ FeaturesImpl::veto (uint256 const& feature) } bool -FeaturesImpl::unVeto (uint256 const& feature) +AmendmentTableImpl::unVeto (uint256 const& amendment) { ScopedLockType sl (mLock); - FeatureState* s = getCreate (feature, false); + AmendmentState* s = getCreate (amendment, false); if (!s || !s->mVetoed) return false; @@ -197,10 +197,10 @@ FeaturesImpl::unVeto (uint256 const& feature) } bool -FeaturesImpl::enable (uint256 const& feature) +AmendmentTableImpl::enable (uint256 const& amendment) { ScopedLockType sl (mLock); - FeatureState* s = getCreate (feature, true); + AmendmentState* s = getCreate (amendment, true); if (s->mEnabled) return false; @@ -210,10 +210,10 @@ FeaturesImpl::enable (uint256 const& feature) } bool -FeaturesImpl::disable (uint256 const& feature) +AmendmentTableImpl::disable (uint256 const& amendment) { ScopedLockType sl (mLock); - FeatureState* s = getCreate (feature, false); + AmendmentState* s = getCreate (amendment, false); if (!s || !s->mEnabled) return false; @@ -223,27 +223,27 @@ FeaturesImpl::disable (uint256 const& feature) } bool -FeaturesImpl::isEnabled (uint256 const& feature) +AmendmentTableImpl::isEnabled (uint256 const& amendment) { ScopedLockType sl (mLock); - FeatureState* s = getCreate (feature, false); + AmendmentState* s = getCreate (amendment, false); return s && s->mEnabled; } bool -FeaturesImpl::isSupported (uint256 const& feature) +AmendmentTableImpl::isSupported (uint256 const& amendment) { ScopedLockType sl (mLock); - FeatureState* s = getCreate (feature, false); + AmendmentState* s = getCreate (amendment, false); return s && s->mSupported; } -FeaturesImpl::featureList_t -FeaturesImpl::getVetoed () +AmendmentTableImpl::amendmentList_t +AmendmentTableImpl::getVetoed () { - featureList_t ret; + amendmentList_t ret; ScopedLockType sl (mLock); - for (auto const& e : mFeatureMap) + for (auto const& e : m_amendmentMap) { if (e.second.mVetoed) ret.insert (e.first); @@ -251,12 +251,12 @@ FeaturesImpl::getVetoed () return ret; } -FeaturesImpl::featureList_t -FeaturesImpl::getEnabled () +AmendmentTableImpl::amendmentList_t +AmendmentTableImpl::getEnabled () { - featureList_t ret; + amendmentList_t ret; ScopedLockType sl (mLock); - for (auto const& e : mFeatureMap) + for (auto const& e : m_amendmentMap) { if (e.second.mEnabled) ret.insert (e.first); @@ -265,7 +265,8 @@ FeaturesImpl::getEnabled () } bool -FeaturesImpl::shouldEnable (std::uint32_t closeTime, const FeatureState& fs) +AmendmentTableImpl::shouldEnable (std::uint32_t closeTime, + const AmendmentState& fs) { if (fs.mVetoed || fs.mEnabled || !fs.mSupported || (fs.m_lastMajority != m_lastReport)) return false; @@ -280,15 +281,15 @@ FeaturesImpl::shouldEnable (std::uint32_t closeTime, const FeatureState& fs) return (fs.m_lastMajority - fs.m_firstMajority) > m_majorityTime.count(); } -FeaturesImpl::featureList_t -FeaturesImpl::getToEnable (core::Clock::time_point closeTime) +AmendmentTableImpl::amendmentList_t +AmendmentTableImpl::getToEnable (core::Clock::time_point closeTime) { - featureList_t ret; + amendmentList_t ret; ScopedLockType sl (mLock); if (m_lastReport != 0) { - for (auto const& e : mFeatureMap) + for (auto const& e : m_amendmentMap) { if (shouldEnable (closeTime, e.second)) ret.insert (e.first); @@ -298,13 +299,13 @@ FeaturesImpl::getToEnable (core::Clock::time_point closeTime) return ret; } -FeaturesImpl::featureList_t -FeaturesImpl::getDesired () +AmendmentTableImpl::amendmentList_t +AmendmentTableImpl::getDesired () { - featureList_t ret; + amendmentList_t ret; ScopedLockType sl (mLock); - for (auto const& e : mFeatureMap) + for (auto const& e : m_amendmentMap) { if (e.second.mSupported && !e.second.mEnabled && !e.second.mVetoed) ret.insert (e.first); @@ -314,7 +315,7 @@ FeaturesImpl::getDesired () } void -FeaturesImpl::reportValidations (const FeatureSet& set) +AmendmentTableImpl::reportValidations (const AmendmentSet& set) { if (set.mTrustedValidations == 0) return; @@ -328,14 +329,14 @@ FeaturesImpl::reportValidations (const FeatureSet& set) if (m_firstReport == 0) m_firstReport = set.mCloseTime; - std::vector changedFeatures; - changedFeatures.resize (set.mVotes.size ()); + std::vector changedAmendments; + changedAmendments.resize(set.mVotes.size()); for (auto const& e : set.mVotes) { - FeatureState& state = mFeatureMap[e.first]; + AmendmentState& state = m_amendmentMap[e.first]; if (m_journal.debug) m_journal.debug << - "Feature " << e.first.GetHex () << + "Amendment " << e.first.GetHex () << " has " << e.second << " votes, needs " << threshold; @@ -347,11 +348,11 @@ FeaturesImpl::reportValidations (const FeatureSet& set) if (state.m_firstMajority == 0) { if (m_journal.warning) m_journal.warning << - "Feature " << e.first << + "Amendment " << e.first << " attains a majority vote"; state.m_firstMajority = set.mCloseTime; - changedFeatures.push_back (e.first); + changedAmendments.push_back(e.first); } } else // we have no majority @@ -359,26 +360,26 @@ FeaturesImpl::reportValidations (const FeatureSet& set) if (state.m_firstMajority != 0) { if (m_journal.warning) m_journal.warning << - "Feature " << e.first << + "Amendment " << e.first << " loses majority vote"; state.m_firstMajority = 0; state.m_lastMajority = 0; - changedFeatures.push_back (e.first); + changedAmendments.push_back(e.first); } } } m_lastReport = set.mCloseTime; - if (!changedFeatures.empty ()) + if (!changedAmendments.empty()) { DeprecatedScopedLock sl (getApp().getWalletDB ()->getDBLock ()); Database* db = getApp().getWalletDB ()->getDB (); db->executeSQL ("BEGIN TRANSACTION;"); - for (auto const& hash : changedFeatures) + for (auto const& hash : changedAmendments) { - FeatureState& fState = mFeatureMap[hash]; + AmendmentState& fState = m_amendmentMap[hash]; db->executeSQL (boost::str (boost::format ( "UPDATE Features SET FirstMajority = %d WHERE Hash = '%s';" ) % fState.m_firstMajority % hash.GetHex ())); @@ -387,63 +388,65 @@ FeaturesImpl::reportValidations (const FeatureSet& set) ) % fState.m_lastMajority % hash.GetHex())); } db->executeSQL ("END TRANSACTION;"); - changedFeatures.clear (); + changedAmendments.clear(); } } void -FeaturesImpl::setEnabled (const std::vector& features) +AmendmentTableImpl::setEnabled (const std::vector& amendments) { ScopedLockType sl (mLock); - for (auto& e : mFeatureMap) + for (auto& e : m_amendmentMap) { e.second.mEnabled = false; } - for (auto const& e : features) + for (auto const& e : amendments) { - mFeatureMap[e].mEnabled = true; + m_amendmentMap[e].mEnabled = true; } } void -FeaturesImpl::setSupported (const std::vector& features) +AmendmentTableImpl::setSupported (const std::vector& amendments) { ScopedLockType sl (mLock); - for (auto &e : mFeatureMap) + for (auto &e : m_amendmentMap) { e.second.mSupported = false; } - for (auto const& e : features) + for (auto const& e : amendments) { - mFeatureMap[e].mSupported = true; + m_amendmentMap[e].mSupported = true; } } void -FeaturesImpl::doValidation (Ledger::ref lastClosedLedger, STObject& baseValidation) +AmendmentTableImpl::doValidation (Ledger::ref lastClosedLedger, + STObject& baseValidation) { - featureList_t lFeatures = getDesired (); + amendmentList_t lAmendments = getDesired(); - if (lFeatures.empty ()) + if (lAmendments.empty()) return; - STVector256 vFeatures (sfFeatures); - for (auto const& uFeature : lFeatures) + STVector256 vAmendments (sfAmendments); + for (auto const& uAmendment : lAmendments) { - vFeatures.addValue (uFeature); + vAmendments.addValue (uAmendment); } - vFeatures.sort (); - baseValidation.setFieldV256 (sfFeatures, vFeatures); + vAmendments.sort (); + baseValidation.setFieldV256 (sfAmendments, vAmendments); } void -FeaturesImpl::doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPosition) +AmendmentTableImpl::doVoting (Ledger::ref lastClosedLedger, + SHAMap::ref initialPosition) { // LCL must be flag ledger assert((lastClosedLedger->getLedgerSeq () % 256) == 0); - FeatureSet featureSet (lastClosedLedger->getParentCloseTimeNC ()); + AmendmentSet amendmentSet (lastClosedLedger->getParentCloseTimeNC ()); // get validations for ledger before flag ledger ValidationSet valSet = getApp().getValidations ().getValidations (lastClosedLedger->getParentHash ()); @@ -453,29 +456,28 @@ FeaturesImpl::doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPositio if (val.isTrusted ()) { - featureSet.addVoter (); - if (val.isFieldPresent (sfFeatures)) + amendmentSet.addVoter (); + if (val.isFieldPresent (sfAmendments)) { - for (auto const& feature : val.getFieldV256 (sfFeatures)) + for (auto const& amendment : val.getFieldV256 (sfAmendments)) { - featureSet.addVote (feature); + amendmentSet.addVote (amendment); } } - } } - reportValidations (featureSet); + reportValidations (amendmentSet); - featureList_t lFeatures = getToEnable (lastClosedLedger->getCloseTimeNC ()); - for (auto const& uFeature : lFeatures) + amendmentList_t lAmendments = getToEnable (lastClosedLedger->getCloseTimeNC ()); + for (auto const& uAmendment : lAmendments) { if (m_journal.warning) m_journal.warning << - "Voting for feature: " << uFeature; + "Voting for amendment: " << uAmendment; - // Create the transaction to enable the feature - SerializedTransaction trans (ttFEATURE); + // Create the transaction to enable the amendment + SerializedTransaction trans (ttAMENDMENT); trans.setFieldAccount (sfAccount, uint160 ()); - trans.setFieldH256 (sfFeature, uFeature); + trans.setFieldH256 (sfAmendment, uAmendment); uint256 txID = trans.getTransactionID (); if (m_journal.warning) m_journal.warning << @@ -484,24 +486,24 @@ FeaturesImpl::doVoting (Ledger::ref lastClosedLedger, SHAMap::ref initialPositio // Inject the transaction into our initial proposal Serializer s; trans.add (s, true); -#if RIPPLE_PROPOSE_FEATURES +#if RIPPLE_PROPOSE_AMENDMENTS SHAMapItem::pointer tItem = boost::make_shared (txID, s.peekData ()); if (!initialPosition->addGiveItem (tItem, true, false)) { if (m_journal.warning) m_journal.warning << - "Ledger already had feature transaction"; + "Ledger already had amendment transaction"; } #endif } } Json::Value -FeaturesImpl::getJson (int) +AmendmentTableImpl::getJson (int) { Json::Value ret(Json::objectValue); { ScopedLockType sl(mLock); - for (auto const& e : mFeatureMap) + for (auto const& e : m_amendmentMap) { setJson (ret[e.first.GetHex ()] = Json::objectValue, e.second); } @@ -510,7 +512,7 @@ FeaturesImpl::getJson (int) } void -FeaturesImpl::setJson (Json::Value& v, const FeatureState& fs) +AmendmentTableImpl::setJson (Json::Value& v, const AmendmentState& fs) { if (!fs.mFriendlyName.empty()) v["name"] = fs.mFriendlyName; @@ -556,26 +558,26 @@ FeaturesImpl::setJson (Json::Value& v, const FeatureState& fs) } Json::Value -FeaturesImpl::getJson (uint256 const& featureID) +AmendmentTableImpl::getJson (uint256 const& amendmentID) { Json::Value ret = Json::objectValue; - Json::Value& jFeature = (ret[featureID.GetHex()] = Json::objectValue); + Json::Value& jAmendment = (ret[amendmentID.GetHex ()] = Json::objectValue); { ScopedLockType sl(mLock); - FeatureState *featureState = getCreate (featureID, true); - setJson (jFeature, *featureState); + AmendmentState *amendmentState = getCreate (amendmentID, true); + setJson (jAmendment, *amendmentState); } return ret; } -std::unique_ptr -make_FeatureTable (std::chrono::seconds majorityTime, int majorityFraction, +std::unique_ptr +make_AmendmentTable (std::chrono::seconds majorityTime, int majorityFraction, beast::Journal journal) { - return std::make_unique (majorityTime, majorityFraction, + return std::make_unique (majorityTime, majorityFraction, journal); } diff --git a/src/ripple_app/misc/NetworkOPs.cpp b/src/ripple_app/misc/NetworkOPs.cpp index a94a6a32d8..62641c7159 100644 --- a/src/ripple_app/misc/NetworkOPs.cpp +++ b/src/ripple_app/misc/NetworkOPs.cpp @@ -58,7 +58,7 @@ public: , mNeedNetworkLedger (false) , mProposing (false) , mValidating (false) - , mFeatureBlocked (false) + , m_amendmentBlocked (false) , m_heartbeatTimer (this) , m_clusterTimer (this) , m_ledgerMaster (ledgerMaster) @@ -299,11 +299,11 @@ public: { return mValidating; } - bool isFeatureBlocked () + bool isAmendmentBlocked () { - return mFeatureBlocked; + return m_amendmentBlocked; } - void setFeatureBlocked (); + void setAmendmentBlocked (); void consensusViewChange (); int getPreviousProposers () { @@ -469,7 +469,7 @@ private: OperatingMode mMode; bool mNeedNetworkLedger; bool mProposing, mValidating; - bool mFeatureBlocked; + bool m_amendmentBlocked; boost::posix_time::ptime mConnectTime; beast::DeadlineTimer m_heartbeatTimer; beast::DeadlineTimer m_clusterTimer; @@ -1191,9 +1191,9 @@ Json::Value NetworkOPsImp::getOwnerInfo (Ledger::pointer lpLedger, const RippleA // Other // -void NetworkOPsImp::setFeatureBlocked () +void NetworkOPsImp::setAmendmentBlocked () { - mFeatureBlocked = true; + m_amendmentBlocked = true; setMode (omTRACKING); } @@ -1728,7 +1728,7 @@ void NetworkOPsImp::setMode (OperatingMode om) om = omCONNECTED; } - if ((om > omTRACKING) && mFeatureBlocked) + if ((om > omTRACKING) && m_amendmentBlocked) om = omTRACKING; if (mMode == om) @@ -2207,8 +2207,8 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin) info["complete_ledgers"] = getApp().getLedgerMaster ().getCompleteLedgers (); - if (mFeatureBlocked) - info["feature_blocked"] = true; + if (m_amendmentBlocked) + info["amendment_blocked"] = true; size_t fp = mFetchPack.getCacheSize (); diff --git a/src/ripple_app/misc/NetworkOPs.h b/src/ripple_app/misc/NetworkOPs.h index 9293c1c239..2777b14c99 100644 --- a/src/ripple_app/misc/NetworkOPs.h +++ b/src/ripple_app/misc/NetworkOPs.h @@ -251,8 +251,8 @@ public: virtual void setProposing (bool isProposing, bool isValidating) = 0; virtual bool isProposing () = 0; virtual bool isValidating () = 0; - virtual bool isFeatureBlocked () = 0; - virtual void setFeatureBlocked () = 0; + virtual bool isAmendmentBlocked () = 0; + virtual void setAmendmentBlocked () = 0; virtual void consensusViewChange () = 0; virtual int getPreviousProposers () = 0; virtual int getPreviousConvergeTime () = 0; diff --git a/src/ripple_app/misc/README.md b/src/ripple_app/misc/README.md new file mode 100644 index 0000000000..8963803f5e --- /dev/null +++ b/src/ripple_app/misc/README.md @@ -0,0 +1,30 @@ + +# Amendment + +An Amendment is a new or proposed change to a ledger rule. Ledger rules affect +transaction processing and consensus; peers must use the same set of rules for +consensus to succeed, otherwise different instances of rippled will get +different results. Amendments can be almost anything but they must be accepted +by a network majority through a consensus process before they are utilized. An +Amendment must receive at least an 80% approval rate from validating nodes for +a period of two weeks before being accepted. The following example outlines the +process of an Amendment from its conception to approval and usage. + +* A community member makes proposes to change transaction processing in some + way. The proposal is discussed amongst the community and receives its support + creating a community or human consensus. + +* Some members contribute their time and work to develop the Amendment. + +* A pull request is created and the new code is folded into a rippled build + and made available for use. + +* The consensus process begins with the validating nodes. + +* If the Amendment holds an 80% majority for a two week period, nodes will begin + including the transaction to enable it in their initial sets. + +Nodes may veto Amendments they consider undesirable by never announcing their +support for those Amendments. Just a few nodes vetoing an Amendment will normally +keep it from being accepted. Nodes could also vote yes on an Amendments even +before it obtains a super-majority. This might make sense for a critical bug fix. \ No newline at end of file diff --git a/src/ripple_app/ripple_app.h b/src/ripple_app/ripple_app.h index 17e5371535..104a10165e 100644 --- a/src/ripple_app/ripple_app.h +++ b/src/ripple_app/ripple_app.h @@ -83,7 +83,7 @@ #include "main/LoadManager.h" #include "misc/OrderBook.h" #include "shamap/SHAMapSyncFilters.h" -#include "misc/FeatureTable.h" +#include "misc/AmendmentTable.h" #include "misc/FeeVote.h" #include "misc/IHashRouter.h" #include "peers/ClusterNodeStatus.h" diff --git a/src/ripple_app/ripple_app_pt6.cpp b/src/ripple_app/ripple_app_pt6.cpp index 55645f420b..aa93928eb3 100644 --- a/src/ripple_app/ripple_app_pt6.cpp +++ b/src/ripple_app/ripple_app_pt6.cpp @@ -31,4 +31,4 @@ #include "misc/HashRouter.cpp" #include "misc/Offer.cpp" #include "paths/Pathfinder.cpp" -#include "misc/FeaturesImpl.cpp" +#include "misc/AmendmentTableImpl.cpp" diff --git a/src/ripple_app/transactors/ChangeTransactor.cpp b/src/ripple_app/transactors/ChangeTransactor.cpp index 237d170509..ea073408b8 100644 --- a/src/ripple_app/transactors/ChangeTransactor.cpp +++ b/src/ripple_app/transactors/ChangeTransactor.cpp @@ -21,8 +21,8 @@ namespace ripple { TER ChangeTransactor::doApply () { - if (mTxn.getTxnType () == ttFEATURE) - return applyFeature (); + if (mTxn.getTxnType () == ttAMENDMENT) + return applyAmendment (); if (mTxn.getTxnType () == ttFEE) return applyFee (); @@ -89,30 +89,32 @@ TER ChangeTransactor::preCheck () return tesSUCCESS; } -TER ChangeTransactor::applyFeature () +TER ChangeTransactor::applyAmendment () { - uint256 feature (mTxn.getFieldH256 (sfFeature)); + uint256 amendment (mTxn.getFieldH256 (sfAmendment)); - SLE::pointer featureObject (mEngine->entryCache ( - ltFEATURES, Ledger::getLedgerFeatureIndex ())); + SLE::pointer amendmentObject (mEngine->entryCache ( + ltAMENDMENTS, Ledger::getLedgerAmendmentIndex ())); - if (!featureObject) - featureObject = mEngine->entryCreate ( - ltFEATURES, Ledger::getLedgerFeatureIndex ()); + if (!amendmentObject) + { + amendmentObject = mEngine->entryCreate( + ltAMENDMENTS, Ledger::getLedgerAmendmentIndex()); + } - STVector256 features (featureObject->getFieldV256 (sfFeatures)); + STVector256 amendments (amendmentObject->getFieldV256 (sfAmendments)); - if (features.hasValue (feature)) + if (amendments.hasValue (amendment)) return tefALREADY; - features.addValue (feature); - featureObject->setFieldV256 (sfFeatures, features); - mEngine->entryModify (featureObject); + amendments.addValue (amendment); + amendmentObject->setFieldV256 (sfAmendments, amendments); + mEngine->entryModify (amendmentObject); - getApp().getFeatureTable ().enable (feature); + getApp().getAmendmentTable ().enable (amendment); - if (!getApp().getFeatureTable ().isSupported (feature)) - getApp().getOPs ().setFeatureBlocked (); + if (!getApp().getAmendmentTable ().isSupported (amendment)) + getApp().getOPs ().setAmendmentBlocked (); return tesSUCCESS; } diff --git a/src/ripple_app/transactors/ChangeTransactor.h b/src/ripple_app/transactors/ChangeTransactor.h index 51cc0d9ce5..54692c2260 100644 --- a/src/ripple_app/transactors/ChangeTransactor.h +++ b/src/ripple_app/transactors/ChangeTransactor.h @@ -54,7 +54,7 @@ public: TER preCheck () override; private: - TER applyFeature (); + TER applyAmendment (); TER applyFee (); // VFALCO TODO Can this be removed? diff --git a/src/ripple_app/transactors/Transactor.cpp b/src/ripple_app/transactors/Transactor.cpp index cb75948500..9e9fc9bfae 100644 --- a/src/ripple_app/transactors/Transactor.cpp +++ b/src/ripple_app/transactors/Transactor.cpp @@ -64,7 +64,7 @@ std::unique_ptr Transactor::makeTransactor ( return std::unique_ptr ( new WalletAddTransactor (txn, params, engine)); - case ttFEATURE: + case ttAMENDMENT: case ttFEE: return std::unique_ptr ( new ChangeTransactor (txn, params, engine)); diff --git a/src/ripple_data/protocol/LedgerFormats.cpp b/src/ripple_data/protocol/LedgerFormats.cpp index dadcb6e475..32bc04464b 100644 --- a/src/ripple_data/protocol/LedgerFormats.cpp +++ b/src/ripple_data/protocol/LedgerFormats.cpp @@ -108,8 +108,8 @@ LedgerFormats::LedgerFormats () << SOElement (sfHashes, SOE_REQUIRED) ; - add ("EnabledFeatures", ltFEATURES) - << SOElement (sfFeatures, SOE_REQUIRED) + add ("EnabledAmendments", ltAMENDMENTS) + << SOElement (sfAmendments, SOE_REQUIRED) ; add ("FeeSettings", ltFEE_SETTINGS) diff --git a/src/ripple_data/protocol/LedgerFormats.h b/src/ripple_data/protocol/LedgerFormats.h index 0bca7a0a04..ebcae8735a 100644 --- a/src/ripple_data/protocol/LedgerFormats.h +++ b/src/ripple_data/protocol/LedgerFormats.h @@ -65,7 +65,7 @@ enum LedgerEntryType ltLEDGER_HASHES = 'h', - ltFEATURES = 'f', + ltAMENDMENTS = 'f', ltFEE_SETTINGS = 's', }; @@ -87,7 +87,7 @@ enum LedgerNameSpace spaceBookDir = 'B', // Directory of order books. spaceContract = 'c', spaceSkipList = 's', - spaceFeature = 'f', + spaceAmendment = 'f', spaceFee = 'e', }; diff --git a/src/ripple_data/protocol/SerializeDeclarations.h b/src/ripple_data/protocol/SerializeDeclarations.h index f5ba6931b6..4d86dbb7c0 100644 --- a/src/ripple_data/protocol/SerializeDeclarations.h +++ b/src/ripple_data/protocol/SerializeDeclarations.h @@ -124,7 +124,7 @@ FIELD (AccountTxnID, HASH256, 9) FIELD (BookDirectory, HASH256, 16) FIELD (InvoiceID, HASH256, 17) FIELD (Nickname, HASH256, 18) -FIELD (Feature, HASH256, 19) +FIELD (Amendment, HASH256, 19) // 160-bit (common) FIELD (TakerPaysCurrency, HASH160, 1) @@ -177,7 +177,7 @@ FIELD (Paths, PATHSET, 1) // vector of 256-bit FIELD (Indexes, VECTOR256, 1) FIELD (Hashes, VECTOR256, 2) -FIELD (Features, VECTOR256, 3) +FIELD (Amendments, VECTOR256, 3) // inner object // OBJECT/1 is reserved for end of object diff --git a/src/ripple_data/protocol/TxFormats.cpp b/src/ripple_data/protocol/TxFormats.cpp index b6f26ba65e..89a87855c2 100644 --- a/src/ripple_data/protocol/TxFormats.cpp +++ b/src/ripple_data/protocol/TxFormats.cpp @@ -77,8 +77,8 @@ TxFormats::TxFormats () << SOElement (sfTarget, SOE_REQUIRED) ; - add ("EnableFeature", ttFEATURE) - << SOElement (sfFeature, SOE_REQUIRED) + add ("EnableAmendment", ttAMENDMENT) + << SOElement (sfAmendment, SOE_REQUIRED) ; add ("SetFee", ttFEE) diff --git a/src/ripple_data/protocol/TxFormats.h b/src/ripple_data/protocol/TxFormats.h index 1ea8d1d0c6..cd5485d03d 100644 --- a/src/ripple_data/protocol/TxFormats.h +++ b/src/ripple_data/protocol/TxFormats.h @@ -46,7 +46,7 @@ enum TxType ttTRUST_SET = 20, - ttFEATURE = 100, + ttAMENDMENT = 100, ttFEE = 101, }; diff --git a/src/ripple_rpc/handlers/Feature.cpp b/src/ripple_rpc/handlers/Feature.cpp index cdf30b0648..7c8cbe997d 100644 --- a/src/ripple_rpc/handlers/Feature.cpp +++ b/src/ripple_rpc/handlers/Feature.cpp @@ -45,11 +45,11 @@ Json::Value RPCHandler::doFeature (Json::Value params, Resource::Charge& loadTyp if (!params.isMember ("feature")) { Json::Value jvReply = Json::objectValue; - jvReply["features"] = getApp().getFeatureTable ().getJson (0); + jvReply["features"] = getApp().getAmendmentTable ().getJson(0); return jvReply; } - uint256 uFeature = getApp().getFeatureTable ().get (params["feature"].asString ()); + uint256 uFeature = getApp().getAmendmentTable ().get(params["feature"].asString()); if (uFeature.isZero ()) { @@ -60,7 +60,7 @@ Json::Value RPCHandler::doFeature (Json::Value params, Resource::Charge& loadTyp } if (!params.isMember ("vote")) - return getApp().getFeatureTable ().getJson (uFeature); + return getApp().getAmendmentTable ().getJson(uFeature); // WRITEME return rpcError (rpcNOT_SUPPORTED);