From 69a904133fa4dee67fe7ffc62b8e5597fa0b8d27 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 30 May 2013 14:30:06 -0700 Subject: [PATCH] Block operation if a feature we don't support is enabled in the ledger. --- src/cpp/ripple/Application.cpp | 6 ++++++ src/cpp/ripple/ChangeTransactor.cpp | 4 ++++ src/cpp/ripple/FeatureTable.cpp | 7 +++++++ src/cpp/ripple/FeatureTable.h | 1 + src/cpp/ripple/Ledger.cpp | 9 +++------ src/cpp/ripple/Ledger.h | 2 +- src/cpp/ripple/NetworkOPs.cpp | 12 ++++++++++++ src/cpp/ripple/NetworkOPs.h | 3 +++ 8 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 4746d1ef86..6464e40102 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -547,6 +547,12 @@ bool serverOkay(std::string& reason) return false; } + if (theApp->getOPs().isFeatureBlocked()) + { + reason = "Server version too old"; + return false; + } + return true; } diff --git a/src/cpp/ripple/ChangeTransactor.cpp b/src/cpp/ripple/ChangeTransactor.cpp index fa9723732f..790b823686 100644 --- a/src/cpp/ripple/ChangeTransactor.cpp +++ b/src/cpp/ripple/ChangeTransactor.cpp @@ -85,6 +85,10 @@ TER ChangeTransactor::applyFeature() featureObject->setFieldV256(sfFeatures, features); mEngine->entryModify(featureObject); + theApp->getFeatureTable().enableFeature(feature); + if (!theApp->getFeatureTable().isFeatureSupported(feature)) + theApp->getOPs().setFeatureBlocked(); + return tesSUCCESS; } diff --git a/src/cpp/ripple/FeatureTable.cpp b/src/cpp/ripple/FeatureTable.cpp index e93a5821b4..1581d0d6ca 100644 --- a/src/cpp/ripple/FeatureTable.cpp +++ b/src/cpp/ripple/FeatureTable.cpp @@ -87,6 +87,13 @@ bool FeatureTable::isFeatureEnabled(const uint256& feature) return s && s->mEnabled; } +bool FeatureTable::isFeatureSupported(const uint256& feature) +{ + boost::mutex::scoped_lock sl(mMutex); + FeatureState *s = getCreateFeature(feature, false); + return s && s->mSupported; +} + FeatureTable::featureList_t FeatureTable::getVetoedFeatures() { featureList_t ret; diff --git a/src/cpp/ripple/FeatureTable.h b/src/cpp/ripple/FeatureTable.h index 0adcf2bf3c..222603d64e 100644 --- a/src/cpp/ripple/FeatureTable.h +++ b/src/cpp/ripple/FeatureTable.h @@ -75,6 +75,7 @@ public: 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); diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index da9b4e105e..4e58876c54 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -1327,15 +1327,12 @@ std::vector< std::pair > Ledger::getLedgerHashes() return ret; } -boost::unordered_set Ledger::getLedgerFeatures() +std::vector Ledger::getLedgerFeatures() { - boost::unordered_set usFeatures; + std::vector usFeatures; SLE::pointer sleFeatures = getSLEi(getLedgerFeatureIndex()); if (sleFeatures) - { - BOOST_FOREACH(const uint256& uFeature, sleFeatures->getFieldV256(sfFeatures).peekValue()) - usFeatures.insert(uFeature); - } + usFeatures = sleFeatures->getFieldV256(sfFeatures).peekValue(); return usFeatures; } diff --git a/src/cpp/ripple/Ledger.h b/src/cpp/ripple/Ledger.h index 3ad00ca8cb..db56195efb 100644 --- a/src/cpp/ripple/Ledger.h +++ b/src/cpp/ripple/Ledger.h @@ -220,7 +220,7 @@ public: static uint256 getLedgerFeatureIndex(); static uint256 getLedgerFeeIndex(); - boost::unordered_set getLedgerFeatures(); + std::vector getLedgerFeatures(); std::vector getNeededTransactionHashes(int max, SHAMapSyncFilter* filter); std::vector getNeededAccountStateHashes(int max, SHAMapSyncFilter* filter); diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index 5eac4efe35..153647f4f7 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -31,6 +31,7 @@ void InfoSub::onSendEmpty() NetworkOPs::NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster) : mMode(omDISCONNECTED), mNeedNetworkLedger(false), mProposing(false), mValidating(false), + mFeatureBlocked(false), mNetTimer(io_service), mLedgerMaster(pLedgerMaster), mCloseTimeOffset(0), mLastCloseProposers(0), mLastCloseConvergeTime(1000 * LEDGER_IDLE_INTERVAL), mLastCloseTime(0), mLastValidationTime(0), mFetchPack("FetchPack", 2048, 20), mLastFetchPack(0), mFetchSeq(static_cast(-1)), @@ -553,6 +554,12 @@ Json::Value NetworkOPs::getOwnerInfo(Ledger::pointer lpLedger, const RippleAddre // Other // +void NetworkOPs::setFeatureBlocked() +{ + mFeatureBlocked = true; + setMode(omTRACKING); +} + void NetworkOPs::setStateTimer() { mNetTimer.expires_from_now(boost::posix_time::milliseconds(LEDGER_GRANULARITY)); @@ -1047,6 +1054,9 @@ void NetworkOPs::setMode(OperatingMode om) om = omCONNECTED; } + if ((om > omTRACKING) && mFeatureBlocked) + om = omTRACKING; + if (mMode == om) return; @@ -1265,6 +1275,8 @@ Json::Value NetworkOPs::getServerInfo(bool human, bool admin) info["complete_ledgers"] = theApp->getLedgerMaster().getCompleteLedgers(); + if (mFeatureBlocked) + info["feature_blocked"] = true; size_t fp = mFetchPack.getCacheSize(); if (fp != 0) diff --git a/src/cpp/ripple/NetworkOPs.h b/src/cpp/ripple/NetworkOPs.h index ec1927170f..592573969d 100644 --- a/src/cpp/ripple/NetworkOPs.h +++ b/src/cpp/ripple/NetworkOPs.h @@ -115,6 +115,7 @@ protected: OperatingMode mMode; bool mNeedNetworkLedger; bool mProposing, mValidating; + bool mFeatureBlocked; boost::posix_time::ptime mConnectTime; boost::asio::deadline_timer mNetTimer; boost::shared_ptr mConsensus; @@ -309,6 +310,8 @@ public: void setProposing(bool p, bool v) { mProposing = p; mValidating = v; } bool isProposing() { return mProposing; } bool isValidating() { return mValidating; } + bool isFeatureBlocked() { return mFeatureBlocked; } + void setFeatureBlocked(); void consensusViewChange(); int getPreviousProposers() { return mLastCloseProposers; } int getPreviousConvergeTime() { return mLastCloseConvergeTime; }