From cb744e76a404da8f447cb3b940ead8384ed4fc6b Mon Sep 17 00:00:00 2001 From: Valentin Balaschenko <13349202+vlntb@users.noreply.github.com> Date: Wed, 10 Dec 2025 16:58:30 +0000 Subject: [PATCH] GlobalFreezeIssuer amendment --- include/xrpl/protocol/detail/features.macro | 1 + src/libxrpl/ledger/View.cpp | 7 ++- src/test/app/Freeze_test.cpp | 68 +++++++++++++++++++++ 3 files changed, 74 insertions(+), 2 deletions(-) diff --git a/include/xrpl/protocol/detail/features.macro b/include/xrpl/protocol/detail/features.macro index 5c8d2aa198..521e625a85 100644 --- a/include/xrpl/protocol/detail/features.macro +++ b/include/xrpl/protocol/detail/features.macro @@ -16,6 +16,7 @@ // Add new amendments to the top of this list. // Keep it sorted in reverse chronological order. +XRPL_FIX (GlobalFreezeIssuer, Supported::no, VoteBehavior::DefaultNo) XRPL_FEATURE(LendingProtocol, Supported::no, VoteBehavior::DefaultNo) XRPL_FEATURE(PermissionDelegationV1_1, Supported::no, VoteBehavior::DefaultNo) XRPL_FIX (DirectoryLimit, Supported::yes, VoteBehavior::DefaultNo) diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index 3d43a1541e..3c97b104ac 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -234,8 +234,11 @@ isFrozen( if (isXRP(currency)) return false; auto sle = view.read(keylet::account(issuer)); - if (sle && sle->isFlag(lsfGlobalFreeze) && issuer != account) - return true; + if (sle && sle->isFlag(lsfGlobalFreeze)) + { + if (!view.rules().enabled(fixGlobalFreezeIssuer) || issuer != account) + return true; + } if (issuer != account) { // Check if the issuer froze the line diff --git a/src/test/app/Freeze_test.cpp b/src/test/app/Freeze_test.cpp index e9a714de21..b96cbfd73a 100644 --- a/src/test/app/Freeze_test.cpp +++ b/src/test/app/Freeze_test.cpp @@ -2054,6 +2054,73 @@ class Freeze_test : public beast::unit_test::suite env(pay(holder, other, USD(10)), ter(tecPATH_DRY)); } + void + testGlobalFreezeIssuerAmendment(FeatureBitset features) + { + testcase("Global Freeze Issuer Amendment"); + + using namespace test::jtx; + + Account issuer{"issuer"}; + Account holder{"holder"}; + + // Test pre-amendment behavior (issuer IS frozen under global freeze) + { + Env env_pre(*this, features - fixGlobalFreezeIssuer); + + env_pre.fund(XRP(10000), issuer, holder); + env_pre.close(); + + auto const USD = issuer["USD"]; + env_pre.trust(USD(1000), holder); + env_pre.close(); + + env_pre(pay(issuer, holder, USD(100))); + env_pre.close(); + + env_pre(fset(issuer, asfGlobalFreeze)); + env_pre.close(); + + BEAST_EXPECT(isFrozen( + *env_pre.current(), issuer.id(), USD.currency, issuer.id())); + + BEAST_EXPECT(isFrozen( + *env_pre.current(), holder.id(), USD.currency, issuer.id())); + } + + // Test post-amendment behavior (issuer is NOT frozen under global + // freeze) + if (features[fixGlobalFreezeIssuer]) + { + Env env_post(*this, features); + + env_post.fund(XRP(10000), issuer, holder); + env_post.close(); + + auto const USD = issuer["USD"]; + env_post.trust(USD(1000), holder); + env_post.close(); + + env_post(pay(issuer, holder, USD(100))); + env_post.close(); + + env_post(fset(issuer, asfGlobalFreeze)); + env_post.close(); + + BEAST_EXPECT(!isFrozen( + *env_post.current(), issuer.id(), USD.currency, issuer.id())); + + BEAST_EXPECT(isFrozen( + *env_post.current(), holder.id(), USD.currency, issuer.id())); + + env_post(pay(issuer, holder, USD(10))); + env_post.close(); + + env_post(pay(holder, issuer, USD(10))); + env_post.close(); + } + } + // Helper function to extract trustline flags from open ledger uint32_t getTrustlineFlags( @@ -2118,6 +2185,7 @@ public: testSetAndClear(features); testGlobalFreeze(features); testIsFrozenDirectly(features); + testGlobalFreezeIssuerAmendment(features); testNoFreeze(features); testOffersWhenFrozen(features); testOffersWhenDeepFrozen(features);