refactor: Retire DeletableAccounts amendment (#6056)

Amendments activated for more than 2 years can be retired. This change retires the DeletableAccounts amendment.
This commit is contained in:
Jingchen
2025-11-24 11:52:08 +00:00
committed by GitHub
parent 800a315383
commit a791c03dc1
14 changed files with 20 additions and 98 deletions

View File

@@ -66,7 +66,6 @@ XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo
XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(FlowSortStrands, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(RequireFullyCanonicalSig, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(DeletableAccounts, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYes)
// The following amendments are obsolete, but must remain supported
@@ -118,6 +117,7 @@ XRPL_RETIRE_FEATURE(Checks)
XRPL_RETIRE_FEATURE(CheckCashMakesTrustLine)
XRPL_RETIRE_FEATURE(CryptoConditions)
XRPL_RETIRE_FEATURE(CryptoConditionsSuite)
XRPL_RETIRE_FEATURE(DeletableAccounts)
XRPL_RETIRE_FEATURE(DepositAuth)
XRPL_RETIRE_FEATURE(DepositPreauth)
XRPL_RETIRE_FEATURE(DisallowIncoming)

View File

@@ -297,7 +297,7 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet,
#endif
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
Delegation::notDelegatable,
featureDeletableAccounts,
uint256{},
mustDeleteAcct,
({
{sfDestination, soeREQUIRED},

View File

@@ -1863,7 +1863,7 @@ rippleSendIOU(
// Direct send: redeeming IOUs and/or sending own IOUs.
auto const ter =
rippleCreditIOU(view, uSenderID, uReceiverID, saAmount, false, j);
if (view.rules().enabled(featureDeletableAccounts) && ter != tesSUCCESS)
if (ter != tesSUCCESS)
return ter;
saActual = saAmount;
return tesSUCCESS;

View File

@@ -418,60 +418,6 @@ public:
env.close();
}
void
testAmendmentEnable()
{
// Start with the featureDeletableAccounts amendment disabled.
// Then enable the amendment and delete an account.
using namespace jtx;
testcase("Amendment enable");
Env env{*this, testable_amendments() - featureDeletableAccounts};
Account const alice("alice");
Account const becky("becky");
env.fund(XRP(10000), alice, becky);
env.close();
// Close enough ledgers to be able to delete alice's account.
incLgrSeqForAccDel(env, alice);
// Verify that alice's account root is present.
Keylet const aliceAcctKey{keylet::account(alice.id())};
BEAST_EXPECT(env.closed()->exists(aliceAcctKey));
auto const alicePreDelBal{env.balance(alice)};
auto const beckyPreDelBal{env.balance(becky)};
auto const acctDelFee{drops(env.current()->fees().increment)};
env(acctdelete(alice, becky), fee(acctDelFee), ter(temDISABLED));
env.close();
// Verify that alice's account root is still present and alice and
// becky both have their XRP.
BEAST_EXPECT(env.current()->exists(aliceAcctKey));
BEAST_EXPECT(env.balance(alice) == alicePreDelBal);
BEAST_EXPECT(env.balance(becky) == beckyPreDelBal);
// When the amendment is enabled the previous transaction is
// retried into the new open ledger and succeeds.
env.enableFeature(featureDeletableAccounts);
env.close();
// alice's account is still in the most recently closed ledger.
BEAST_EXPECT(env.closed()->exists(aliceAcctKey));
// Verify that alice's account root is gone from the current ledger
// and becky has alice's XRP.
BEAST_EXPECT(!env.current()->exists(aliceAcctKey));
BEAST_EXPECT(
env.balance(becky) == alicePreDelBal + beckyPreDelBal - acctDelFee);
env.close();
BEAST_EXPECT(!env.closed()->exists(aliceAcctKey));
}
void
testTooManyOffers()
{
@@ -1148,7 +1094,6 @@ public:
testBasics();
testDirectories();
testOwnedTypes();
testAmendmentEnable();
testTooManyOffers();
testImplicitlyCreatedTrustline();
testBalanceTooSmallForFee();

View File

@@ -5720,7 +5720,6 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite
// Close the ledger until the ledger sequence is large enough to delete
// the account (no longer within <Sequence + 256>)
// This is enforced by the featureDeletableAccounts amendment
auto incLgrSeqForAcctDel = [&](Env& env, Account const& acct) {
int const delta = [&]() -> int {
if (env.seq(acct) + 255 > openLedgerSeq(env))
@@ -5839,8 +5838,6 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite
}
env.close();
// Increment ledger sequence to the number that is
// enforced by the featureDeletableAccounts amendment
incLgrSeqForAcctDel(env, alice);
// Verify that alice's account root is present.
@@ -5943,8 +5940,6 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite
BEAST_EXPECT(ticketCount(env, alice) == 0);
// Increment ledger sequence to the number that is
// enforced by the featureDeletableAccounts amendment
incLgrSeqForAcctDel(env, alice);
// Verify that alice's account root is present.
@@ -6053,8 +6048,6 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite
BEAST_EXPECT(ticketCount(env, minter) == 0);
// Increment ledger sequence to the number that is
// enforced by the featureDeletableAccounts amendment
incLgrSeqForAcctDel(env, alice);
// Verify that alice's account root is present.

View File

@@ -4330,7 +4330,7 @@ public:
Account const ellie("ellie");
Account const fiona("fiona");
constexpr int ledgersInQueue = 10;
constexpr int ledgersInQueue = 20;
auto cfg = makeConfig(
{{"minimum_txn_in_ledger_standalone", "1"},
{"ledgers_in_queue", std::to_string(ledgersInQueue)},

View File

@@ -124,8 +124,7 @@ class Feature_test : public beast::unit_test::suite
featureToName(fixRemoveNFTokenAutoTrustLine) ==
"fixRemoveNFTokenAutoTrustLine");
BEAST_EXPECT(featureToName(featureFlow) == "Flow");
BEAST_EXPECT(
featureToName(featureDeletableAccounts) == "DeletableAccounts");
BEAST_EXPECT(featureToName(featureDID) == "DID");
BEAST_EXPECT(
featureToName(fixIncludeKeyletFields) == "fixIncludeKeyletFields");
BEAST_EXPECT(featureToName(featureTokenEscrow) == "TokenEscrow");

View File

@@ -38,7 +38,7 @@ public:
lc_result = env.rpc("ledger_closed")[jss::result];
BEAST_EXPECT(
lc_result[jss::ledger_hash] ==
"E86DE7F3D7A4D9CE17EF7C8BA08A8F4D8F643B9552F0D895A31CDA78F541DE4E");
"0F1A9E0C109ADEF6DA2BDE19217C12BBEC57174CBDBD212B0EBDC1CEDB853185");
BEAST_EXPECT(lc_result[jss::ledger_index] == 3);
}

View File

@@ -307,8 +307,8 @@ class LedgerRPC_test : public beast::unit_test::suite
{
std::string const hash3{
"E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
"8F643B9552F0D895A31CDA78F541DE4E"};
"0F1A9E0C109ADEF6DA2BDE19217C12BBEC57174CBDBD212B0EBDC1CEDB8531"
"85"};
// access via the ledger_hash field
Json::Value jvParams;
jvParams[jss::ledger_hash] = hash3;

View File

@@ -200,7 +200,7 @@ public:
result = env.rpc("ledger_request", "3")[jss::result];
constexpr char const* hash3 =
"8D631B20BC989AF568FBA97375290544B0703A5ADC1CF9E9053580461690C9EE";
"9FFD8AE09190D5002FE4252A1B29EABCF40DABBCE3B42619C6BD0BE381D51103";
BEAST_EXPECT(result[jss::ledger][jss::ledger_index] == "3");
BEAST_EXPECT(
result[jss::ledger][jss::total_coins] == "99999999999999980");
@@ -209,14 +209,14 @@ public:
BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash2);
BEAST_EXPECT(
result[jss::ledger][jss::account_hash] ==
"BC9EF2A16BFF80BCFABA6FA84688D858D33BD0FA0435CAA9DF6DA4105A39A29E");
"35738B8517F37D08983AF6BC7DA483CCA9CF6B41B1FECB31A20028D78FE0BB22");
BEAST_EXPECT(
result[jss::ledger][jss::transaction_hash] ==
"0213EC486C058B3942FBE3DAC6839949A5C5B02B8B4244C8998EFDF04DBD8222");
"CBD7F0948EBFA2241DE4EA627939A0FFEE6B80A90FE09C42C825DA546E9B73FF");
result = env.rpc("ledger_request", "4")[jss::result];
constexpr char const* hash4 =
"1A8E7098B23597E73094DADA58C9D62F3AB93A12C6F7666D56CA85A6CFDE530F";
"7C9B614445517B8C6477E0AB10A35FFC1A23A34FEA41A91ECBDE884CC097C6E1";
BEAST_EXPECT(result[jss::ledger][jss::ledger_index] == "4");
BEAST_EXPECT(
result[jss::ledger][jss::total_coins] == "99999999999999960");
@@ -225,14 +225,14 @@ public:
BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash3);
BEAST_EXPECT(
result[jss::ledger][jss::account_hash] ==
"C690188F123C91355ADA8BDF4AC5B5C927076D3590C215096868A5255264C6DD");
"1EE701DD2A150205173E1EDE8D474DF6803EC95253DAAEE965B9D896CFC32A04");
BEAST_EXPECT(
result[jss::ledger][jss::transaction_hash] ==
"3CBDB8F42E04333E1642166BFB93AC9A7E1C6C067092CD5D881D6F3AB3D67E76");
"9BBDDBF926100DFFF364E16268F544B19F5B9BC6ECCBBC104F98D13FA9F3BC35");
result = env.rpc("ledger_request", "5")[jss::result];
constexpr char const* hash5 =
"C6A222D71AE65D7B4F240009EAD5DEB20D7EEDE5A4064F28BBDBFEEB6FBE48E5";
"98885D02145CCE4AD2605F1809F17188DB2053B14ED399CAC985DD8E03DCA8C0";
BEAST_EXPECT(result[jss::ledger][jss::ledger_index] == "5");
BEAST_EXPECT(
result[jss::ledger][jss::total_coins] == "99999999999999940");
@@ -241,10 +241,10 @@ public:
BEAST_EXPECT(result[jss::ledger][jss::parent_hash] == hash4);
BEAST_EXPECT(
result[jss::ledger][jss::account_hash] ==
"EA81CD9D36740736F00CB747E0D0E32D3C10B695823D961F0FB9A1CE7133DD4D");
"41D64D64796468DEA7AE2A7282C0BB525D6FD7ABC29453C5E5BC6406E947CBCE");
BEAST_EXPECT(
result[jss::ledger][jss::transaction_hash] ==
"C3D086CD6BDB9E97AD1D513B2C049EF2840BD21D0B3E22D84EBBB89B6D2EF59D");
"8FE8592EF22FBC2E8C774C7A1ED76AA3FCE64BED17D748CBA9AFDF7072FE36C7");
result = env.rpc("ledger_request", "6")[jss::result];
BEAST_EXPECT(result[jss::error] == "invalidParams");

View File

@@ -22,9 +22,6 @@ namespace ripple {
bool
DeleteAccount::checkExtraFeatures(PreflightContext const& ctx)
{
if (!ctx.rules.enabled(featureDeletableAccounts))
return false;
if (ctx.tx.isFieldPresent(sfCredentialIDs) &&
!ctx.rules.enabled(featureCredentials))
return false;

View File

@@ -1028,12 +1028,7 @@ ValidNewAccountRoot::finalize(
return false;
}
std::uint32_t const startingSeq = //
pseudoAccount //
? 0 //
: view.rules().enabled(featureDeletableAccounts) //
? view.seq() //
: 1;
std::uint32_t const startingSeq = pseudoAccount ? 0 : view.seq();
if (accountSeq_ != startingSeq)
{

View File

@@ -398,14 +398,10 @@ Payment::doApply()
if (!sleDst)
{
std::uint32_t const seqno{
view().rules().enabled(featureDeletableAccounts) ? view().seq()
: 1};
// Create the account.
sleDst = std::make_shared<SLE>(k);
sleDst->setAccountID(sfAccount, dstAccountID);
sleDst->setFieldU32(sfSequence, seqno);
sleDst->setFieldU32(sfSequence, view().seq());
view().insert(sleDst);
}

View File

@@ -464,12 +464,9 @@ transferHelper(
}
// Create the account.
std::uint32_t const seqno{
psb.rules().enabled(featureDeletableAccounts) ? psb.seq() : 1};
sleDst = std::make_shared<SLE>(dstK);
sleDst->setAccountID(sfAccount, dst);
sleDst->setFieldU32(sfSequence, seqno);
sleDst->setFieldU32(sfSequence, psb.seq());
psb.insert(sleDst);
}