From 1e565e848841227bf05bc852d130ce4869831e82 Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Mon, 24 Mar 2025 10:49:05 +0000 Subject: [PATCH] Pseudo-accounts to use sequence 0 --- src/xrpld/app/tx/detail/InvariantCheck.cpp | 11 +++++++++-- src/xrpld/app/tx/detail/InvariantCheck.h | 1 + src/xrpld/ledger/detail/View.cpp | 12 ++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/xrpld/app/tx/detail/InvariantCheck.cpp b/src/xrpld/app/tx/detail/InvariantCheck.cpp index 7dd2f1b81a..ef4dc73bc1 100644 --- a/src/xrpld/app/tx/detail/InvariantCheck.cpp +++ b/src/xrpld/app/tx/detail/InvariantCheck.cpp @@ -884,6 +884,8 @@ ValidNewAccountRoot::visitEntry( { accountsCreated_++; accountSeq_ = (*after)[sfSequence]; + pseudoAccount_ = + after->isFieldPresent(sfAMMID) || after->isFieldPresent(sfVaultID); } } @@ -912,8 +914,13 @@ ValidNewAccountRoot::finalize( tx.getTxnType() == ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION) && result == tesSUCCESS) { - std::uint32_t const startingSeq{ - view.rules().enabled(featureDeletableAccounts) ? view.seq() : 1}; + std::uint32_t const startingSeq = // + (pseudoAccount_ && + view.rules().enabled(featureSingleAssetVault)) // + ? 0 // + : view.rules().enabled(featureDeletableAccounts) // + ? view.seq() // + : 1; if (accountSeq_ != startingSeq) { diff --git a/src/xrpld/app/tx/detail/InvariantCheck.h b/src/xrpld/app/tx/detail/InvariantCheck.h index cb06b0fb05..d6d0d1bec9 100644 --- a/src/xrpld/app/tx/detail/InvariantCheck.h +++ b/src/xrpld/app/tx/detail/InvariantCheck.h @@ -438,6 +438,7 @@ class ValidNewAccountRoot { std::uint32_t accountsCreated_ = 0; std::uint32_t accountSeq_ = 0; + bool pseudoAccount_ = false; public: void diff --git a/src/xrpld/ledger/detail/View.cpp b/src/xrpld/ledger/detail/View.cpp index f1db503b0c..65b0305130 100644 --- a/src/xrpld/ledger/detail/View.cpp +++ b/src/xrpld/ledger/detail/View.cpp @@ -1058,8 +1058,16 @@ createPseudoAccount( auto account = std::make_shared(keylet::account(accountId)); account->setAccountID(sfAccount, accountId); account->setFieldAmount(sfBalance, STAmount{}); - std::uint32_t const seqno{ - view.rules().enabled(featureDeletableAccounts) ? view.seq() : 1}; + + // Pseudo-accounts can't submit transactions, so set the sequence number + // to 0 to make them easier to spot and verify, and add an extra level + // of protection. + std::uint32_t const seqno = // + view.rules().enabled(featureSingleAssetVault) // + ? 0 // + : view.rules().enabled(featureDeletableAccounts) // + ? view.seq() // + : 1; account->setFieldU32(sfSequence, seqno); // Ignore reserves requirement, disable the master key, allow default // rippling, and enable deposit authorization to prevent payments into