Compare commits

...

2 Commits

Author SHA1 Message Date
Gregory Tsipenyuk
56c9d1d497 fix: Add description for terLOCKED error (#6811) 2026-04-08 20:56:19 +00:00
yinyiqian1
d52dd29d20 fix: Address AI reviewer comments for Permission Delegation (#6675) 2026-04-08 20:22:19 +00:00
7 changed files with 30 additions and 6 deletions

View File

@@ -344,10 +344,6 @@ enum TECcodes : TERUnderlyingType {
tecLIMIT_EXCEEDED = 195,
tecPSEUDO_ACCOUNT = 196,
tecPRECISION_LOSS = 197,
// DEPRECATED: This error code tecNO_DELEGATE_PERMISSION is reserved for
// backward compatibility with historical data on non-prod networks, can be
// reclaimed after those networks reset.
tecNO_DELEGATE_PERMISSION = 198,
};
//------------------------------------------------------------------------------

View File

@@ -67,6 +67,11 @@ Permission::Permission()
#pragma pop_macro("PERMISSION")
};
XRPL_ASSERT(
txFeatureMap_.size() == delegableTx_.size(),
"xrpl::Permission : txFeatureMap_ and delegableTx_ must have same "
"size");
for ([[maybe_unused]] auto const& permission : granularPermissionMap_)
{
XRPL_ASSERT(

View File

@@ -215,6 +215,7 @@ transResults()
MAKE_ERROR(terNO_AMM, "AMM doesn't exist for the asset pair."),
MAKE_ERROR(terADDRESS_COLLISION, "Failed to allocate an unique account address."),
MAKE_ERROR(terNO_DELEGATE_PERMISSION, "Delegated account lacks permission to perform this transaction."),
MAKE_ERROR(terLOCKED, "Fund is locked."),
MAKE_ERROR(tesSUCCESS, "The transaction was applied. Only final in a validated ledger."),
};

View File

@@ -6,7 +6,7 @@ NotTEC
checkTxPermission(std::shared_ptr<SLE const> const& delegate, STTx const& tx)
{
if (!delegate)
return terNO_DELEGATE_PERMISSION; // LCOV_EXCL_LINE
return terNO_DELEGATE_PERMISSION;
auto const permissionArray = delegate->getFieldArray(sfPermissions);
auto const txPermission = tx.getTxnType() + 1;
@@ -28,7 +28,7 @@ loadGranularPermission(
std::unordered_set<GranularPermissionType>& granularPermissions)
{
if (!delegate)
return; // LCOV_EXCL_LINE
return;
auto const permissionArray = delegate->getFieldArray(sfPermissions);
for (auto const& permission : permissionArray)

View File

@@ -265,6 +265,7 @@ Payment::checkPermission(ReadView const& view, STTx const& tx)
tx.isFieldPresent(sfPaths))
return terNO_DELEGATE_PERMISSION;
// PaymentMint and PaymentBurn apply to both IOU and MPT direct payments.
if (granularPermissions.contains(PaymentMint) && !isXRP(amountAsset) &&
amountAsset.getIssuer() == tx[sfAccount])
return tesSUCCESS;

View File

@@ -4155,8 +4155,12 @@ class Batch_test : public beast::unit_test::suite
std::vector<TestLedgerData> const testCases = {
{0, "Batch", "tesSUCCESS", batchID, std::nullopt},
{1, "TrustSet", "tesSUCCESS", txIDs[0], batchID},
// jv2 fails with terNO_DELEGATE_PERMISSION.
};
validateClosedLedger(env, testCases);
// verify jv2 is not present in the closed ledger.
BEAST_EXPECT(env.rpc("tx", txIDs[1])[jss::result][jss::error] == "txnNotFound");
}
}

View File

@@ -2,6 +2,7 @@
#include <test/jtx/CaptureLogs.h>
#include <test/jtx/delegate.h>
#include <xrpl/ledger/helpers/DelegateHelpers.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Permissions.h>
@@ -1856,6 +1857,21 @@ class Delegate_test : public beast::unit_test::suite
"\n Action: Verify security requirements to interact with Delegation feature");
}
void
testDelegateUtilsNullptrCheck()
{
testcase("DelegateUtils nullptr check");
// checkTxPermission nullptr check
STTx const tx{ttPAYMENT, [](STObject&) {}};
BEAST_EXPECT(checkTxPermission(nullptr, tx) == terNO_DELEGATE_PERMISSION);
// loadGranularPermission nullptr check
std::unordered_set<GranularPermissionType> granularPermissions;
loadGranularPermission(nullptr, ttPAYMENT, granularPermissions);
BEAST_EXPECT(granularPermissions.empty());
}
void
run() override
{
@@ -1881,6 +1897,7 @@ class Delegate_test : public beast::unit_test::suite
testPermissionValue(all);
testTxRequireFeatures(all);
testTxDelegableCount();
testDelegateUtilsNullptrCheck();
}
};
BEAST_DEFINE_TESTSUITE(Delegate, app, xrpl);