diff --git a/include/xrpl/ledger/helpers/MPToken.h b/include/xrpl/ledger/helpers/MPToken.h index 61fd9e4bfa..8706dc2c8e 100644 --- a/include/xrpl/ledger/helpers/MPToken.h +++ b/include/xrpl/ledger/helpers/MPToken.h @@ -75,7 +75,7 @@ public: AccountID const& account, std::uint32_t const flags) { - WritableMPToken mptoken(issuance, account); + WritableMPToken mptoken = makeNew(issuance, account); auto const ownerNode = mptoken.applyView().dirInsert( keylet::ownerDir(account), mptoken->key(), describeOwnerDir(account)); @@ -83,18 +83,40 @@ public: if (!ownerNode) return tecDIR_FULL; // LCOV_EXCL_LINE - mptoken.newSLE(); - (*mptoken)[sfAccount] = account; (*mptoken)[sfMPTokenIssuanceID] = issuance.getMptID(); (*mptoken)[sfFlags] = flags; (*mptoken)[sfOwnerNode] = *ownerNode; - mptoken.insert(); - return tesSUCCESS; } + /** Create a WritableMPToken backed by a brand-new SLE + * (not yet inserted into the view). + */ + [[nodiscard]] static WritableMPToken + makeNew(WritableMPTokenIssuance& issuance, AccountID const& holder) + { + return WritableMPToken( + issuance, holder, std::make_shared(keylet::mptoken(issuance.getMptID(), holder))); + } + +private: + // This is a private constructor only used by `makeNew` + WritableMPToken( + WritableMPTokenIssuance& issuance, + AccountID const& holder, + std::shared_ptr sle) + : ReadOnlySLE(sle, issuance.applyView()) + , TokenHolderBase(issuance.applyView(), sle, issuance, holder) + , WritableSLE(sle, issuance.applyView()) + , WritableTokenHolderBase(issuance.applyView(), sle, issuance, holder) + , MPToken(issuance, holder) + , writableIssuance_(issuance) + { + insert(); + } + protected: WritableMPTokenIssuance& writableIssuance_; }; diff --git a/include/xrpl/ledger/helpers/RippleState.h b/include/xrpl/ledger/helpers/RippleState.h index a2ef3b1ede..7969eaa22a 100644 --- a/include/xrpl/ledger/helpers/RippleState.h +++ b/include/xrpl/ledger/helpers/RippleState.h @@ -90,15 +90,6 @@ public: return writableIOUToken_; } - static Expected - makeNew(WritableIOUToken& token, AccountID const& accountID, beast::Journal journal) - { - auto const ter = token.addEmptyHolding(accountID, XRPAmount{0}, journal); - if (ter != tesSUCCESS) - return Unexpected(ter); - return WritableRippleState{token.applyView(), token, accountID}; - } - //-------------------------------------------------------------------------- // // Trust line operations @@ -137,6 +128,29 @@ public: AccountID const& uHighAccountID, beast::Journal j); + /** Create a WritableRippleState backed by a brand-new SLE + * (not yet inserted into the view). + */ + [[nodiscard]] static WritableRippleState + makeNew(WritableIOUToken& token, AccountID const& holder) + { + return WritableRippleState( + token, holder, std::make_shared(keylet::line(holder, token.getIssue()))); + } + +private: + // This is a private constructor only used by `makeNew` + WritableRippleState(WritableIOUToken& token, AccountID const& holder, std::shared_ptr sle) + : ReadOnlySLE(sle, token.applyView()) + , TokenHolderBase(token.applyView(), sle, token, holder) + , WritableSLE(sle, token.applyView()) + , WritableTokenHolderBase(token.applyView(), sle, token, holder) + , RippleState(token, holder) + , writableIOUToken_(token) + { + insert(); + } + protected: WritableIOUToken& writableIOUToken_; }; diff --git a/include/xrpl/ledger/helpers/RippleStateHelpers.h b/include/xrpl/ledger/helpers/RippleStateHelpers.h index 3b87bf14bf..d5148e2997 100644 --- a/include/xrpl/ledger/helpers/RippleStateHelpers.h +++ b/include/xrpl/ledger/helpers/RippleStateHelpers.h @@ -49,6 +49,12 @@ public: return currency_; } + [[nodiscard]] Issue const& + getIssue() const + { + return issue_; + } + [[nodiscard]] bool isGlobalFrozen() const override {