Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/xrpl/protocol/Permissions.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ class Permission
isDelegable(std::uint32_t const& permissionValue, Rules const& rules) const;

// for tx level permission, permission value is equal to tx type plus one
static uint32_t
[[nodiscard]] static uint32_t
txToPermissionType(TxType const& type);

// tx type value is permission value minus one
static TxType
[[nodiscard]] static std::optional<TxType>
permissionToTxType(uint32_t const& value);
};

Expand Down
23 changes: 17 additions & 6 deletions src/libxrpl/protocol/Permissions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
#include <string>

Expand Down Expand Up @@ -104,9 +105,11 @@ Permission::getPermissionName(std::uint32_t const value) const
return granular;

// not a granular permission, check if it maps to a transaction type
auto const txType = permissionToTxType(value);
if (auto const* item = TxFormats::getInstance().findByType(txType); item != nullptr)
return item->getName();
if (auto const txType = permissionToTxType(value))
{
if (auto const* item = TxFormats::getInstance().findByType(*txType); item != nullptr)
return item->getName();
}

return std::nullopt;
}
Expand Down Expand Up @@ -166,12 +169,15 @@ Permission::isDelegable(std::uint32_t const& permissionValue, Rules const& rules
}

auto const txType = permissionToTxType(permissionValue);
auto const it = delegableTx_.find(txType);
if (!txType)
return false;

auto const it = delegableTx_.find(*txType);

if (it == delegableTx_.end())
return false;

auto const txFeaturesIt = txFeatureMap_.find(txType);
auto const txFeaturesIt = txFeatureMap_.find(*txType);
XRPL_ASSERT(
txFeaturesIt != txFeatureMap_.end(),
"xrpl::Permissions::isDelegable : tx exists in txFeatureMap_");
Expand All @@ -194,9 +200,14 @@ Permission::txToPermissionType(TxType const& type)
return static_cast<uint32_t>(type) + 1;
}

TxType
std::optional<TxType>
Permission::permissionToTxType(uint32_t const& value)
{
// Defensive check: values outside this range would silently truncate when cast to
// uint16_t, for example, 65537 would become 1, mapping to the Payment transaction.
if (value == 0 || value > std::numeric_limits<std::uint16_t>::max() + 1u)
return std::nullopt;

return static_cast<TxType>(value - 1);
}

Expand Down
34 changes: 34 additions & 0 deletions src/test/app/Delegate_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

#include <cstddef>
#include <cstdint>
#include <limits>
#include <memory>
#include <string>
#include <tuple>
Expand Down Expand Up @@ -1915,6 +1916,38 @@ class Delegate_test : public beast::unit_test::suite
BEAST_EXPECT(granularPermissions.empty());
}

void
testPermissionToTxType()
{
testcase("test Permission to Tx type");

// 0 is not a valid permission value
BEAST_EXPECT(!Permission::permissionToTxType(0));

// 1 maps to Payment transaction
BEAST_EXPECT(Permission::permissionToTxType(1) == ttPAYMENT);

// UINT16_MAX+1 is the maximum possible tx-level permission value
constexpr uint32_t maxTxPermission = std::numeric_limits<uint16_t>::max() + 1u;
BEAST_EXPECT(Permission::permissionToTxType(maxTxPermission).has_value());

// exceeding maximum value should return nullopt
BEAST_EXPECT(!Permission::permissionToTxType(maxTxPermission + 1));

// All granular permission values should return nullopt since they do not map to a TxType.
for (auto const gp : {
#pragma push_macro("PERMISSION")
#undef PERMISSION
#define PERMISSION(type, txType, value) GranularPermissionType::type,
#include <xrpl/protocol/detail/permissions.macro>
#undef PERMISSION
#pragma pop_macro("PERMISSION")
})
{
BEAST_EXPECT(!Permission::permissionToTxType(static_cast<uint32_t>(gp)));
}
}

void
run() override
{
Expand All @@ -1941,6 +1974,7 @@ class Delegate_test : public beast::unit_test::suite
testTxRequireFeatures(all);
testTxDelegableCount();
testDelegateUtilsNullptrCheck();
testPermissionToTxType();
}
};
BEAST_DEFINE_TESTSUITE(Delegate, app, xrpl);
Expand Down
Loading