Change features default behavior in Env (RIPD-1460):

Enable all supported amendments in Env by default. Rename `features()`
to `with_features()` and add `all_features_except()` to support feature
subsets in Env. Refactor internal feature handling based on a bitset.
This commit is contained in:
Mike Ellery
2017-05-01 16:03:44 -07:00
committed by seelabs
parent 3dfb4a13f1
commit 56946e8128
36 changed files with 749 additions and 367 deletions

View File

@@ -21,18 +21,124 @@
#define RIPPLE_PROTOCOL_FEATURE_H_INCLUDED
#include <ripple/basics/base_uint.h>
#include <boost/container/flat_map.hpp>
#include <boost/optional.hpp>
#include <array>
#include <bitset>
#include <string>
/**
* @page Feature How to add new features
*
* Steps required to add new features to the code:
*
* 1) add the new feature name to the featureNames array below
* 2) add a uint256 declaration for the feature to the bottom of this file
* 3) add a uint256 definition for the feature to the corresponding source
* file (Feature.cpp)
* 4) if the feature is going to be supported in the near future, add its
* sha512half value and name (matching exactly the featureName here) to the
* supportedAmendments in Amendments.cpp.
*
*/
namespace ripple {
/** Convert feature description to feature id. */
/** @{ */
uint256
feature (std::string const& name);
namespace detail {
class FeatureCollections
{
static constexpr char const* const featureNames[] =
{"MultiSign",
"Tickets",
"TrustSetAuth",
"FeeEscalation",
"OwnerPaysFee",
"CompareFlowV1V2",
"SHAMapV2",
"PayChan",
"Flow",
"CompareTakerFlowCross",
"FlowCross",
"CryptoConditions",
"TickSize",
"fix1368",
"Escrow",
"CryptoConditionsSuite",
"fix1373",
"EnforceInvariants"};
std::vector<uint256> features;
boost::container::flat_map<uint256, std::size_t> featureToIndex;
boost::container::flat_map<std::string, uint256> nameToFeature;
public:
FeatureCollections();
static constexpr std::size_t numFeatures()
{
return sizeof (featureNames) / sizeof (featureNames[0]);
}
boost::optional<uint256>
getRegisteredFeature(std::string const& name) const;
std::size_t
featureToBitsetIndex(uint256 const& f) const;
uint256 const&
bitsetIndexToFeature(size_t i) const;
};
} // detail
boost::optional<uint256>
getRegisteredFeature (std::string const& name);
using FeatureBitset = std::bitset<detail::FeatureCollections::numFeatures()>;
size_t
featureToBitsetIndex(uint256 const& f);
uint256
feature (const char* name);
/** @} */
bitsetIndexToFeature(size_t i);
template <class F>
void
foreachFeature(FeatureBitset bs, F&& f)
{
for (size_t i = 0; i < bs.size(); ++i)
if (bs[i])
f(bitsetIndexToFeature(i));
}
template <class Col>
FeatureBitset
makeFeatureBitset(Col&& fs)
{
FeatureBitset result;
for (auto const& f : fs)
result.set(featureToBitsetIndex(f));
return result;
}
template <class Col>
FeatureBitset
addFeatures(FeatureBitset bs, Col&& fs)
{
for (auto const& f : fs)
bs.set(featureToBitsetIndex(f));
return bs;
}
template <class Col>
FeatureBitset
removeFeatures(FeatureBitset bs, Col&& fs)
{
for (auto const& f : fs)
bs.reset(featureToBitsetIndex(f));
return bs;
}
extern uint256 const featureMultiSign;
extern uint256 const featureTickets;