mirror of
https://github.com/XRPLF/rippled.git
synced 2026-03-07 13:22:27 +00:00
Compare commits
11 Commits
develop
...
Bronek/max
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87d0527b93 | ||
|
|
f6153e4d74 | ||
|
|
5d11334b2d | ||
|
|
1650258fc1 | ||
|
|
72cee507b5 | ||
|
|
7c9a77702f | ||
|
|
ba2ac69f55 | ||
|
|
242b11f314 | ||
|
|
6af70476e8 | ||
|
|
4152dc53ba | ||
|
|
eb95da9cd3 |
@@ -64,6 +64,24 @@
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
// Feature names must not exceed this length (in characters, excluding the null terminator).
|
||||
static constexpr std::size_t maxFeatureNameSize = 63;
|
||||
// Reserve this exact feature-name length (in characters/bytes, excluding the null terminator)
|
||||
// so that a 32-byte uint256 (for example, in WASM or other interop contexts) can be used
|
||||
// as a compact, fixed-size feature selector without conflicting with human-readable names.
|
||||
static constexpr std::size_t reservedFeatureNameSize = 32;
|
||||
|
||||
// Exposed for testing, used only by enforceValidFeatureNameSize in Feature.cpp
|
||||
template <std::size_t N>
|
||||
constexpr auto
|
||||
validFeatureNameSize(char const (*)[N]) -> bool
|
||||
{
|
||||
// The -1 is to account for the null terminator in the string literal.
|
||||
return N - 1 != reservedFeatureNameSize && //
|
||||
N - 1 != reservedFeatureNameSize + 1 && //
|
||||
N - 1 <= maxFeatureNameSize;
|
||||
}
|
||||
|
||||
enum class VoteBehavior : int { Obsolete = -1, DefaultNo = 0, DefaultYes };
|
||||
enum class AmendmentSupport : int { Retired = -1, Supported = 0, Unsupported };
|
||||
|
||||
|
||||
@@ -395,10 +395,20 @@ featureToName(uint256 const& f)
|
||||
#pragma push_macro("XRPL_RETIRE_FIX")
|
||||
#undef XRPL_RETIRE_FIX
|
||||
|
||||
template <std::size_t N>
|
||||
constexpr auto
|
||||
enforceValidFeatureNameSize(char const (&n)[N]) -> char const*
|
||||
{
|
||||
static_assert(validFeatureNameSize<N>(nullptr), "Invalid feature name size");
|
||||
return n;
|
||||
}
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) \
|
||||
uint256 const feature##name = registerFeature(#name, supported, vote);
|
||||
uint256 const feature##name = \
|
||||
registerFeature(enforceValidFeatureNameSize(#name), supported, vote);
|
||||
#define XRPL_FIX(name, supported, vote) \
|
||||
uint256 const fix##name = registerFeature("fix" #name, supported, vote);
|
||||
uint256 const fix##name = \
|
||||
registerFeature(enforceValidFeatureNameSize("fix" #name), supported, vote);
|
||||
|
||||
// clang-format off
|
||||
#define XRPL_RETIRE_FEATURE(name) \
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <xrpl/ledger/AmendmentTable.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/digest.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -168,16 +169,18 @@ class Feature_test : public beast::unit_test::suite
|
||||
using namespace test::jtx;
|
||||
Env env{*this};
|
||||
|
||||
auto jrr = env.rpc("feature", "fixAMMOverflowOffer")[jss::result];
|
||||
std::string const name = "fixAMMOverflowOffer";
|
||||
auto jrr = env.rpc("feature", name)[jss::result];
|
||||
BEAST_EXPECTS(jrr[jss::status] == jss::success, "status");
|
||||
jrr.removeMember(jss::status);
|
||||
BEAST_EXPECT(jrr.size() == 1);
|
||||
BEAST_EXPECT(jrr.isMember(
|
||||
"12523DF04B553A0B1AD74F42DDB741DE8DC06A03FC089A0EF197E"
|
||||
"2A87F1D8107"));
|
||||
auto const expected = to_string(sha512Half(Slice(name.data(), name.size())));
|
||||
char const sha[] = "12523DF04B553A0B1AD74F42DDB741DE8DC06A03FC089A0EF197E2A87F1D8107";
|
||||
BEAST_EXPECT(expected == sha);
|
||||
BEAST_EXPECT(jrr.isMember(expected));
|
||||
auto feature = *(jrr.begin());
|
||||
|
||||
BEAST_EXPECTS(feature[jss::name] == "fixAMMOverflowOffer", "name");
|
||||
BEAST_EXPECTS(feature[jss::name] == name, "name");
|
||||
BEAST_EXPECTS(!feature[jss::enabled].asBool(), "enabled");
|
||||
BEAST_EXPECTS(feature[jss::vetoed].isBool() && !feature[jss::vetoed].asBool(), "vetoed");
|
||||
BEAST_EXPECTS(feature[jss::supported].asBool(), "supported");
|
||||
@@ -186,6 +189,24 @@ class Feature_test : public beast::unit_test::suite
|
||||
jrr = env.rpc("feature", "fMM")[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "badFeature");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "Feature unknown or invalid.");
|
||||
|
||||
// Test feature name size checks
|
||||
char const ok63Name[] = "123456789012345678901234567890123456789012345678901234567890123";
|
||||
static_assert(validFeatureNameSize(&ok63Name));
|
||||
|
||||
char const bad64Name[] = "1234567890123456789012345678901234567890123456789012345678901234";
|
||||
static_assert(!validFeatureNameSize(&bad64Name));
|
||||
|
||||
char const ok31Name[] = "1234567890123456789012345678901";
|
||||
static_assert(validFeatureNameSize(&ok31Name));
|
||||
|
||||
char const bad32Name[] = "12345678901234567890123456789012";
|
||||
static_assert(!validFeatureNameSize(&bad32Name));
|
||||
char const bad33Name[] = "123456789012345678901234567890123";
|
||||
static_assert(!validFeatureNameSize(&bad33Name));
|
||||
|
||||
char const ok34Name[] = "1234567890123456789012345678901234";
|
||||
static_assert(validFeatureNameSize(&ok34Name));
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user