From 697fb64e8c833d189f7dbd1a12fdeea5b0327d6a Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Wed, 18 Mar 2026 17:46:27 +0000 Subject: [PATCH 01/10] ci: Don't check PR title for drafts (#6573) --- .github/workflows/check-pr-title.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-pr-title.yml b/.github/workflows/check-pr-title.yml index a524d759b5..b88816cfea 100644 --- a/.github/workflows/check-pr-title.yml +++ b/.github/workflows/check-pr-title.yml @@ -5,9 +5,10 @@ on: types: - checks_requested pull_request: - types: [opened, edited, reopened, synchronize] + types: [opened, edited, reopened, synchronize, ready_for_review] branches: [develop] jobs: check_title: + if: ${{ github.event.pull_request.draft != true }} uses: XRPLF/actions/.github/workflows/check-pr-title.yml@c6311685db43aa07971c4a6764320fecbc2acdcd From 804a351773c1d28eead4377227cac5e4420d475b Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Wed, 18 Mar 2026 18:31:42 +0000 Subject: [PATCH 02/10] ci: Use external action implementation of check-pr-title (#6578) --- .github/workflows/check-pr-title.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-pr-title.yml b/.github/workflows/check-pr-title.yml index b88816cfea..1181ca586f 100644 --- a/.github/workflows/check-pr-title.yml +++ b/.github/workflows/check-pr-title.yml @@ -11,4 +11,4 @@ on: jobs: check_title: if: ${{ github.event.pull_request.draft != true }} - uses: XRPLF/actions/.github/workflows/check-pr-title.yml@c6311685db43aa07971c4a6764320fecbc2acdcd + uses: XRPLF/actions/.github/workflows/check-pr-title.yml@f9c2b57a7ac30d70555b5de6e627005f62e933f3 From d360e7c5b6aadfe87454bab43d0a6668f9d00455 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Wed, 18 Mar 2026 15:52:07 -0400 Subject: [PATCH 03/10] refactor: Rename transactor files/classes to match the tx name (#6580) --- .../xrpl/protocol/detail/transactions.macro | 30 ++++++++-------- include/xrpl/tx/Transactor.h | 2 +- .../{DeleteAccount.h => AccountDelete.h} | 6 ++-- .../account/{SetAccount.h => AccountSet.h} | 6 ++-- .../{SetSignerList.h => SignerListSet.h} | 10 +++--- .../check/{CashCheck.h => CheckCancel.h} | 6 ++-- .../check/{CreateCheck.h => CheckCash.h} | 6 ++-- .../check/{CancelCheck.h => CheckCreate.h} | 6 ++-- .../tx/transactors/delegate/DelegateSet.h | 2 +- .../dex/{CancelOffer.h => OfferCancel.h} | 6 ++-- .../dex/{CreateOffer.h => OfferCreate.h} | 6 ++-- .../oracle/{DeleteOracle.h => OracleDelete.h} | 8 ++--- .../oracle/{SetOracle.h => OracleSet.h} | 8 ++--- .../tx/transactors/payment/DepositPreauth.h | 2 +- .../{PayChanClaim.h => PaymentChannelClaim.h} | 6 ++-- ...PayChanCreate.h => PaymentChannelCreate.h} | 6 ++-- .../{PayChanFund.h => PaymentChannelFund.h} | 6 ++-- .../system/{CreateTicket.h => TicketCreate.h} | 8 ++--- .../token/{SetTrust.h => TrustSet.h} | 6 ++-- sanitizers/suppressions/ubsan.supp | 8 ++--- src/libxrpl/ledger/View.cpp | 4 +-- src/libxrpl/protocol/Indexes.cpp | 2 +- .../{DeleteAccount.cpp => AccountDelete.cpp} | 36 +++++++++---------- .../{SetAccount.cpp => AccountSet.cpp} | 18 +++++----- .../{SetSignerList.cpp => SignerListSet.cpp} | 34 +++++++++--------- .../{CancelCheck.cpp => CheckCancel.cpp} | 8 ++--- .../check/{CashCheck.cpp => CheckCash.cpp} | 8 ++--- .../{CreateCheck.cpp => CheckCreate.cpp} | 8 ++--- .../tx/transactors/dex/AMMWithdraw.cpp | 2 +- .../dex/{CancelOffer.cpp => OfferCancel.cpp} | 10 +++--- .../dex/{CreateOffer.cpp => OfferCreate.cpp} | 36 +++++++++---------- .../{DeleteOracle.cpp => OracleDelete.cpp} | 10 +++--- .../oracle/{SetOracle.cpp => OracleSet.cpp} | 8 ++--- .../tx/transactors/payment/DepositPreauth.cpp | 2 +- ...yChanClaim.cpp => PaymentChannelClaim.cpp} | 17 ++++----- ...hanCreate.cpp => PaymentChannelCreate.cpp} | 10 +++--- ...PayChanFund.cpp => PaymentChannelFund.cpp} | 10 +++--- ...nHelpers.cpp => PaymentChannelHelpers.cpp} | 2 +- ...yChanHelpers.h => PaymentChannelHelpers.h} | 0 .../{CreateTicket.cpp => TicketCreate.cpp} | 10 +++--- .../token/{SetTrust.cpp => TrustSet.cpp} | 14 ++++---- src/test/app/AMM_test.cpp | 6 ++-- src/test/app/AccountSet_test.cpp | 2 +- src/test/app/NFToken_test.cpp | 4 +-- src/test/app/Ticket_test.cpp | 2 +- .../{SetTrust_test.cpp => TrustSet_test.cpp} | 14 ++++---- src/xrpld/app/misc/detail/TxQ.cpp | 2 +- 47 files changed, 197 insertions(+), 226 deletions(-) rename include/xrpl/tx/transactors/account/{DeleteAccount.h => AccountDelete.h} (77%) rename include/xrpl/tx/transactors/account/{SetAccount.h => AccountSet.h} (82%) rename include/xrpl/tx/transactors/account/{SetSignerList.h => SignerListSet.h} (86%) rename include/xrpl/tx/transactors/check/{CashCheck.h => CheckCancel.h} (73%) rename include/xrpl/tx/transactors/check/{CreateCheck.h => CheckCash.h} (71%) rename include/xrpl/tx/transactors/check/{CancelCheck.h => CheckCreate.h} (71%) rename include/xrpl/tx/transactors/dex/{CancelOffer.h => OfferCancel.h} (73%) rename include/xrpl/tx/transactors/dex/{CreateOffer.h => OfferCreate.h} (93%) rename include/xrpl/tx/transactors/oracle/{DeleteOracle.h => OracleDelete.h} (79%) rename include/xrpl/tx/transactors/oracle/{SetOracle.h => OracleSet.h} (77%) rename include/xrpl/tx/transactors/payment_channel/{PayChanClaim.h => PaymentChannelClaim.h} (76%) rename include/xrpl/tx/transactors/payment_channel/{PayChanCreate.h => PaymentChannelCreate.h} (73%) rename include/xrpl/tx/transactors/payment_channel/{PayChanFund.h => PaymentChannelFund.h} (72%) rename include/xrpl/tx/transactors/system/{CreateTicket.h => TicketCreate.h} (91%) rename include/xrpl/tx/transactors/token/{SetTrust.h => TrustSet.h} (81%) rename src/libxrpl/tx/transactors/account/{DeleteAccount.cpp => AccountDelete.cpp} (91%) rename src/libxrpl/tx/transactors/account/{SetAccount.cpp => AccountSet.cpp} (97%) rename src/libxrpl/tx/transactors/account/{SetSignerList.cpp => SignerListSet.cpp} (93%) rename src/libxrpl/tx/transactors/check/{CancelCheck.cpp => CheckCancel.cpp} (94%) rename src/libxrpl/tx/transactors/check/{CashCheck.cpp => CheckCash.cpp} (99%) rename src/libxrpl/tx/transactors/check/{CreateCheck.cpp => CheckCreate.cpp} (97%) rename src/libxrpl/tx/transactors/dex/{CancelOffer.cpp => OfferCancel.cpp} (85%) rename src/libxrpl/tx/transactors/dex/{CreateOffer.cpp => OfferCreate.cpp} (97%) rename src/libxrpl/tx/transactors/oracle/{DeleteOracle.cpp => OracleDelete.cpp} (89%) rename src/libxrpl/tx/transactors/oracle/{SetOracle.cpp => OracleSet.cpp} (98%) rename src/libxrpl/tx/transactors/payment_channel/{PayChanClaim.cpp => PaymentChannelClaim.cpp} (90%) rename src/libxrpl/tx/transactors/payment_channel/{PayChanCreate.cpp => PaymentChannelCreate.cpp} (95%) rename src/libxrpl/tx/transactors/payment_channel/{PayChanFund.cpp => PaymentChannelFund.cpp} (89%) rename src/libxrpl/tx/transactors/payment_channel/{PayChanHelpers.cpp => PaymentChannelHelpers.cpp} (95%) rename src/libxrpl/tx/transactors/payment_channel/{PayChanHelpers.h => PaymentChannelHelpers.h} (100%) rename src/libxrpl/tx/transactors/system/{CreateTicket.cpp => TicketCreate.cpp} (94%) rename src/libxrpl/tx/transactors/token/{SetTrust.cpp => TrustSet.cpp} (98%) rename src/test/app/{SetTrust_test.cpp => TrustSet_test.cpp} (98%) diff --git a/include/xrpl/protocol/detail/transactions.macro b/include/xrpl/protocol/detail/transactions.macro index c9d4376082..a2f3c1be43 100644 --- a/include/xrpl/protocol/detail/transactions.macro +++ b/include/xrpl/protocol/detail/transactions.macro @@ -76,7 +76,7 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, /** This transaction type adjusts various account settings. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttACCOUNT_SET, 3, AccountSet, Delegation::notDelegable, @@ -124,7 +124,7 @@ TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey, /** This transaction type creates an offer to trade one asset for another. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, Delegation::delegable, @@ -140,7 +140,7 @@ TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, /** This transaction type cancels existing offers to trade one asset for another. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, Delegation::delegable, @@ -154,7 +154,7 @@ TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, /** This transaction type creates a new set of tickets. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, Delegation::delegable, @@ -170,7 +170,7 @@ TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, // The SignerEntries are optional because a SignerList is deleted by // setting the SignerQuorum to zero and omitting SignerEntries. #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet, Delegation::notDelegable, @@ -183,7 +183,7 @@ TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet, /** This transaction type creates a new unidirectional XRP payment channel. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, Delegation::delegable, @@ -200,7 +200,7 @@ TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, /** This transaction type funds an existing unidirectional XRP payment channel. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund, Delegation::delegable, @@ -214,7 +214,7 @@ TRANSACTION(ttPAYCHAN_FUND, 14, PaymentChannelFund, /** This transaction type submits a claim against an existing unidirectional payment channel. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, Delegation::delegable, @@ -231,7 +231,7 @@ TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim, /** This transaction type creates a new check. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, Delegation::delegable, @@ -247,7 +247,7 @@ TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, /** This transaction type cashes an existing check. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttCHECK_CASH, 17, CheckCash, Delegation::delegable, @@ -261,7 +261,7 @@ TRANSACTION(ttCHECK_CASH, 17, CheckCash, /** This transaction type cancels an existing check. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel, Delegation::delegable, @@ -288,7 +288,7 @@ TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, /** This transaction type modifies a trustline between two accounts. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttTRUST_SET, 20, TrustSet, Delegation::delegable, @@ -302,7 +302,7 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet, /** This transaction type deletes an existing account. */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, Delegation::notDelegable, @@ -650,7 +650,7 @@ TRANSACTION(ttDID_DELETE, 50, DIDDelete, /** This transaction type creates an Oracle instance */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttORACLE_SET, 51, OracleSet, Delegation::delegable, @@ -667,7 +667,7 @@ TRANSACTION(ttORACLE_SET, 51, OracleSet, /** This transaction type deletes an Oracle instance */ #if TRANSACTION_INCLUDE -# include +# include #endif TRANSACTION(ttORACLE_DELETE, 52, OracleDelete, Delegation::delegable, diff --git a/include/xrpl/tx/Transactor.h b/include/xrpl/tx/Transactor.h index 03cbd60a8e..8d816f60f8 100644 --- a/include/xrpl/tx/Transactor.h +++ b/include/xrpl/tx/Transactor.h @@ -209,7 +209,7 @@ public: checkPermission(ReadView const& view, STTx const& tx); ///////////////////////////////////////////////////// - // Interface used by DeleteAccount + // Interface used by AccountDelete static TER ticketDelete( ApplyView& view, diff --git a/include/xrpl/tx/transactors/account/DeleteAccount.h b/include/xrpl/tx/transactors/account/AccountDelete.h similarity index 77% rename from include/xrpl/tx/transactors/account/DeleteAccount.h rename to include/xrpl/tx/transactors/account/AccountDelete.h index f55888ee00..81a11152ed 100644 --- a/include/xrpl/tx/transactors/account/DeleteAccount.h +++ b/include/xrpl/tx/transactors/account/AccountDelete.h @@ -4,12 +4,12 @@ namespace xrpl { -class DeleteAccount : public Transactor +class AccountDelete : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Blocker}; - explicit DeleteAccount(ApplyContext& ctx) : Transactor(ctx) + explicit AccountDelete(ApplyContext& ctx) : Transactor(ctx) { } @@ -29,6 +29,4 @@ public: doApply() override; }; -using AccountDelete = DeleteAccount; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/account/SetAccount.h b/include/xrpl/tx/transactors/account/AccountSet.h similarity index 82% rename from include/xrpl/tx/transactors/account/SetAccount.h rename to include/xrpl/tx/transactors/account/AccountSet.h index 3abfcb43bb..0940ab0739 100644 --- a/include/xrpl/tx/transactors/account/SetAccount.h +++ b/include/xrpl/tx/transactors/account/AccountSet.h @@ -5,12 +5,12 @@ namespace xrpl { -class SetAccount : public Transactor +class AccountSet : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Custom}; - explicit SetAccount(ApplyContext& ctx) : Transactor(ctx) + explicit AccountSet(ApplyContext& ctx) : Transactor(ctx) { } @@ -33,6 +33,4 @@ public: doApply() override; }; -using AccountSet = SetAccount; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/account/SetSignerList.h b/include/xrpl/tx/transactors/account/SignerListSet.h similarity index 86% rename from include/xrpl/tx/transactors/account/SetSignerList.h rename to include/xrpl/tx/transactors/account/SignerListSet.h index 4c2489922d..2529f0d36c 100644 --- a/include/xrpl/tx/transactors/account/SetSignerList.h +++ b/include/xrpl/tx/transactors/account/SignerListSet.h @@ -11,10 +11,10 @@ namespace xrpl { /** -See the README.md for an overview of the SetSignerList transaction that +See the README.md for an overview of the SignerListSet transaction that this class implements. */ -class SetSignerList : public Transactor +class SignerListSet : public Transactor { private: // Values determined during preCompute for use later. @@ -26,7 +26,7 @@ private: public: static constexpr ConsequencesFactoryType ConsequencesFactory{Blocker}; - explicit SetSignerList(ApplyContext& ctx) : Transactor(ctx) + explicit SignerListSet(ApplyContext& ctx) : Transactor(ctx) { } @@ -41,7 +41,7 @@ public: void preCompute() override; - // Interface used by DeleteAccount + // Interface used by AccountDelete static TER removeFromLedger( ServiceRegistry& registry, @@ -70,6 +70,4 @@ private: writeSignersToSLE(SLE::pointer const& ledgerEntry, std::uint32_t flags) const; }; -using SignerListSet = SetSignerList; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/check/CashCheck.h b/include/xrpl/tx/transactors/check/CheckCancel.h similarity index 73% rename from include/xrpl/tx/transactors/check/CashCheck.h rename to include/xrpl/tx/transactors/check/CheckCancel.h index 138790cf34..f16c6d2827 100644 --- a/include/xrpl/tx/transactors/check/CashCheck.h +++ b/include/xrpl/tx/transactors/check/CheckCancel.h @@ -4,12 +4,12 @@ namespace xrpl { -class CashCheck : public Transactor +class CheckCancel : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit CashCheck(ApplyContext& ctx) : Transactor(ctx) + explicit CheckCancel(ApplyContext& ctx) : Transactor(ctx) { } @@ -23,6 +23,4 @@ public: doApply() override; }; -using CheckCash = CashCheck; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/check/CreateCheck.h b/include/xrpl/tx/transactors/check/CheckCash.h similarity index 71% rename from include/xrpl/tx/transactors/check/CreateCheck.h rename to include/xrpl/tx/transactors/check/CheckCash.h index 98950b68f2..c64d45061d 100644 --- a/include/xrpl/tx/transactors/check/CreateCheck.h +++ b/include/xrpl/tx/transactors/check/CheckCash.h @@ -4,12 +4,12 @@ namespace xrpl { -class CreateCheck : public Transactor +class CheckCash : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit CreateCheck(ApplyContext& ctx) : Transactor(ctx) + explicit CheckCash(ApplyContext& ctx) : Transactor(ctx) { } @@ -23,6 +23,4 @@ public: doApply() override; }; -using CheckCreate = CreateCheck; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/check/CancelCheck.h b/include/xrpl/tx/transactors/check/CheckCreate.h similarity index 71% rename from include/xrpl/tx/transactors/check/CancelCheck.h rename to include/xrpl/tx/transactors/check/CheckCreate.h index 8a0e42c7ca..2b5aa9123d 100644 --- a/include/xrpl/tx/transactors/check/CancelCheck.h +++ b/include/xrpl/tx/transactors/check/CheckCreate.h @@ -4,12 +4,12 @@ namespace xrpl { -class CancelCheck : public Transactor +class CheckCreate : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit CancelCheck(ApplyContext& ctx) : Transactor(ctx) + explicit CheckCreate(ApplyContext& ctx) : Transactor(ctx) { } @@ -23,6 +23,4 @@ public: doApply() override; }; -using CheckCancel = CancelCheck; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/delegate/DelegateSet.h b/include/xrpl/tx/transactors/delegate/DelegateSet.h index 452a6d8305..cc3a8fe4cb 100644 --- a/include/xrpl/tx/transactors/delegate/DelegateSet.h +++ b/include/xrpl/tx/transactors/delegate/DelegateSet.h @@ -22,7 +22,7 @@ public: TER doApply() override; - // Interface used by DeleteAccount + // Interface used by AccountDelete static TER deleteDelegate( ApplyView& view, diff --git a/include/xrpl/tx/transactors/dex/CancelOffer.h b/include/xrpl/tx/transactors/dex/OfferCancel.h similarity index 73% rename from include/xrpl/tx/transactors/dex/CancelOffer.h rename to include/xrpl/tx/transactors/dex/OfferCancel.h index 6107c3211f..c4c57ff3b4 100644 --- a/include/xrpl/tx/transactors/dex/CancelOffer.h +++ b/include/xrpl/tx/transactors/dex/OfferCancel.h @@ -5,12 +5,12 @@ namespace xrpl { -class CancelOffer : public Transactor +class OfferCancel : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit CancelOffer(ApplyContext& ctx) : Transactor(ctx) + explicit OfferCancel(ApplyContext& ctx) : Transactor(ctx) { } @@ -24,6 +24,4 @@ public: doApply() override; }; -using OfferCancel = CancelOffer; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/dex/CreateOffer.h b/include/xrpl/tx/transactors/dex/OfferCreate.h similarity index 93% rename from include/xrpl/tx/transactors/dex/CreateOffer.h rename to include/xrpl/tx/transactors/dex/OfferCreate.h index cb15d08ace..2179180054 100644 --- a/include/xrpl/tx/transactors/dex/CreateOffer.h +++ b/include/xrpl/tx/transactors/dex/OfferCreate.h @@ -9,13 +9,13 @@ class PaymentSandbox; class Sandbox; /** Transactor specialized for creating offers in the ledger. */ -class CreateOffer : public Transactor +class OfferCreate : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Custom}; /** Construct a Transactor subclass that creates an offer in the ledger. */ - explicit CreateOffer(ApplyContext& ctx) : Transactor(ctx) + explicit OfferCreate(ApplyContext& ctx) : Transactor(ctx) { } @@ -74,6 +74,4 @@ private: std::function)> const& setDir); }; -using OfferCreate = CreateOffer; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/oracle/DeleteOracle.h b/include/xrpl/tx/transactors/oracle/OracleDelete.h similarity index 79% rename from include/xrpl/tx/transactors/oracle/DeleteOracle.h rename to include/xrpl/tx/transactors/oracle/OracleDelete.h index bff33205aa..9d1e6d3a44 100644 --- a/include/xrpl/tx/transactors/oracle/DeleteOracle.h +++ b/include/xrpl/tx/transactors/oracle/OracleDelete.h @@ -10,15 +10,15 @@ namespace xrpl { to decentralized applications (dApps) on the blockchain. This implementation conforms to the requirements specified in the XLS-47d. - The DeleteOracle transactor implements the deletion of Oracle objects. + The OracleDelete transactor implements the deletion of Oracle objects. */ -class DeleteOracle : public Transactor +class OracleDelete : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit DeleteOracle(ApplyContext& ctx) : Transactor(ctx) + explicit OracleDelete(ApplyContext& ctx) : Transactor(ctx) { } @@ -39,6 +39,4 @@ public: beast::Journal j); }; -using OracleDelete = DeleteOracle; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/oracle/SetOracle.h b/include/xrpl/tx/transactors/oracle/OracleSet.h similarity index 77% rename from include/xrpl/tx/transactors/oracle/SetOracle.h rename to include/xrpl/tx/transactors/oracle/OracleSet.h index be1a7b8821..d879d14a84 100644 --- a/include/xrpl/tx/transactors/oracle/SetOracle.h +++ b/include/xrpl/tx/transactors/oracle/OracleSet.h @@ -10,15 +10,15 @@ namespace xrpl { to decentralized applications (dApps) on the blockchain. This implementation conforms to the requirements specified in the XLS-47d. - The SetOracle transactor implements creating or updating Oracle objects. + The OracleSet transactor implements creating or updating Oracle objects. */ -class SetOracle : public Transactor +class OracleSet : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit SetOracle(ApplyContext& ctx) : Transactor(ctx) + explicit OracleSet(ApplyContext& ctx) : Transactor(ctx) { } @@ -32,6 +32,4 @@ public: doApply() override; }; -using OracleSet = SetOracle; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/payment/DepositPreauth.h b/include/xrpl/tx/transactors/payment/DepositPreauth.h index 24050da600..b397a81748 100644 --- a/include/xrpl/tx/transactors/payment/DepositPreauth.h +++ b/include/xrpl/tx/transactors/payment/DepositPreauth.h @@ -25,7 +25,7 @@ public: TER doApply() override; - // Interface used by DeleteAccount + // Interface used by AccountDelete static TER removeFromLedger(ApplyView& view, uint256 const& delIndex, beast::Journal j); }; diff --git a/include/xrpl/tx/transactors/payment_channel/PayChanClaim.h b/include/xrpl/tx/transactors/payment_channel/PaymentChannelClaim.h similarity index 76% rename from include/xrpl/tx/transactors/payment_channel/PayChanClaim.h rename to include/xrpl/tx/transactors/payment_channel/PaymentChannelClaim.h index a2728a60e7..449e503bc4 100644 --- a/include/xrpl/tx/transactors/payment_channel/PayChanClaim.h +++ b/include/xrpl/tx/transactors/payment_channel/PaymentChannelClaim.h @@ -4,12 +4,12 @@ namespace xrpl { -class PayChanClaim : public Transactor +class PaymentChannelClaim : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit PayChanClaim(ApplyContext& ctx) : Transactor(ctx) + explicit PaymentChannelClaim(ApplyContext& ctx) : Transactor(ctx) { } @@ -29,6 +29,4 @@ public: doApply() override; }; -using PaymentChannelClaim = PayChanClaim; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/payment_channel/PayChanCreate.h b/include/xrpl/tx/transactors/payment_channel/PaymentChannelCreate.h similarity index 73% rename from include/xrpl/tx/transactors/payment_channel/PayChanCreate.h rename to include/xrpl/tx/transactors/payment_channel/PaymentChannelCreate.h index ff59fdbdd0..7fdacf9b3a 100644 --- a/include/xrpl/tx/transactors/payment_channel/PayChanCreate.h +++ b/include/xrpl/tx/transactors/payment_channel/PaymentChannelCreate.h @@ -4,12 +4,12 @@ namespace xrpl { -class PayChanCreate : public Transactor +class PaymentChannelCreate : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Custom}; - explicit PayChanCreate(ApplyContext& ctx) : Transactor(ctx) + explicit PaymentChannelCreate(ApplyContext& ctx) : Transactor(ctx) { } @@ -26,6 +26,4 @@ public: doApply() override; }; -using PaymentChannelCreate = PayChanCreate; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/payment_channel/PayChanFund.h b/include/xrpl/tx/transactors/payment_channel/PaymentChannelFund.h similarity index 72% rename from include/xrpl/tx/transactors/payment_channel/PayChanFund.h rename to include/xrpl/tx/transactors/payment_channel/PaymentChannelFund.h index ac0f9e0ce2..69f74a4c53 100644 --- a/include/xrpl/tx/transactors/payment_channel/PayChanFund.h +++ b/include/xrpl/tx/transactors/payment_channel/PaymentChannelFund.h @@ -4,12 +4,12 @@ namespace xrpl { -class PayChanFund : public Transactor +class PaymentChannelFund : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Custom}; - explicit PayChanFund(ApplyContext& ctx) : Transactor(ctx) + explicit PaymentChannelFund(ApplyContext& ctx) : Transactor(ctx) { } @@ -23,6 +23,4 @@ public: doApply() override; }; -using PaymentChannelFund = PayChanFund; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/system/CreateTicket.h b/include/xrpl/tx/transactors/system/TicketCreate.h similarity index 91% rename from include/xrpl/tx/transactors/system/CreateTicket.h rename to include/xrpl/tx/transactors/system/TicketCreate.h index 867ad99c12..88d83c37a7 100644 --- a/include/xrpl/tx/transactors/system/CreateTicket.h +++ b/include/xrpl/tx/transactors/system/TicketCreate.h @@ -4,7 +4,7 @@ namespace xrpl { -class CreateTicket : public Transactor +class TicketCreate : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Custom}; @@ -25,7 +25,7 @@ public: // average, 1.25 ms. // // Using that same test set up creating 250 Tickets in a single - // CreateTicket::doApply() in a unit test took, on average, 1.21 ms. + // TicketCreate::doApply() in a unit test took, on average, 1.21 ms. // // So, for the moment, a single transaction creating 250 Tickets takes // about the same compute time as a single compute-intensive payment. @@ -41,7 +41,7 @@ public: // ledger-stuffing with Tickets. constexpr static std::uint32_t maxTicketThreshold = 250; - explicit CreateTicket(ApplyContext& ctx) : Transactor(ctx) + explicit TicketCreate(ApplyContext& ctx) : Transactor(ctx) { } @@ -61,6 +61,4 @@ public: doApply() override; }; -using TicketCreate = CreateTicket; - } // namespace xrpl diff --git a/include/xrpl/tx/transactors/token/SetTrust.h b/include/xrpl/tx/transactors/token/TrustSet.h similarity index 81% rename from include/xrpl/tx/transactors/token/SetTrust.h rename to include/xrpl/tx/transactors/token/TrustSet.h index 47ec26b6ad..2e67aaeded 100644 --- a/include/xrpl/tx/transactors/token/SetTrust.h +++ b/include/xrpl/tx/transactors/token/TrustSet.h @@ -5,12 +5,12 @@ namespace xrpl { -class SetTrust : public Transactor +class TrustSet : public Transactor { public: static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; - explicit SetTrust(ApplyContext& ctx) : Transactor(ctx) + explicit TrustSet(ApplyContext& ctx) : Transactor(ctx) { } @@ -30,6 +30,4 @@ public: doApply() override; }; -using TrustSet = SetTrust; - } // namespace xrpl diff --git a/sanitizers/suppressions/ubsan.supp b/sanitizers/suppressions/ubsan.supp index bd38e43c32..a02cbb17de 100644 --- a/sanitizers/suppressions/ubsan.supp +++ b/sanitizers/suppressions/ubsan.supp @@ -104,7 +104,7 @@ undefined:src/xrpld/app/misc/NetworkOPs.cpp undefined:src/libxrpl/json/json_value.cpp undefined:src/xrpld/app/paths/detail/StrandFlow.h undefined:src/xrpld/app/tx/detail/NFTokenMint.cpp -undefined:src/xrpld/app/tx/detail/SetOracle.cpp +undefined:src/xrpld/app/tx/detail/OracleSet.cpp undefined:src/xrpld/core/detail/JobQueue.cpp undefined:src/xrpld/core/detail/Workers.cpp undefined:src/xrpld/rpc/detail/Role.cpp @@ -154,7 +154,7 @@ unsigned-integer-overflow:src/xrpld/app/misc/detail/AmendmentTable.cpp unsigned-integer-overflow:src/xrpld/app/misc/NetworkOPs.cpp unsigned-integer-overflow:src/xrpld/app/paths/detail/StrandFlow.h unsigned-integer-overflow:src/xrpld/app/tx/detail/NFTokenMint.cpp -unsigned-integer-overflow:src/xrpld/app/tx/detail/SetOracle.cpp +unsigned-integer-overflow:src/xrpld/app/tx/detail/OracleSet.cpp unsigned-integer-overflow:src/xrpld/rpc/detail/Role.cpp unsigned-integer-overflow:src/xrpld/rpc/handlers/GetAggregatePrice.cpp unsigned-integer-overflow:xrpl/basics/base_uint.h @@ -188,8 +188,8 @@ undefined:src/test/app/Loan_test.cpp # Source tree restructured paths (libxrpl/tx/transactors/) # These duplicate the xrpld/app/tx/detail entries above for the new layout -unsigned-integer-overflow:src/libxrpl/tx/transactors/oracle/SetOracle.cpp -undefined:src/libxrpl/tx/transactors/oracle/SetOracle.cpp +unsigned-integer-overflow:src/libxrpl/tx/transactors/oracle/OracleSet.cpp +undefined:src/libxrpl/tx/transactors/oracle/OracleSet.cpp unsigned-integer-overflow:src/libxrpl/tx/transactors/nft/NFTokenMint.cpp undefined:src/libxrpl/tx/transactors/nft/NFTokenMint.cpp diff --git a/src/libxrpl/ledger/View.cpp b/src/libxrpl/ledger/View.cpp index e76f0bfddc..d5c94a9981 100644 --- a/src/libxrpl/ledger/View.cpp +++ b/src/libxrpl/ledger/View.cpp @@ -3234,7 +3234,7 @@ cleanupOnAccountDelete( { // Directory node has an invalid index. Bail out. // LCOV_EXCL_START - JLOG(j.fatal()) << "DeleteAccount: Directory node in ledger " << view.seq() + JLOG(j.fatal()) << "AccountDelete: Directory node in ledger " << view.seq() << " has index to object that is missing: " << to_string(dirEntry); return tefBAD_LEDGER; // LCOV_EXCL_STOP @@ -3269,7 +3269,7 @@ cleanupOnAccountDelete( if (uDirEntry == 0) { // LCOV_EXCL_START - JLOG(j.error()) << "DeleteAccount iterator re-validation failed."; + JLOG(j.error()) << "AccountDelete iterator re-validation failed."; return tefBAD_LEDGER; // LCOV_EXCL_STOP } diff --git a/src/libxrpl/protocol/Indexes.cpp b/src/libxrpl/protocol/Indexes.cpp index aabe8395ae..61a64b2a54 100644 --- a/src/libxrpl/protocol/Indexes.cpp +++ b/src/libxrpl/protocol/Indexes.cpp @@ -219,7 +219,7 @@ book_t::operator()(Book const& b) const Keylet line(AccountID const& id0, AccountID const& id1, Currency const& currency) noexcept { - // There is code in SetTrust that calls us with id0 == id1, to allow users + // There is code in TrustSet that calls us with id0 == id1, to allow users // to locate and delete such "weird" trustlines. If we remove that code, we // could enable this assert: // XRPL_ASSERT(id0 != id1, "xrpl::keylet::line : accounts must be diff --git a/src/libxrpl/tx/transactors/account/DeleteAccount.cpp b/src/libxrpl/tx/transactors/account/AccountDelete.cpp similarity index 91% rename from src/libxrpl/tx/transactors/account/DeleteAccount.cpp rename to src/libxrpl/tx/transactors/account/AccountDelete.cpp index a70cc24549..b50b254ec9 100644 --- a/src/libxrpl/tx/transactors/account/DeleteAccount.cpp +++ b/src/libxrpl/tx/transactors/account/AccountDelete.cpp @@ -7,18 +7,18 @@ #include #include #include -#include -#include +#include +#include #include #include #include -#include +#include #include namespace xrpl { bool -DeleteAccount::checkExtraFeatures(PreflightContext const& ctx) +AccountDelete::checkExtraFeatures(PreflightContext const& ctx) { if (ctx.tx.isFieldPresent(sfCredentialIDs) && !ctx.rules.enabled(featureCredentials)) return false; @@ -27,7 +27,7 @@ DeleteAccount::checkExtraFeatures(PreflightContext const& ctx) } NotTEC -DeleteAccount::preflight(PreflightContext const& ctx) +AccountDelete::preflight(PreflightContext const& ctx) { if (ctx.tx[sfAccount] == ctx.tx[sfDestination]) { @@ -42,7 +42,7 @@ DeleteAccount::preflight(PreflightContext const& ctx) } XRPAmount -DeleteAccount::calculateBaseFee(ReadView const& view, STTx const& tx) +AccountDelete::calculateBaseFee(ReadView const& view, STTx const& tx) { // The fee required for AccountDelete is one owner reserve. return calculateOwnerReserveFee(view, tx); @@ -80,7 +80,7 @@ removeSignersFromLedger( std::shared_ptr const& sleDel, beast::Journal j) { - return SetSignerList::removeFromLedger(registry, view, account, j); + return SignerListSet::removeFromLedger(registry, view, account, j); } TER @@ -143,7 +143,7 @@ removeOracleFromLedger( std::shared_ptr const& sleDel, beast::Journal j) { - return DeleteOracle::deleteOracle(view, sleDel, account, j); + return OracleDelete::deleteOracle(view, sleDel, account, j); } TER @@ -204,7 +204,7 @@ nonObligationDeleter(LedgerEntryType t) } // namespace TER -DeleteAccount::preclaim(PreclaimContext const& ctx) +AccountDelete::preclaim(PreclaimContext const& ctx) { AccountID const account{ctx.tx[sfAccount]}; AccountID const dst{ctx.tx[sfDestination]}; @@ -234,7 +234,7 @@ DeleteAccount::preclaim(PreclaimContext const& ctx) } auto sleAccount = ctx.view.read(keylet::account(account)); - XRPL_ASSERT(sleAccount, "xrpl::DeleteAccount::preclaim : non-null account"); + XRPL_ASSERT(sleAccount, "xrpl::AccountDelete::preclaim : non-null account"); if (!sleAccount) return terNO_ACCOUNT; @@ -303,7 +303,7 @@ DeleteAccount::preclaim(PreclaimContext const& ctx) { // Directory node has an invalid index. Bail out. // LCOV_EXCL_START - JLOG(ctx.j.fatal()) << "DeleteAccount: directory node in ledger " << ctx.view.seq() + JLOG(ctx.j.fatal()) << "AccountDelete: directory node in ledger " << ctx.view.seq() << " has index to object that is missing: " << to_string(dirEntry); return tefBAD_LEDGER; // LCOV_EXCL_STOP @@ -325,14 +325,14 @@ DeleteAccount::preclaim(PreclaimContext const& ctx) } TER -DeleteAccount::doApply() +AccountDelete::doApply() { auto src = view().peek(keylet::account(account_)); - XRPL_ASSERT(src, "xrpl::DeleteAccount::doApply : non-null source account"); + XRPL_ASSERT(src, "xrpl::AccountDelete::doApply : non-null source account"); auto const dstID = ctx_.tx[sfDestination]; auto dst = view().peek(keylet::account(dstID)); - XRPL_ASSERT(dst, "xrpl::DeleteAccount::doApply : non-null destination account"); + XRPL_ASSERT(dst, "xrpl::AccountDelete::doApply : non-null destination account"); if (!src || !dst) return tefBAD_LEDGER; // LCOV_EXCL_LINE @@ -361,9 +361,9 @@ DeleteAccount::doApply() // LCOV_EXCL_START UNREACHABLE( - "xrpl::DeleteAccount::doApply : undeletable item not found " + "xrpl::AccountDelete::doApply : undeletable item not found " "in preclaim"); - JLOG(j_.error()) << "DeleteAccount undeletable item not " + JLOG(j_.error()) << "AccountDelete undeletable item not " "found in preclaim."; return {tecHAS_OBLIGATIONS, SkipEntry::No}; // LCOV_EXCL_STOP @@ -379,13 +379,13 @@ DeleteAccount::doApply() ctx_.deliver(remainingBalance); XRPL_ASSERT( - (*src)[sfBalance] == XRPAmount(0), "xrpl::DeleteAccount::doApply : source balance is zero"); + (*src)[sfBalance] == XRPAmount(0), "xrpl::AccountDelete::doApply : source balance is zero"); // If there's still an owner directory associated with the source account // delete it. if (view().exists(ownerDirKeylet) && !view().emptyDirDelete(ownerDirKeylet)) { - JLOG(j_.error()) << "DeleteAccount cannot delete root dir node of " << toBase58(account_); + JLOG(j_.error()) << "AccountDelete cannot delete root dir node of " << toBase58(account_); return tecHAS_OBLIGATIONS; } diff --git a/src/libxrpl/tx/transactors/account/SetAccount.cpp b/src/libxrpl/tx/transactors/account/AccountSet.cpp similarity index 97% rename from src/libxrpl/tx/transactors/account/SetAccount.cpp rename to src/libxrpl/tx/transactors/account/AccountSet.cpp index 9bb92c2ea5..a3afe2092c 100644 --- a/src/libxrpl/tx/transactors/account/SetAccount.cpp +++ b/src/libxrpl/tx/transactors/account/AccountSet.cpp @@ -5,15 +5,15 @@ #include #include #include -#include +#include #include namespace xrpl { TxConsequences -SetAccount::makeTxConsequences(PreflightContext const& ctx) +AccountSet::makeTxConsequences(PreflightContext const& ctx) { - // The SetAccount may be a blocker, but only if it sets or clears + // The AccountSet may be a blocker, but only if it sets or clears // specific account flags. auto getTxConsequencesCategory = [](STTx const& tx) { if (std::uint32_t const uTxFlags = tx.getFlags(); @@ -37,13 +37,13 @@ SetAccount::makeTxConsequences(PreflightContext const& ctx) } std::uint32_t -SetAccount::getFlagsMask(PreflightContext const& ctx) +AccountSet::getFlagsMask(PreflightContext const& ctx) { return tfAccountSetMask; } NotTEC -SetAccount::preflight(PreflightContext const& ctx) +AccountSet::preflight(PreflightContext const& ctx) { auto& tx = ctx.tx; auto& j = ctx.j; @@ -150,9 +150,9 @@ SetAccount::preflight(PreflightContext const& ctx) } NotTEC -SetAccount::checkPermission(ReadView const& view, STTx const& tx) +AccountSet::checkPermission(ReadView const& view, STTx const& tx) { - // SetAccount is prohibited to be granted on a transaction level, + // AccountSet is prohibited to be granted on a transaction level, // but some granular permissions are allowed. auto const delegate = tx[~sfDelegate]; if (!delegate) @@ -199,7 +199,7 @@ SetAccount::checkPermission(ReadView const& view, STTx const& tx) } TER -SetAccount::preclaim(PreclaimContext const& ctx) +AccountSet::preclaim(PreclaimContext const& ctx) { auto const id = ctx.tx[sfAccount]; @@ -262,7 +262,7 @@ SetAccount::preclaim(PreclaimContext const& ctx) } TER -SetAccount::doApply() +AccountSet::doApply() { auto const sle = view().peek(keylet::account(account_)); if (!sle) diff --git a/src/libxrpl/tx/transactors/account/SetSignerList.cpp b/src/libxrpl/tx/transactors/account/SignerListSet.cpp similarity index 93% rename from src/libxrpl/tx/transactors/account/SetSignerList.cpp rename to src/libxrpl/tx/transactors/account/SignerListSet.cpp index 54fe91aaa6..399e832740 100644 --- a/src/libxrpl/tx/transactors/account/SetSignerList.cpp +++ b/src/libxrpl/tx/transactors/account/SignerListSet.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include @@ -19,8 +19,8 @@ namespace xrpl { // setting the sfSignerListID to zero in all cases. static std::uint32_t const DEFAULT_SIGNER_LIST_ID = 0; -std::tuple, SetSignerList::Operation> -SetSignerList::determineOperation(STTx const& tx, ApplyFlags flags, beast::Journal j) +std::tuple, SignerListSet::Operation> +SignerListSet::determineOperation(STTx const& tx, ApplyFlags flags, beast::Journal j) { // Check the quorum. A non-zero quorum means we're creating or replacing // the list. A zero quorum means we're destroying the list. @@ -51,14 +51,14 @@ SetSignerList::determineOperation(STTx const& tx, ApplyFlags flags, beast::Journ } std::uint32_t -SetSignerList::getFlagsMask(PreflightContext const& ctx) +SignerListSet::getFlagsMask(PreflightContext const& ctx) { // 0 means "Allow any flags" return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; } NotTEC -SetSignerList::preflight(PreflightContext const& ctx) +SignerListSet::preflight(PreflightContext const& ctx) { auto const result = determineOperation(ctx.tx, ctx.flags, ctx.j); @@ -88,7 +88,7 @@ SetSignerList::preflight(PreflightContext const& ctx) } TER -SetSignerList::doApply() +SignerListSet::doApply() { // Perform the operation preCompute() decided on. switch (do_) @@ -103,22 +103,22 @@ SetSignerList::doApply() break; } // LCOV_EXCL_START - UNREACHABLE("xrpl::SetSignerList::doApply : invalid operation"); + UNREACHABLE("xrpl::SignerListSet::doApply : invalid operation"); return temMALFORMED; // LCOV_EXCL_STOP } void -SetSignerList::preCompute() +SignerListSet::preCompute() { // Get the quorum and operation info. auto result = determineOperation(ctx_.tx, view().flags(), j_); XRPL_ASSERT( isTesSuccess(std::get<0>(result)), - "xrpl::SetSignerList::preCompute : result is tesSUCCESS"); + "xrpl::SignerListSet::preCompute : result is tesSUCCESS"); XRPL_ASSERT( std::get<3>(result) != unknown, - "xrpl::SetSignerList::preCompute : result is known operation"); + "xrpl::SignerListSet::preCompute : result is known operation"); quorum_ = std::get<1>(result); signers_ = std::get<2>(result); @@ -204,7 +204,7 @@ removeSignersFromLedger( } TER -SetSignerList::removeFromLedger( +SignerListSet::removeFromLedger( ServiceRegistry& registry, ApplyView& view, AccountID const& account, @@ -219,7 +219,7 @@ SetSignerList::removeFromLedger( } NotTEC -SetSignerList::validateQuorumAndSignerEntries( +SignerListSet::validateQuorumAndSignerEntries( std::uint32_t quorum, std::vector const& signers, AccountID const& account, @@ -239,7 +239,7 @@ SetSignerList::validateQuorumAndSignerEntries( // Make sure there are no duplicate signers. XRPL_ASSERT( std::is_sorted(signers.begin(), signers.end()), - "xrpl::SetSignerList::validateQuorumAndSignerEntries : sorted " + "xrpl::SignerListSet::validateQuorumAndSignerEntries : sorted " "signers"); if (std::adjacent_find(signers.begin(), signers.end()) != signers.end()) { @@ -278,7 +278,7 @@ SetSignerList::validateQuorumAndSignerEntries( } TER -SetSignerList::replaceSignerList() +SignerListSet::replaceSignerList() { auto const accountKeylet = keylet::account(account_); auto const ownerDirKeylet = keylet::ownerDir(account_); @@ -305,7 +305,7 @@ SetSignerList::replaceSignerList() // We check the reserve against the starting balance because we want to // allow dipping into the reserve to pay fees. This behavior is consistent - // with CreateTicket. + // with TicketCreate. if (preFeeBalance_ < newReserve) return tecINSUFFICIENT_RESERVE; @@ -334,7 +334,7 @@ SetSignerList::replaceSignerList() } TER -SetSignerList::destroySignerList() +SignerListSet::destroySignerList() { auto const accountKeylet = keylet::account(account_); // Destroying the signer list is only allowed if either the master key @@ -353,7 +353,7 @@ SetSignerList::destroySignerList() } void -SetSignerList::writeSignersToSLE(SLE::pointer const& ledgerEntry, std::uint32_t flags) const +SignerListSet::writeSignersToSLE(SLE::pointer const& ledgerEntry, std::uint32_t flags) const { // Assign the quorum, default SignerListID, and flags. if (ctx_.view().rules().enabled(fixIncludeKeyletFields)) diff --git a/src/libxrpl/tx/transactors/check/CancelCheck.cpp b/src/libxrpl/tx/transactors/check/CheckCancel.cpp similarity index 94% rename from src/libxrpl/tx/transactors/check/CancelCheck.cpp rename to src/libxrpl/tx/transactors/check/CheckCancel.cpp index 59d80fb27e..d2a77698e0 100644 --- a/src/libxrpl/tx/transactors/check/CancelCheck.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCancel.cpp @@ -5,18 +5,18 @@ #include #include #include -#include +#include namespace xrpl { NotTEC -CancelCheck::preflight(PreflightContext const& ctx) +CheckCancel::preflight(PreflightContext const& ctx) { return tesSUCCESS; } TER -CancelCheck::preclaim(PreclaimContext const& ctx) +CheckCancel::preclaim(PreclaimContext const& ctx) { auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID])); if (!sleCheck) @@ -45,7 +45,7 @@ CancelCheck::preclaim(PreclaimContext const& ctx) } TER -CancelCheck::doApply() +CheckCancel::doApply() { auto const sleCheck = view().peek(keylet::check(ctx_.tx[sfCheckID])); if (!sleCheck) diff --git a/src/libxrpl/tx/transactors/check/CashCheck.cpp b/src/libxrpl/tx/transactors/check/CheckCash.cpp similarity index 99% rename from src/libxrpl/tx/transactors/check/CashCheck.cpp rename to src/libxrpl/tx/transactors/check/CheckCash.cpp index cba945cc82..2edd3c3a9c 100644 --- a/src/libxrpl/tx/transactors/check/CashCheck.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCash.cpp @@ -6,14 +6,14 @@ #include #include #include -#include +#include #include namespace xrpl { NotTEC -CashCheck::preflight(PreflightContext const& ctx) +CheckCash::preflight(PreflightContext const& ctx) { // Exactly one of Amount or DeliverMin must be present. auto const optAmount = ctx.tx[~sfAmount]; @@ -44,7 +44,7 @@ CashCheck::preflight(PreflightContext const& ctx) } TER -CashCheck::preclaim(PreclaimContext const& ctx) +CheckCash::preclaim(PreclaimContext const& ctx) { auto const sleCheck = ctx.view.read(keylet::check(ctx.tx[sfCheckID])); if (!sleCheck) @@ -196,7 +196,7 @@ CashCheck::preclaim(PreclaimContext const& ctx) } TER -CashCheck::doApply() +CheckCash::doApply() { // Flow requires that we operate on a PaymentSandbox, rather than // directly on a View. diff --git a/src/libxrpl/tx/transactors/check/CreateCheck.cpp b/src/libxrpl/tx/transactors/check/CheckCreate.cpp similarity index 97% rename from src/libxrpl/tx/transactors/check/CreateCheck.cpp rename to src/libxrpl/tx/transactors/check/CheckCreate.cpp index 1530b20f40..43e000ad5b 100644 --- a/src/libxrpl/tx/transactors/check/CreateCheck.cpp +++ b/src/libxrpl/tx/transactors/check/CheckCreate.cpp @@ -4,12 +4,12 @@ #include #include #include -#include +#include namespace xrpl { NotTEC -CreateCheck::preflight(PreflightContext const& ctx) +CheckCreate::preflight(PreflightContext const& ctx) { if (ctx.tx[sfAccount] == ctx.tx[sfDestination]) { @@ -47,7 +47,7 @@ CreateCheck::preflight(PreflightContext const& ctx) } TER -CreateCheck::preclaim(PreclaimContext const& ctx) +CheckCreate::preclaim(PreclaimContext const& ctx) { AccountID const dstId{ctx.tx[sfDestination]}; auto const sleDst = ctx.view.read(keylet::account(dstId)); @@ -128,7 +128,7 @@ CreateCheck::preclaim(PreclaimContext const& ctx) } TER -CreateCheck::doApply() +CheckCreate::doApply() { auto const sle = view().peek(keylet::account(account_)); if (!sle) diff --git a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp index f43367ac21..b822ff6b84 100644 --- a/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp +++ b/src/libxrpl/tx/transactors/dex/AMMWithdraw.cpp @@ -538,7 +538,7 @@ AMMWithdraw::withdraw( auto const balance = (*sleAccount)[sfBalance].xrp(); std::uint32_t const ownerCount = sleAccount->at(sfOwnerCount); - // See also SetTrust::doApply() + // See also TrustSet::doApply() XRPAmount const reserve( (ownerCount < 2) ? XRPAmount(beast::zero) : view.fees().accountReserve(ownerCount + 1)); diff --git a/src/libxrpl/tx/transactors/dex/CancelOffer.cpp b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp similarity index 85% rename from src/libxrpl/tx/transactors/dex/CancelOffer.cpp rename to src/libxrpl/tx/transactors/dex/OfferCancel.cpp index 2549fd327e..58f9525f61 100644 --- a/src/libxrpl/tx/transactors/dex/CancelOffer.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCancel.cpp @@ -1,16 +1,16 @@ #include #include #include -#include +#include namespace xrpl { NotTEC -CancelOffer::preflight(PreflightContext const& ctx) +OfferCancel::preflight(PreflightContext const& ctx) { if (!ctx.tx[sfOfferSequence]) { - JLOG(ctx.j.trace()) << "CancelOffer::preflight: missing sequence"; + JLOG(ctx.j.trace()) << "OfferCancel::preflight: missing sequence"; return temBAD_SEQUENCE; } @@ -20,7 +20,7 @@ CancelOffer::preflight(PreflightContext const& ctx) //------------------------------------------------------------------------------ TER -CancelOffer::preclaim(PreclaimContext const& ctx) +OfferCancel::preclaim(PreclaimContext const& ctx) { auto const id = ctx.tx[sfAccount]; auto const offerSequence = ctx.tx[sfOfferSequence]; @@ -42,7 +42,7 @@ CancelOffer::preclaim(PreclaimContext const& ctx) //------------------------------------------------------------------------------ TER -CancelOffer::doApply() +OfferCancel::doApply() { auto const offerSequence = ctx_.tx[sfOfferSequence]; diff --git a/src/libxrpl/tx/transactors/dex/CreateOffer.cpp b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp similarity index 97% rename from src/libxrpl/tx/transactors/dex/CreateOffer.cpp rename to src/libxrpl/tx/transactors/dex/OfferCreate.cpp index 58241803a9..90c00c6280 100644 --- a/src/libxrpl/tx/transactors/dex/CreateOffer.cpp +++ b/src/libxrpl/tx/transactors/dex/OfferCreate.cpp @@ -8,12 +8,12 @@ #include #include #include -#include +#include #include namespace xrpl { TxConsequences -CreateOffer::makeTxConsequences(PreflightContext const& ctx) +OfferCreate::makeTxConsequences(PreflightContext const& ctx) { auto calculateMaxXRPSpend = [](STTx const& tx) -> XRPAmount { auto const& amount{tx[sfTakerGets]}; @@ -24,7 +24,7 @@ CreateOffer::makeTxConsequences(PreflightContext const& ctx) } bool -CreateOffer::checkExtraFeatures(PreflightContext const& ctx) +OfferCreate::checkExtraFeatures(PreflightContext const& ctx) { if (ctx.tx.isFieldPresent(sfDomainID) && !ctx.rules.enabled(featurePermissionedDEX)) return false; @@ -33,7 +33,7 @@ CreateOffer::checkExtraFeatures(PreflightContext const& ctx) } std::uint32_t -CreateOffer::getFlagsMask(PreflightContext const& ctx) +OfferCreate::getFlagsMask(PreflightContext const& ctx) { // The tfOfferCreateMask is built assuming that PermissionedDEX is // enabled @@ -45,7 +45,7 @@ CreateOffer::getFlagsMask(PreflightContext const& ctx) } NotTEC -CreateOffer::preflight(PreflightContext const& ctx) +OfferCreate::preflight(PreflightContext const& ctx) { auto& tx = ctx.tx; auto& j = ctx.j; @@ -123,7 +123,7 @@ CreateOffer::preflight(PreflightContext const& ctx) } TER -CreateOffer::preclaim(PreclaimContext const& ctx) +OfferCreate::preclaim(PreclaimContext const& ctx) { auto const id = ctx.tx[sfAccount]; @@ -194,7 +194,7 @@ CreateOffer::preclaim(PreclaimContext const& ctx) } TER -CreateOffer::checkAcceptAsset( +OfferCreate::checkAcceptAsset( ReadView const& view, ApplyFlags const flags, AccountID const id, @@ -202,7 +202,7 @@ CreateOffer::checkAcceptAsset( Issue const& issue) { // Only valid for custom currencies - XRPL_ASSERT(!isXRP(issue.currency), "xrpl::CreateOffer::checkAcceptAsset : input is not XRP"); + XRPL_ASSERT(!isXRP(issue.currency), "xrpl::OfferCreate::checkAcceptAsset : input is not XRP"); auto const issuerAccount = view.read(keylet::account(issue.account)); @@ -264,7 +264,7 @@ CreateOffer::checkAcceptAsset( } std::pair -CreateOffer::flowCross( +OfferCreate::flowCross( PaymentSandbox& psb, PaymentSandbox& psbCancel, Amounts const& takerAmount, @@ -433,7 +433,7 @@ CreateOffer::flowCross( afterCross.out -= result.actualAmountOut; XRPL_ASSERT( afterCross.out >= beast::zero, - "xrpl::CreateOffer::flowCross : minimum offer"); + "xrpl::OfferCreate::flowCross : minimum offer"); if (afterCross.out < beast::zero) afterCross.out.clear(); afterCross.in = mulRound(afterCross.out, rate, takerAmount.in.issue(), true); @@ -452,7 +452,7 @@ CreateOffer::flowCross( } std::string -CreateOffer::format_amount(STAmount const& amount) +OfferCreate::format_amount(STAmount const& amount) { std::string txt = amount.getText(); txt += "/"; @@ -461,7 +461,7 @@ CreateOffer::format_amount(STAmount const& amount) } TER -CreateOffer::applyHybrid( +OfferCreate::applyHybrid( Sandbox& sb, std::shared_ptr sleOffer, Keylet const& offerKey, @@ -507,7 +507,7 @@ CreateOffer::applyHybrid( } std::pair -CreateOffer::applyGuts(Sandbox& sb, Sandbox& sbCancel) +OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel) { using beast::zero; @@ -638,7 +638,7 @@ CreateOffer::applyGuts(Sandbox& sb, Sandbox& sbCancel) // or give a tec. XRPL_ASSERT( isTesSuccess(result) || isTecClaim(result), - "xrpl::CreateOffer::applyGuts : result is tesSUCCESS or " + "xrpl::OfferCreate::applyGuts : result is tesSUCCESS or " "tecCLAIM"); if (auto stream = j_.trace()) @@ -659,10 +659,10 @@ CreateOffer::applyGuts(Sandbox& sb, Sandbox& sbCancel) XRPL_ASSERT( saTakerGets.issue() == place_offer.in.issue(), - "xrpl::CreateOffer::applyGuts : taker gets issue match"); + "xrpl::OfferCreate::applyGuts : taker gets issue match"); XRPL_ASSERT( saTakerPays.issue() == place_offer.out.issue(), - "xrpl::CreateOffer::applyGuts : taker pays issue match"); + "xrpl::OfferCreate::applyGuts : taker pays issue match"); if (takerAmount != place_offer) crossed = true; @@ -692,7 +692,7 @@ CreateOffer::applyGuts(Sandbox& sb, Sandbox& sbCancel) XRPL_ASSERT( saTakerPays > zero && saTakerGets > zero, - "xrpl::CreateOffer::applyGuts : taker pays and gets positive"); + "xrpl::OfferCreate::applyGuts : taker pays and gets positive"); if (!isTesSuccess(result)) { @@ -852,7 +852,7 @@ CreateOffer::applyGuts(Sandbox& sb, Sandbox& sbCancel) } TER -CreateOffer::doApply() +OfferCreate::doApply() { // This is the ledger view that we work against. Transactions are applied // as we go on processing transactions. diff --git a/src/libxrpl/tx/transactors/oracle/DeleteOracle.cpp b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp similarity index 89% rename from src/libxrpl/tx/transactors/oracle/DeleteOracle.cpp rename to src/libxrpl/tx/transactors/oracle/OracleDelete.cpp index 78bba900da..e55d96e246 100644 --- a/src/libxrpl/tx/transactors/oracle/DeleteOracle.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleDelete.cpp @@ -2,18 +2,18 @@ #include #include #include -#include +#include namespace xrpl { NotTEC -DeleteOracle::preflight(PreflightContext const& ctx) +OracleDelete::preflight(PreflightContext const& ctx) { return tesSUCCESS; } TER -DeleteOracle::preclaim(PreclaimContext const& ctx) +OracleDelete::preclaim(PreclaimContext const& ctx) { if (!ctx.view.exists(keylet::account(ctx.tx.getAccountID(sfAccount)))) return terNO_ACCOUNT; // LCOV_EXCL_LINE @@ -38,7 +38,7 @@ DeleteOracle::preclaim(PreclaimContext const& ctx) } TER -DeleteOracle::deleteOracle( +OracleDelete::deleteOracle( ApplyView& view, std::shared_ptr const& sle, AccountID const& account, @@ -69,7 +69,7 @@ DeleteOracle::deleteOracle( } TER -DeleteOracle::doApply() +OracleDelete::doApply() { if (auto sle = ctx_.view().peek(keylet::oracle(account_, ctx_.tx[sfOracleDocumentID]))) return deleteOracle(ctx_.view(), sle, account_, j_); diff --git a/src/libxrpl/tx/transactors/oracle/SetOracle.cpp b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp similarity index 98% rename from src/libxrpl/tx/transactors/oracle/SetOracle.cpp rename to src/libxrpl/tx/transactors/oracle/OracleSet.cpp index 62ca6c5ea0..f0fc114d7f 100644 --- a/src/libxrpl/tx/transactors/oracle/SetOracle.cpp +++ b/src/libxrpl/tx/transactors/oracle/OracleSet.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include namespace xrpl { @@ -17,7 +17,7 @@ tokenPairKey(STObject const& pair) } NotTEC -SetOracle::preflight(PreflightContext const& ctx) +OracleSet::preflight(PreflightContext const& ctx) { auto const& dataSeries = ctx.tx.getFieldArray(sfPriceDataSeries); if (dataSeries.empty()) @@ -38,7 +38,7 @@ SetOracle::preflight(PreflightContext const& ctx) } TER -SetOracle::preclaim(PreclaimContext const& ctx) +OracleSet::preclaim(PreclaimContext const& ctx) { auto const sleSetter = ctx.view.read(keylet::account(ctx.tx.getAccountID(sfAccount))); if (!sleSetter) @@ -178,7 +178,7 @@ setPriceDataInnerObjTemplate(STObject& obj) } TER -SetOracle::doApply() +OracleSet::doApply() { auto const oracleID = keylet::oracle(account_, ctx_.tx[sfOracleDocumentID]); diff --git a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp index ceb90411a4..2b9a8dfd3a 100644 --- a/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp +++ b/src/libxrpl/tx/transactors/payment/DepositPreauth.cpp @@ -249,7 +249,7 @@ DepositPreauth::doApply() TER DepositPreauth::removeFromLedger(ApplyView& view, uint256 const& preauthIndex, beast::Journal j) { - // Existence already checked in preclaim and DeleteAccount + // Existence already checked in preclaim and AccountDelete auto const slePreauth{view.peek(keylet::depositPreauth(preauthIndex))}; if (!slePreauth) { diff --git a/src/libxrpl/tx/transactors/payment_channel/PayChanClaim.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp similarity index 90% rename from src/libxrpl/tx/transactors/payment_channel/PayChanClaim.cpp rename to src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp index e70c1f11ac..a97b4c9e56 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PayChanClaim.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelClaim.cpp @@ -7,26 +7,26 @@ #include #include #include -#include +#include -#include +#include namespace xrpl { bool -PayChanClaim::checkExtraFeatures(PreflightContext const& ctx) +PaymentChannelClaim::checkExtraFeatures(PreflightContext const& ctx) { return !ctx.tx.isFieldPresent(sfCredentialIDs) || ctx.rules.enabled(featureCredentials); } std::uint32_t -PayChanClaim::getFlagsMask(PreflightContext const&) +PaymentChannelClaim::getFlagsMask(PreflightContext const&) { return tfPaymentChannelClaimMask; } NotTEC -PayChanClaim::preflight(PreflightContext const& ctx) +PaymentChannelClaim::preflight(PreflightContext const& ctx) { auto const bal = ctx.tx[~sfBalance]; if (bal && (!isXRP(*bal) || *bal <= beast::zero)) @@ -79,7 +79,7 @@ PayChanClaim::preflight(PreflightContext const& ctx) } TER -PayChanClaim::preclaim(PreclaimContext const& ctx) +PaymentChannelClaim::preclaim(PreclaimContext const& ctx) { if (!ctx.view.rules().enabled(featureCredentials)) return Transactor::preclaim(ctx); @@ -92,7 +92,7 @@ PayChanClaim::preclaim(PreclaimContext const& ctx) } TER -PayChanClaim::doApply() +PaymentChannelClaim::doApply() { Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]); auto const slep = ctx_.view().peek(k); @@ -151,7 +151,8 @@ PayChanClaim::doApply() (*slep)[sfBalance] = ctx_.tx[sfBalance]; XRPAmount const reqDelta = reqBalance - chanBalance; - XRPL_ASSERT(reqDelta >= beast::zero, "xrpl::PayChanClaim::doApply : minimum balance delta"); + XRPL_ASSERT( + reqDelta >= beast::zero, "xrpl::PaymentChannelClaim::doApply : minimum balance delta"); (*sled)[sfBalance] = (*sled)[sfBalance] + reqDelta; ctx_.view().update(sled); ctx_.view().update(slep); diff --git a/src/libxrpl/tx/transactors/payment_channel/PayChanCreate.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp similarity index 95% rename from src/libxrpl/tx/transactors/payment_channel/PayChanCreate.cpp rename to src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp index ccb0fa1a63..113dd89221 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PayChanCreate.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelCreate.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include namespace xrpl { @@ -32,13 +32,13 @@ namespace xrpl { //------------------------------------------------------------------------------ TxConsequences -PayChanCreate::makeTxConsequences(PreflightContext const& ctx) +PaymentChannelCreate::makeTxConsequences(PreflightContext const& ctx) { return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()}; } NotTEC -PayChanCreate::preflight(PreflightContext const& ctx) +PaymentChannelCreate::preflight(PreflightContext const& ctx) { if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero)) return temBAD_AMOUNT; @@ -53,7 +53,7 @@ PayChanCreate::preflight(PreflightContext const& ctx) } TER -PayChanCreate::preclaim(PreclaimContext const& ctx) +PaymentChannelCreate::preclaim(PreclaimContext const& ctx) { auto const account = ctx.tx[sfAccount]; auto const sle = ctx.view.read(keylet::account(account)); @@ -103,7 +103,7 @@ PayChanCreate::preclaim(PreclaimContext const& ctx) } TER -PayChanCreate::doApply() +PaymentChannelCreate::doApply() { auto const account = ctx_.tx[sfAccount]; auto const sle = ctx_.view().peek(keylet::account(account)); diff --git a/src/libxrpl/tx/transactors/payment_channel/PayChanFund.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp similarity index 89% rename from src/libxrpl/tx/transactors/payment_channel/PayChanFund.cpp rename to src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp index f01b8a7c40..6c08cc466c 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PayChanFund.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelFund.cpp @@ -1,20 +1,20 @@ #include #include #include -#include +#include -#include +#include namespace xrpl { TxConsequences -PayChanFund::makeTxConsequences(PreflightContext const& ctx) +PaymentChannelFund::makeTxConsequences(PreflightContext const& ctx) { return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()}; } NotTEC -PayChanFund::preflight(PreflightContext const& ctx) +PaymentChannelFund::preflight(PreflightContext const& ctx) { if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero)) return temBAD_AMOUNT; @@ -23,7 +23,7 @@ PayChanFund::preflight(PreflightContext const& ctx) } TER -PayChanFund::doApply() +PaymentChannelFund::doApply() { Keylet const k(ltPAYCHAN, ctx_.tx[sfChannel]); auto const slep = ctx_.view().peek(k); diff --git a/src/libxrpl/tx/transactors/payment_channel/PayChanHelpers.cpp b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp similarity index 95% rename from src/libxrpl/tx/transactors/payment_channel/PayChanHelpers.cpp rename to src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp index b761bb3fc3..75b68768ed 100644 --- a/src/libxrpl/tx/transactors/payment_channel/PayChanHelpers.cpp +++ b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include namespace xrpl { diff --git a/src/libxrpl/tx/transactors/payment_channel/PayChanHelpers.h b/src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.h similarity index 100% rename from src/libxrpl/tx/transactors/payment_channel/PayChanHelpers.h rename to src/libxrpl/tx/transactors/payment_channel/PaymentChannelHelpers.h diff --git a/src/libxrpl/tx/transactors/system/CreateTicket.cpp b/src/libxrpl/tx/transactors/system/TicketCreate.cpp similarity index 94% rename from src/libxrpl/tx/transactors/system/CreateTicket.cpp rename to src/libxrpl/tx/transactors/system/TicketCreate.cpp index b16cdeb7a2..8a9a5cbc93 100644 --- a/src/libxrpl/tx/transactors/system/CreateTicket.cpp +++ b/src/libxrpl/tx/transactors/system/TicketCreate.cpp @@ -3,19 +3,19 @@ #include #include #include -#include +#include namespace xrpl { TxConsequences -CreateTicket::makeTxConsequences(PreflightContext const& ctx) +TicketCreate::makeTxConsequences(PreflightContext const& ctx) { // Create TxConsequences identifying the number of sequences consumed. return TxConsequences{ctx.tx, ctx.tx[sfTicketCount]}; } NotTEC -CreateTicket::preflight(PreflightContext const& ctx) +TicketCreate::preflight(PreflightContext const& ctx) { if (std::uint32_t const count = ctx.tx[sfTicketCount]; count < minValidCount || count > maxValidCount) @@ -25,7 +25,7 @@ CreateTicket::preflight(PreflightContext const& ctx) } TER -CreateTicket::preclaim(PreclaimContext const& ctx) +TicketCreate::preclaim(PreclaimContext const& ctx) { auto const id = ctx.tx[sfAccount]; auto const sleAccountRoot = ctx.view.read(keylet::account(id)); @@ -51,7 +51,7 @@ CreateTicket::preclaim(PreclaimContext const& ctx) } TER -CreateTicket::doApply() +TicketCreate::doApply() { SLE::pointer const sleAccountRoot = view().peek(keylet::account(account_)); if (!sleAccountRoot) diff --git a/src/libxrpl/tx/transactors/token/SetTrust.cpp b/src/libxrpl/tx/transactors/token/TrustSet.cpp similarity index 98% rename from src/libxrpl/tx/transactors/token/SetTrust.cpp rename to src/libxrpl/tx/transactors/token/TrustSet.cpp index 7140d5ef2a..c620592619 100644 --- a/src/libxrpl/tx/transactors/token/SetTrust.cpp +++ b/src/libxrpl/tx/transactors/token/TrustSet.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include namespace { @@ -46,13 +46,13 @@ computeFreezeFlags( namespace xrpl { std::uint32_t -SetTrust::getFlagsMask(PreflightContext const& ctx) +TrustSet::getFlagsMask(PreflightContext const& ctx) { return tfTrustSetMask; } NotTEC -SetTrust::preflight(PreflightContext const& ctx) +TrustSet::preflight(PreflightContext const& ctx) { auto& tx = ctx.tx; auto& j = ctx.j; @@ -106,7 +106,7 @@ SetTrust::preflight(PreflightContext const& ctx) } NotTEC -SetTrust::checkPermission(ReadView const& view, STTx const& tx) +TrustSet::checkPermission(ReadView const& view, STTx const& tx) { auto const delegate = tx[~sfDelegate]; if (!delegate) @@ -167,7 +167,7 @@ SetTrust::checkPermission(ReadView const& view, STTx const& tx) } TER -SetTrust::preclaim(PreclaimContext const& ctx) +TrustSet::preclaim(PreclaimContext const& ctx) { auto const id = ctx.tx[sfAccount]; @@ -226,7 +226,7 @@ SetTrust::preclaim(PreclaimContext const& ctx) if (sleDst && isPseudoAccount(sleDst)) { // If destination is AMM and the trustline doesn't exist then only allow - // SetTrust if the asset is AMM LP token and AMM is not in empty state. + // TrustSet if the asset is AMM LP token and AMM is not in empty state. if (sleDst->isFieldPresent(sfAMMID)) { if (ctx.view.exists(keylet::line(id, uDstAccountID, currency))) @@ -308,7 +308,7 @@ SetTrust::preclaim(PreclaimContext const& ctx) } TER -SetTrust::doApply() +TrustSet::doApply() { TER terResult = tesSUCCESS; diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index 152a97fece..f84253588c 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -1973,7 +1973,7 @@ private: // Withdraw all tokens. testAMM([&](AMM& ammAlice, Env& env) { env(trust(carol, STAmount{ammAlice.lptIssue(), 10'000})); - // Can SetTrust only for AMM LP tokens + // Can TrustSet only for AMM LP tokens env(trust(carol, STAmount{Issue{EUR.currency, ammAlice.ammAccount()}, 10'000}), ter(tecNO_PERMISSION)); env.close(); @@ -4415,7 +4415,7 @@ private: AMM amm(env, C, TSTA(5'000), TSTB(5'000)); auto const ammIss = Issue(TSTA.currency, amm.ammAccount()); - // Can SetTrust only for AMM LP tokens + // Can TrustSet only for AMM LP tokens env(trust(D, STAmount{ammIss, 10'000}), ter(tecNO_PERMISSION)); env.close(); @@ -5108,7 +5108,7 @@ private: amm.withdrawAll(gw); BEAST_EXPECT(amm.ammExists()); - // Bid,Vote,Deposit,Withdraw,SetTrust failing with + // Bid,Vote,Deposit,Withdraw,TrustSet failing with // tecAMM_EMPTY. Deposit succeeds with tfTwoAssetIfEmpty option. env(amm.bid({ .account = alice, diff --git a/src/test/app/AccountSet_test.cpp b/src/test/app/AccountSet_test.cpp index 73e807a8aa..cfd7262a50 100644 --- a/src/test/app/AccountSet_test.cpp +++ b/src/test/app/AccountSet_test.cpp @@ -189,7 +189,7 @@ public: BEAST_EXPECT(!env.le(alice)->isFieldPresent(sfDomain)); // The upper limit on the length is 256 bytes - // (defined as DOMAIN_BYTES_MAX in SetAccount) + // (defined as DOMAIN_BYTES_MAX in AccountSet) // test the edge cases: 255, 256, 257. std::size_t const maxLength = 256; for (std::size_t len = maxLength - 1; len <= maxLength + 1; ++len) diff --git a/src/test/app/NFToken_test.cpp b/src/test/app/NFToken_test.cpp index d9010d5d6e..ba61830758 100644 --- a/src/test/app/NFToken_test.cpp +++ b/src/test/app/NFToken_test.cpp @@ -2500,7 +2500,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite void testCreateOfferDestination(FeatureBitset features) { - // Explore the CreateOffer Destination field. + // Explore the OfferCreate Destination field. testcase("Create offer destination"); using namespace test::jtx; @@ -2915,7 +2915,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::suite void testCreateOfferExpiration(FeatureBitset features) { - // Explore the CreateOffer Expiration field. + // Explore the OfferCreate Expiration field. testcase("Create offer expiration"); using namespace test::jtx; diff --git a/src/test/app/Ticket_test.cpp b/src/test/app/Ticket_test.cpp index 35fc7ea979..7d300f61ca 100644 --- a/src/test/app/Ticket_test.cpp +++ b/src/test/app/Ticket_test.cpp @@ -9,7 +9,7 @@ namespace xrpl { class Ticket_test : public beast::unit_test::suite { - /// @brief Validate metadata for a successful CreateTicket transaction. + /// @brief Validate metadata for a successful TicketCreate transaction. /// /// @param env current jtx env (tx and meta are extracted using it) void diff --git a/src/test/app/SetTrust_test.cpp b/src/test/app/TrustSet_test.cpp similarity index 98% rename from src/test/app/SetTrust_test.cpp rename to src/test/app/TrustSet_test.cpp index fdc73eed79..51828fa544 100644 --- a/src/test/app/SetTrust_test.cpp +++ b/src/test/app/TrustSet_test.cpp @@ -7,7 +7,7 @@ namespace xrpl { namespace test { -class SetTrust_test : public beast::unit_test::suite +class TrustSet_test : public beast::unit_test::suite { public: void @@ -227,9 +227,9 @@ public: } void - testTicketSetTrust(FeatureBitset features) + testTicketTrustSet(FeatureBitset features) { - testcase("SetTrust using a ticket"); + testcase("TrustSet using a ticket"); using namespace jtx; @@ -274,7 +274,7 @@ public: void testMalformedTransaction(FeatureBitset features) { - testcase("SetTrust checks for malformed transactions"); + testcase("TrustSet checks for malformed transactions"); using namespace jtx; Env env{*this, features}; @@ -411,7 +411,7 @@ public: void testModifyQualityOfTrustline(FeatureBitset features, bool createQuality, bool createOnHighAcct) { - testcase << "SetTrust " << (createQuality ? "creates" : "removes") + testcase << "TrustSet " << (createQuality ? "creates" : "removes") << " quality of trustline for " << (createOnHighAcct ? "high" : "low") << " account"; @@ -576,7 +576,7 @@ public: // true, true case doesn't matter since creating a trustline ledger // entry requires reserve from the creator // independent of hi/low account ids for endpoints - testTicketSetTrust(features); + testTicketTrustSet(features); testMalformedTransaction(features); testModifyQualityOfTrustline(features, false, false); testModifyQualityOfTrustline(features, false, true); @@ -599,6 +599,6 @@ public: testWithFeats(sa); } }; -BEAST_DEFINE_TESTSUITE(SetTrust, app, xrpl); +BEAST_DEFINE_TESTSUITE(TrustSet, app, xrpl); } // namespace test } // namespace xrpl diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index 2b90cb8161..020fa501d5 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -938,7 +938,7 @@ TxQ::apply( // // o Additional transactions with Sequences should // follow preceding sequence-based transactions with no - // gaps (except for those required by CreateTicket + // gaps (except for those required by TicketCreate // transactions). // Find the entry in the queue that precedes the new From b1e5ba0518acb745f22d53c5d5dbdf1e8becca6c Mon Sep 17 00:00:00 2001 From: Jingchen Date: Wed, 18 Mar 2026 21:11:51 +0000 Subject: [PATCH 04/10] feat: Add code generator for transactions and ledger entries (#6443) Signed-off-by: JCW Co-authored-by: Bart --- .gersemi/definitions.cmake | 3 + .../scripts/levelization/results/ordering.txt | 5 + .../workflows/reusable-build-test-config.yml | 23 + .pre-commit-config.yaml | 9 +- cmake/XrplCore.cmake | 31 +- cmake/XrplProtocolAutogen.cmake | 287 ++++++ cspell.config.yaml | 2 + .../xrpl/protocol_autogen/LedgerEntryBase.h | 152 +++ .../protocol_autogen/LedgerEntryBuilderBase.h | 84 ++ include/xrpl/protocol_autogen/README.md | 79 ++ .../protocol_autogen/STObjectValidation.h | 43 + .../xrpl/protocol_autogen/TransactionBase.h | 457 +++++++++ .../protocol_autogen/TransactionBuilderBase.h | 269 +++++ include/xrpl/protocol_autogen/Utils.h | 14 + .../protocol_autogen/ledger_entries/AMM.h | 392 ++++++++ .../ledger_entries/AccountRoot.h | 834 ++++++++++++++++ .../ledger_entries/Amendments.h | 236 +++++ .../protocol_autogen/ledger_entries/Bridge.h | 346 +++++++ .../protocol_autogen/ledger_entries/Check.h | 427 ++++++++ .../ledger_entries/Credential.h | 344 +++++++ .../protocol_autogen/ledger_entries/DID.h | 296 ++++++ .../ledger_entries/Delegate.h | 240 +++++ .../ledger_entries/DepositPreauth.h | 262 +++++ .../ledger_entries/DirectoryNode.h | 563 +++++++++++ .../protocol_autogen/ledger_entries/Escrow.h | 554 +++++++++++ .../ledger_entries/FeeSettings.h | 410 ++++++++ .../ledger_entries/LedgerHashes.h | 189 ++++ .../protocol_autogen/ledger_entries/Loan.h | 930 ++++++++++++++++++ .../ledger_entries/LoanBroker.h | 591 +++++++++++ .../protocol_autogen/ledger_entries/MPToken.h | 285 ++++++ .../ledger_entries/MPTokenIssuance.h | 484 +++++++++ .../ledger_entries/NFTokenOffer.h | 333 +++++++ .../ledger_entries/NFTokenPage.h | 238 +++++ .../ledger_entries/NegativeUNL.h | 271 +++++ .../protocol_autogen/ledger_entries/Offer.h | 417 ++++++++ .../protocol_autogen/ledger_entries/Oracle.h | 358 +++++++ .../ledger_entries/PayChannel.h | 521 ++++++++++ .../ledger_entries/PermissionedDomain.h | 240 +++++ .../ledger_entries/RippleState.h | 425 ++++++++ .../ledger_entries/SignerList.h | 275 ++++++ .../protocol_autogen/ledger_entries/Ticket.h | 215 ++++ .../protocol_autogen/ledger_entries/Vault.h | 521 ++++++++++ .../ledger_entries/XChainOwnedClaimID.h | 312 ++++++ .../XChainOwnedCreateAccountClaimID.h | 264 +++++ .../protocol_autogen/transactions/AMMBid.h | 262 +++++ .../transactions/AMMClawback.h | 214 ++++ .../protocol_autogen/transactions/AMMCreate.h | 177 ++++ .../protocol_autogen/transactions/AMMDelete.h | 153 +++ .../transactions/AMMDeposit.h | 338 +++++++ .../protocol_autogen/transactions/AMMVote.h | 177 ++++ .../transactions/AMMWithdraw.h | 301 ++++++ .../transactions/AccountDelete.h | 203 ++++ .../transactions/AccountSet.h | 475 +++++++++ .../protocol_autogen/transactions/Batch.h | 164 +++ .../transactions/CheckCancel.h | 129 +++ .../protocol_autogen/transactions/CheckCash.h | 203 ++++ .../transactions/CheckCreate.h | 264 +++++ .../protocol_autogen/transactions/Clawback.h | 168 ++++ .../transactions/CredentialAccept.h | 153 +++ .../transactions/CredentialCreate.h | 227 +++++ .../transactions/CredentialDelete.h | 203 ++++ .../protocol_autogen/transactions/DIDDelete.h | 105 ++ .../protocol_autogen/transactions/DIDSet.h | 216 ++++ .../transactions/DelegateSet.h | 153 +++ .../transactions/DepositPreauth.h | 249 +++++ .../transactions/EnableAmendment.h | 153 +++ .../transactions/EscrowCancel.h | 153 +++ .../transactions/EscrowCreate.h | 303 ++++++ .../transactions/EscrowFinish.h | 264 +++++ .../transactions/LedgerStateFix.h | 166 ++++ .../transactions/LoanBrokerCoverClawback.h | 181 ++++ .../transactions/LoanBrokerCoverDeposit.h | 155 +++ .../transactions/LoanBrokerCoverWithdraw.h | 229 +++++ .../transactions/LoanBrokerDelete.h | 129 +++ .../transactions/LoanBrokerSet.h | 351 +++++++ .../transactions/LoanDelete.h | 129 +++ .../transactions/LoanManage.h | 129 +++ .../protocol_autogen/transactions/LoanPay.h | 155 +++ .../protocol_autogen/transactions/LoanSet.h | 706 +++++++++++++ .../transactions/MPTokenAuthorize.h | 166 ++++ .../transactions/MPTokenIssuanceCreate.h | 327 ++++++ .../transactions/MPTokenIssuanceDestroy.h | 129 +++ .../transactions/MPTokenIssuanceSet.h | 314 ++++++ .../transactions/NFTokenAcceptOffer.h | 216 ++++ .../transactions/NFTokenBurn.h | 166 ++++ .../transactions/NFTokenCancelOffer.h | 129 +++ .../transactions/NFTokenCreateOffer.h | 264 +++++ .../transactions/NFTokenMint.h | 351 +++++++ .../transactions/NFTokenModify.h | 203 ++++ .../transactions/OfferCancel.h | 129 +++ .../transactions/OfferCreate.h | 264 +++++ .../transactions/OracleDelete.h | 129 +++ .../protocol_autogen/transactions/OracleSet.h | 288 ++++++ .../protocol_autogen/transactions/Payment.h | 416 ++++++++ .../transactions/PaymentChannelClaim.h | 314 ++++++ .../transactions/PaymentChannelCreate.h | 275 ++++++ .../transactions/PaymentChannelFund.h | 190 ++++ .../transactions/PermissionedDomainDelete.h | 129 +++ .../transactions/PermissionedDomainSet.h | 166 ++++ .../protocol_autogen/transactions/SetFee.h | 401 ++++++++ .../transactions/SetRegularKey.h | 142 +++ .../transactions/SignerListSet.h | 164 +++ .../transactions/TicketCreate.h | 129 +++ .../protocol_autogen/transactions/TrustSet.h | 216 ++++ .../protocol_autogen/transactions/UNLModify.h | 177 ++++ .../transactions/VaultClawback.h | 192 ++++ .../transactions/VaultCreate.h | 353 +++++++ .../transactions/VaultDelete.h | 129 +++ .../transactions/VaultDeposit.h | 155 +++ .../protocol_autogen/transactions/VaultSet.h | 240 +++++ .../transactions/VaultWithdraw.h | 229 +++++ .../transactions/XChainAccountCreateCommit.h | 201 ++++ .../XChainAddAccountCreateAttestation.h | 369 +++++++ .../transactions/XChainAddClaimAttestation.h | 358 +++++++ .../transactions/XChainClaim.h | 238 +++++ .../transactions/XChainCommit.h | 214 ++++ .../transactions/XChainCreateBridge.h | 190 ++++ .../transactions/XChainCreateClaimID.h | 177 ++++ .../transactions/XChainModifyBridge.h | 203 ++++ scripts/generate_ledger_classes.py | 227 +++++ scripts/generate_tx_classes.py | 247 +++++ scripts/macro_parser_common.py | 297 ++++++ scripts/requirements.txt | 13 + scripts/templates/LedgerEntry.h.mako | 216 ++++ scripts/templates/LedgerEntryTests.cpp.mako | 231 +++++ scripts/templates/Transaction.h.mako | 226 +++++ scripts/templates/TransactionTests.cpp.mako | 241 +++++ src/libxrpl/protocol_autogen/placeholder.cpp | 5 + src/tests/libxrpl/CMakeLists.txt | 15 + .../protocol_autogen/STObjectValidation.cpp | 70 ++ .../libxrpl/protocol_autogen/TestHelpers.h | 209 ++++ .../ledger_entries/AMMTests.cpp | 361 +++++++ .../ledger_entries/AccountRootTests.cpp | 707 +++++++++++++ .../ledger_entries/AmendmentsTests.cpp | 224 +++++ .../ledger_entries/BridgeTests.cpp | 341 +++++++ .../ledger_entries/CheckTests.cpp | 400 ++++++++ .../ledger_entries/CredentialTests.cpp | 329 +++++++ .../ledger_entries/DIDTests.cpp | 285 ++++++ .../ledger_entries/DelegateTests.cpp | 223 +++++ .../ledger_entries/DepositPreauthTests.cpp | 258 +++++ .../ledger_entries/DirectoryNodeTests.cpp | 484 +++++++++ .../ledger_entries/EscrowTests.cpp | 491 +++++++++ .../ledger_entries/FeeSettingsTests.cpp | 359 +++++++ .../ledger_entries/LedgerHashesTests.cpp | 192 ++++ .../ledger_entries/LoanBrokerTests.cpp | 530 ++++++++++ .../ledger_entries/LoanTests.cpp | 795 +++++++++++++++ .../ledger_entries/MPTokenIssuanceTests.cpp | 437 ++++++++ .../ledger_entries/MPTokenTests.cpp | 280 ++++++ .../ledger_entries/NFTokenOfferTests.cpp | 324 ++++++ .../ledger_entries/NFTokenPageTests.cpp | 236 +++++ .../ledger_entries/NegativeUNLTests.cpp | 251 +++++ .../ledger_entries/OfferTests.cpp | 395 ++++++++ .../ledger_entries/OracleTests.cpp | 346 +++++++ .../ledger_entries/PayChannelTests.cpp | 476 +++++++++ .../PermissionedDomainTests.cpp | 223 +++++ .../ledger_entries/RippleStateTests.cpp | 388 ++++++++ .../ledger_entries/SignerListTests.cpp | 275 ++++++ .../ledger_entries/TicketTests.cpp | 209 ++++ .../ledger_entries/VaultTests.cpp | 476 +++++++++ .../XChainOwnedClaimIDTests.cpp | 283 ++++++ .../XChainOwnedCreateAccountClaimIDTests.cpp | 243 +++++ src/tests/libxrpl/protocol_autogen/main.cpp | 8 + .../transactions/AMMBidTests.cpp | 255 +++++ .../transactions/AMMClawbackTests.cpp | 231 +++++ .../transactions/AMMCreateTests.cpp | 178 ++++ .../transactions/AMMDeleteTests.cpp | 162 +++ .../transactions/AMMDepositTests.cpp | 297 ++++++ .../transactions/AMMVoteTests.cpp | 178 ++++ .../transactions/AMMWithdrawTests.cpp | 276 ++++++ .../transactions/AccountDeleteTests.cpp | 216 ++++ .../transactions/AccountSetTests.cpp | 366 +++++++ .../transactions/BatchTests.cpp | 195 ++++ .../transactions/CheckCancelTests.cpp | 146 +++ .../transactions/CheckCashTests.cpp | 216 ++++ .../transactions/CheckCreateTests.cpp | 255 +++++ .../transactions/ClawbackTests.cpp | 195 ++++ .../transactions/CredentialAcceptTests.cpp | 162 +++ .../transactions/CredentialCreateTests.cpp | 234 +++++ .../transactions/CredentialDeleteTests.cpp | 216 ++++ .../transactions/DIDDeleteTests.cpp | 130 +++ .../transactions/DIDSetTests.cpp | 219 +++++ .../transactions/DelegateSetTests.cpp | 162 +++ .../transactions/DepositPreauthTests.cpp | 240 +++++ .../transactions/EnableAmendmentTests.cpp | 162 +++ .../transactions/EscrowCancelTests.cpp | 162 +++ .../transactions/EscrowCreateTests.cpp | 276 ++++++ .../transactions/EscrowFinishTests.cpp | 255 +++++ .../transactions/LedgerStateFixTests.cpp | 195 ++++ .../LoanBrokerCoverClawbackTests.cpp | 198 ++++ .../LoanBrokerCoverDepositTests.cpp | 162 +++ .../LoanBrokerCoverWithdrawTests.cpp | 234 +++++ .../transactions/LoanBrokerDeleteTests.cpp | 146 +++ .../transactions/LoanBrokerSetTests.cpp | 300 ++++++ .../transactions/LoanDeleteTests.cpp | 146 +++ .../transactions/LoanManageTests.cpp | 146 +++ .../transactions/LoanPayTests.cpp | 162 +++ .../transactions/LoanSetTests.cpp | 507 ++++++++++ .../transactions/MPTokenAuthorizeTests.cpp | 195 ++++ .../MPTokenIssuanceCreateTests.cpp | 282 ++++++ .../MPTokenIssuanceDestroyTests.cpp | 146 +++ .../transactions/MPTokenIssuanceSetTests.cpp | 279 ++++++ .../transactions/NFTokenAcceptOfferTests.cpp | 219 +++++ .../transactions/NFTokenBurnTests.cpp | 195 ++++ .../transactions/NFTokenCancelOfferTests.cpp | 146 +++ .../transactions/NFTokenCreateOfferTests.cpp | 255 +++++ .../transactions/NFTokenMintTests.cpp | 300 ++++++ .../transactions/NFTokenModifyTests.cpp | 216 ++++ .../transactions/OfferCancelTests.cpp | 146 +++ .../transactions/OfferCreateTests.cpp | 255 +++++ .../transactions/OracleDeleteTests.cpp | 146 +++ .../transactions/OracleSetTests.cpp | 273 +++++ .../transactions/PaymentChannelClaimTests.cpp | 279 ++++++ .../PaymentChannelCreateTests.cpp | 270 +++++ .../transactions/PaymentChannelFundTests.cpp | 213 ++++ .../transactions/PaymentTests.cpp | 339 +++++++ .../PermissionedDomainDeleteTests.cpp | 146 +++ .../PermissionedDomainSetTests.cpp | 195 ++++ .../transactions/SetFeeTests.cpp | 324 ++++++ .../transactions/SetRegularKeyTests.cpp | 177 ++++ .../transactions/SignerListSetTests.cpp | 195 ++++ .../transactions/TicketCreateTests.cpp | 146 +++ .../transactions/TrustSetTests.cpp | 219 +++++ .../transactions/UNLModifyTests.cpp | 178 ++++ .../transactions/VaultClawbackTests.cpp | 213 ++++ .../transactions/VaultCreateTests.cpp | 300 ++++++ .../transactions/VaultDeleteTests.cpp | 146 +++ .../transactions/VaultDepositTests.cpp | 162 +++ .../transactions/VaultSetTests.cpp | 237 +++++ .../transactions/VaultWithdrawTests.cpp | 234 +++++ .../XChainAccountCreateCommitTests.cpp | 194 ++++ ...XChainAddAccountCreateAttestationTests.cpp | 306 ++++++ .../XChainAddClaimAttestationTests.cpp | 339 +++++++ .../transactions/XChainClaimTests.cpp | 249 +++++ .../transactions/XChainCommitTests.cpp | 231 +++++ .../transactions/XChainCreateBridgeTests.cpp | 213 ++++ .../transactions/XChainCreateClaimIDTests.cpp | 178 ++++ .../transactions/XChainModifyBridgeTests.cpp | 216 ++++ 237 files changed, 59363 insertions(+), 5 deletions(-) create mode 100644 cmake/XrplProtocolAutogen.cmake create mode 100644 include/xrpl/protocol_autogen/LedgerEntryBase.h create mode 100644 include/xrpl/protocol_autogen/LedgerEntryBuilderBase.h create mode 100644 include/xrpl/protocol_autogen/README.md create mode 100644 include/xrpl/protocol_autogen/STObjectValidation.h create mode 100644 include/xrpl/protocol_autogen/TransactionBase.h create mode 100644 include/xrpl/protocol_autogen/TransactionBuilderBase.h create mode 100644 include/xrpl/protocol_autogen/Utils.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/AMM.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/AccountRoot.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Amendments.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Bridge.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Check.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Credential.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/DID.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Delegate.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/DepositPreauth.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/DirectoryNode.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Escrow.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/FeeSettings.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/LedgerHashes.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Loan.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/LoanBroker.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/MPToken.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/MPTokenIssuance.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/NFTokenOffer.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/NFTokenPage.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/NegativeUNL.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Offer.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Oracle.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/PayChannel.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/PermissionedDomain.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/RippleState.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/SignerList.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Ticket.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/Vault.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/XChainOwnedClaimID.h create mode 100644 include/xrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimID.h create mode 100644 include/xrpl/protocol_autogen/transactions/AMMBid.h create mode 100644 include/xrpl/protocol_autogen/transactions/AMMClawback.h create mode 100644 include/xrpl/protocol_autogen/transactions/AMMCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/AMMDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/AMMDeposit.h create mode 100644 include/xrpl/protocol_autogen/transactions/AMMVote.h create mode 100644 include/xrpl/protocol_autogen/transactions/AMMWithdraw.h create mode 100644 include/xrpl/protocol_autogen/transactions/AccountDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/AccountSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/Batch.h create mode 100644 include/xrpl/protocol_autogen/transactions/CheckCancel.h create mode 100644 include/xrpl/protocol_autogen/transactions/CheckCash.h create mode 100644 include/xrpl/protocol_autogen/transactions/CheckCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/Clawback.h create mode 100644 include/xrpl/protocol_autogen/transactions/CredentialAccept.h create mode 100644 include/xrpl/protocol_autogen/transactions/CredentialCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/CredentialDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/DIDDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/DIDSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/DelegateSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/DepositPreauth.h create mode 100644 include/xrpl/protocol_autogen/transactions/EnableAmendment.h create mode 100644 include/xrpl/protocol_autogen/transactions/EscrowCancel.h create mode 100644 include/xrpl/protocol_autogen/transactions/EscrowCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/EscrowFinish.h create mode 100644 include/xrpl/protocol_autogen/transactions/LedgerStateFix.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanBrokerCoverClawback.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanBrokerCoverDeposit.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanBrokerCoverWithdraw.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanBrokerDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanBrokerSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanManage.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanPay.h create mode 100644 include/xrpl/protocol_autogen/transactions/LoanSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/MPTokenAuthorize.h create mode 100644 include/xrpl/protocol_autogen/transactions/MPTokenIssuanceCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/MPTokenIssuanceDestroy.h create mode 100644 include/xrpl/protocol_autogen/transactions/MPTokenIssuanceSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/NFTokenAcceptOffer.h create mode 100644 include/xrpl/protocol_autogen/transactions/NFTokenBurn.h create mode 100644 include/xrpl/protocol_autogen/transactions/NFTokenCancelOffer.h create mode 100644 include/xrpl/protocol_autogen/transactions/NFTokenCreateOffer.h create mode 100644 include/xrpl/protocol_autogen/transactions/NFTokenMint.h create mode 100644 include/xrpl/protocol_autogen/transactions/NFTokenModify.h create mode 100644 include/xrpl/protocol_autogen/transactions/OfferCancel.h create mode 100644 include/xrpl/protocol_autogen/transactions/OfferCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/OracleDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/OracleSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/Payment.h create mode 100644 include/xrpl/protocol_autogen/transactions/PaymentChannelClaim.h create mode 100644 include/xrpl/protocol_autogen/transactions/PaymentChannelCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/PaymentChannelFund.h create mode 100644 include/xrpl/protocol_autogen/transactions/PermissionedDomainDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/PermissionedDomainSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/SetFee.h create mode 100644 include/xrpl/protocol_autogen/transactions/SetRegularKey.h create mode 100644 include/xrpl/protocol_autogen/transactions/SignerListSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/TicketCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/TrustSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/UNLModify.h create mode 100644 include/xrpl/protocol_autogen/transactions/VaultClawback.h create mode 100644 include/xrpl/protocol_autogen/transactions/VaultCreate.h create mode 100644 include/xrpl/protocol_autogen/transactions/VaultDelete.h create mode 100644 include/xrpl/protocol_autogen/transactions/VaultDeposit.h create mode 100644 include/xrpl/protocol_autogen/transactions/VaultSet.h create mode 100644 include/xrpl/protocol_autogen/transactions/VaultWithdraw.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainAccountCreateCommit.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestation.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainAddClaimAttestation.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainClaim.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainCommit.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainCreateBridge.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainCreateClaimID.h create mode 100644 include/xrpl/protocol_autogen/transactions/XChainModifyBridge.h create mode 100644 scripts/generate_ledger_classes.py create mode 100644 scripts/generate_tx_classes.py create mode 100644 scripts/macro_parser_common.py create mode 100644 scripts/requirements.txt create mode 100644 scripts/templates/LedgerEntry.h.mako create mode 100644 scripts/templates/LedgerEntryTests.cpp.mako create mode 100644 scripts/templates/Transaction.h.mako create mode 100644 scripts/templates/TransactionTests.cpp.mako create mode 100644 src/libxrpl/protocol_autogen/placeholder.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/STObjectValidation.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/TestHelpers.h create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/AMMTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/AccountRootTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/AmendmentsTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/BridgeTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/CheckTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/CredentialTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/DIDTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/DelegateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/DepositPreauthTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/DirectoryNodeTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/EscrowTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/FeeSettingsTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/LedgerHashesTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/LoanBrokerTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/LoanTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenIssuanceTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenOfferTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenPageTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/NegativeUNLTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/OfferTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/OracleTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/PayChannelTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/PermissionedDomainTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/RippleStateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/SignerListTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/TicketTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/VaultTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedClaimIDTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimIDTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/main.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AMMBidTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AMMClawbackTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AMMCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AMMDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AMMDepositTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AMMVoteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AMMWithdrawTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AccountDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/AccountSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/BatchTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/CheckCancelTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/CheckCashTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/CheckCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/ClawbackTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/CredentialAcceptTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/CredentialCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/CredentialDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/DIDDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/DIDSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/DelegateSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/DepositPreauthTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/EnableAmendmentTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/EscrowCancelTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/EscrowCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/EscrowFinishTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LedgerStateFixTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverClawbackTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverDepositTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverWithdrawTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanManageTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanPayTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/LoanSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/MPTokenAuthorizeTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceDestroyTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/NFTokenAcceptOfferTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/NFTokenBurnTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/NFTokenCancelOfferTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/NFTokenCreateOfferTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/NFTokenMintTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/NFTokenModifyTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/OfferCancelTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/OfferCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/OracleDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/OracleSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelClaimTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelFundTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/PaymentTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/SetFeeTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/SetRegularKeyTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/SignerListSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/TicketCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/TrustSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/UNLModifyTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/VaultClawbackTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/VaultCreateTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/VaultDeleteTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/VaultDepositTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/VaultSetTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/VaultWithdrawTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainAccountCreateCommitTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestationTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainAddClaimAttestationTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainClaimTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainCommitTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainCreateBridgeTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainCreateClaimIDTests.cpp create mode 100644 src/tests/libxrpl/protocol_autogen/transactions/XChainModifyBridgeTests.cpp diff --git a/.gersemi/definitions.cmake b/.gersemi/definitions.cmake index 13061629a4..a16e330ffa 100644 --- a/.gersemi/definitions.cmake +++ b/.gersemi/definitions.cmake @@ -51,6 +51,9 @@ endfunction() function(add_module parent name) endfunction() +function(setup_protocol_autogen) +endfunction() + function(target_link_modules parent scope) endfunction() diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index 747ea8b6a6..d26a5a1963 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -19,6 +19,7 @@ libxrpl.nodestore > xrpl.protocol libxrpl.protocol > xrpl.basics libxrpl.protocol > xrpl.json libxrpl.protocol > xrpl.protocol +libxrpl.protocol_autogen > xrpl.protocol_autogen libxrpl.rdb > xrpl.basics libxrpl.rdb > xrpl.rdb libxrpl.resource > xrpl.basics @@ -176,6 +177,8 @@ test.unit_test > xrpl.protocol tests.libxrpl > xrpl.basics tests.libxrpl > xrpl.json tests.libxrpl > xrpl.net +tests.libxrpl > xrpl.protocol +tests.libxrpl > xrpl.protocol_autogen xrpl.conditions > xrpl.basics xrpl.conditions > xrpl.protocol xrpl.core > xrpl.basics @@ -192,6 +195,8 @@ xrpl.nodestore > xrpl.basics xrpl.nodestore > xrpl.protocol xrpl.protocol > xrpl.basics xrpl.protocol > xrpl.json +xrpl.protocol_autogen > xrpl.json +xrpl.protocol_autogen > xrpl.protocol xrpl.rdb > xrpl.basics xrpl.rdb > xrpl.core xrpl.rdb > xrpl.protocol diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index efec2afe0a..6e7a093b96 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -166,6 +166,29 @@ jobs: --parallel "${BUILD_NPROC}" \ --target "${CMAKE_TARGET}" + - name: Check protocol autogen files are up-to-date + env: + MESSAGE: | + + The generated protocol wrapper classes are out of date. + + This typically happens when your branch is behind develop and + the macro files or generator scripts have changed. + + To fix this: + 1. Update your branch from develop (merge or rebase) + 2. Build with code generation enabled (XRPL_NO_CODEGEN=OFF) + 3. Commit and push the regenerated files + run: | + set -e + DIFF=$(git status --porcelain -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen) + if [ -n "${DIFF}" ]; then + echo "::error::Generated protocol files are out of date" + git diff -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen + echo "${MESSAGE}" + exit 1 + fi + - name: Show ccache statistics if: ${{ inputs.ccache_enabled }} run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 586cfe860c..0fcd8ca75d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,8 +14,11 @@ repos: rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 hooks: - id: trailing-whitespace + exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/ - id: end-of-file-fixer + exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/ - id: mixed-line-ending + exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/ - id: check-merge-conflict args: [--assume-in-merge] @@ -25,6 +28,7 @@ repos: - id: clang-format args: [--style=file] "types_or": [c++, c, proto] + exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/ - repo: https://github.com/BlankSpruce/gersemi rev: 0.26.0 @@ -45,7 +49,7 @@ repos: rev: a42085ade523f591dca134379a595e7859986445 # frozen: v9.7.0 hooks: - id: cspell # Spell check changed files - exclude: .config/cspell.config.yaml + exclude: (.config/cspell.config.yaml|^include/xrpl/protocol_autogen/(transactions|ledger_entries)/) - id: cspell # Spell check the commit message name: check commit message spelling args: @@ -77,5 +81,6 @@ repos: exclude: | (?x)^( external/.*| - .github/scripts/levelization/results/.*\.txt + .github/scripts/levelization/results/.*\.txt| + src/tests/libxrpl/protocol_autogen/(transactions|ledger_entries)/.* )$ diff --git a/cmake/XrplCore.cmake b/cmake/XrplCore.cmake index 580c4155eb..a50e30f660 100644 --- a/cmake/XrplCore.cmake +++ b/cmake/XrplCore.cmake @@ -108,17 +108,40 @@ target_link_libraries( ) # Level 05 +## Set up code generation for protocol_autogen module +include(XrplProtocolAutogen) +# Must call setup_protocol_autogen before add_module so that: +# 1. Stale generated files are cleared before GLOB runs +# 2. Output file list is known for custom commands +setup_protocol_autogen() + +add_module(xrpl protocol_autogen) +target_link_libraries( + xrpl.libxrpl.protocol_autogen + PUBLIC xrpl.libxrpl.protocol +) + +# Ensure code generation runs before compiling protocol_autogen +if(TARGET protocol_autogen_generate) + add_dependencies(xrpl.libxrpl.protocol_autogen protocol_autogen_generate) +endif() + +# Level 06 add_module(xrpl core) target_link_libraries( xrpl.libxrpl.core - PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol + PUBLIC + xrpl.libxrpl.basics + xrpl.libxrpl.json + xrpl.libxrpl.protocol + xrpl.libxrpl.protocol_autogen ) -# Level 06 +# Level 07 add_module(xrpl resource) target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol) -# Level 07 +# Level 08 add_module(xrpl net) target_link_libraries( xrpl.libxrpl.net @@ -171,6 +194,7 @@ target_link_libraries( xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol + xrpl.libxrpl.protocol_autogen xrpl.libxrpl.rdb xrpl.libxrpl.server xrpl.libxrpl.shamap @@ -206,6 +230,7 @@ target_link_modules( net nodestore protocol + protocol_autogen rdb resource server diff --git a/cmake/XrplProtocolAutogen.cmake b/cmake/XrplProtocolAutogen.cmake new file mode 100644 index 0000000000..44857712cd --- /dev/null +++ b/cmake/XrplProtocolAutogen.cmake @@ -0,0 +1,287 @@ +#[===================================================================[ + Protocol Autogen - Code generation for protocol wrapper classes +#]===================================================================] + +# Options for code generation +option( + XRPL_NO_CODEGEN + "Disable code generation (use pre-generated files from repository)" + OFF +) +set(CODEGEN_VENV_DIR + "" + CACHE PATH + "Path to Python virtual environment for code generation. If provided, automatic venv setup is skipped." +) + +# Function to set up code generation for protocol_autogen module +# This runs at configure time to generate C++ wrapper classes from macro files +function(setup_protocol_autogen) + # Directory paths + set(MACRO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl/protocol/detail") + set(AUTOGEN_HEADER_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl/protocol_autogen" + ) + set(AUTOGEN_TEST_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/libxrpl/protocol_autogen" + ) + set(SCRIPTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/scripts") + + # Input macro files + set(TRANSACTIONS_MACRO "${MACRO_DIR}/transactions.macro") + set(LEDGER_ENTRIES_MACRO "${MACRO_DIR}/ledger_entries.macro") + set(SFIELDS_MACRO "${MACRO_DIR}/sfields.macro") + + # Python scripts and templates + set(GENERATE_TX_SCRIPT "${SCRIPTS_DIR}/generate_tx_classes.py") + set(GENERATE_LEDGER_SCRIPT "${SCRIPTS_DIR}/generate_ledger_classes.py") + set(REQUIREMENTS_FILE "${SCRIPTS_DIR}/requirements.txt") + set(MACRO_PARSER_COMMON "${SCRIPTS_DIR}/macro_parser_common.py") + set(TX_TEMPLATE "${SCRIPTS_DIR}/templates/Transaction.h.mako") + set(TX_TEST_TEMPLATE "${SCRIPTS_DIR}/templates/TransactionTests.cpp.mako") + set(LEDGER_TEMPLATE "${SCRIPTS_DIR}/templates/LedgerEntry.h.mako") + set(LEDGER_TEST_TEMPLATE + "${SCRIPTS_DIR}/templates/LedgerEntryTests.cpp.mako" + ) + + # Check if code generation is disabled + if(XRPL_NO_CODEGEN) + message( + WARNING + "Protocol autogen: Code generation is disabled (XRPL_NO_CODEGEN=ON). " + "Generated files may be out of date." + ) + return() + endif() + + # Create output directories + file(MAKE_DIRECTORY "${AUTOGEN_HEADER_DIR}/transactions") + file(MAKE_DIRECTORY "${AUTOGEN_HEADER_DIR}/ledger_entries") + file(MAKE_DIRECTORY "${AUTOGEN_TEST_DIR}/ledger_entries") + file(MAKE_DIRECTORY "${AUTOGEN_TEST_DIR}/transactions") + + # Find Python3 - check if already found by Conan or find it ourselves + if(NOT Python3_EXECUTABLE) + find_package(Python3 COMPONENTS Interpreter QUIET) + endif() + + if(NOT Python3_EXECUTABLE) + # Try finding python3 executable directly + find_program(Python3_EXECUTABLE NAMES python3 python) + endif() + + if(NOT Python3_EXECUTABLE) + message( + FATAL_ERROR + "Python3 not found. Code generation cannot proceed.\n" + "Please install Python 3, or set -DXRPL_NO_CODEGEN=ON to use existing generated files." + ) + return() + endif() + + message(STATUS "Using Python3 for code generation: ${Python3_EXECUTABLE}") + + # Set up Python virtual environment for code generation + if(CODEGEN_VENV_DIR) + # User-provided venv - skip automatic setup + set(VENV_DIR "${CODEGEN_VENV_DIR}") + message(STATUS "Using user-provided Python venv: ${VENV_DIR}") + else() + # Use default venv in build directory + set(VENV_DIR "${CMAKE_CURRENT_BINARY_DIR}/codegen_venv") + endif() + + # Determine the Python executable path in the venv + if(WIN32) + set(VENV_PYTHON "${VENV_DIR}/Scripts/python.exe") + set(VENV_PIP "${VENV_DIR}/Scripts/pip.exe") + else() + set(VENV_PYTHON "${VENV_DIR}/bin/python") + set(VENV_PIP "${VENV_DIR}/bin/pip") + endif() + + # Only auto-setup venv if not user-provided + if(NOT CODEGEN_VENV_DIR) + # Check if venv needs to be created or updated + set(VENV_NEEDS_UPDATE FALSE) + if(NOT EXISTS "${VENV_PYTHON}") + set(VENV_NEEDS_UPDATE TRUE) + message( + STATUS + "Creating Python virtual environment for code generation..." + ) + elseif( + "${REQUIREMENTS_FILE}" + IS_NEWER_THAN + "${VENV_DIR}/.requirements_installed" + ) + set(VENV_NEEDS_UPDATE TRUE) + message( + STATUS + "Updating Python virtual environment (requirements changed)..." + ) + endif() + + # Create/update virtual environment if needed + if(VENV_NEEDS_UPDATE) + message( + STATUS + "Setting up Python virtual environment at ${VENV_DIR}" + ) + execute_process( + COMMAND ${Python3_EXECUTABLE} -m venv "${VENV_DIR}" + RESULT_VARIABLE VENV_RESULT + ERROR_VARIABLE VENV_ERROR + ) + if(NOT VENV_RESULT EQUAL 0) + message( + FATAL_ERROR + "Failed to create virtual environment: ${VENV_ERROR}" + ) + endif() + + message(STATUS "Installing Python dependencies...") + execute_process( + COMMAND ${VENV_PIP} install --upgrade pip + RESULT_VARIABLE PIP_UPGRADE_RESULT + OUTPUT_QUIET + ERROR_VARIABLE PIP_UPGRADE_ERROR + ) + if(NOT PIP_UPGRADE_RESULT EQUAL 0) + message(WARNING "Failed to upgrade pip: ${PIP_UPGRADE_ERROR}") + endif() + + execute_process( + COMMAND ${VENV_PIP} install -r "${REQUIREMENTS_FILE}" + RESULT_VARIABLE PIP_INSTALL_RESULT + ERROR_VARIABLE PIP_INSTALL_ERROR + ) + if(NOT PIP_INSTALL_RESULT EQUAL 0) + message( + FATAL_ERROR + "Failed to install Python dependencies: ${PIP_INSTALL_ERROR}" + ) + endif() + + # Mark requirements as installed + file(TOUCH "${VENV_DIR}/.requirements_installed") + message(STATUS "Python virtual environment ready") + endif() + endif() + + # At configure time - get list of output files for transactions + execute_process( + COMMAND + ${VENV_PYTHON} "${GENERATE_TX_SCRIPT}" "${TRANSACTIONS_MACRO}" + --header-dir "${AUTOGEN_HEADER_DIR}/transactions" --test-dir + "${AUTOGEN_TEST_DIR}/transactions" --list-outputs + OUTPUT_VARIABLE TX_OUTPUT_FILES + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE TX_LIST_RESULT + ERROR_VARIABLE TX_LIST_ERROR + ) + if(NOT TX_LIST_RESULT EQUAL 0) + message( + FATAL_ERROR + "Failed to list transaction output files:\n${TX_LIST_ERROR}" + ) + endif() + # Convert newline-separated list to CMake list + string(REPLACE "\\" "/" TX_OUTPUT_FILES "${TX_OUTPUT_FILES}") + string(REPLACE "\n" ";" TX_OUTPUT_FILES "${TX_OUTPUT_FILES}") + + # At configure time - get list of output files for ledger entries + execute_process( + COMMAND + ${VENV_PYTHON} "${GENERATE_LEDGER_SCRIPT}" "${LEDGER_ENTRIES_MACRO}" + --header-dir "${AUTOGEN_HEADER_DIR}/ledger_entries" --test-dir + "${AUTOGEN_TEST_DIR}/ledger_entries" --list-outputs + OUTPUT_VARIABLE LEDGER_OUTPUT_FILES + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE LEDGER_LIST_RESULT + ERROR_VARIABLE LEDGER_LIST_ERROR + ) + if(NOT LEDGER_LIST_RESULT EQUAL 0) + message( + FATAL_ERROR + "Failed to list ledger entry output files:\n${LEDGER_LIST_ERROR}" + ) + endif() + # Convert newline-separated list to CMake list + string(REPLACE "\\" "/" LEDGER_OUTPUT_FILES "${LEDGER_OUTPUT_FILES}") + string(REPLACE "\n" ";" LEDGER_OUTPUT_FILES "${LEDGER_OUTPUT_FILES}") + + # Custom command to generate transaction classes at build time + add_custom_command( + OUTPUT ${TX_OUTPUT_FILES} + COMMAND + ${VENV_PYTHON} "${GENERATE_TX_SCRIPT}" "${TRANSACTIONS_MACRO}" + --header-dir "${AUTOGEN_HEADER_DIR}/transactions" --test-dir + "${AUTOGEN_TEST_DIR}/transactions" --sfields-macro + "${SFIELDS_MACRO}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + DEPENDS + "${TRANSACTIONS_MACRO}" + "${SFIELDS_MACRO}" + "${GENERATE_TX_SCRIPT}" + "${MACRO_PARSER_COMMON}" + "${TX_TEMPLATE}" + "${TX_TEST_TEMPLATE}" + "${REQUIREMENTS_FILE}" + COMMENT "Generating transaction classes from transactions.macro..." + VERBATIM + ) + + # Custom command to generate ledger entry classes at build time + add_custom_command( + OUTPUT ${LEDGER_OUTPUT_FILES} + COMMAND + ${VENV_PYTHON} "${GENERATE_LEDGER_SCRIPT}" "${LEDGER_ENTRIES_MACRO}" + --header-dir "${AUTOGEN_HEADER_DIR}/ledger_entries" --test-dir + "${AUTOGEN_TEST_DIR}/ledger_entries" --sfields-macro + "${SFIELDS_MACRO}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + DEPENDS + "${LEDGER_ENTRIES_MACRO}" + "${SFIELDS_MACRO}" + "${GENERATE_LEDGER_SCRIPT}" + "${MACRO_PARSER_COMMON}" + "${LEDGER_TEMPLATE}" + "${LEDGER_TEST_TEMPLATE}" + "${REQUIREMENTS_FILE}" + COMMENT "Generating ledger entry classes from ledger_entries.macro..." + VERBATIM + ) + + # Create a custom target that depends on all generated files + add_custom_target( + protocol_autogen_generate + DEPENDS ${TX_OUTPUT_FILES} ${LEDGER_OUTPUT_FILES} + COMMENT "Protocol autogen code generation" + ) + + # Extract test files from output lists (files ending in Tests.cpp) + set(PROTOCOL_AUTOGEN_TEST_SOURCES "") + foreach(FILE ${TX_OUTPUT_FILES} ${LEDGER_OUTPUT_FILES}) + if(FILE MATCHES "Tests\\.cpp$") + list(APPEND PROTOCOL_AUTOGEN_TEST_SOURCES "${FILE}") + endif() + endforeach() + # Export test sources to parent scope for use in test CMakeLists.txt + set(PROTOCOL_AUTOGEN_TEST_SOURCES + "${PROTOCOL_AUTOGEN_TEST_SOURCES}" + CACHE INTERNAL + "Generated protocol_autogen test sources" + ) + + # Register dependencies so CMake reconfigures when macro files change + # (to update the list of output files) + set_property( + DIRECTORY + APPEND + PROPERTY + CMAKE_CONFIGURE_DEPENDS + "${TRANSACTIONS_MACRO}" + "${LEDGER_ENTRIES_MACRO}" + ) +endfunction() diff --git a/cspell.config.yaml b/cspell.config.yaml index eeae3d12ff..d1b8504021 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -206,6 +206,7 @@ words: - ptrs - pushd - pyenv + - pyparsing - qalloc - queuable - Raphson @@ -231,6 +232,7 @@ words: - seqit - sf - SFIELD + - sfields - shamap - shamapitem - sidechain diff --git a/include/xrpl/protocol_autogen/LedgerEntryBase.h b/include/xrpl/protocol_autogen/LedgerEntryBase.h new file mode 100644 index 0000000000..0c5b367391 --- /dev/null +++ b/include/xrpl/protocol_autogen/LedgerEntryBase.h @@ -0,0 +1,152 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +/** + * @brief Base class for type-safe ledger entry wrappers. + * + * This class provides common functionality for all ledger entry types, + * including access to common fields (sfLedgerIndex, sfLedgerEntryType, sfFlags). + * + * This is an immutable wrapper around SLE (Serialized Ledger Entry). + * Use the corresponding Builder classes to construct new ledger entries. + */ +class LedgerEntryBase +{ +public: + /** + * @brief Construct a ledger entry wrapper from an existing SLE object. + * @param sle The underlying serialized ledger entry to wrap + */ + explicit LedgerEntryBase(std::shared_ptr sle) : sle_(std::move(sle)) + { + } + + /** + * @brief Validate the ledger entry + * @return true if validation passes, false otherwise + */ + [[nodiscard]] + bool + validate() const + { + if (!sle_->isFieldPresent(sfLedgerEntryType)) + { + return false; // LCOV_EXCL_LINE + } + auto ledgerEntryType = static_cast(sle_->getFieldU16(sfLedgerEntryType)); + return protocol_autogen::validateSTObject( + *sle_, LedgerFormats::getInstance().findByType(ledgerEntryType)->getSOTemplate()); + } + + /** + * @brief Get the ledger entry type. + * @return The type of this ledger entry + */ + [[nodiscard]] + LedgerEntryType + getType() const + { + return sle_->getType(); + } + + /** + * @brief Get the key (index) of this ledger entry. + * + * The key uniquely identifies this ledger entry in the ledger state. + * @return A constant reference to the 256-bit key + */ + [[nodiscard]] + uint256 const& + getKey() const + { + return sle_->key(); + } + + // Common field getters (from LedgerFormats.cpp commonFields) + + /** + * @brief Get the ledger index (sfLedgerIndex). + * + * This field is OPTIONAL and represents the index of the ledger entry. + * @return The ledger index if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getLedgerIndex() const + { + if (sle_->isFieldPresent(sfLedgerIndex)) + { + return sle_->at(sfLedgerIndex); + } + return std::nullopt; + } + + /** + * @brief Check if the ledger entry has a ledger index. + * @return true if sfLedgerIndex is present, false otherwise + */ + [[nodiscard]] + bool + hasLedgerIndex() const + { + return sle_->isFieldPresent(sfLedgerIndex); + } + + /** + * @brief Get the ledger entry type field (sfLedgerEntryType). + * + * This field is REQUIRED for all ledger entries and indicates the type + * of the ledger entry (e.g., AccountRoot, RippleState, Offer, etc.). + * @return The ledger entry type as a 16-bit unsigned integer + */ + [[nodiscard]] + uint16_t + getLedgerEntryType() const + { + return sle_->at(sfLedgerEntryType); + } + + /** + * @brief Get the flags field (sfFlags). + * + * This field is REQUIRED for all ledger entries and contains + * type-specific flags that modify the behavior of the ledger entry. + * @return The flags value as a 32-bit unsigned integer + */ + [[nodiscard]] + std::uint32_t + getFlags() const + { + return sle_->at(sfFlags); + } + + /** + * @brief Get the underlying SLE object. + * + * Provides direct access to the wrapped serialized ledger entry object + * for cases where the type-safe accessors are insufficient. + * @return A constant reference to the underlying SLE object + */ + [[nodiscard]] + std::shared_ptr + getSle() const + { + return sle_; + } + +protected: + /** @brief The underlying serialized ledger entry being wrapped. */ + std::shared_ptr sle_; +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/LedgerEntryBuilderBase.h b/include/xrpl/protocol_autogen/LedgerEntryBuilderBase.h new file mode 100644 index 0000000000..e2f05c31ab --- /dev/null +++ b/include/xrpl/protocol_autogen/LedgerEntryBuilderBase.h @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xrpl::ledger_entries { + +/** + * Base class for all ledger entry builders. + * Provides common field setters that are available for all ledger entry types. + */ +template +class LedgerEntryBuilderBase +{ +public: + LedgerEntryBuilderBase() = default; + + LedgerEntryBuilderBase( + SF_UINT16::type::value_type ledgerEntryType, + SF_UINT32::type::value_type flags = 0) + { + // Don't call object_.set(soTemplate) - keep object_ as a free object. + // This avoids creating STBase placeholders for soeDEFAULT fields, + // which would cause applyTemplate() to throw "may not be explicitly + // set to default" when building the SLE. + // The SLE constructor will call applyTemplate() which properly + // handles missing fields. + object_[sfLedgerEntryType] = ledgerEntryType; + object_[sfFlags] = flags; + } + + /** + * @brief Validate the ledger entry + * @return true if validation passes, false otherwise + */ + [[nodiscard]] + bool + validate() const + { + if (!object_.isFieldPresent(sfLedgerEntryType)) + { + return false; // LCOV_EXCL_LINE + } + auto ledgerEntryType = static_cast(object_.getFieldU16(sfLedgerEntryType)); + return protocol_autogen::validateSTObject( + object_, LedgerFormats::getInstance().findByType(ledgerEntryType)->getSOTemplate()); + } + + /** + * Set the ledger index. + * @param value Ledger index + * @return Reference to the derived builder for method chaining. + */ + Derived& + setLedgerIndex(uint256 const& value) + { + object_[sfLedgerIndex] = value; + return static_cast(*this); + } + + /** + * Set the flags. + * @param value Flags value + * @return Reference to the derived builder for method chaining. + */ + Derived& + setFlags(uint32_t value) + { + object_.setFieldU32(sfFlags, value); + return static_cast(*this); + } + +protected: + STObject object_{sfLedgerEntry}; +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/README.md b/include/xrpl/protocol_autogen/README.md new file mode 100644 index 0000000000..be90788b05 --- /dev/null +++ b/include/xrpl/protocol_autogen/README.md @@ -0,0 +1,79 @@ +# Protocol Autogen + +This directory contains auto-generated C++ wrapper classes for XRP Ledger protocol types. + +## Generated Files + +The files in this directory are automatically generated at **CMake configure time** from macro definition files: + +- **Transaction classes** (in `transactions/`): Generated from `include/xrpl/protocol/detail/transactions.macro` by `scripts/generate_tx_classes.py` +- **Ledger entry classes** (in `ledger_entries/`): Generated from `include/xrpl/protocol/detail/ledger_entries.macro` by `scripts/generate_ledger_classes.py` + +## Generation Process + +The generation happens automatically when you **configure** the project (not during build). When you run CMake, the system: + +1. Creates a Python virtual environment in the build directory (`codegen_venv`) +2. Installs Python dependencies from `scripts/requirements.txt` into the venv (only if needed) +3. Runs the Python generation scripts using the venv Python interpreter +4. Parses the macro files to extract type definitions +5. Generates type-safe C++ wrapper classes using Mako templates +6. Places the generated headers in this directory + +### When Regeneration Happens + +The code is regenerated when: + +- You run CMake configure for the first time +- The Python virtual environment doesn't exist +- `scripts/requirements.txt` has been modified + +To force regeneration, delete the build directory and reconfigure. + +### Python Dependencies + +The code generation requires the following Python packages (automatically installed): + +- `pcpp` - C preprocessor for Python +- `pyparsing` - Parser combinator library +- `Mako` - Template engine + +These are isolated in a virtual environment and won't affect your system Python installation. + +## Version Control + +The generated `.h` files **are checked into version control**. This means: + +- Developers without Python 3 can still build the project using the committed files +- CI/CD systems don't need to run code generation if files are up to date +- Changes to generated files are visible in code review + +## Modifying Generated Code + +**Do not manually edit generated files.** Any changes will be overwritten the next time CMake configure runs. + +To modify the generated classes: + +- Edit the macro files in `include/xrpl/protocol/detail/` +- Edit the Mako templates in `scripts/templates/` +- Edit the generation scripts in `scripts/` +- Update Python dependencies in `scripts/requirements.txt` +- Run CMake configure to regenerate + +## Adding Common Fields + +If you add a new common field to `TxFormats.cpp` or `LedgerFormats.cpp`, you should also update the corresponding base classes and templates manually: + +Base classes: + +- `TransactionBase.h` - Add getters for new common transaction fields +- `TransactionBuilderBase.h` - Add setters, and if the field is required, add it to the constructor parameters +- `LedgerEntryBase.h` - Add getters for new common ledger entry fields +- `LedgerEntryBuilderBase.h` - Add setters, and if the field is required, add it to the constructor parameters + +Templates (update to pass required common fields to base class constructors): + +- `scripts/templates/Transaction.h.mako` +- `scripts/templates/LedgerEntry.h.mako` + +These files are **not auto-generated** and must be updated by hand. diff --git a/include/xrpl/protocol_autogen/STObjectValidation.h b/include/xrpl/protocol_autogen/STObjectValidation.h new file mode 100644 index 0000000000..cd0633af5d --- /dev/null +++ b/include/xrpl/protocol_autogen/STObjectValidation.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +namespace xrpl::protocol_autogen { + +[[nodiscard]] +inline bool +validateSTObject(STObject const& obj, SOTemplate const& format) +{ + for (auto const& field : format) + { + if (!obj.isFieldPresent(field.sField()) && field.style() == soeREQUIRED) + { + return false; // LCOV_EXCL_LINE + } + + if (field.supportMPT() == soeMPTNotSupported && obj.isFieldPresent(field.sField())) + { + if (field.sField().fieldType == STI_AMOUNT) + { + auto const& amount = obj.getFieldAmount(field.sField()); + + if (amount.asset().holds()) + return false; // LCOV_EXCL_LINE + } + else if (field.sField().fieldType == STI_ISSUE) + { + auto issue = dynamic_cast(obj.peekAtPField(field.sField())); + if (!issue) + return false; // LCOV_EXCL_LINE + + if (issue->holds()) + return false; // LCOV_EXCL_LINE + } + } + } + + return true; +} + +} // namespace xrpl::protocol_autogen diff --git a/include/xrpl/protocol_autogen/TransactionBase.h b/include/xrpl/protocol_autogen/TransactionBase.h new file mode 100644 index 0000000000..161d718c66 --- /dev/null +++ b/include/xrpl/protocol_autogen/TransactionBase.h @@ -0,0 +1,457 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +/** + * @brief Base class for all transaction wrapper types. + * + * Provides type-safe read-only accessors for common transaction fields. + * This is an immutable wrapper around STTx. Use the corresponding Builder classes + * to construct new transactions. + */ +class TransactionBase +{ +public: + /** + * @brief Construct a transaction wrapper from an existing STTx object. + * @param tx The underlying transaction object to wrap + */ + explicit TransactionBase(std::shared_ptr tx) : tx_(std::move(tx)) + { + } + + /** + * @brief Validate the transaction + * @return true if validation passes, false otherwise + */ + [[nodiscard]] + bool + validate(std::string& reason) const + { + if (!protocol_autogen::validateSTObject( + *tx_, TxFormats::getInstance().findByType(tx_->getTxnType())->getSOTemplate())) + { + // LCOV_EXCL_START + reason = "Transaction failed schema validation"; + return false; + // LCOV_EXCL_STOP + } + + // Pseudo transactions are not submitted to the network + if (isPseudoTx(*tx_)) + { + return true; + } + return passesLocalChecks(*tx_, reason); + } + + /** + * @brief Get the transaction type. + * @return The type of this transaction + */ + [[nodiscard]] + xrpl::TxType + getTransactionType() const + { + return tx_->getTxnType(); + } + + /** + * @brief Get the account initiating the transaction (sfAccount). + * + * This field is REQUIRED for all transactions. + * @return The account ID of the transaction sender + */ + [[nodiscard]] + AccountID + getAccount() const + { + return tx_->at(sfAccount); + } + + /** + * @brief Get the sequence number of the transaction (sfSequence). + * + * This field is REQUIRED for all transactions. + * @return The sequence number + */ + [[nodiscard]] + std::uint32_t + getSequence() const + { + return tx_->at(sfSequence); + } + + /** + * @brief Get the transaction fee (sfFee). + * + * This field is REQUIRED for all transactions. + * @return The fee amount + */ + [[nodiscard]] + STAmount + getFee() const + { + return tx_->at(sfFee); + } + + /** + * @brief Get the signing public key (sfSigningPubKey). + * + * This field is REQUIRED for all transactions. + * @return The public key used for signing as a blob + */ + [[nodiscard]] + Blob + getSigningPubKey() const + { + return tx_->getFieldVL(sfSigningPubKey); + } + + /** + * @brief Get the transaction flags (sfFlags). + * + * This field is OPTIONAL. + * @return The flags value if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getFlags() const + { + if (tx_->isFieldPresent(sfFlags)) + return tx_->at(sfFlags); + return std::nullopt; + } + + /** + * @brief Check if the transaction has flags set. + * @return true if sfFlags is present, false otherwise + */ + [[nodiscard]] + bool + hasFlags() const + { + return tx_->isFieldPresent(sfFlags); + } + + /** + * @brief Get the source tag (sfSourceTag). + * + * This field is OPTIONAL and used to identify the source of a payment. + * @return The source tag value if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getSourceTag() const + { + if (tx_->isFieldPresent(sfSourceTag)) + return tx_->at(sfSourceTag); + return std::nullopt; + } + + /** + * @brief Check if the transaction has a source tag. + * @return true if sfSourceTag is present, false otherwise + */ + [[nodiscard]] + bool + hasSourceTag() const + { + return tx_->isFieldPresent(sfSourceTag); + } + + /** + * @brief Get the previous transaction ID (sfPreviousTxnID). + * + * This field is OPTIONAL and used for transaction chaining. + * @return The previous transaction ID if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getPreviousTxnID() const + { + if (tx_->isFieldPresent(sfPreviousTxnID)) + return tx_->at(sfPreviousTxnID); + return std::nullopt; + } + + /** + * @brief Check if the transaction has a previous transaction ID. + * @return true if sfPreviousTxnID is present, false otherwise + */ + [[nodiscard]] + bool + hasPreviousTxnID() const + { + return tx_->isFieldPresent(sfPreviousTxnID); + } + + /** + * @brief Get the last ledger sequence (sfLastLedgerSequence). + * + * This field is OPTIONAL and specifies the latest ledger sequence + * in which this transaction can be included. + * @return The last ledger sequence if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getLastLedgerSequence() const + { + if (tx_->isFieldPresent(sfLastLedgerSequence)) + return tx_->at(sfLastLedgerSequence); + return std::nullopt; + } + + /** + * @brief Check if the transaction has a last ledger sequence. + * @return true if sfLastLedgerSequence is present, false otherwise + */ + [[nodiscard]] + bool + hasLastLedgerSequence() const + { + return tx_->isFieldPresent(sfLastLedgerSequence); + } + + /** + * @brief Get the account transaction ID (sfAccountTxnID). + * + * This field is OPTIONAL and used to track transaction sequences. + * @return The account transaction ID if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getAccountTxnID() const + { + if (tx_->isFieldPresent(sfAccountTxnID)) + return tx_->at(sfAccountTxnID); + return std::nullopt; + } + + /** + * @brief Check if the transaction has an account transaction ID. + * @return true if sfAccountTxnID is present, false otherwise + */ + [[nodiscard]] + bool + hasAccountTxnID() const + { + return tx_->isFieldPresent(sfAccountTxnID); + } + + /** + * @brief Get the operation limit (sfOperationLimit). + * + * This field is OPTIONAL and limits the number of operations in a transaction. + * @return The operation limit if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getOperationLimit() const + { + if (tx_->isFieldPresent(sfOperationLimit)) + return tx_->at(sfOperationLimit); + return std::nullopt; + } + + /** + * @brief Check if the transaction has an operation limit. + * @return true if sfOperationLimit is present, false otherwise + */ + [[nodiscard]] + bool + hasOperationLimit() const + { + return tx_->isFieldPresent(sfOperationLimit); + } + + /** + * @brief Get the memos array (sfMemos). + * + * This field is OPTIONAL and contains arbitrary data attached to the transaction. + * @note This is an untyped field (STArray). + * @return A reference wrapper to the memos array if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional> + getMemos() const + { + if (tx_->isFieldPresent(sfMemos)) + return tx_->getFieldArray(sfMemos); + return std::nullopt; + } + + /** + * @brief Check if the transaction has memos. + * @return true if sfMemos is present, false otherwise + */ + [[nodiscard]] + bool + hasMemos() const + { + return tx_->isFieldPresent(sfMemos); + } + + /** + * @brief Get the ticket sequence (sfTicketSequence). + * + * This field is OPTIONAL and used when consuming a ticket instead of a sequence number. + * @return The ticket sequence if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getTicketSequence() const + { + if (tx_->isFieldPresent(sfTicketSequence)) + return tx_->at(sfTicketSequence); + return std::nullopt; + } + + /** + * @brief Check if the transaction has a ticket sequence. + * @return true if sfTicketSequence is present, false otherwise + */ + [[nodiscard]] + bool + hasTicketSequence() const + { + return tx_->isFieldPresent(sfTicketSequence); + } + + /** + * @brief Get the transaction signature (sfTxnSignature). + * + * This field is OPTIONAL and contains the signature for single-signed transactions. + * @return The transaction signature as a blob if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getTxnSignature() const + { + if (tx_->isFieldPresent(sfTxnSignature)) + return tx_->getFieldVL(sfTxnSignature); + return std::nullopt; + } + + /** + * @brief Check if the transaction has a transaction signature. + * @return true if sfTxnSignature is present, false otherwise + */ + [[nodiscard]] + bool + hasTxnSignature() const + { + return tx_->isFieldPresent(sfTxnSignature); + } + + /** + * @brief Get the signers array (sfSigners). + * + * This field is OPTIONAL and contains the list of signers for multi-signed transactions. + * @note This is an untyped field (STArray). + * @return A reference wrapper to the signers array if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional> + getSigners() const + { + if (tx_->isFieldPresent(sfSigners)) + return tx_->getFieldArray(sfSigners); + return std::nullopt; + } + + /** + * @brief Check if the transaction has signers. + * @return true if sfSigners is present, false otherwise + */ + [[nodiscard]] + bool + hasSigners() const + { + return tx_->isFieldPresent(sfSigners); + } + + /** + * @brief Get the network ID (sfNetworkID). + * + * This field is OPTIONAL and identifies the network this transaction is intended for. + * @return The network ID if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getNetworkID() const + { + if (tx_->isFieldPresent(sfNetworkID)) + return tx_->at(sfNetworkID); + return std::nullopt; + } + + /** + * @brief Check if the transaction has a network ID. + * @return true if sfNetworkID is present, false otherwise + */ + [[nodiscard]] + bool + hasNetworkID() const + { + return tx_->isFieldPresent(sfNetworkID); + } + + /** + * @brief Get the delegate account (sfDelegate). + * + * This field is OPTIONAL and specifies a delegate account for the transaction. + * @return The delegate account ID if present, std::nullopt otherwise + */ + [[nodiscard]] + std::optional + getDelegate() const + { + if (tx_->isFieldPresent(sfDelegate)) + return tx_->at(sfDelegate); + return std::nullopt; + } + + /** + * @brief Check if the transaction has a delegate account. + * @return true if sfDelegate is present, false otherwise + */ + [[nodiscard]] + bool + hasDelegate() const + { + return tx_->isFieldPresent(sfDelegate); + } + + /** + * @brief Get the underlying STTx object. + * + * Provides direct access to the wrapped transaction object for cases + * where the type-safe accessors are insufficient. + * @return A constant reference to the underlying STTx object + */ + [[nodiscard]] + std::shared_ptr + getSTTx() const + { + return tx_; + } + +protected: + /** @brief The underlying transaction object being wrapped. */ + std::shared_ptr tx_; +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/TransactionBuilderBase.h b/include/xrpl/protocol_autogen/TransactionBuilderBase.h new file mode 100644 index 0000000000..3abfd07a1c --- /dev/null +++ b/include/xrpl/protocol_autogen/TransactionBuilderBase.h @@ -0,0 +1,269 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xrpl::transactions { + +/** + * Base class for all transaction builders. + * Provides common field setters that are available for all transaction types. + */ +template +class TransactionBuilderBase +{ +public: + TransactionBuilderBase() = default; + + TransactionBuilderBase( + SF_UINT16::type::value_type transactionType, + SF_ACCOUNT::type::value_type account, + std::optional sequence, + std::optional fee) + { + // Don't call object_.set(soTemplate) - keep object_ as a free object. + // This avoids creating STBase placeholders for soeDEFAULT fields, + // which would cause applyTemplate() to throw "may not be explicitly + // set to default" when building the STTx. + // The STTx constructor will call applyTemplate() which properly + // handles missing fields. + object_[sfTransactionType] = transactionType; + setAccount(account); + + if (sequence) + { + setSequence(*sequence); + } + if (fee) + { + setFee(*fee); + } + } + + /** + * Set the account that is sending the transaction. + * @param value Account address (typically as a string) + * @return Reference to the derived builder for method chaining. + */ + Derived& + setAccount(AccountID const& value) + { + object_[sfAccount] = value; + return static_cast(*this); + } + + /** + * Set the transaction fee. + * @param value Fee in drops (typically as a string or number) + * @return Reference to the derived builder for method chaining. + */ + Derived& + setFee(STAmount const& value) + { + object_[sfFee] = value; + return static_cast(*this); + } + + /** + * Set the sequence number. + * @param value Sequence number + * @return Reference to the derived builder for method chaining. + */ + Derived& + setSequence(std::uint32_t const& value) + { + object_[sfSequence] = value; + return static_cast(*this); + } + + /** + * Set the ticket sequence to use for this transaction. + * When using a ticket, the regular sequence number is set to 0. + * @param value Ticket sequence number + * @return Reference to the derived builder for method chaining. + */ + Derived& + setTicketSequence(std::uint32_t const& value) + { + object_[sfSequence] = 0u; + object_[sfTicketSequence] = value; + return static_cast(*this); + } + + /** + * Set transaction flags. + * @param value Flags value + * @return Reference to the derived builder for method chaining. + */ + Derived& + setFlags(std::uint32_t const& value) + { + object_[sfFlags] = value; + return static_cast(*this); + } + + /** + * Set the source tag. + * @param value Source tag + * @return Reference to the derived builder for method chaining. + */ + Derived& + setSourceTag(std::uint32_t const& value) + { + object_[sfSourceTag] = value; + return static_cast(*this); + } + + /** + * Set the last ledger sequence. + * @param value Last ledger sequence number + * @return Reference to the derived builder for method chaining. + */ + Derived& + setLastLedgerSequence(std::uint32_t const& value) + { + object_[sfLastLedgerSequence] = value; + return static_cast(*this); + } + + /** + * Set the account transaction ID. + * @param value Account transaction ID (typically as a hex string) + * @return Reference to the derived builder for method chaining. + */ + Derived& + setAccountTxnID(uint256 const& value) + { + object_[sfAccountTxnID] = value; + return static_cast(*this); + } + + /** + * Set the previous transaction ID. + * Used for emulate027 compatibility. + * @param value Previous transaction ID + * @return Reference to the derived builder for method chaining. + */ + Derived& + setPreviousTxnID(uint256 const& value) + { + object_[sfPreviousTxnID] = value; + return static_cast(*this); + } + + /** + * Set the operation limit. + * @param value Operation limit + * @return Reference to the derived builder for method chaining. + */ + Derived& + setOperationLimit(std::uint32_t const& value) + { + object_[sfOperationLimit] = value; + return static_cast(*this); + } + + /** + * Set the memos array. + * @param value Array of memo objects + * @return Reference to the derived builder for method chaining. + */ + Derived& + setMemos(STArray const& value) + { + object_.setFieldArray(sfMemos, value); + return static_cast(*this); + } + + /** + * Set the signers array for multi-signing. + * @param value Array of signer objects + * @return Reference to the derived builder for method chaining. + */ + Derived& + setSigners(STArray const& value) + { + object_.setFieldArray(sfSigners, value); + return static_cast(*this); + } + + /** + * Set the network ID. + * @param value Network ID + * @return Reference to the derived builder for method chaining. + */ + Derived& + setNetworkID(std::uint32_t const& value) + { + object_[sfNetworkID] = value; + return static_cast(*this); + } + + /** + * Set the delegate account for delegated transactions. + * @param value Delegate account ID + * @return Reference to the derived builder for method chaining. + */ + Derived& + setDelegate(AccountID const& value) + { + object_[sfDelegate] = value; + return static_cast(*this); + } + + /** + * Get the underlying STObject. + * @return The STObject + */ + STObject const& + getSTObject() const + { + return object_; + } + +protected: + /** + * Sign the transaction with the given keys. + * + * This sets the SigningPubKey field and computes the TxnSignature. + * + * @param publicKey The public key for signing + * @param secretKey The secret key for signing + * @return Reference to the derived builder for method chaining. + */ + Derived& + sign(PublicKey const& publicKey, SecretKey const& secretKey) + { + // Set the signing public key + object_.setFieldVL(sfSigningPubKey, publicKey.slice()); + + // Build the signing data: HashPrefix::txSign + serialized object + // (without signing fields) + Serializer s; + s.add32(HashPrefix::txSign); + object_.addWithoutSigningFields(s); + + // Sign and set the signature + auto const sig = xrpl::sign(publicKey, secretKey, s.slice()); + object_.setFieldVL(sfTxnSignature, sig); + + return static_cast(*this); + } + + STObject object_{sfTransaction}; +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/Utils.h b/include/xrpl/protocol_autogen/Utils.h new file mode 100644 index 0000000000..057c685209 --- /dev/null +++ b/include/xrpl/protocol_autogen/Utils.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include + +namespace xrpl::protocol_autogen { + +template +using Optional = std::conditional_t< + std::is_reference_v, + std::optional>>, + std::optional>; + +} diff --git a/include/xrpl/protocol_autogen/ledger_entries/AMM.h b/include/xrpl/protocol_autogen/ledger_entries/AMM.h new file mode 100644 index 0000000000..f92f15eaa8 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/AMM.h @@ -0,0 +1,392 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class AMMBuilder; + +/** + * @brief Ledger Entry: AMM + * + * Type: ltAMM (0x0079) + * RPC Name: amm + * + * Immutable wrapper around SLE providing type-safe field access. + * Use AMMBuilder to construct new ledger entries. + */ +class AMM : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltAMM; + + /** + * @brief Construct a AMM ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit AMM(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for AMM"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfTradingFee (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTradingFee() const + { + if (hasTradingFee()) + return this->sle_->at(sfTradingFee); + return std::nullopt; + } + + /** + * @brief Check if sfTradingFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTradingFee() const + { + return this->sle_->isFieldPresent(sfTradingFee); + } + + /** + * @brief Get sfVoteSlots (soeOPTIONAL) + * @note This is an untyped field (unknown). + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getVoteSlots() const + { + if (this->sle_->isFieldPresent(sfVoteSlots)) + return this->sle_->getFieldArray(sfVoteSlots); + return std::nullopt; + } + + /** + * @brief Check if sfVoteSlots is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasVoteSlots() const + { + return this->sle_->isFieldPresent(sfVoteSlots); + } + + /** + * @brief Get sfAuctionSlot (soeOPTIONAL) + * @note This is an untyped field (unknown). + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional + getAuctionSlot() const + { + if (this->sle_->isFieldPresent(sfAuctionSlot)) + return this->sle_->getFieldObject(sfAuctionSlot); + return std::nullopt; + } + + /** + * @brief Check if sfAuctionSlot is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAuctionSlot() const + { + return this->sle_->isFieldPresent(sfAuctionSlot); + } + + /** + * @brief Get sfLPTokenBalance (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getLPTokenBalance() const + { + return this->sle_->at(sfLPTokenBalance); + } + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->sle_->at(sfAsset); + } + + /** + * @brief Get sfAsset2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset2() const + { + return this->sle_->at(sfAsset2); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnID() const + { + if (hasPreviousTxnID()) + return this->sle_->at(sfPreviousTxnID); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnID() const + { + return this->sle_->isFieldPresent(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnLgrSeq() const + { + if (hasPreviousTxnLgrSeq()) + return this->sle_->at(sfPreviousTxnLgrSeq); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnLgrSeq is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnLgrSeq() const + { + return this->sle_->isFieldPresent(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for AMM ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class AMMBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new AMMBuilder with required fields. + * @param account The sfAccount field value. + * @param lPTokenBalance The sfLPTokenBalance field value. + * @param asset The sfAsset field value. + * @param asset2 The sfAsset2 field value. + * @param ownerNode The sfOwnerNode field value. + */ + AMMBuilder(std::decay_t const& account,std::decay_t const& lPTokenBalance,std::decay_t const& asset,std::decay_t const& asset2,std::decay_t const& ownerNode) + : LedgerEntryBuilderBase(ltAMM) + { + setAccount(account); + setLPTokenBalance(lPTokenBalance); + setAsset(asset); + setAsset2(asset2); + setOwnerNode(ownerNode); + } + + /** + * @brief Construct a AMMBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + AMMBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltAMM) + { + throw std::runtime_error("Invalid ledger entry type for AMM"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfTradingFee (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setTradingFee(std::decay_t const& value) + { + object_[sfTradingFee] = value; + return *this; + } + + /** + * @brief Set sfVoteSlots (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setVoteSlots(STArray const& value) + { + object_.setFieldArray(sfVoteSlots, value); + return *this; + } + + /** + * @brief Set sfAuctionSlot (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setAuctionSlot(STObject const& value) + { + object_.setFieldObject(sfAuctionSlot, value); + return *this; + } + + /** + * @brief Set sfLPTokenBalance (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setLPTokenBalance(std::decay_t const& value) + { + object_[sfLPTokenBalance] = value; + return *this; + } + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAsset2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setAsset2(std::decay_t const& value) + { + object_[sfAsset2] = STIssue(sfAsset2, value); + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed AMM wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + AMM + build(uint256 const& index) + { + return AMM{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/AccountRoot.h b/include/xrpl/protocol_autogen/ledger_entries/AccountRoot.h new file mode 100644 index 0000000000..15cf14b21a --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/AccountRoot.h @@ -0,0 +1,834 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class AccountRootBuilder; + +/** + * @brief Ledger Entry: AccountRoot + * + * Type: ltACCOUNT_ROOT (0x0061) + * RPC Name: account + * + * Immutable wrapper around SLE providing type-safe field access. + * Use AccountRootBuilder to construct new ledger entries. + */ +class AccountRoot : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltACCOUNT_ROOT; + + /** + * @brief Construct a AccountRoot ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit AccountRoot(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for AccountRoot"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSequence() const + { + return this->sle_->at(sfSequence); + } + + /** + * @brief Get sfBalance (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getBalance() const + { + return this->sle_->at(sfBalance); + } + + /** + * @brief Get sfOwnerCount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getOwnerCount() const + { + return this->sle_->at(sfOwnerCount); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfAccountTxnID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAccountTxnID() const + { + if (hasAccountTxnID()) + return this->sle_->at(sfAccountTxnID); + return std::nullopt; + } + + /** + * @brief Check if sfAccountTxnID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAccountTxnID() const + { + return this->sle_->isFieldPresent(sfAccountTxnID); + } + + /** + * @brief Get sfRegularKey (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getRegularKey() const + { + if (hasRegularKey()) + return this->sle_->at(sfRegularKey); + return std::nullopt; + } + + /** + * @brief Check if sfRegularKey is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasRegularKey() const + { + return this->sle_->isFieldPresent(sfRegularKey); + } + + /** + * @brief Get sfEmailHash (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getEmailHash() const + { + if (hasEmailHash()) + return this->sle_->at(sfEmailHash); + return std::nullopt; + } + + /** + * @brief Check if sfEmailHash is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasEmailHash() const + { + return this->sle_->isFieldPresent(sfEmailHash); + } + + /** + * @brief Get sfWalletLocator (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getWalletLocator() const + { + if (hasWalletLocator()) + return this->sle_->at(sfWalletLocator); + return std::nullopt; + } + + /** + * @brief Check if sfWalletLocator is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasWalletLocator() const + { + return this->sle_->isFieldPresent(sfWalletLocator); + } + + /** + * @brief Get sfWalletSize (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getWalletSize() const + { + if (hasWalletSize()) + return this->sle_->at(sfWalletSize); + return std::nullopt; + } + + /** + * @brief Check if sfWalletSize is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasWalletSize() const + { + return this->sle_->isFieldPresent(sfWalletSize); + } + + /** + * @brief Get sfMessageKey (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMessageKey() const + { + if (hasMessageKey()) + return this->sle_->at(sfMessageKey); + return std::nullopt; + } + + /** + * @brief Check if sfMessageKey is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMessageKey() const + { + return this->sle_->isFieldPresent(sfMessageKey); + } + + /** + * @brief Get sfTransferRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTransferRate() const + { + if (hasTransferRate()) + return this->sle_->at(sfTransferRate); + return std::nullopt; + } + + /** + * @brief Check if sfTransferRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTransferRate() const + { + return this->sle_->isFieldPresent(sfTransferRate); + } + + /** + * @brief Get sfDomain (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomain() const + { + if (hasDomain()) + return this->sle_->at(sfDomain); + return std::nullopt; + } + + /** + * @brief Check if sfDomain is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomain() const + { + return this->sle_->isFieldPresent(sfDomain); + } + + /** + * @brief Get sfTickSize (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTickSize() const + { + if (hasTickSize()) + return this->sle_->at(sfTickSize); + return std::nullopt; + } + + /** + * @brief Check if sfTickSize is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTickSize() const + { + return this->sle_->isFieldPresent(sfTickSize); + } + + /** + * @brief Get sfTicketCount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTicketCount() const + { + if (hasTicketCount()) + return this->sle_->at(sfTicketCount); + return std::nullopt; + } + + /** + * @brief Check if sfTicketCount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTicketCount() const + { + return this->sle_->isFieldPresent(sfTicketCount); + } + + /** + * @brief Get sfNFTokenMinter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNFTokenMinter() const + { + if (hasNFTokenMinter()) + return this->sle_->at(sfNFTokenMinter); + return std::nullopt; + } + + /** + * @brief Check if sfNFTokenMinter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNFTokenMinter() const + { + return this->sle_->isFieldPresent(sfNFTokenMinter); + } + + /** + * @brief Get sfMintedNFTokens (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMintedNFTokens() const + { + if (hasMintedNFTokens()) + return this->sle_->at(sfMintedNFTokens); + return std::nullopt; + } + + /** + * @brief Check if sfMintedNFTokens is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMintedNFTokens() const + { + return this->sle_->isFieldPresent(sfMintedNFTokens); + } + + /** + * @brief Get sfBurnedNFTokens (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBurnedNFTokens() const + { + if (hasBurnedNFTokens()) + return this->sle_->at(sfBurnedNFTokens); + return std::nullopt; + } + + /** + * @brief Check if sfBurnedNFTokens is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBurnedNFTokens() const + { + return this->sle_->isFieldPresent(sfBurnedNFTokens); + } + + /** + * @brief Get sfFirstNFTokenSequence (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getFirstNFTokenSequence() const + { + if (hasFirstNFTokenSequence()) + return this->sle_->at(sfFirstNFTokenSequence); + return std::nullopt; + } + + /** + * @brief Check if sfFirstNFTokenSequence is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasFirstNFTokenSequence() const + { + return this->sle_->isFieldPresent(sfFirstNFTokenSequence); + } + + /** + * @brief Get sfAMMID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAMMID() const + { + if (hasAMMID()) + return this->sle_->at(sfAMMID); + return std::nullopt; + } + + /** + * @brief Check if sfAMMID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAMMID() const + { + return this->sle_->isFieldPresent(sfAMMID); + } + + /** + * @brief Get sfVaultID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getVaultID() const + { + if (hasVaultID()) + return this->sle_->at(sfVaultID); + return std::nullopt; + } + + /** + * @brief Check if sfVaultID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasVaultID() const + { + return this->sle_->isFieldPresent(sfVaultID); + } + + /** + * @brief Get sfLoanBrokerID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanBrokerID() const + { + if (hasLoanBrokerID()) + return this->sle_->at(sfLoanBrokerID); + return std::nullopt; + } + + /** + * @brief Check if sfLoanBrokerID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanBrokerID() const + { + return this->sle_->isFieldPresent(sfLoanBrokerID); + } +}; + +/** + * @brief Builder for AccountRoot ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class AccountRootBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new AccountRootBuilder with required fields. + * @param account The sfAccount field value. + * @param sequence The sfSequence field value. + * @param balance The sfBalance field value. + * @param ownerCount The sfOwnerCount field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + AccountRootBuilder(std::decay_t const& account,std::decay_t const& sequence,std::decay_t const& balance,std::decay_t const& ownerCount,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltACCOUNT_ROOT) + { + setAccount(account); + setSequence(sequence); + setBalance(balance); + setOwnerCount(ownerCount); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a AccountRootBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + AccountRootBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltACCOUNT_ROOT) + { + throw std::runtime_error("Invalid ledger entry type for AccountRoot"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfBalance (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setBalance(std::decay_t const& value) + { + object_[sfBalance] = value; + return *this; + } + + /** + * @brief Set sfOwnerCount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setOwnerCount(std::decay_t const& value) + { + object_[sfOwnerCount] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfAccountTxnID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setAccountTxnID(std::decay_t const& value) + { + object_[sfAccountTxnID] = value; + return *this; + } + + /** + * @brief Set sfRegularKey (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setRegularKey(std::decay_t const& value) + { + object_[sfRegularKey] = value; + return *this; + } + + /** + * @brief Set sfEmailHash (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setEmailHash(std::decay_t const& value) + { + object_[sfEmailHash] = value; + return *this; + } + + /** + * @brief Set sfWalletLocator (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setWalletLocator(std::decay_t const& value) + { + object_[sfWalletLocator] = value; + return *this; + } + + /** + * @brief Set sfWalletSize (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setWalletSize(std::decay_t const& value) + { + object_[sfWalletSize] = value; + return *this; + } + + /** + * @brief Set sfMessageKey (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setMessageKey(std::decay_t const& value) + { + object_[sfMessageKey] = value; + return *this; + } + + /** + * @brief Set sfTransferRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setTransferRate(std::decay_t const& value) + { + object_[sfTransferRate] = value; + return *this; + } + + /** + * @brief Set sfDomain (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setDomain(std::decay_t const& value) + { + object_[sfDomain] = value; + return *this; + } + + /** + * @brief Set sfTickSize (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setTickSize(std::decay_t const& value) + { + object_[sfTickSize] = value; + return *this; + } + + /** + * @brief Set sfTicketCount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setTicketCount(std::decay_t const& value) + { + object_[sfTicketCount] = value; + return *this; + } + + /** + * @brief Set sfNFTokenMinter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setNFTokenMinter(std::decay_t const& value) + { + object_[sfNFTokenMinter] = value; + return *this; + } + + /** + * @brief Set sfMintedNFTokens (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setMintedNFTokens(std::decay_t const& value) + { + object_[sfMintedNFTokens] = value; + return *this; + } + + /** + * @brief Set sfBurnedNFTokens (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setBurnedNFTokens(std::decay_t const& value) + { + object_[sfBurnedNFTokens] = value; + return *this; + } + + /** + * @brief Set sfFirstNFTokenSequence (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setFirstNFTokenSequence(std::decay_t const& value) + { + object_[sfFirstNFTokenSequence] = value; + return *this; + } + + /** + * @brief Set sfAMMID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setAMMID(std::decay_t const& value) + { + object_[sfAMMID] = value; + return *this; + } + + /** + * @brief Set sfVaultID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Set sfLoanBrokerID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountRootBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Build and return the completed AccountRoot wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + AccountRoot + build(uint256 const& index) + { + return AccountRoot{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Amendments.h b/include/xrpl/protocol_autogen/ledger_entries/Amendments.h new file mode 100644 index 0000000000..2b51b83747 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Amendments.h @@ -0,0 +1,236 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class AmendmentsBuilder; + +/** + * @brief Ledger Entry: Amendments + * + * Type: ltAMENDMENTS (0x0066) + * RPC Name: amendments + * + * Immutable wrapper around SLE providing type-safe field access. + * Use AmendmentsBuilder to construct new ledger entries. + */ +class Amendments : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltAMENDMENTS; + + /** + * @brief Construct a Amendments ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Amendments(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Amendments"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAmendments (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmendments() const + { + if (hasAmendments()) + return this->sle_->at(sfAmendments); + return std::nullopt; + } + + /** + * @brief Check if sfAmendments is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmendments() const + { + return this->sle_->isFieldPresent(sfAmendments); + } + + /** + * @brief Get sfMajorities (soeOPTIONAL) + * @note This is an untyped field (unknown). + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getMajorities() const + { + if (this->sle_->isFieldPresent(sfMajorities)) + return this->sle_->getFieldArray(sfMajorities); + return std::nullopt; + } + + /** + * @brief Check if sfMajorities is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMajorities() const + { + return this->sle_->isFieldPresent(sfMajorities); + } + + /** + * @brief Get sfPreviousTxnID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnID() const + { + if (hasPreviousTxnID()) + return this->sle_->at(sfPreviousTxnID); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnID() const + { + return this->sle_->isFieldPresent(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnLgrSeq() const + { + if (hasPreviousTxnLgrSeq()) + return this->sle_->at(sfPreviousTxnLgrSeq); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnLgrSeq is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnLgrSeq() const + { + return this->sle_->isFieldPresent(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for Amendments ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class AmendmentsBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new AmendmentsBuilder with required fields. + */ + AmendmentsBuilder() + : LedgerEntryBuilderBase(ltAMENDMENTS) + { + } + + /** + * @brief Construct a AmendmentsBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + AmendmentsBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltAMENDMENTS) + { + throw std::runtime_error("Invalid ledger entry type for Amendments"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAmendments (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AmendmentsBuilder& + setAmendments(std::decay_t const& value) + { + object_[sfAmendments] = value; + return *this; + } + + /** + * @brief Set sfMajorities (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AmendmentsBuilder& + setMajorities(STArray const& value) + { + object_.setFieldArray(sfMajorities, value); + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AmendmentsBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AmendmentsBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed Amendments wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Amendments + build(uint256 const& index) + { + return Amendments{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Bridge.h b/include/xrpl/protocol_autogen/ledger_entries/Bridge.h new file mode 100644 index 0000000000..3926ff65fa --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Bridge.h @@ -0,0 +1,346 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class BridgeBuilder; + +/** + * @brief Ledger Entry: Bridge + * + * Type: ltBRIDGE (0x0069) + * RPC Name: bridge + * + * Immutable wrapper around SLE providing type-safe field access. + * Use BridgeBuilder to construct new ledger entries. + */ +class Bridge : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltBRIDGE; + + /** + * @brief Construct a Bridge ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Bridge(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Bridge"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfSignatureReward (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSignatureReward() const + { + return this->sle_->at(sfSignatureReward); + } + + /** + * @brief Get sfMinAccountCreateAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMinAccountCreateAmount() const + { + if (hasMinAccountCreateAmount()) + return this->sle_->at(sfMinAccountCreateAmount); + return std::nullopt; + } + + /** + * @brief Check if sfMinAccountCreateAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMinAccountCreateAmount() const + { + return this->sle_->isFieldPresent(sfMinAccountCreateAmount); + } + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->sle_->at(sfXChainBridge); + } + + /** + * @brief Get sfXChainClaimID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainClaimID() const + { + return this->sle_->at(sfXChainClaimID); + } + + /** + * @brief Get sfXChainAccountCreateCount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainAccountCreateCount() const + { + return this->sle_->at(sfXChainAccountCreateCount); + } + + /** + * @brief Get sfXChainAccountClaimCount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainAccountClaimCount() const + { + return this->sle_->at(sfXChainAccountClaimCount); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for Bridge ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class BridgeBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new BridgeBuilder with required fields. + * @param account The sfAccount field value. + * @param signatureReward The sfSignatureReward field value. + * @param xChainBridge The sfXChainBridge field value. + * @param xChainClaimID The sfXChainClaimID field value. + * @param xChainAccountCreateCount The sfXChainAccountCreateCount field value. + * @param xChainAccountClaimCount The sfXChainAccountClaimCount field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + BridgeBuilder(std::decay_t const& account,std::decay_t const& signatureReward,std::decay_t const& xChainBridge,std::decay_t const& xChainClaimID,std::decay_t const& xChainAccountCreateCount,std::decay_t const& xChainAccountClaimCount,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltBRIDGE) + { + setAccount(account); + setSignatureReward(signatureReward); + setXChainBridge(xChainBridge); + setXChainClaimID(xChainClaimID); + setXChainAccountCreateCount(xChainAccountCreateCount); + setXChainAccountClaimCount(xChainAccountClaimCount); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a BridgeBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + BridgeBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltBRIDGE) + { + throw std::runtime_error("Invalid ledger entry type for Bridge"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfSignatureReward (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setSignatureReward(std::decay_t const& value) + { + object_[sfSignatureReward] = value; + return *this; + } + + /** + * @brief Set sfMinAccountCreateAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setMinAccountCreateAmount(std::decay_t const& value) + { + object_[sfMinAccountCreateAmount] = value; + return *this; + } + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfXChainClaimID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setXChainClaimID(std::decay_t const& value) + { + object_[sfXChainClaimID] = value; + return *this; + } + + /** + * @brief Set sfXChainAccountCreateCount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setXChainAccountCreateCount(std::decay_t const& value) + { + object_[sfXChainAccountCreateCount] = value; + return *this; + } + + /** + * @brief Set sfXChainAccountClaimCount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setXChainAccountClaimCount(std::decay_t const& value) + { + object_[sfXChainAccountClaimCount] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BridgeBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed Bridge wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Bridge + build(uint256 const& index) + { + return Bridge{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Check.h b/include/xrpl/protocol_autogen/ledger_entries/Check.h new file mode 100644 index 0000000000..c071186afb --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Check.h @@ -0,0 +1,427 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class CheckBuilder; + +/** + * @brief Ledger Entry: Check + * + * Type: ltCHECK (0x0043) + * RPC Name: check + * + * Immutable wrapper around SLE providing type-safe field access. + * Use CheckBuilder to construct new ledger entries. + */ +class Check : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltCHECK; + + /** + * @brief Construct a Check ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Check(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Check"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->sle_->at(sfDestination); + } + + /** + * @brief Get sfSendMax (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSendMax() const + { + return this->sle_->at(sfSendMax); + } + + /** + * @brief Get sfSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSequence() const + { + return this->sle_->at(sfSequence); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfDestinationNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getDestinationNode() const + { + return this->sle_->at(sfDestinationNode); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + return this->sle_->at(sfExpiration); + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->sle_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfInvoiceID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getInvoiceID() const + { + if (hasInvoiceID()) + return this->sle_->at(sfInvoiceID); + return std::nullopt; + } + + /** + * @brief Check if sfInvoiceID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasInvoiceID() const + { + return this->sle_->isFieldPresent(sfInvoiceID); + } + + /** + * @brief Get sfSourceTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSourceTag() const + { + if (hasSourceTag()) + return this->sle_->at(sfSourceTag); + return std::nullopt; + } + + /** + * @brief Check if sfSourceTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSourceTag() const + { + return this->sle_->isFieldPresent(sfSourceTag); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + return this->sle_->at(sfDestinationTag); + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->sle_->isFieldPresent(sfDestinationTag); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for Check ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class CheckBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new CheckBuilder with required fields. + * @param account The sfAccount field value. + * @param destination The sfDestination field value. + * @param sendMax The sfSendMax field value. + * @param sequence The sfSequence field value. + * @param ownerNode The sfOwnerNode field value. + * @param destinationNode The sfDestinationNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + CheckBuilder(std::decay_t const& account,std::decay_t const& destination,std::decay_t const& sendMax,std::decay_t const& sequence,std::decay_t const& ownerNode,std::decay_t const& destinationNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltCHECK) + { + setAccount(account); + setDestination(destination); + setSendMax(sendMax); + setSequence(sequence); + setOwnerNode(ownerNode); + setDestinationNode(destinationNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a CheckBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + CheckBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltCHECK) + { + throw std::runtime_error("Invalid ledger entry type for Check"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfSendMax (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setSendMax(std::decay_t const& value) + { + object_[sfSendMax] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfDestinationNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setDestinationNode(std::decay_t const& value) + { + object_[sfDestinationNode] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfInvoiceID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setInvoiceID(std::decay_t const& value) + { + object_[sfInvoiceID] = value; + return *this; + } + + /** + * @brief Set sfSourceTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setSourceTag(std::decay_t const& value) + { + object_[sfSourceTag] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed Check wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Check + build(uint256 const& index) + { + return Check{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Credential.h b/include/xrpl/protocol_autogen/ledger_entries/Credential.h new file mode 100644 index 0000000000..4c45f80a8d --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Credential.h @@ -0,0 +1,344 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class CredentialBuilder; + +/** + * @brief Ledger Entry: Credential + * + * Type: ltCREDENTIAL (0x0081) + * RPC Name: credential + * + * Immutable wrapper around SLE providing type-safe field access. + * Use CredentialBuilder to construct new ledger entries. + */ +class Credential : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltCREDENTIAL; + + /** + * @brief Construct a Credential ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Credential(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Credential"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfSubject (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getSubject() const + { + return this->sle_->at(sfSubject); + } + + /** + * @brief Get sfIssuer (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getIssuer() const + { + return this->sle_->at(sfIssuer); + } + + /** + * @brief Get sfCredentialType (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getCredentialType() const + { + return this->sle_->at(sfCredentialType); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + return this->sle_->at(sfExpiration); + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->sle_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + return this->sle_->at(sfURI); + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->sle_->isFieldPresent(sfURI); + } + + /** + * @brief Get sfIssuerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getIssuerNode() const + { + return this->sle_->at(sfIssuerNode); + } + + /** + * @brief Get sfSubjectNode (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSubjectNode() const + { + if (hasSubjectNode()) + return this->sle_->at(sfSubjectNode); + return std::nullopt; + } + + /** + * @brief Check if sfSubjectNode is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSubjectNode() const + { + return this->sle_->isFieldPresent(sfSubjectNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for Credential ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class CredentialBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new CredentialBuilder with required fields. + * @param subject The sfSubject field value. + * @param issuer The sfIssuer field value. + * @param credentialType The sfCredentialType field value. + * @param issuerNode The sfIssuerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + CredentialBuilder(std::decay_t const& subject,std::decay_t const& issuer,std::decay_t const& credentialType,std::decay_t const& issuerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltCREDENTIAL) + { + setSubject(subject); + setIssuer(issuer); + setCredentialType(credentialType); + setIssuerNode(issuerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a CredentialBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + CredentialBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltCREDENTIAL) + { + throw std::runtime_error("Invalid ledger entry type for Credential"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfSubject (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setSubject(std::decay_t const& value) + { + object_[sfSubject] = value; + return *this; + } + + /** + * @brief Set sfIssuer (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setIssuer(std::decay_t const& value) + { + object_[sfIssuer] = value; + return *this; + } + + /** + * @brief Set sfCredentialType (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setCredentialType(std::decay_t const& value) + { + object_[sfCredentialType] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Set sfIssuerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setIssuerNode(std::decay_t const& value) + { + object_[sfIssuerNode] = value; + return *this; + } + + /** + * @brief Set sfSubjectNode (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setSubjectNode(std::decay_t const& value) + { + object_[sfSubjectNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed Credential wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Credential + build(uint256 const& index) + { + return Credential{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/DID.h b/include/xrpl/protocol_autogen/ledger_entries/DID.h new file mode 100644 index 0000000000..fc88e988df --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/DID.h @@ -0,0 +1,296 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class DIDBuilder; + +/** + * @brief Ledger Entry: DID + * + * Type: ltDID (0x0049) + * RPC Name: did + * + * Immutable wrapper around SLE providing type-safe field access. + * Use DIDBuilder to construct new ledger entries. + */ +class DID : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltDID; + + /** + * @brief Construct a DID ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit DID(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for DID"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfDIDDocument (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDIDDocument() const + { + if (hasDIDDocument()) + return this->sle_->at(sfDIDDocument); + return std::nullopt; + } + + /** + * @brief Check if sfDIDDocument is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDIDDocument() const + { + return this->sle_->isFieldPresent(sfDIDDocument); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + return this->sle_->at(sfURI); + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->sle_->isFieldPresent(sfURI); + } + + /** + * @brief Get sfData (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + return this->sle_->at(sfData); + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->sle_->isFieldPresent(sfData); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for DID ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class DIDBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new DIDBuilder with required fields. + * @param account The sfAccount field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + DIDBuilder(std::decay_t const& account,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltDID) + { + setAccount(account); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a DIDBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + DIDBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltDID) + { + throw std::runtime_error("Invalid ledger entry type for DID"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DIDBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfDIDDocument (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DIDBuilder& + setDIDDocument(std::decay_t const& value) + { + object_[sfDIDDocument] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DIDBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Set sfData (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DIDBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DIDBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DIDBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DIDBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed DID wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + DID + build(uint256 const& index) + { + return DID{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Delegate.h b/include/xrpl/protocol_autogen/ledger_entries/Delegate.h new file mode 100644 index 0000000000..4d937eb99a --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Delegate.h @@ -0,0 +1,240 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class DelegateBuilder; + +/** + * @brief Ledger Entry: Delegate + * + * Type: ltDELEGATE (0x0083) + * RPC Name: delegate + * + * Immutable wrapper around SLE providing type-safe field access. + * Use DelegateBuilder to construct new ledger entries. + */ +class Delegate : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltDELEGATE; + + /** + * @brief Construct a Delegate ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Delegate(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Delegate"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfAuthorize (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAuthorize() const + { + return this->sle_->at(sfAuthorize); + } + + /** + * @brief Get sfPermissions (soeREQUIRED) + * @note This is an untyped field (unknown). + * @return The field value. + */ + [[nodiscard]] + STArray const& + getPermissions() const + { + return this->sle_->getFieldArray(sfPermissions); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for Delegate ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class DelegateBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new DelegateBuilder with required fields. + * @param account The sfAccount field value. + * @param authorize The sfAuthorize field value. + * @param permissions The sfPermissions field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + DelegateBuilder(std::decay_t const& account,std::decay_t const& authorize,STArray const& permissions,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltDELEGATE) + { + setAccount(account); + setAuthorize(authorize); + setPermissions(permissions); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a DelegateBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + DelegateBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltDELEGATE) + { + throw std::runtime_error("Invalid ledger entry type for Delegate"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfAuthorize (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateBuilder& + setAuthorize(std::decay_t const& value) + { + object_[sfAuthorize] = value; + return *this; + } + + /** + * @brief Set sfPermissions (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateBuilder& + setPermissions(STArray const& value) + { + object_.setFieldArray(sfPermissions, value); + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed Delegate wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Delegate + build(uint256 const& index) + { + return Delegate{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/DepositPreauth.h b/include/xrpl/protocol_autogen/ledger_entries/DepositPreauth.h new file mode 100644 index 0000000000..533caba619 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/DepositPreauth.h @@ -0,0 +1,262 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class DepositPreauthBuilder; + +/** + * @brief Ledger Entry: DepositPreauth + * + * Type: ltDEPOSIT_PREAUTH (0x0070) + * RPC Name: deposit_preauth + * + * Immutable wrapper around SLE providing type-safe field access. + * Use DepositPreauthBuilder to construct new ledger entries. + */ +class DepositPreauth : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltDEPOSIT_PREAUTH; + + /** + * @brief Construct a DepositPreauth ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit DepositPreauth(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for DepositPreauth"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfAuthorize (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAuthorize() const + { + if (hasAuthorize()) + return this->sle_->at(sfAuthorize); + return std::nullopt; + } + + /** + * @brief Check if sfAuthorize is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAuthorize() const + { + return this->sle_->isFieldPresent(sfAuthorize); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfAuthorizeCredentials (soeOPTIONAL) + * @note This is an untyped field (unknown). + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getAuthorizeCredentials() const + { + if (this->sle_->isFieldPresent(sfAuthorizeCredentials)) + return this->sle_->getFieldArray(sfAuthorizeCredentials); + return std::nullopt; + } + + /** + * @brief Check if sfAuthorizeCredentials is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAuthorizeCredentials() const + { + return this->sle_->isFieldPresent(sfAuthorizeCredentials); + } +}; + +/** + * @brief Builder for DepositPreauth ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class DepositPreauthBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new DepositPreauthBuilder with required fields. + * @param account The sfAccount field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + DepositPreauthBuilder(std::decay_t const& account,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltDEPOSIT_PREAUTH) + { + setAccount(account); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a DepositPreauthBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + DepositPreauthBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltDEPOSIT_PREAUTH) + { + throw std::runtime_error("Invalid ledger entry type for DepositPreauth"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfAuthorize (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setAuthorize(std::decay_t const& value) + { + object_[sfAuthorize] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfAuthorizeCredentials (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setAuthorizeCredentials(STArray const& value) + { + object_.setFieldArray(sfAuthorizeCredentials, value); + return *this; + } + + /** + * @brief Build and return the completed DepositPreauth wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + DepositPreauth + build(uint256 const& index) + { + return DepositPreauth{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/DirectoryNode.h b/include/xrpl/protocol_autogen/ledger_entries/DirectoryNode.h new file mode 100644 index 0000000000..545542ec6c --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/DirectoryNode.h @@ -0,0 +1,563 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class DirectoryNodeBuilder; + +/** + * @brief Ledger Entry: DirectoryNode + * + * Type: ltDIR_NODE (0x0064) + * RPC Name: directory + * + * Immutable wrapper around SLE providing type-safe field access. + * Use DirectoryNodeBuilder to construct new ledger entries. + */ +class DirectoryNode : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltDIR_NODE; + + /** + * @brief Construct a DirectoryNode ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit DirectoryNode(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for DirectoryNode"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfOwner (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOwner() const + { + if (hasOwner()) + return this->sle_->at(sfOwner); + return std::nullopt; + } + + /** + * @brief Check if sfOwner is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOwner() const + { + return this->sle_->isFieldPresent(sfOwner); + } + + /** + * @brief Get sfTakerPaysCurrency (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTakerPaysCurrency() const + { + if (hasTakerPaysCurrency()) + return this->sle_->at(sfTakerPaysCurrency); + return std::nullopt; + } + + /** + * @brief Check if sfTakerPaysCurrency is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTakerPaysCurrency() const + { + return this->sle_->isFieldPresent(sfTakerPaysCurrency); + } + + /** + * @brief Get sfTakerPaysIssuer (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTakerPaysIssuer() const + { + if (hasTakerPaysIssuer()) + return this->sle_->at(sfTakerPaysIssuer); + return std::nullopt; + } + + /** + * @brief Check if sfTakerPaysIssuer is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTakerPaysIssuer() const + { + return this->sle_->isFieldPresent(sfTakerPaysIssuer); + } + + /** + * @brief Get sfTakerGetsCurrency (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTakerGetsCurrency() const + { + if (hasTakerGetsCurrency()) + return this->sle_->at(sfTakerGetsCurrency); + return std::nullopt; + } + + /** + * @brief Check if sfTakerGetsCurrency is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTakerGetsCurrency() const + { + return this->sle_->isFieldPresent(sfTakerGetsCurrency); + } + + /** + * @brief Get sfTakerGetsIssuer (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTakerGetsIssuer() const + { + if (hasTakerGetsIssuer()) + return this->sle_->at(sfTakerGetsIssuer); + return std::nullopt; + } + + /** + * @brief Check if sfTakerGetsIssuer is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTakerGetsIssuer() const + { + return this->sle_->isFieldPresent(sfTakerGetsIssuer); + } + + /** + * @brief Get sfExchangeRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExchangeRate() const + { + if (hasExchangeRate()) + return this->sle_->at(sfExchangeRate); + return std::nullopt; + } + + /** + * @brief Check if sfExchangeRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExchangeRate() const + { + return this->sle_->isFieldPresent(sfExchangeRate); + } + + /** + * @brief Get sfIndexes (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VECTOR256::type::value_type + getIndexes() const + { + return this->sle_->at(sfIndexes); + } + + /** + * @brief Get sfRootIndex (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getRootIndex() const + { + return this->sle_->at(sfRootIndex); + } + + /** + * @brief Get sfIndexNext (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getIndexNext() const + { + if (hasIndexNext()) + return this->sle_->at(sfIndexNext); + return std::nullopt; + } + + /** + * @brief Check if sfIndexNext is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasIndexNext() const + { + return this->sle_->isFieldPresent(sfIndexNext); + } + + /** + * @brief Get sfIndexPrevious (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getIndexPrevious() const + { + if (hasIndexPrevious()) + return this->sle_->at(sfIndexPrevious); + return std::nullopt; + } + + /** + * @brief Check if sfIndexPrevious is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasIndexPrevious() const + { + return this->sle_->isFieldPresent(sfIndexPrevious); + } + + /** + * @brief Get sfNFTokenID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNFTokenID() const + { + if (hasNFTokenID()) + return this->sle_->at(sfNFTokenID); + return std::nullopt; + } + + /** + * @brief Check if sfNFTokenID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNFTokenID() const + { + return this->sle_->isFieldPresent(sfNFTokenID); + } + + /** + * @brief Get sfPreviousTxnID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnID() const + { + if (hasPreviousTxnID()) + return this->sle_->at(sfPreviousTxnID); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnID() const + { + return this->sle_->isFieldPresent(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnLgrSeq() const + { + if (hasPreviousTxnLgrSeq()) + return this->sle_->at(sfPreviousTxnLgrSeq); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnLgrSeq is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnLgrSeq() const + { + return this->sle_->isFieldPresent(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + return this->sle_->at(sfDomainID); + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->sle_->isFieldPresent(sfDomainID); + } +}; + +/** + * @brief Builder for DirectoryNode ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class DirectoryNodeBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new DirectoryNodeBuilder with required fields. + * @param indexes The sfIndexes field value. + * @param rootIndex The sfRootIndex field value. + */ + DirectoryNodeBuilder(std::decay_t const& indexes,std::decay_t const& rootIndex) + : LedgerEntryBuilderBase(ltDIR_NODE) + { + setIndexes(indexes); + setRootIndex(rootIndex); + } + + /** + * @brief Construct a DirectoryNodeBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + DirectoryNodeBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltDIR_NODE) + { + throw std::runtime_error("Invalid ledger entry type for DirectoryNode"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfOwner (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfTakerPaysCurrency (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setTakerPaysCurrency(std::decay_t const& value) + { + object_[sfTakerPaysCurrency] = value; + return *this; + } + + /** + * @brief Set sfTakerPaysIssuer (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setTakerPaysIssuer(std::decay_t const& value) + { + object_[sfTakerPaysIssuer] = value; + return *this; + } + + /** + * @brief Set sfTakerGetsCurrency (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setTakerGetsCurrency(std::decay_t const& value) + { + object_[sfTakerGetsCurrency] = value; + return *this; + } + + /** + * @brief Set sfTakerGetsIssuer (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setTakerGetsIssuer(std::decay_t const& value) + { + object_[sfTakerGetsIssuer] = value; + return *this; + } + + /** + * @brief Set sfExchangeRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setExchangeRate(std::decay_t const& value) + { + object_[sfExchangeRate] = value; + return *this; + } + + /** + * @brief Set sfIndexes (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setIndexes(std::decay_t const& value) + { + object_[sfIndexes] = value; + return *this; + } + + /** + * @brief Set sfRootIndex (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setRootIndex(std::decay_t const& value) + { + object_[sfRootIndex] = value; + return *this; + } + + /** + * @brief Set sfIndexNext (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setIndexNext(std::decay_t const& value) + { + object_[sfIndexNext] = value; + return *this; + } + + /** + * @brief Set sfIndexPrevious (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setIndexPrevious(std::decay_t const& value) + { + object_[sfIndexPrevious] = value; + return *this; + } + + /** + * @brief Set sfNFTokenID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setNFTokenID(std::decay_t const& value) + { + object_[sfNFTokenID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DirectoryNodeBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Build and return the completed DirectoryNode wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + DirectoryNode + build(uint256 const& index) + { + return DirectoryNode{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Escrow.h b/include/xrpl/protocol_autogen/ledger_entries/Escrow.h new file mode 100644 index 0000000000..fd15b2a713 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Escrow.h @@ -0,0 +1,554 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class EscrowBuilder; + +/** + * @brief Ledger Entry: Escrow + * + * Type: ltESCROW (0x0075) + * RPC Name: escrow + * + * Immutable wrapper around SLE providing type-safe field access. + * Use EscrowBuilder to construct new ledger entries. + */ +class Escrow : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltESCROW; + + /** + * @brief Construct a Escrow ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Escrow(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Escrow"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfSequence (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSequence() const + { + if (hasSequence()) + return this->sle_->at(sfSequence); + return std::nullopt; + } + + /** + * @brief Check if sfSequence is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSequence() const + { + return this->sle_->isFieldPresent(sfSequence); + } + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->sle_->at(sfDestination); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->sle_->at(sfAmount); + } + + /** + * @brief Get sfCondition (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCondition() const + { + if (hasCondition()) + return this->sle_->at(sfCondition); + return std::nullopt; + } + + /** + * @brief Check if sfCondition is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCondition() const + { + return this->sle_->isFieldPresent(sfCondition); + } + + /** + * @brief Get sfCancelAfter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCancelAfter() const + { + if (hasCancelAfter()) + return this->sle_->at(sfCancelAfter); + return std::nullopt; + } + + /** + * @brief Check if sfCancelAfter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCancelAfter() const + { + return this->sle_->isFieldPresent(sfCancelAfter); + } + + /** + * @brief Get sfFinishAfter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getFinishAfter() const + { + if (hasFinishAfter()) + return this->sle_->at(sfFinishAfter); + return std::nullopt; + } + + /** + * @brief Check if sfFinishAfter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasFinishAfter() const + { + return this->sle_->isFieldPresent(sfFinishAfter); + } + + /** + * @brief Get sfSourceTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSourceTag() const + { + if (hasSourceTag()) + return this->sle_->at(sfSourceTag); + return std::nullopt; + } + + /** + * @brief Check if sfSourceTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSourceTag() const + { + return this->sle_->isFieldPresent(sfSourceTag); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + return this->sle_->at(sfDestinationTag); + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->sle_->isFieldPresent(sfDestinationTag); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfDestinationNode (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationNode() const + { + if (hasDestinationNode()) + return this->sle_->at(sfDestinationNode); + return std::nullopt; + } + + /** + * @brief Check if sfDestinationNode is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationNode() const + { + return this->sle_->isFieldPresent(sfDestinationNode); + } + + /** + * @brief Get sfTransferRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTransferRate() const + { + if (hasTransferRate()) + return this->sle_->at(sfTransferRate); + return std::nullopt; + } + + /** + * @brief Check if sfTransferRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTransferRate() const + { + return this->sle_->isFieldPresent(sfTransferRate); + } + + /** + * @brief Get sfIssuerNode (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getIssuerNode() const + { + if (hasIssuerNode()) + return this->sle_->at(sfIssuerNode); + return std::nullopt; + } + + /** + * @brief Check if sfIssuerNode is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasIssuerNode() const + { + return this->sle_->isFieldPresent(sfIssuerNode); + } +}; + +/** + * @brief Builder for Escrow ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class EscrowBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new EscrowBuilder with required fields. + * @param account The sfAccount field value. + * @param destination The sfDestination field value. + * @param amount The sfAmount field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + EscrowBuilder(std::decay_t const& account,std::decay_t const& destination,std::decay_t const& amount,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltESCROW) + { + setAccount(account); + setDestination(destination); + setAmount(amount); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a EscrowBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + EscrowBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltESCROW) + { + throw std::runtime_error("Invalid ledger entry type for Escrow"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfCondition (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setCondition(std::decay_t const& value) + { + object_[sfCondition] = value; + return *this; + } + + /** + * @brief Set sfCancelAfter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setCancelAfter(std::decay_t const& value) + { + object_[sfCancelAfter] = value; + return *this; + } + + /** + * @brief Set sfFinishAfter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setFinishAfter(std::decay_t const& value) + { + object_[sfFinishAfter] = value; + return *this; + } + + /** + * @brief Set sfSourceTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setSourceTag(std::decay_t const& value) + { + object_[sfSourceTag] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfDestinationNode (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setDestinationNode(std::decay_t const& value) + { + object_[sfDestinationNode] = value; + return *this; + } + + /** + * @brief Set sfTransferRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setTransferRate(std::decay_t const& value) + { + object_[sfTransferRate] = value; + return *this; + } + + /** + * @brief Set sfIssuerNode (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowBuilder& + setIssuerNode(std::decay_t const& value) + { + object_[sfIssuerNode] = value; + return *this; + } + + /** + * @brief Build and return the completed Escrow wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Escrow + build(uint256 const& index) + { + return Escrow{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/FeeSettings.h b/include/xrpl/protocol_autogen/ledger_entries/FeeSettings.h new file mode 100644 index 0000000000..e3c9ca0091 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/FeeSettings.h @@ -0,0 +1,410 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class FeeSettingsBuilder; + +/** + * @brief Ledger Entry: FeeSettings + * + * Type: ltFEE_SETTINGS (0x0073) + * RPC Name: fee + * + * Immutable wrapper around SLE providing type-safe field access. + * Use FeeSettingsBuilder to construct new ledger entries. + */ +class FeeSettings : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltFEE_SETTINGS; + + /** + * @brief Construct a FeeSettings ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit FeeSettings(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for FeeSettings"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfBaseFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBaseFee() const + { + if (hasBaseFee()) + return this->sle_->at(sfBaseFee); + return std::nullopt; + } + + /** + * @brief Check if sfBaseFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBaseFee() const + { + return this->sle_->isFieldPresent(sfBaseFee); + } + + /** + * @brief Get sfReferenceFeeUnits (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReferenceFeeUnits() const + { + if (hasReferenceFeeUnits()) + return this->sle_->at(sfReferenceFeeUnits); + return std::nullopt; + } + + /** + * @brief Check if sfReferenceFeeUnits is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReferenceFeeUnits() const + { + return this->sle_->isFieldPresent(sfReferenceFeeUnits); + } + + /** + * @brief Get sfReserveBase (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveBase() const + { + if (hasReserveBase()) + return this->sle_->at(sfReserveBase); + return std::nullopt; + } + + /** + * @brief Check if sfReserveBase is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveBase() const + { + return this->sle_->isFieldPresent(sfReserveBase); + } + + /** + * @brief Get sfReserveIncrement (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveIncrement() const + { + if (hasReserveIncrement()) + return this->sle_->at(sfReserveIncrement); + return std::nullopt; + } + + /** + * @brief Check if sfReserveIncrement is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveIncrement() const + { + return this->sle_->isFieldPresent(sfReserveIncrement); + } + + /** + * @brief Get sfBaseFeeDrops (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBaseFeeDrops() const + { + if (hasBaseFeeDrops()) + return this->sle_->at(sfBaseFeeDrops); + return std::nullopt; + } + + /** + * @brief Check if sfBaseFeeDrops is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBaseFeeDrops() const + { + return this->sle_->isFieldPresent(sfBaseFeeDrops); + } + + /** + * @brief Get sfReserveBaseDrops (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveBaseDrops() const + { + if (hasReserveBaseDrops()) + return this->sle_->at(sfReserveBaseDrops); + return std::nullopt; + } + + /** + * @brief Check if sfReserveBaseDrops is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveBaseDrops() const + { + return this->sle_->isFieldPresent(sfReserveBaseDrops); + } + + /** + * @brief Get sfReserveIncrementDrops (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveIncrementDrops() const + { + if (hasReserveIncrementDrops()) + return this->sle_->at(sfReserveIncrementDrops); + return std::nullopt; + } + + /** + * @brief Check if sfReserveIncrementDrops is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveIncrementDrops() const + { + return this->sle_->isFieldPresent(sfReserveIncrementDrops); + } + + /** + * @brief Get sfPreviousTxnID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnID() const + { + if (hasPreviousTxnID()) + return this->sle_->at(sfPreviousTxnID); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnID() const + { + return this->sle_->isFieldPresent(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnLgrSeq() const + { + if (hasPreviousTxnLgrSeq()) + return this->sle_->at(sfPreviousTxnLgrSeq); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnLgrSeq is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnLgrSeq() const + { + return this->sle_->isFieldPresent(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for FeeSettings ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class FeeSettingsBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new FeeSettingsBuilder with required fields. + */ + FeeSettingsBuilder() + : LedgerEntryBuilderBase(ltFEE_SETTINGS) + { + } + + /** + * @brief Construct a FeeSettingsBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + FeeSettingsBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltFEE_SETTINGS) + { + throw std::runtime_error("Invalid ledger entry type for FeeSettings"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfBaseFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setBaseFee(std::decay_t const& value) + { + object_[sfBaseFee] = value; + return *this; + } + + /** + * @brief Set sfReferenceFeeUnits (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setReferenceFeeUnits(std::decay_t const& value) + { + object_[sfReferenceFeeUnits] = value; + return *this; + } + + /** + * @brief Set sfReserveBase (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setReserveBase(std::decay_t const& value) + { + object_[sfReserveBase] = value; + return *this; + } + + /** + * @brief Set sfReserveIncrement (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setReserveIncrement(std::decay_t const& value) + { + object_[sfReserveIncrement] = value; + return *this; + } + + /** + * @brief Set sfBaseFeeDrops (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setBaseFeeDrops(std::decay_t const& value) + { + object_[sfBaseFeeDrops] = value; + return *this; + } + + /** + * @brief Set sfReserveBaseDrops (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setReserveBaseDrops(std::decay_t const& value) + { + object_[sfReserveBaseDrops] = value; + return *this; + } + + /** + * @brief Set sfReserveIncrementDrops (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setReserveIncrementDrops(std::decay_t const& value) + { + object_[sfReserveIncrementDrops] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + FeeSettingsBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed FeeSettings wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + FeeSettings + build(uint256 const& index) + { + return FeeSettings{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/LedgerHashes.h b/include/xrpl/protocol_autogen/ledger_entries/LedgerHashes.h new file mode 100644 index 0000000000..c95ca303ba --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/LedgerHashes.h @@ -0,0 +1,189 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class LedgerHashesBuilder; + +/** + * @brief Ledger Entry: LedgerHashes + * + * Type: ltLEDGER_HASHES (0x0068) + * RPC Name: hashes + * + * Immutable wrapper around SLE providing type-safe field access. + * Use LedgerHashesBuilder to construct new ledger entries. + */ +class LedgerHashes : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltLEDGER_HASHES; + + /** + * @brief Construct a LedgerHashes ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit LedgerHashes(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for LedgerHashes"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfFirstLedgerSequence (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getFirstLedgerSequence() const + { + if (hasFirstLedgerSequence()) + return this->sle_->at(sfFirstLedgerSequence); + return std::nullopt; + } + + /** + * @brief Check if sfFirstLedgerSequence is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasFirstLedgerSequence() const + { + return this->sle_->isFieldPresent(sfFirstLedgerSequence); + } + + /** + * @brief Get sfLastLedgerSequence (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLastLedgerSequence() const + { + if (hasLastLedgerSequence()) + return this->sle_->at(sfLastLedgerSequence); + return std::nullopt; + } + + /** + * @brief Check if sfLastLedgerSequence is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLastLedgerSequence() const + { + return this->sle_->isFieldPresent(sfLastLedgerSequence); + } + + /** + * @brief Get sfHashes (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VECTOR256::type::value_type + getHashes() const + { + return this->sle_->at(sfHashes); + } +}; + +/** + * @brief Builder for LedgerHashes ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class LedgerHashesBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new LedgerHashesBuilder with required fields. + * @param hashes The sfHashes field value. + */ + LedgerHashesBuilder(std::decay_t const& hashes) + : LedgerEntryBuilderBase(ltLEDGER_HASHES) + { + setHashes(hashes); + } + + /** + * @brief Construct a LedgerHashesBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + LedgerHashesBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltLEDGER_HASHES) + { + throw std::runtime_error("Invalid ledger entry type for LedgerHashes"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfFirstLedgerSequence (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LedgerHashesBuilder& + setFirstLedgerSequence(std::decay_t const& value) + { + object_[sfFirstLedgerSequence] = value; + return *this; + } + + /** + * @brief Set sfLastLedgerSequence (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LedgerHashesBuilder& + setLastLedgerSequence(std::decay_t const& value) + { + object_[sfLastLedgerSequence] = value; + return *this; + } + + /** + * @brief Set sfHashes (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LedgerHashesBuilder& + setHashes(std::decay_t const& value) + { + object_[sfHashes] = value; + return *this; + } + + /** + * @brief Build and return the completed LedgerHashes wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + LedgerHashes + build(uint256 const& index) + { + return LedgerHashes{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Loan.h b/include/xrpl/protocol_autogen/ledger_entries/Loan.h new file mode 100644 index 0000000000..73b37ea892 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Loan.h @@ -0,0 +1,930 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class LoanBuilder; + +/** + * @brief Ledger Entry: Loan + * + * Type: ltLOAN (0x0089) + * RPC Name: loan + * + * Immutable wrapper around SLE providing type-safe field access. + * Use LoanBuilder to construct new ledger entries. + */ +class Loan : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltLOAN; + + /** + * @brief Construct a Loan ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Loan(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Loan"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfLoanBrokerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getLoanBrokerNode() const + { + return this->sle_->at(sfLoanBrokerNode); + } + + /** + * @brief Get sfLoanBrokerID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanBrokerID() const + { + return this->sle_->at(sfLoanBrokerID); + } + + /** + * @brief Get sfLoanSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getLoanSequence() const + { + return this->sle_->at(sfLoanSequence); + } + + /** + * @brief Get sfBorrower (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getBorrower() const + { + return this->sle_->at(sfBorrower); + } + + /** + * @brief Get sfLoanOriginationFee (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanOriginationFee() const + { + if (hasLoanOriginationFee()) + return this->sle_->at(sfLoanOriginationFee); + return std::nullopt; + } + + /** + * @brief Check if sfLoanOriginationFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanOriginationFee() const + { + return this->sle_->isFieldPresent(sfLoanOriginationFee); + } + + /** + * @brief Get sfLoanServiceFee (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanServiceFee() const + { + if (hasLoanServiceFee()) + return this->sle_->at(sfLoanServiceFee); + return std::nullopt; + } + + /** + * @brief Check if sfLoanServiceFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanServiceFee() const + { + return this->sle_->isFieldPresent(sfLoanServiceFee); + } + + /** + * @brief Get sfLatePaymentFee (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLatePaymentFee() const + { + if (hasLatePaymentFee()) + return this->sle_->at(sfLatePaymentFee); + return std::nullopt; + } + + /** + * @brief Check if sfLatePaymentFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLatePaymentFee() const + { + return this->sle_->isFieldPresent(sfLatePaymentFee); + } + + /** + * @brief Get sfClosePaymentFee (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getClosePaymentFee() const + { + if (hasClosePaymentFee()) + return this->sle_->at(sfClosePaymentFee); + return std::nullopt; + } + + /** + * @brief Check if sfClosePaymentFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasClosePaymentFee() const + { + return this->sle_->isFieldPresent(sfClosePaymentFee); + } + + /** + * @brief Get sfOverpaymentFee (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOverpaymentFee() const + { + if (hasOverpaymentFee()) + return this->sle_->at(sfOverpaymentFee); + return std::nullopt; + } + + /** + * @brief Check if sfOverpaymentFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOverpaymentFee() const + { + return this->sle_->isFieldPresent(sfOverpaymentFee); + } + + /** + * @brief Get sfInterestRate (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getInterestRate() const + { + if (hasInterestRate()) + return this->sle_->at(sfInterestRate); + return std::nullopt; + } + + /** + * @brief Check if sfInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasInterestRate() const + { + return this->sle_->isFieldPresent(sfInterestRate); + } + + /** + * @brief Get sfLateInterestRate (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLateInterestRate() const + { + if (hasLateInterestRate()) + return this->sle_->at(sfLateInterestRate); + return std::nullopt; + } + + /** + * @brief Check if sfLateInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLateInterestRate() const + { + return this->sle_->isFieldPresent(sfLateInterestRate); + } + + /** + * @brief Get sfCloseInterestRate (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCloseInterestRate() const + { + if (hasCloseInterestRate()) + return this->sle_->at(sfCloseInterestRate); + return std::nullopt; + } + + /** + * @brief Check if sfCloseInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCloseInterestRate() const + { + return this->sle_->isFieldPresent(sfCloseInterestRate); + } + + /** + * @brief Get sfOverpaymentInterestRate (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOverpaymentInterestRate() const + { + if (hasOverpaymentInterestRate()) + return this->sle_->at(sfOverpaymentInterestRate); + return std::nullopt; + } + + /** + * @brief Check if sfOverpaymentInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOverpaymentInterestRate() const + { + return this->sle_->isFieldPresent(sfOverpaymentInterestRate); + } + + /** + * @brief Get sfStartDate (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getStartDate() const + { + return this->sle_->at(sfStartDate); + } + + /** + * @brief Get sfPaymentInterval (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPaymentInterval() const + { + return this->sle_->at(sfPaymentInterval); + } + + /** + * @brief Get sfGracePeriod (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getGracePeriod() const + { + if (hasGracePeriod()) + return this->sle_->at(sfGracePeriod); + return std::nullopt; + } + + /** + * @brief Check if sfGracePeriod is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasGracePeriod() const + { + return this->sle_->isFieldPresent(sfGracePeriod); + } + + /** + * @brief Get sfPreviousPaymentDueDate (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousPaymentDueDate() const + { + if (hasPreviousPaymentDueDate()) + return this->sle_->at(sfPreviousPaymentDueDate); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousPaymentDueDate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousPaymentDueDate() const + { + return this->sle_->isFieldPresent(sfPreviousPaymentDueDate); + } + + /** + * @brief Get sfNextPaymentDueDate (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNextPaymentDueDate() const + { + if (hasNextPaymentDueDate()) + return this->sle_->at(sfNextPaymentDueDate); + return std::nullopt; + } + + /** + * @brief Check if sfNextPaymentDueDate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNextPaymentDueDate() const + { + return this->sle_->isFieldPresent(sfNextPaymentDueDate); + } + + /** + * @brief Get sfPaymentRemaining (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPaymentRemaining() const + { + if (hasPaymentRemaining()) + return this->sle_->at(sfPaymentRemaining); + return std::nullopt; + } + + /** + * @brief Check if sfPaymentRemaining is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPaymentRemaining() const + { + return this->sle_->isFieldPresent(sfPaymentRemaining); + } + + /** + * @brief Get sfPeriodicPayment (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_NUMBER::type::value_type + getPeriodicPayment() const + { + return this->sle_->at(sfPeriodicPayment); + } + + /** + * @brief Get sfPrincipalOutstanding (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPrincipalOutstanding() const + { + if (hasPrincipalOutstanding()) + return this->sle_->at(sfPrincipalOutstanding); + return std::nullopt; + } + + /** + * @brief Check if sfPrincipalOutstanding is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPrincipalOutstanding() const + { + return this->sle_->isFieldPresent(sfPrincipalOutstanding); + } + + /** + * @brief Get sfTotalValueOutstanding (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTotalValueOutstanding() const + { + if (hasTotalValueOutstanding()) + return this->sle_->at(sfTotalValueOutstanding); + return std::nullopt; + } + + /** + * @brief Check if sfTotalValueOutstanding is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTotalValueOutstanding() const + { + return this->sle_->isFieldPresent(sfTotalValueOutstanding); + } + + /** + * @brief Get sfManagementFeeOutstanding (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getManagementFeeOutstanding() const + { + if (hasManagementFeeOutstanding()) + return this->sle_->at(sfManagementFeeOutstanding); + return std::nullopt; + } + + /** + * @brief Check if sfManagementFeeOutstanding is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasManagementFeeOutstanding() const + { + return this->sle_->isFieldPresent(sfManagementFeeOutstanding); + } + + /** + * @brief Get sfLoanScale (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanScale() const + { + if (hasLoanScale()) + return this->sle_->at(sfLoanScale); + return std::nullopt; + } + + /** + * @brief Check if sfLoanScale is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanScale() const + { + return this->sle_->isFieldPresent(sfLoanScale); + } +}; + +/** + * @brief Builder for Loan ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class LoanBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new LoanBuilder with required fields. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + * @param ownerNode The sfOwnerNode field value. + * @param loanBrokerNode The sfLoanBrokerNode field value. + * @param loanBrokerID The sfLoanBrokerID field value. + * @param loanSequence The sfLoanSequence field value. + * @param borrower The sfBorrower field value. + * @param startDate The sfStartDate field value. + * @param paymentInterval The sfPaymentInterval field value. + * @param periodicPayment The sfPeriodicPayment field value. + */ + LoanBuilder(std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq,std::decay_t const& ownerNode,std::decay_t const& loanBrokerNode,std::decay_t const& loanBrokerID,std::decay_t const& loanSequence,std::decay_t const& borrower,std::decay_t const& startDate,std::decay_t const& paymentInterval,std::decay_t const& periodicPayment) + : LedgerEntryBuilderBase(ltLOAN) + { + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + setOwnerNode(ownerNode); + setLoanBrokerNode(loanBrokerNode); + setLoanBrokerID(loanBrokerID); + setLoanSequence(loanSequence); + setBorrower(borrower); + setStartDate(startDate); + setPaymentInterval(paymentInterval); + setPeriodicPayment(periodicPayment); + } + + /** + * @brief Construct a LoanBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + LoanBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltLOAN) + { + throw std::runtime_error("Invalid ledger entry type for Loan"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfLoanBrokerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLoanBrokerNode(std::decay_t const& value) + { + object_[sfLoanBrokerNode] = value; + return *this; + } + + /** + * @brief Set sfLoanBrokerID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Set sfLoanSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLoanSequence(std::decay_t const& value) + { + object_[sfLoanSequence] = value; + return *this; + } + + /** + * @brief Set sfBorrower (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setBorrower(std::decay_t const& value) + { + object_[sfBorrower] = value; + return *this; + } + + /** + * @brief Set sfLoanOriginationFee (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLoanOriginationFee(std::decay_t const& value) + { + object_[sfLoanOriginationFee] = value; + return *this; + } + + /** + * @brief Set sfLoanServiceFee (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLoanServiceFee(std::decay_t const& value) + { + object_[sfLoanServiceFee] = value; + return *this; + } + + /** + * @brief Set sfLatePaymentFee (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLatePaymentFee(std::decay_t const& value) + { + object_[sfLatePaymentFee] = value; + return *this; + } + + /** + * @brief Set sfClosePaymentFee (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setClosePaymentFee(std::decay_t const& value) + { + object_[sfClosePaymentFee] = value; + return *this; + } + + /** + * @brief Set sfOverpaymentFee (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setOverpaymentFee(std::decay_t const& value) + { + object_[sfOverpaymentFee] = value; + return *this; + } + + /** + * @brief Set sfInterestRate (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setInterestRate(std::decay_t const& value) + { + object_[sfInterestRate] = value; + return *this; + } + + /** + * @brief Set sfLateInterestRate (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLateInterestRate(std::decay_t const& value) + { + object_[sfLateInterestRate] = value; + return *this; + } + + /** + * @brief Set sfCloseInterestRate (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setCloseInterestRate(std::decay_t const& value) + { + object_[sfCloseInterestRate] = value; + return *this; + } + + /** + * @brief Set sfOverpaymentInterestRate (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setOverpaymentInterestRate(std::decay_t const& value) + { + object_[sfOverpaymentInterestRate] = value; + return *this; + } + + /** + * @brief Set sfStartDate (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setStartDate(std::decay_t const& value) + { + object_[sfStartDate] = value; + return *this; + } + + /** + * @brief Set sfPaymentInterval (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setPaymentInterval(std::decay_t const& value) + { + object_[sfPaymentInterval] = value; + return *this; + } + + /** + * @brief Set sfGracePeriod (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setGracePeriod(std::decay_t const& value) + { + object_[sfGracePeriod] = value; + return *this; + } + + /** + * @brief Set sfPreviousPaymentDueDate (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setPreviousPaymentDueDate(std::decay_t const& value) + { + object_[sfPreviousPaymentDueDate] = value; + return *this; + } + + /** + * @brief Set sfNextPaymentDueDate (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setNextPaymentDueDate(std::decay_t const& value) + { + object_[sfNextPaymentDueDate] = value; + return *this; + } + + /** + * @brief Set sfPaymentRemaining (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setPaymentRemaining(std::decay_t const& value) + { + object_[sfPaymentRemaining] = value; + return *this; + } + + /** + * @brief Set sfPeriodicPayment (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setPeriodicPayment(std::decay_t const& value) + { + object_[sfPeriodicPayment] = value; + return *this; + } + + /** + * @brief Set sfPrincipalOutstanding (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setPrincipalOutstanding(std::decay_t const& value) + { + object_[sfPrincipalOutstanding] = value; + return *this; + } + + /** + * @brief Set sfTotalValueOutstanding (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setTotalValueOutstanding(std::decay_t const& value) + { + object_[sfTotalValueOutstanding] = value; + return *this; + } + + /** + * @brief Set sfManagementFeeOutstanding (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setManagementFeeOutstanding(std::decay_t const& value) + { + object_[sfManagementFeeOutstanding] = value; + return *this; + } + + /** + * @brief Set sfLoanScale (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBuilder& + setLoanScale(std::decay_t const& value) + { + object_[sfLoanScale] = value; + return *this; + } + + /** + * @brief Build and return the completed Loan wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Loan + build(uint256 const& index) + { + return Loan{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/LoanBroker.h b/include/xrpl/protocol_autogen/ledger_entries/LoanBroker.h new file mode 100644 index 0000000000..99083d6fce --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/LoanBroker.h @@ -0,0 +1,591 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class LoanBrokerBuilder; + +/** + * @brief Ledger Entry: LoanBroker + * + * Type: ltLOAN_BROKER (0x0088) + * RPC Name: loan_broker + * + * Immutable wrapper around SLE providing type-safe field access. + * Use LoanBrokerBuilder to construct new ledger entries. + */ +class LoanBroker : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltLOAN_BROKER; + + /** + * @brief Construct a LoanBroker ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit LoanBroker(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for LoanBroker"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSequence() const + { + return this->sle_->at(sfSequence); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfVaultNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getVaultNode() const + { + return this->sle_->at(sfVaultNode); + } + + /** + * @brief Get sfVaultID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getVaultID() const + { + return this->sle_->at(sfVaultID); + } + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfOwner (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOwner() const + { + return this->sle_->at(sfOwner); + } + + /** + * @brief Get sfLoanSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getLoanSequence() const + { + return this->sle_->at(sfLoanSequence); + } + + /** + * @brief Get sfData (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + return this->sle_->at(sfData); + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->sle_->isFieldPresent(sfData); + } + + /** + * @brief Get sfManagementFeeRate (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getManagementFeeRate() const + { + if (hasManagementFeeRate()) + return this->sle_->at(sfManagementFeeRate); + return std::nullopt; + } + + /** + * @brief Check if sfManagementFeeRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasManagementFeeRate() const + { + return this->sle_->isFieldPresent(sfManagementFeeRate); + } + + /** + * @brief Get sfOwnerCount (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOwnerCount() const + { + if (hasOwnerCount()) + return this->sle_->at(sfOwnerCount); + return std::nullopt; + } + + /** + * @brief Check if sfOwnerCount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOwnerCount() const + { + return this->sle_->isFieldPresent(sfOwnerCount); + } + + /** + * @brief Get sfDebtTotal (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDebtTotal() const + { + if (hasDebtTotal()) + return this->sle_->at(sfDebtTotal); + return std::nullopt; + } + + /** + * @brief Check if sfDebtTotal is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDebtTotal() const + { + return this->sle_->isFieldPresent(sfDebtTotal); + } + + /** + * @brief Get sfDebtMaximum (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDebtMaximum() const + { + if (hasDebtMaximum()) + return this->sle_->at(sfDebtMaximum); + return std::nullopt; + } + + /** + * @brief Check if sfDebtMaximum is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDebtMaximum() const + { + return this->sle_->isFieldPresent(sfDebtMaximum); + } + + /** + * @brief Get sfCoverAvailable (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCoverAvailable() const + { + if (hasCoverAvailable()) + return this->sle_->at(sfCoverAvailable); + return std::nullopt; + } + + /** + * @brief Check if sfCoverAvailable is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCoverAvailable() const + { + return this->sle_->isFieldPresent(sfCoverAvailable); + } + + /** + * @brief Get sfCoverRateMinimum (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCoverRateMinimum() const + { + if (hasCoverRateMinimum()) + return this->sle_->at(sfCoverRateMinimum); + return std::nullopt; + } + + /** + * @brief Check if sfCoverRateMinimum is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCoverRateMinimum() const + { + return this->sle_->isFieldPresent(sfCoverRateMinimum); + } + + /** + * @brief Get sfCoverRateLiquidation (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCoverRateLiquidation() const + { + if (hasCoverRateLiquidation()) + return this->sle_->at(sfCoverRateLiquidation); + return std::nullopt; + } + + /** + * @brief Check if sfCoverRateLiquidation is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCoverRateLiquidation() const + { + return this->sle_->isFieldPresent(sfCoverRateLiquidation); + } +}; + +/** + * @brief Builder for LoanBroker ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class LoanBrokerBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new LoanBrokerBuilder with required fields. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + * @param sequence The sfSequence field value. + * @param ownerNode The sfOwnerNode field value. + * @param vaultNode The sfVaultNode field value. + * @param vaultID The sfVaultID field value. + * @param account The sfAccount field value. + * @param owner The sfOwner field value. + * @param loanSequence The sfLoanSequence field value. + */ + LoanBrokerBuilder(std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq,std::decay_t const& sequence,std::decay_t const& ownerNode,std::decay_t const& vaultNode,std::decay_t const& vaultID,std::decay_t const& account,std::decay_t const& owner,std::decay_t const& loanSequence) + : LedgerEntryBuilderBase(ltLOAN_BROKER) + { + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + setSequence(sequence); + setOwnerNode(ownerNode); + setVaultNode(vaultNode); + setVaultID(vaultID); + setAccount(account); + setOwner(owner); + setLoanSequence(loanSequence); + } + + /** + * @brief Construct a LoanBrokerBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + LoanBrokerBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltLOAN_BROKER) + { + throw std::runtime_error("Invalid ledger entry type for LoanBroker"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfVaultNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setVaultNode(std::decay_t const& value) + { + object_[sfVaultNode] = value; + return *this; + } + + /** + * @brief Set sfVaultID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfOwner (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfLoanSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setLoanSequence(std::decay_t const& value) + { + object_[sfLoanSequence] = value; + return *this; + } + + /** + * @brief Set sfData (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Set sfManagementFeeRate (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setManagementFeeRate(std::decay_t const& value) + { + object_[sfManagementFeeRate] = value; + return *this; + } + + /** + * @brief Set sfOwnerCount (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setOwnerCount(std::decay_t const& value) + { + object_[sfOwnerCount] = value; + return *this; + } + + /** + * @brief Set sfDebtTotal (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setDebtTotal(std::decay_t const& value) + { + object_[sfDebtTotal] = value; + return *this; + } + + /** + * @brief Set sfDebtMaximum (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setDebtMaximum(std::decay_t const& value) + { + object_[sfDebtMaximum] = value; + return *this; + } + + /** + * @brief Set sfCoverAvailable (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setCoverAvailable(std::decay_t const& value) + { + object_[sfCoverAvailable] = value; + return *this; + } + + /** + * @brief Set sfCoverRateMinimum (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setCoverRateMinimum(std::decay_t const& value) + { + object_[sfCoverRateMinimum] = value; + return *this; + } + + /** + * @brief Set sfCoverRateLiquidation (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + LoanBrokerBuilder& + setCoverRateLiquidation(std::decay_t const& value) + { + object_[sfCoverRateLiquidation] = value; + return *this; + } + + /** + * @brief Build and return the completed LoanBroker wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + LoanBroker + build(uint256 const& index) + { + return LoanBroker{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/MPToken.h b/include/xrpl/protocol_autogen/ledger_entries/MPToken.h new file mode 100644 index 0000000000..d11a8effd3 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/MPToken.h @@ -0,0 +1,285 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class MPTokenBuilder; + +/** + * @brief Ledger Entry: MPToken + * + * Type: ltMPTOKEN (0x007f) + * RPC Name: mptoken + * + * Immutable wrapper around SLE providing type-safe field access. + * Use MPTokenBuilder to construct new ledger entries. + */ +class MPToken : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltMPTOKEN; + + /** + * @brief Construct a MPToken ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit MPToken(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for MPToken"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfMPTokenIssuanceID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT192::type::value_type + getMPTokenIssuanceID() const + { + return this->sle_->at(sfMPTokenIssuanceID); + } + + /** + * @brief Get sfMPTAmount (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMPTAmount() const + { + if (hasMPTAmount()) + return this->sle_->at(sfMPTAmount); + return std::nullopt; + } + + /** + * @brief Check if sfMPTAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMPTAmount() const + { + return this->sle_->isFieldPresent(sfMPTAmount); + } + + /** + * @brief Get sfLockedAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLockedAmount() const + { + if (hasLockedAmount()) + return this->sle_->at(sfLockedAmount); + return std::nullopt; + } + + /** + * @brief Check if sfLockedAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLockedAmount() const + { + return this->sle_->isFieldPresent(sfLockedAmount); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for MPToken ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class MPTokenBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new MPTokenBuilder with required fields. + * @param account The sfAccount field value. + * @param mPTokenIssuanceID The sfMPTokenIssuanceID field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + MPTokenBuilder(std::decay_t const& account,std::decay_t const& mPTokenIssuanceID,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltMPTOKEN) + { + setAccount(account); + setMPTokenIssuanceID(mPTokenIssuanceID); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a MPTokenBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + MPTokenBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltMPTOKEN) + { + throw std::runtime_error("Invalid ledger entry type for MPToken"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfMPTokenIssuanceID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenBuilder& + setMPTokenIssuanceID(std::decay_t const& value) + { + object_[sfMPTokenIssuanceID] = value; + return *this; + } + + /** + * @brief Set sfMPTAmount (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + MPTokenBuilder& + setMPTAmount(std::decay_t const& value) + { + object_[sfMPTAmount] = value; + return *this; + } + + /** + * @brief Set sfLockedAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenBuilder& + setLockedAmount(std::decay_t const& value) + { + object_[sfLockedAmount] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed MPToken wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + MPToken + build(uint256 const& index) + { + return MPToken{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/MPTokenIssuance.h b/include/xrpl/protocol_autogen/ledger_entries/MPTokenIssuance.h new file mode 100644 index 0000000000..23b8a05015 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/MPTokenIssuance.h @@ -0,0 +1,484 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class MPTokenIssuanceBuilder; + +/** + * @brief Ledger Entry: MPTokenIssuance + * + * Type: ltMPTOKEN_ISSUANCE (0x007e) + * RPC Name: mpt_issuance + * + * Immutable wrapper around SLE providing type-safe field access. + * Use MPTokenIssuanceBuilder to construct new ledger entries. + */ +class MPTokenIssuance : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltMPTOKEN_ISSUANCE; + + /** + * @brief Construct a MPTokenIssuance ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit MPTokenIssuance(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for MPTokenIssuance"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfIssuer (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getIssuer() const + { + return this->sle_->at(sfIssuer); + } + + /** + * @brief Get sfSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSequence() const + { + return this->sle_->at(sfSequence); + } + + /** + * @brief Get sfTransferFee (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTransferFee() const + { + if (hasTransferFee()) + return this->sle_->at(sfTransferFee); + return std::nullopt; + } + + /** + * @brief Check if sfTransferFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTransferFee() const + { + return this->sle_->isFieldPresent(sfTransferFee); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfAssetScale (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetScale() const + { + if (hasAssetScale()) + return this->sle_->at(sfAssetScale); + return std::nullopt; + } + + /** + * @brief Check if sfAssetScale is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetScale() const + { + return this->sle_->isFieldPresent(sfAssetScale); + } + + /** + * @brief Get sfMaximumAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMaximumAmount() const + { + if (hasMaximumAmount()) + return this->sle_->at(sfMaximumAmount); + return std::nullopt; + } + + /** + * @brief Check if sfMaximumAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMaximumAmount() const + { + return this->sle_->isFieldPresent(sfMaximumAmount); + } + + /** + * @brief Get sfOutstandingAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOutstandingAmount() const + { + return this->sle_->at(sfOutstandingAmount); + } + + /** + * @brief Get sfLockedAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLockedAmount() const + { + if (hasLockedAmount()) + return this->sle_->at(sfLockedAmount); + return std::nullopt; + } + + /** + * @brief Check if sfLockedAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLockedAmount() const + { + return this->sle_->isFieldPresent(sfLockedAmount); + } + + /** + * @brief Get sfMPTokenMetadata (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMPTokenMetadata() const + { + if (hasMPTokenMetadata()) + return this->sle_->at(sfMPTokenMetadata); + return std::nullopt; + } + + /** + * @brief Check if sfMPTokenMetadata is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMPTokenMetadata() const + { + return this->sle_->isFieldPresent(sfMPTokenMetadata); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + return this->sle_->at(sfDomainID); + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->sle_->isFieldPresent(sfDomainID); + } + + /** + * @brief Get sfMutableFlags (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMutableFlags() const + { + if (hasMutableFlags()) + return this->sle_->at(sfMutableFlags); + return std::nullopt; + } + + /** + * @brief Check if sfMutableFlags is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMutableFlags() const + { + return this->sle_->isFieldPresent(sfMutableFlags); + } +}; + +/** + * @brief Builder for MPTokenIssuance ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class MPTokenIssuanceBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new MPTokenIssuanceBuilder with required fields. + * @param issuer The sfIssuer field value. + * @param sequence The sfSequence field value. + * @param ownerNode The sfOwnerNode field value. + * @param outstandingAmount The sfOutstandingAmount field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + MPTokenIssuanceBuilder(std::decay_t const& issuer,std::decay_t const& sequence,std::decay_t const& ownerNode,std::decay_t const& outstandingAmount,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltMPTOKEN_ISSUANCE) + { + setIssuer(issuer); + setSequence(sequence); + setOwnerNode(ownerNode); + setOutstandingAmount(outstandingAmount); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a MPTokenIssuanceBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + MPTokenIssuanceBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltMPTOKEN_ISSUANCE) + { + throw std::runtime_error("Invalid ledger entry type for MPTokenIssuance"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfIssuer (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setIssuer(std::decay_t const& value) + { + object_[sfIssuer] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfTransferFee (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setTransferFee(std::decay_t const& value) + { + object_[sfTransferFee] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfAssetScale (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setAssetScale(std::decay_t const& value) + { + object_[sfAssetScale] = value; + return *this; + } + + /** + * @brief Set sfMaximumAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setMaximumAmount(std::decay_t const& value) + { + object_[sfMaximumAmount] = value; + return *this; + } + + /** + * @brief Set sfOutstandingAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setOutstandingAmount(std::decay_t const& value) + { + object_[sfOutstandingAmount] = value; + return *this; + } + + /** + * @brief Set sfLockedAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setLockedAmount(std::decay_t const& value) + { + object_[sfLockedAmount] = value; + return *this; + } + + /** + * @brief Set sfMPTokenMetadata (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setMPTokenMetadata(std::decay_t const& value) + { + object_[sfMPTokenMetadata] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Set sfMutableFlags (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceBuilder& + setMutableFlags(std::decay_t const& value) + { + object_[sfMutableFlags] = value; + return *this; + } + + /** + * @brief Build and return the completed MPTokenIssuance wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + MPTokenIssuance + build(uint256 const& index) + { + return MPTokenIssuance{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/NFTokenOffer.h b/include/xrpl/protocol_autogen/ledger_entries/NFTokenOffer.h new file mode 100644 index 0000000000..c500cde14c --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/NFTokenOffer.h @@ -0,0 +1,333 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class NFTokenOfferBuilder; + +/** + * @brief Ledger Entry: NFTokenOffer + * + * Type: ltNFTOKEN_OFFER (0x0037) + * RPC Name: nft_offer + * + * Immutable wrapper around SLE providing type-safe field access. + * Use NFTokenOfferBuilder to construct new ledger entries. + */ +class NFTokenOffer : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltNFTOKEN_OFFER; + + /** + * @brief Construct a NFTokenOffer ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit NFTokenOffer(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for NFTokenOffer"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfOwner (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOwner() const + { + return this->sle_->at(sfOwner); + } + + /** + * @brief Get sfNFTokenID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getNFTokenID() const + { + return this->sle_->at(sfNFTokenID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->sle_->at(sfAmount); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfNFTokenOfferNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getNFTokenOfferNode() const + { + return this->sle_->at(sfNFTokenOfferNode); + } + + /** + * @brief Get sfDestination (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestination() const + { + if (hasDestination()) + return this->sle_->at(sfDestination); + return std::nullopt; + } + + /** + * @brief Check if sfDestination is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestination() const + { + return this->sle_->isFieldPresent(sfDestination); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + return this->sle_->at(sfExpiration); + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->sle_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for NFTokenOffer ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class NFTokenOfferBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenOfferBuilder with required fields. + * @param owner The sfOwner field value. + * @param nFTokenID The sfNFTokenID field value. + * @param amount The sfAmount field value. + * @param ownerNode The sfOwnerNode field value. + * @param nFTokenOfferNode The sfNFTokenOfferNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + NFTokenOfferBuilder(std::decay_t const& owner,std::decay_t const& nFTokenID,std::decay_t const& amount,std::decay_t const& ownerNode,std::decay_t const& nFTokenOfferNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltNFTOKEN_OFFER) + { + setOwner(owner); + setNFTokenID(nFTokenID); + setAmount(amount); + setOwnerNode(ownerNode); + setNFTokenOfferNode(nFTokenOfferNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a NFTokenOfferBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + NFTokenOfferBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltNFTOKEN_OFFER) + { + throw std::runtime_error("Invalid ledger entry type for NFTokenOffer"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfOwner (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfNFTokenID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setNFTokenID(std::decay_t const& value) + { + object_[sfNFTokenID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfNFTokenOfferNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setNFTokenOfferNode(std::decay_t const& value) + { + object_[sfNFTokenOfferNode] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenOfferBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed NFTokenOffer wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + NFTokenOffer + build(uint256 const& index) + { + return NFTokenOffer{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/NFTokenPage.h b/include/xrpl/protocol_autogen/ledger_entries/NFTokenPage.h new file mode 100644 index 0000000000..fa8c415495 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/NFTokenPage.h @@ -0,0 +1,238 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class NFTokenPageBuilder; + +/** + * @brief Ledger Entry: NFTokenPage + * + * Type: ltNFTOKEN_PAGE (0x0050) + * RPC Name: nft_page + * + * Immutable wrapper around SLE providing type-safe field access. + * Use NFTokenPageBuilder to construct new ledger entries. + */ +class NFTokenPage : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltNFTOKEN_PAGE; + + /** + * @brief Construct a NFTokenPage ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit NFTokenPage(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for NFTokenPage"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfPreviousPageMin (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousPageMin() const + { + if (hasPreviousPageMin()) + return this->sle_->at(sfPreviousPageMin); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousPageMin is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousPageMin() const + { + return this->sle_->isFieldPresent(sfPreviousPageMin); + } + + /** + * @brief Get sfNextPageMin (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNextPageMin() const + { + if (hasNextPageMin()) + return this->sle_->at(sfNextPageMin); + return std::nullopt; + } + + /** + * @brief Check if sfNextPageMin is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNextPageMin() const + { + return this->sle_->isFieldPresent(sfNextPageMin); + } + + /** + * @brief Get sfNFTokens (soeREQUIRED) + * @note This is an untyped field (unknown). + * @return The field value. + */ + [[nodiscard]] + STArray const& + getNFTokens() const + { + return this->sle_->getFieldArray(sfNFTokens); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for NFTokenPage ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class NFTokenPageBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenPageBuilder with required fields. + * @param nFTokens The sfNFTokens field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + NFTokenPageBuilder(STArray const& nFTokens,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltNFTOKEN_PAGE) + { + setNFTokens(nFTokens); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a NFTokenPageBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + NFTokenPageBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltNFTOKEN_PAGE) + { + throw std::runtime_error("Invalid ledger entry type for NFTokenPage"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfPreviousPageMin (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenPageBuilder& + setPreviousPageMin(std::decay_t const& value) + { + object_[sfPreviousPageMin] = value; + return *this; + } + + /** + * @brief Set sfNextPageMin (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenPageBuilder& + setNextPageMin(std::decay_t const& value) + { + object_[sfNextPageMin] = value; + return *this; + } + + /** + * @brief Set sfNFTokens (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenPageBuilder& + setNFTokens(STArray const& value) + { + object_.setFieldArray(sfNFTokens, value); + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenPageBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenPageBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed NFTokenPage wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + NFTokenPage + build(uint256 const& index) + { + return NFTokenPage{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/NegativeUNL.h b/include/xrpl/protocol_autogen/ledger_entries/NegativeUNL.h new file mode 100644 index 0000000000..8ac2db5683 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/NegativeUNL.h @@ -0,0 +1,271 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class NegativeUNLBuilder; + +/** + * @brief Ledger Entry: NegativeUNL + * + * Type: ltNEGATIVE_UNL (0x004e) + * RPC Name: nunl + * + * Immutable wrapper around SLE providing type-safe field access. + * Use NegativeUNLBuilder to construct new ledger entries. + */ +class NegativeUNL : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltNEGATIVE_UNL; + + /** + * @brief Construct a NegativeUNL ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit NegativeUNL(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for NegativeUNL"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfDisabledValidators (soeOPTIONAL) + * @note This is an untyped field (unknown). + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getDisabledValidators() const + { + if (this->sle_->isFieldPresent(sfDisabledValidators)) + return this->sle_->getFieldArray(sfDisabledValidators); + return std::nullopt; + } + + /** + * @brief Check if sfDisabledValidators is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDisabledValidators() const + { + return this->sle_->isFieldPresent(sfDisabledValidators); + } + + /** + * @brief Get sfValidatorToDisable (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getValidatorToDisable() const + { + if (hasValidatorToDisable()) + return this->sle_->at(sfValidatorToDisable); + return std::nullopt; + } + + /** + * @brief Check if sfValidatorToDisable is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasValidatorToDisable() const + { + return this->sle_->isFieldPresent(sfValidatorToDisable); + } + + /** + * @brief Get sfValidatorToReEnable (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getValidatorToReEnable() const + { + if (hasValidatorToReEnable()) + return this->sle_->at(sfValidatorToReEnable); + return std::nullopt; + } + + /** + * @brief Check if sfValidatorToReEnable is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasValidatorToReEnable() const + { + return this->sle_->isFieldPresent(sfValidatorToReEnable); + } + + /** + * @brief Get sfPreviousTxnID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnID() const + { + if (hasPreviousTxnID()) + return this->sle_->at(sfPreviousTxnID); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnID() const + { + return this->sle_->isFieldPresent(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPreviousTxnLgrSeq() const + { + if (hasPreviousTxnLgrSeq()) + return this->sle_->at(sfPreviousTxnLgrSeq); + return std::nullopt; + } + + /** + * @brief Check if sfPreviousTxnLgrSeq is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPreviousTxnLgrSeq() const + { + return this->sle_->isFieldPresent(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for NegativeUNL ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class NegativeUNLBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new NegativeUNLBuilder with required fields. + */ + NegativeUNLBuilder() + : LedgerEntryBuilderBase(ltNEGATIVE_UNL) + { + } + + /** + * @brief Construct a NegativeUNLBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + NegativeUNLBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltNEGATIVE_UNL) + { + throw std::runtime_error("Invalid ledger entry type for NegativeUNL"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfDisabledValidators (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NegativeUNLBuilder& + setDisabledValidators(STArray const& value) + { + object_.setFieldArray(sfDisabledValidators, value); + return *this; + } + + /** + * @brief Set sfValidatorToDisable (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NegativeUNLBuilder& + setValidatorToDisable(std::decay_t const& value) + { + object_[sfValidatorToDisable] = value; + return *this; + } + + /** + * @brief Set sfValidatorToReEnable (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NegativeUNLBuilder& + setValidatorToReEnable(std::decay_t const& value) + { + object_[sfValidatorToReEnable] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NegativeUNLBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NegativeUNLBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed NegativeUNL wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + NegativeUNL + build(uint256 const& index) + { + return NegativeUNL{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Offer.h b/include/xrpl/protocol_autogen/ledger_entries/Offer.h new file mode 100644 index 0000000000..cccd9183a1 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Offer.h @@ -0,0 +1,417 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class OfferBuilder; + +/** + * @brief Ledger Entry: Offer + * + * Type: ltOFFER (0x006f) + * RPC Name: offer + * + * Immutable wrapper around SLE providing type-safe field access. + * Use OfferBuilder to construct new ledger entries. + */ +class Offer : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltOFFER; + + /** + * @brief Construct a Offer ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Offer(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Offer"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSequence() const + { + return this->sle_->at(sfSequence); + } + + /** + * @brief Get sfTakerPays (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getTakerPays() const + { + return this->sle_->at(sfTakerPays); + } + + /** + * @brief Get sfTakerGets (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getTakerGets() const + { + return this->sle_->at(sfTakerGets); + } + + /** + * @brief Get sfBookDirectory (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getBookDirectory() const + { + return this->sle_->at(sfBookDirectory); + } + + /** + * @brief Get sfBookNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getBookNode() const + { + return this->sle_->at(sfBookNode); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + return this->sle_->at(sfExpiration); + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->sle_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + return this->sle_->at(sfDomainID); + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->sle_->isFieldPresent(sfDomainID); + } + + /** + * @brief Get sfAdditionalBooks (soeOPTIONAL) + * @note This is an untyped field (unknown). + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getAdditionalBooks() const + { + if (this->sle_->isFieldPresent(sfAdditionalBooks)) + return this->sle_->getFieldArray(sfAdditionalBooks); + return std::nullopt; + } + + /** + * @brief Check if sfAdditionalBooks is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAdditionalBooks() const + { + return this->sle_->isFieldPresent(sfAdditionalBooks); + } +}; + +/** + * @brief Builder for Offer ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class OfferBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new OfferBuilder with required fields. + * @param account The sfAccount field value. + * @param sequence The sfSequence field value. + * @param takerPays The sfTakerPays field value. + * @param takerGets The sfTakerGets field value. + * @param bookDirectory The sfBookDirectory field value. + * @param bookNode The sfBookNode field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + OfferBuilder(std::decay_t const& account,std::decay_t const& sequence,std::decay_t const& takerPays,std::decay_t const& takerGets,std::decay_t const& bookDirectory,std::decay_t const& bookNode,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltOFFER) + { + setAccount(account); + setSequence(sequence); + setTakerPays(takerPays); + setTakerGets(takerGets); + setBookDirectory(bookDirectory); + setBookNode(bookNode); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a OfferBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + OfferBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltOFFER) + { + throw std::runtime_error("Invalid ledger entry type for Offer"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfTakerPays (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setTakerPays(std::decay_t const& value) + { + object_[sfTakerPays] = value; + return *this; + } + + /** + * @brief Set sfTakerGets (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setTakerGets(std::decay_t const& value) + { + object_[sfTakerGets] = value; + return *this; + } + + /** + * @brief Set sfBookDirectory (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setBookDirectory(std::decay_t const& value) + { + object_[sfBookDirectory] = value; + return *this; + } + + /** + * @brief Set sfBookNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setBookNode(std::decay_t const& value) + { + object_[sfBookNode] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Set sfAdditionalBooks (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OfferBuilder& + setAdditionalBooks(STArray const& value) + { + object_.setFieldArray(sfAdditionalBooks, value); + return *this; + } + + /** + * @brief Build and return the completed Offer wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Offer + build(uint256 const& index) + { + return Offer{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Oracle.h b/include/xrpl/protocol_autogen/ledger_entries/Oracle.h new file mode 100644 index 0000000000..4da93773e6 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Oracle.h @@ -0,0 +1,358 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class OracleBuilder; + +/** + * @brief Ledger Entry: Oracle + * + * Type: ltORACLE (0x0080) + * RPC Name: oracle + * + * Immutable wrapper around SLE providing type-safe field access. + * Use OracleBuilder to construct new ledger entries. + */ +class Oracle : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltORACLE; + + /** + * @brief Construct a Oracle ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Oracle(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Oracle"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfOwner (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOwner() const + { + return this->sle_->at(sfOwner); + } + + /** + * @brief Get sfOracleDocumentID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOracleDocumentID() const + { + if (hasOracleDocumentID()) + return this->sle_->at(sfOracleDocumentID); + return std::nullopt; + } + + /** + * @brief Check if sfOracleDocumentID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOracleDocumentID() const + { + return this->sle_->isFieldPresent(sfOracleDocumentID); + } + + /** + * @brief Get sfProvider (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getProvider() const + { + return this->sle_->at(sfProvider); + } + + /** + * @brief Get sfPriceDataSeries (soeREQUIRED) + * @note This is an untyped field (unknown). + * @return The field value. + */ + [[nodiscard]] + STArray const& + getPriceDataSeries() const + { + return this->sle_->getFieldArray(sfPriceDataSeries); + } + + /** + * @brief Get sfAssetClass (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getAssetClass() const + { + return this->sle_->at(sfAssetClass); + } + + /** + * @brief Get sfLastUpdateTime (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getLastUpdateTime() const + { + return this->sle_->at(sfLastUpdateTime); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + return this->sle_->at(sfURI); + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->sle_->isFieldPresent(sfURI); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for Oracle ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class OracleBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new OracleBuilder with required fields. + * @param owner The sfOwner field value. + * @param provider The sfProvider field value. + * @param priceDataSeries The sfPriceDataSeries field value. + * @param assetClass The sfAssetClass field value. + * @param lastUpdateTime The sfLastUpdateTime field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + OracleBuilder(std::decay_t const& owner,std::decay_t const& provider,STArray const& priceDataSeries,std::decay_t const& assetClass,std::decay_t const& lastUpdateTime,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltORACLE) + { + setOwner(owner); + setProvider(provider); + setPriceDataSeries(priceDataSeries); + setAssetClass(assetClass); + setLastUpdateTime(lastUpdateTime); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a OracleBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + OracleBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltORACLE) + { + throw std::runtime_error("Invalid ledger entry type for Oracle"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfOwner (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfOracleDocumentID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setOracleDocumentID(std::decay_t const& value) + { + object_[sfOracleDocumentID] = value; + return *this; + } + + /** + * @brief Set sfProvider (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setProvider(std::decay_t const& value) + { + object_[sfProvider] = value; + return *this; + } + + /** + * @brief Set sfPriceDataSeries (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setPriceDataSeries(STArray const& value) + { + object_.setFieldArray(sfPriceDataSeries, value); + return *this; + } + + /** + * @brief Set sfAssetClass (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setAssetClass(std::decay_t const& value) + { + object_[sfAssetClass] = value; + return *this; + } + + /** + * @brief Set sfLastUpdateTime (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setLastUpdateTime(std::decay_t const& value) + { + object_[sfLastUpdateTime] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed Oracle wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Oracle + build(uint256 const& index) + { + return Oracle{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/PayChannel.h b/include/xrpl/protocol_autogen/ledger_entries/PayChannel.h new file mode 100644 index 0000000000..50245bc0d8 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/PayChannel.h @@ -0,0 +1,521 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class PayChannelBuilder; + +/** + * @brief Ledger Entry: PayChannel + * + * Type: ltPAYCHAN (0x0078) + * RPC Name: payment_channel + * + * Immutable wrapper around SLE providing type-safe field access. + * Use PayChannelBuilder to construct new ledger entries. + */ +class PayChannel : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltPAYCHAN; + + /** + * @brief Construct a PayChannel ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit PayChannel(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for PayChannel"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->sle_->at(sfDestination); + } + + /** + * @brief Get sfSequence (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSequence() const + { + if (hasSequence()) + return this->sle_->at(sfSequence); + return std::nullopt; + } + + /** + * @brief Check if sfSequence is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSequence() const + { + return this->sle_->isFieldPresent(sfSequence); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->sle_->at(sfAmount); + } + + /** + * @brief Get sfBalance (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getBalance() const + { + return this->sle_->at(sfBalance); + } + + /** + * @brief Get sfPublicKey (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getPublicKey() const + { + return this->sle_->at(sfPublicKey); + } + + /** + * @brief Get sfSettleDelay (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSettleDelay() const + { + return this->sle_->at(sfSettleDelay); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + return this->sle_->at(sfExpiration); + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->sle_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfCancelAfter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCancelAfter() const + { + if (hasCancelAfter()) + return this->sle_->at(sfCancelAfter); + return std::nullopt; + } + + /** + * @brief Check if sfCancelAfter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCancelAfter() const + { + return this->sle_->isFieldPresent(sfCancelAfter); + } + + /** + * @brief Get sfSourceTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSourceTag() const + { + if (hasSourceTag()) + return this->sle_->at(sfSourceTag); + return std::nullopt; + } + + /** + * @brief Check if sfSourceTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSourceTag() const + { + return this->sle_->isFieldPresent(sfSourceTag); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + return this->sle_->at(sfDestinationTag); + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->sle_->isFieldPresent(sfDestinationTag); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfDestinationNode (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationNode() const + { + if (hasDestinationNode()) + return this->sle_->at(sfDestinationNode); + return std::nullopt; + } + + /** + * @brief Check if sfDestinationNode is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationNode() const + { + return this->sle_->isFieldPresent(sfDestinationNode); + } +}; + +/** + * @brief Builder for PayChannel ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class PayChannelBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new PayChannelBuilder with required fields. + * @param account The sfAccount field value. + * @param destination The sfDestination field value. + * @param amount The sfAmount field value. + * @param balance The sfBalance field value. + * @param publicKey The sfPublicKey field value. + * @param settleDelay The sfSettleDelay field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + PayChannelBuilder(std::decay_t const& account,std::decay_t const& destination,std::decay_t const& amount,std::decay_t const& balance,std::decay_t const& publicKey,std::decay_t const& settleDelay,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltPAYCHAN) + { + setAccount(account); + setDestination(destination); + setAmount(amount); + setBalance(balance); + setPublicKey(publicKey); + setSettleDelay(settleDelay); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a PayChannelBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + PayChannelBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltPAYCHAN) + { + throw std::runtime_error("Invalid ledger entry type for PayChannel"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfBalance (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setBalance(std::decay_t const& value) + { + object_[sfBalance] = value; + return *this; + } + + /** + * @brief Set sfPublicKey (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setPublicKey(std::decay_t const& value) + { + object_[sfPublicKey] = value; + return *this; + } + + /** + * @brief Set sfSettleDelay (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setSettleDelay(std::decay_t const& value) + { + object_[sfSettleDelay] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfCancelAfter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setCancelAfter(std::decay_t const& value) + { + object_[sfCancelAfter] = value; + return *this; + } + + /** + * @brief Set sfSourceTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setSourceTag(std::decay_t const& value) + { + object_[sfSourceTag] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfDestinationNode (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PayChannelBuilder& + setDestinationNode(std::decay_t const& value) + { + object_[sfDestinationNode] = value; + return *this; + } + + /** + * @brief Build and return the completed PayChannel wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + PayChannel + build(uint256 const& index) + { + return PayChannel{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/PermissionedDomain.h b/include/xrpl/protocol_autogen/ledger_entries/PermissionedDomain.h new file mode 100644 index 0000000000..630f46517f --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/PermissionedDomain.h @@ -0,0 +1,240 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class PermissionedDomainBuilder; + +/** + * @brief Ledger Entry: PermissionedDomain + * + * Type: ltPERMISSIONED_DOMAIN (0x0082) + * RPC Name: permissioned_domain + * + * Immutable wrapper around SLE providing type-safe field access. + * Use PermissionedDomainBuilder to construct new ledger entries. + */ +class PermissionedDomain : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltPERMISSIONED_DOMAIN; + + /** + * @brief Construct a PermissionedDomain ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit PermissionedDomain(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for PermissionedDomain"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfOwner (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOwner() const + { + return this->sle_->at(sfOwner); + } + + /** + * @brief Get sfSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSequence() const + { + return this->sle_->at(sfSequence); + } + + /** + * @brief Get sfAcceptedCredentials (soeREQUIRED) + * @note This is an untyped field (unknown). + * @return The field value. + */ + [[nodiscard]] + STArray const& + getAcceptedCredentials() const + { + return this->sle_->getFieldArray(sfAcceptedCredentials); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for PermissionedDomain ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class PermissionedDomainBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new PermissionedDomainBuilder with required fields. + * @param owner The sfOwner field value. + * @param sequence The sfSequence field value. + * @param acceptedCredentials The sfAcceptedCredentials field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + PermissionedDomainBuilder(std::decay_t const& owner,std::decay_t const& sequence,STArray const& acceptedCredentials,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltPERMISSIONED_DOMAIN) + { + setOwner(owner); + setSequence(sequence); + setAcceptedCredentials(acceptedCredentials); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a PermissionedDomainBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + PermissionedDomainBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltPERMISSIONED_DOMAIN) + { + throw std::runtime_error("Invalid ledger entry type for PermissionedDomain"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfOwner (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfAcceptedCredentials (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainBuilder& + setAcceptedCredentials(STArray const& value) + { + object_.setFieldArray(sfAcceptedCredentials, value); + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed PermissionedDomain wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + PermissionedDomain + build(uint256 const& index) + { + return PermissionedDomain{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/RippleState.h b/include/xrpl/protocol_autogen/ledger_entries/RippleState.h new file mode 100644 index 0000000000..993496d38f --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/RippleState.h @@ -0,0 +1,425 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class RippleStateBuilder; + +/** + * @brief Ledger Entry: RippleState + * + * Type: ltRIPPLE_STATE (0x0072) + * RPC Name: state + * + * Immutable wrapper around SLE providing type-safe field access. + * Use RippleStateBuilder to construct new ledger entries. + */ +class RippleState : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltRIPPLE_STATE; + + /** + * @brief Construct a RippleState ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit RippleState(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for RippleState"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfBalance (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getBalance() const + { + return this->sle_->at(sfBalance); + } + + /** + * @brief Get sfLowLimit (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getLowLimit() const + { + return this->sle_->at(sfLowLimit); + } + + /** + * @brief Get sfHighLimit (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getHighLimit() const + { + return this->sle_->at(sfHighLimit); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfLowNode (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLowNode() const + { + if (hasLowNode()) + return this->sle_->at(sfLowNode); + return std::nullopt; + } + + /** + * @brief Check if sfLowNode is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLowNode() const + { + return this->sle_->isFieldPresent(sfLowNode); + } + + /** + * @brief Get sfLowQualityIn (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLowQualityIn() const + { + if (hasLowQualityIn()) + return this->sle_->at(sfLowQualityIn); + return std::nullopt; + } + + /** + * @brief Check if sfLowQualityIn is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLowQualityIn() const + { + return this->sle_->isFieldPresent(sfLowQualityIn); + } + + /** + * @brief Get sfLowQualityOut (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLowQualityOut() const + { + if (hasLowQualityOut()) + return this->sle_->at(sfLowQualityOut); + return std::nullopt; + } + + /** + * @brief Check if sfLowQualityOut is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLowQualityOut() const + { + return this->sle_->isFieldPresent(sfLowQualityOut); + } + + /** + * @brief Get sfHighNode (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getHighNode() const + { + if (hasHighNode()) + return this->sle_->at(sfHighNode); + return std::nullopt; + } + + /** + * @brief Check if sfHighNode is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasHighNode() const + { + return this->sle_->isFieldPresent(sfHighNode); + } + + /** + * @brief Get sfHighQualityIn (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getHighQualityIn() const + { + if (hasHighQualityIn()) + return this->sle_->at(sfHighQualityIn); + return std::nullopt; + } + + /** + * @brief Check if sfHighQualityIn is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasHighQualityIn() const + { + return this->sle_->isFieldPresent(sfHighQualityIn); + } + + /** + * @brief Get sfHighQualityOut (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getHighQualityOut() const + { + if (hasHighQualityOut()) + return this->sle_->at(sfHighQualityOut); + return std::nullopt; + } + + /** + * @brief Check if sfHighQualityOut is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasHighQualityOut() const + { + return this->sle_->isFieldPresent(sfHighQualityOut); + } +}; + +/** + * @brief Builder for RippleState ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class RippleStateBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new RippleStateBuilder with required fields. + * @param balance The sfBalance field value. + * @param lowLimit The sfLowLimit field value. + * @param highLimit The sfHighLimit field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + RippleStateBuilder(std::decay_t const& balance,std::decay_t const& lowLimit,std::decay_t const& highLimit,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltRIPPLE_STATE) + { + setBalance(balance); + setLowLimit(lowLimit); + setHighLimit(highLimit); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a RippleStateBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + RippleStateBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltRIPPLE_STATE) + { + throw std::runtime_error("Invalid ledger entry type for RippleState"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfBalance (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setBalance(std::decay_t const& value) + { + object_[sfBalance] = value; + return *this; + } + + /** + * @brief Set sfLowLimit (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setLowLimit(std::decay_t const& value) + { + object_[sfLowLimit] = value; + return *this; + } + + /** + * @brief Set sfHighLimit (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setHighLimit(std::decay_t const& value) + { + object_[sfHighLimit] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfLowNode (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setLowNode(std::decay_t const& value) + { + object_[sfLowNode] = value; + return *this; + } + + /** + * @brief Set sfLowQualityIn (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setLowQualityIn(std::decay_t const& value) + { + object_[sfLowQualityIn] = value; + return *this; + } + + /** + * @brief Set sfLowQualityOut (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setLowQualityOut(std::decay_t const& value) + { + object_[sfLowQualityOut] = value; + return *this; + } + + /** + * @brief Set sfHighNode (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setHighNode(std::decay_t const& value) + { + object_[sfHighNode] = value; + return *this; + } + + /** + * @brief Set sfHighQualityIn (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setHighQualityIn(std::decay_t const& value) + { + object_[sfHighQualityIn] = value; + return *this; + } + + /** + * @brief Set sfHighQualityOut (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + RippleStateBuilder& + setHighQualityOut(std::decay_t const& value) + { + object_[sfHighQualityOut] = value; + return *this; + } + + /** + * @brief Build and return the completed RippleState wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + RippleState + build(uint256 const& index) + { + return RippleState{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/SignerList.h b/include/xrpl/protocol_autogen/ledger_entries/SignerList.h new file mode 100644 index 0000000000..57d706bc28 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/SignerList.h @@ -0,0 +1,275 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class SignerListBuilder; + +/** + * @brief Ledger Entry: SignerList + * + * Type: ltSIGNER_LIST (0x0053) + * RPC Name: signer_list + * + * Immutable wrapper around SLE providing type-safe field access. + * Use SignerListBuilder to construct new ledger entries. + */ +class SignerList : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltSIGNER_LIST; + + /** + * @brief Construct a SignerList ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit SignerList(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for SignerList"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfOwner (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOwner() const + { + if (hasOwner()) + return this->sle_->at(sfOwner); + return std::nullopt; + } + + /** + * @brief Check if sfOwner is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOwner() const + { + return this->sle_->isFieldPresent(sfOwner); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfSignerQuorum (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSignerQuorum() const + { + return this->sle_->at(sfSignerQuorum); + } + + /** + * @brief Get sfSignerEntries (soeREQUIRED) + * @note This is an untyped field (unknown). + * @return The field value. + */ + [[nodiscard]] + STArray const& + getSignerEntries() const + { + return this->sle_->getFieldArray(sfSignerEntries); + } + + /** + * @brief Get sfSignerListID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSignerListID() const + { + return this->sle_->at(sfSignerListID); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for SignerList ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class SignerListBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new SignerListBuilder with required fields. + * @param ownerNode The sfOwnerNode field value. + * @param signerQuorum The sfSignerQuorum field value. + * @param signerEntries The sfSignerEntries field value. + * @param signerListID The sfSignerListID field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + SignerListBuilder(std::decay_t const& ownerNode,std::decay_t const& signerQuorum,STArray const& signerEntries,std::decay_t const& signerListID,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltSIGNER_LIST) + { + setOwnerNode(ownerNode); + setSignerQuorum(signerQuorum); + setSignerEntries(signerEntries); + setSignerListID(signerListID); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a SignerListBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + SignerListBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltSIGNER_LIST) + { + throw std::runtime_error("Invalid ledger entry type for SignerList"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfOwner (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SignerListBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + SignerListBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfSignerQuorum (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + SignerListBuilder& + setSignerQuorum(std::decay_t const& value) + { + object_[sfSignerQuorum] = value; + return *this; + } + + /** + * @brief Set sfSignerEntries (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + SignerListBuilder& + setSignerEntries(STArray const& value) + { + object_.setFieldArray(sfSignerEntries, value); + return *this; + } + + /** + * @brief Set sfSignerListID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + SignerListBuilder& + setSignerListID(std::decay_t const& value) + { + object_[sfSignerListID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + SignerListBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + SignerListBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed SignerList wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + SignerList + build(uint256 const& index) + { + return SignerList{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Ticket.h b/include/xrpl/protocol_autogen/ledger_entries/Ticket.h new file mode 100644 index 0000000000..f13e8a398f --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Ticket.h @@ -0,0 +1,215 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class TicketBuilder; + +/** + * @brief Ledger Entry: Ticket + * + * Type: ltTICKET (0x0054) + * RPC Name: ticket + * + * Immutable wrapper around SLE providing type-safe field access. + * Use TicketBuilder to construct new ledger entries. + */ +class Ticket : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltTICKET; + + /** + * @brief Construct a Ticket ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Ticket(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Ticket"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfTicketSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getTicketSequence() const + { + return this->sle_->at(sfTicketSequence); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for Ticket ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class TicketBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new TicketBuilder with required fields. + * @param account The sfAccount field value. + * @param ownerNode The sfOwnerNode field value. + * @param ticketSequence The sfTicketSequence field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + TicketBuilder(std::decay_t const& account,std::decay_t const& ownerNode,std::decay_t const& ticketSequence,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltTICKET) + { + setAccount(account); + setOwnerNode(ownerNode); + setTicketSequence(ticketSequence); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a TicketBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + TicketBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltTICKET) + { + throw std::runtime_error("Invalid ledger entry type for Ticket"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + TicketBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + TicketBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfTicketSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + TicketBuilder& + setTicketSequence(std::decay_t const& value) + { + object_[sfTicketSequence] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + TicketBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + TicketBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed Ticket wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Ticket + build(uint256 const& index) + { + return Ticket{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/Vault.h b/include/xrpl/protocol_autogen/ledger_entries/Vault.h new file mode 100644 index 0000000000..e24e73fab3 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/Vault.h @@ -0,0 +1,521 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class VaultBuilder; + +/** + * @brief Ledger Entry: Vault + * + * Type: ltVAULT (0x0084) + * RPC Name: vault + * + * Immutable wrapper around SLE providing type-safe field access. + * Use VaultBuilder to construct new ledger entries. + */ +class Vault : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltVAULT; + + /** + * @brief Construct a Vault ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit Vault(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for Vault"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } + + /** + * @brief Get sfSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSequence() const + { + return this->sle_->at(sfSequence); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfOwner (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOwner() const + { + return this->sle_->at(sfOwner); + } + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfData (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + return this->sle_->at(sfData); + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->sle_->isFieldPresent(sfData); + } + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->sle_->at(sfAsset); + } + + /** + * @brief Get sfAssetsTotal (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetsTotal() const + { + if (hasAssetsTotal()) + return this->sle_->at(sfAssetsTotal); + return std::nullopt; + } + + /** + * @brief Check if sfAssetsTotal is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetsTotal() const + { + return this->sle_->isFieldPresent(sfAssetsTotal); + } + + /** + * @brief Get sfAssetsAvailable (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetsAvailable() const + { + if (hasAssetsAvailable()) + return this->sle_->at(sfAssetsAvailable); + return std::nullopt; + } + + /** + * @brief Check if sfAssetsAvailable is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetsAvailable() const + { + return this->sle_->isFieldPresent(sfAssetsAvailable); + } + + /** + * @brief Get sfAssetsMaximum (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetsMaximum() const + { + if (hasAssetsMaximum()) + return this->sle_->at(sfAssetsMaximum); + return std::nullopt; + } + + /** + * @brief Check if sfAssetsMaximum is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetsMaximum() const + { + return this->sle_->isFieldPresent(sfAssetsMaximum); + } + + /** + * @brief Get sfLossUnrealized (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLossUnrealized() const + { + if (hasLossUnrealized()) + return this->sle_->at(sfLossUnrealized); + return std::nullopt; + } + + /** + * @brief Check if sfLossUnrealized is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLossUnrealized() const + { + return this->sle_->isFieldPresent(sfLossUnrealized); + } + + /** + * @brief Get sfShareMPTID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT192::type::value_type + getShareMPTID() const + { + return this->sle_->at(sfShareMPTID); + } + + /** + * @brief Get sfWithdrawalPolicy (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT8::type::value_type + getWithdrawalPolicy() const + { + return this->sle_->at(sfWithdrawalPolicy); + } + + /** + * @brief Get sfScale (soeDEFAULT) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getScale() const + { + if (hasScale()) + return this->sle_->at(sfScale); + return std::nullopt; + } + + /** + * @brief Check if sfScale is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasScale() const + { + return this->sle_->isFieldPresent(sfScale); + } +}; + +/** + * @brief Builder for Vault ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class VaultBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new VaultBuilder with required fields. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + * @param sequence The sfSequence field value. + * @param ownerNode The sfOwnerNode field value. + * @param owner The sfOwner field value. + * @param account The sfAccount field value. + * @param asset The sfAsset field value. + * @param shareMPTID The sfShareMPTID field value. + * @param withdrawalPolicy The sfWithdrawalPolicy field value. + */ + VaultBuilder(std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq,std::decay_t const& sequence,std::decay_t const& ownerNode,std::decay_t const& owner,std::decay_t const& account,std::decay_t const& asset,std::decay_t const& shareMPTID,std::decay_t const& withdrawalPolicy) + : LedgerEntryBuilderBase(ltVAULT) + { + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + setSequence(sequence); + setOwnerNode(ownerNode); + setOwner(owner); + setAccount(account); + setAsset(asset); + setShareMPTID(shareMPTID); + setWithdrawalPolicy(withdrawalPolicy); + } + + /** + * @brief Construct a VaultBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + VaultBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltVAULT) + { + throw std::runtime_error("Invalid ledger entry type for Vault"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Set sfSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setSequence(std::decay_t const& value) + { + object_[sfSequence] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfOwner (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfData (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAssetsTotal (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setAssetsTotal(std::decay_t const& value) + { + object_[sfAssetsTotal] = value; + return *this; + } + + /** + * @brief Set sfAssetsAvailable (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setAssetsAvailable(std::decay_t const& value) + { + object_[sfAssetsAvailable] = value; + return *this; + } + + /** + * @brief Set sfAssetsMaximum (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setAssetsMaximum(std::decay_t const& value) + { + object_[sfAssetsMaximum] = value; + return *this; + } + + /** + * @brief Set sfLossUnrealized (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setLossUnrealized(std::decay_t const& value) + { + object_[sfLossUnrealized] = value; + return *this; + } + + /** + * @brief Set sfShareMPTID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setShareMPTID(std::decay_t const& value) + { + object_[sfShareMPTID] = value; + return *this; + } + + /** + * @brief Set sfWithdrawalPolicy (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setWithdrawalPolicy(std::decay_t const& value) + { + object_[sfWithdrawalPolicy] = value; + return *this; + } + + /** + * @brief Set sfScale (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + VaultBuilder& + setScale(std::decay_t const& value) + { + object_[sfScale] = value; + return *this; + } + + /** + * @brief Build and return the completed Vault wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + Vault + build(uint256 const& index) + { + return Vault{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/XChainOwnedClaimID.h b/include/xrpl/protocol_autogen/ledger_entries/XChainOwnedClaimID.h new file mode 100644 index 0000000000..3309228951 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/XChainOwnedClaimID.h @@ -0,0 +1,312 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class XChainOwnedClaimIDBuilder; + +/** + * @brief Ledger Entry: XChainOwnedClaimID + * + * Type: ltXCHAIN_OWNED_CLAIM_ID (0x0071) + * RPC Name: xchain_owned_claim_id + * + * Immutable wrapper around SLE providing type-safe field access. + * Use XChainOwnedClaimIDBuilder to construct new ledger entries. + */ +class XChainOwnedClaimID : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltXCHAIN_OWNED_CLAIM_ID; + + /** + * @brief Construct a XChainOwnedClaimID ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit XChainOwnedClaimID(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for XChainOwnedClaimID"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->sle_->at(sfXChainBridge); + } + + /** + * @brief Get sfXChainClaimID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainClaimID() const + { + return this->sle_->at(sfXChainClaimID); + } + + /** + * @brief Get sfOtherChainSource (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOtherChainSource() const + { + return this->sle_->at(sfOtherChainSource); + } + + /** + * @brief Get sfXChainClaimAttestations (soeREQUIRED) + * @note This is an untyped field (unknown). + * @return The field value. + */ + [[nodiscard]] + STArray const& + getXChainClaimAttestations() const + { + return this->sle_->getFieldArray(sfXChainClaimAttestations); + } + + /** + * @brief Get sfSignatureReward (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSignatureReward() const + { + return this->sle_->at(sfSignatureReward); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for XChainOwnedClaimID ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class XChainOwnedClaimIDBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new XChainOwnedClaimIDBuilder with required fields. + * @param account The sfAccount field value. + * @param xChainBridge The sfXChainBridge field value. + * @param xChainClaimID The sfXChainClaimID field value. + * @param otherChainSource The sfOtherChainSource field value. + * @param xChainClaimAttestations The sfXChainClaimAttestations field value. + * @param signatureReward The sfSignatureReward field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + XChainOwnedClaimIDBuilder(std::decay_t const& account,std::decay_t const& xChainBridge,std::decay_t const& xChainClaimID,std::decay_t const& otherChainSource,STArray const& xChainClaimAttestations,std::decay_t const& signatureReward,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltXCHAIN_OWNED_CLAIM_ID) + { + setAccount(account); + setXChainBridge(xChainBridge); + setXChainClaimID(xChainClaimID); + setOtherChainSource(otherChainSource); + setXChainClaimAttestations(xChainClaimAttestations); + setSignatureReward(signatureReward); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a XChainOwnedClaimIDBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + XChainOwnedClaimIDBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltXCHAIN_OWNED_CLAIM_ID) + { + throw std::runtime_error("Invalid ledger entry type for XChainOwnedClaimID"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfXChainClaimID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setXChainClaimID(std::decay_t const& value) + { + object_[sfXChainClaimID] = value; + return *this; + } + + /** + * @brief Set sfOtherChainSource (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setOtherChainSource(std::decay_t const& value) + { + object_[sfOtherChainSource] = value; + return *this; + } + + /** + * @brief Set sfXChainClaimAttestations (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setXChainClaimAttestations(STArray const& value) + { + object_.setFieldArray(sfXChainClaimAttestations, value); + return *this; + } + + /** + * @brief Set sfSignatureReward (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setSignatureReward(std::decay_t const& value) + { + object_[sfSignatureReward] = value; + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedClaimIDBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed XChainOwnedClaimID wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + XChainOwnedClaimID + build(uint256 const& index) + { + return XChainOwnedClaimID{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimID.h b/include/xrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimID.h new file mode 100644 index 0000000000..5415d52884 --- /dev/null +++ b/include/xrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimID.h @@ -0,0 +1,264 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class XChainOwnedCreateAccountClaimIDBuilder; + +/** + * @brief Ledger Entry: XChainOwnedCreateAccountClaimID + * + * Type: ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID (0x0074) + * RPC Name: xchain_owned_create_account_claim_id + * + * Immutable wrapper around SLE providing type-safe field access. + * Use XChainOwnedCreateAccountClaimIDBuilder to construct new ledger entries. + */ +class XChainOwnedCreateAccountClaimID : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID; + + /** + * @brief Construct a XChainOwnedCreateAccountClaimID ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit XChainOwnedCreateAccountClaimID(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for XChainOwnedCreateAccountClaimID"); + } + } + + // Ledger entry-specific field getters + + /** + * @brief Get sfAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAccount() const + { + return this->sle_->at(sfAccount); + } + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->sle_->at(sfXChainBridge); + } + + /** + * @brief Get sfXChainAccountCreateCount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainAccountCreateCount() const + { + return this->sle_->at(sfXChainAccountCreateCount); + } + + /** + * @brief Get sfXChainCreateAccountAttestations (soeREQUIRED) + * @note This is an untyped field (unknown). + * @return The field value. + */ + [[nodiscard]] + STArray const& + getXChainCreateAccountAttestations() const + { + return this->sle_->getFieldArray(sfXChainCreateAccountAttestations); + } + + /** + * @brief Get sfOwnerNode (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getOwnerNode() const + { + return this->sle_->at(sfOwnerNode); + } + + /** + * @brief Get sfPreviousTxnID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getPreviousTxnID() const + { + return this->sle_->at(sfPreviousTxnID); + } + + /** + * @brief Get sfPreviousTxnLgrSeq (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getPreviousTxnLgrSeq() const + { + return this->sle_->at(sfPreviousTxnLgrSeq); + } +}; + +/** + * @brief Builder for XChainOwnedCreateAccountClaimID ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class XChainOwnedCreateAccountClaimIDBuilder : public LedgerEntryBuilderBase +{ +public: + /** + * @brief Construct a new XChainOwnedCreateAccountClaimIDBuilder with required fields. + * @param account The sfAccount field value. + * @param xChainBridge The sfXChainBridge field value. + * @param xChainAccountCreateCount The sfXChainAccountCreateCount field value. + * @param xChainCreateAccountAttestations The sfXChainCreateAccountAttestations field value. + * @param ownerNode The sfOwnerNode field value. + * @param previousTxnID The sfPreviousTxnID field value. + * @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value. + */ + XChainOwnedCreateAccountClaimIDBuilder(std::decay_t const& account,std::decay_t const& xChainBridge,std::decay_t const& xChainAccountCreateCount,STArray const& xChainCreateAccountAttestations,std::decay_t const& ownerNode,std::decay_t const& previousTxnID,std::decay_t const& previousTxnLgrSeq) + : LedgerEntryBuilderBase(ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID) + { + setAccount(account); + setXChainBridge(xChainBridge); + setXChainAccountCreateCount(xChainAccountCreateCount); + setXChainCreateAccountAttestations(xChainCreateAccountAttestations); + setOwnerNode(ownerNode); + setPreviousTxnID(previousTxnID); + setPreviousTxnLgrSeq(previousTxnLgrSeq); + } + + /** + * @brief Construct a XChainOwnedCreateAccountClaimIDBuilder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + XChainOwnedCreateAccountClaimIDBuilder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID) + { + throw std::runtime_error("Invalid ledger entry type for XChainOwnedCreateAccountClaimID"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ + + /** + * @brief Set sfAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedCreateAccountClaimIDBuilder& + setAccount(std::decay_t const& value) + { + object_[sfAccount] = value; + return *this; + } + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedCreateAccountClaimIDBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfXChainAccountCreateCount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedCreateAccountClaimIDBuilder& + setXChainAccountCreateCount(std::decay_t const& value) + { + object_[sfXChainAccountCreateCount] = value; + return *this; + } + + /** + * @brief Set sfXChainCreateAccountAttestations (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedCreateAccountClaimIDBuilder& + setXChainCreateAccountAttestations(STArray const& value) + { + object_.setFieldArray(sfXChainCreateAccountAttestations, value); + return *this; + } + + /** + * @brief Set sfOwnerNode (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedCreateAccountClaimIDBuilder& + setOwnerNode(std::decay_t const& value) + { + object_[sfOwnerNode] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedCreateAccountClaimIDBuilder& + setPreviousTxnID(std::decay_t const& value) + { + object_[sfPreviousTxnID] = value; + return *this; + } + + /** + * @brief Set sfPreviousTxnLgrSeq (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainOwnedCreateAccountClaimIDBuilder& + setPreviousTxnLgrSeq(std::decay_t const& value) + { + object_[sfPreviousTxnLgrSeq] = value; + return *this; + } + + /** + * @brief Build and return the completed XChainOwnedCreateAccountClaimID wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + XChainOwnedCreateAccountClaimID + build(uint256 const& index) + { + return XChainOwnedCreateAccountClaimID{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/include/xrpl/protocol_autogen/transactions/AMMBid.h b/include/xrpl/protocol_autogen/transactions/AMMBid.h new file mode 100644 index 0000000000..d3f8cba8f7 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AMMBid.h @@ -0,0 +1,262 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AMMBidBuilder; + +/** + * @brief Transaction: AMMBid + * + * Type: ttAMM_BID (39) + * Delegable: Delegation::delegable + * Amendment: featureAMM + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AMMBidBuilder to construct new transactions. + */ +class AMMBid : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMM_BID; + + /** + * @brief Construct a AMMBid transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AMMBid(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AMMBid"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->tx_->at(sfAsset); + } + + /** + * @brief Get sfAsset2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset2() const + { + return this->tx_->at(sfAsset2); + } + + /** + * @brief Get sfBidMin (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBidMin() const + { + if (hasBidMin()) + { + return this->tx_->at(sfBidMin); + } + return std::nullopt; + } + + /** + * @brief Check if sfBidMin is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBidMin() const + { + return this->tx_->isFieldPresent(sfBidMin); + } + + /** + * @brief Get sfBidMax (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBidMax() const + { + if (hasBidMax()) + { + return this->tx_->at(sfBidMax); + } + return std::nullopt; + } + + /** + * @brief Check if sfBidMax is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBidMax() const + { + return this->tx_->isFieldPresent(sfBidMax); + } + /** + * @brief Get sfAuthAccounts (soeOPTIONAL) + * @note This is an untyped field. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getAuthAccounts() const + { + if (this->tx_->isFieldPresent(sfAuthAccounts)) + return this->tx_->getFieldArray(sfAuthAccounts); + return std::nullopt; + } + + /** + * @brief Check if sfAuthAccounts is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAuthAccounts() const + { + return this->tx_->isFieldPresent(sfAuthAccounts); + } +}; + +/** + * @brief Builder for AMMBid transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AMMBidBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AMMBidBuilder with required fields. + * @param account The account initiating the transaction. + * @param asset The sfAsset field value. + * @param asset2 The sfAsset2 field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AMMBidBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& asset, std::decay_t const& asset2, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMM_BID, account, sequence, fee) + { + setAsset(asset); + setAsset2(asset2); + } + + /** + * @brief Construct a AMMBidBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AMMBidBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMM_BID) + { + throw std::runtime_error("Invalid transaction type for AMMBidBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMBidBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAsset2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMBidBuilder& + setAsset2(std::decay_t const& value) + { + object_[sfAsset2] = STIssue(sfAsset2, value); + return *this; + } + + /** + * @brief Set sfBidMin (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMBidBuilder& + setBidMin(std::decay_t const& value) + { + object_[sfBidMin] = value; + return *this; + } + + /** + * @brief Set sfBidMax (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMBidBuilder& + setBidMax(std::decay_t const& value) + { + object_[sfBidMax] = value; + return *this; + } + + /** + * @brief Set sfAuthAccounts (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMBidBuilder& + setAuthAccounts(STArray const& value) + { + object_.setFieldArray(sfAuthAccounts, value); + return *this; + } + + /** + * @brief Build and return the AMMBid wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AMMBid + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AMMBid{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AMMClawback.h b/include/xrpl/protocol_autogen/transactions/AMMClawback.h new file mode 100644 index 0000000000..9603cad6ef --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AMMClawback.h @@ -0,0 +1,214 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AMMClawbackBuilder; + +/** + * @brief Transaction: AMMClawback + * + * Type: ttAMM_CLAWBACK (31) + * Delegable: Delegation::delegable + * Amendment: featureAMMClawback + * Privileges: mayDeleteAcct | overrideFreeze + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AMMClawbackBuilder to construct new transactions. + */ +class AMMClawback : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMM_CLAWBACK; + + /** + * @brief Construct a AMMClawback transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AMMClawback(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AMMClawback"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfHolder (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getHolder() const + { + return this->tx_->at(sfHolder); + } + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->tx_->at(sfAsset); + } + + /** + * @brief Get sfAsset2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset2() const + { + return this->tx_->at(sfAsset2); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } +}; + +/** + * @brief Builder for AMMClawback transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AMMClawbackBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AMMClawbackBuilder with required fields. + * @param account The account initiating the transaction. + * @param holder The sfHolder field value. + * @param asset The sfAsset field value. + * @param asset2 The sfAsset2 field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AMMClawbackBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& holder, std::decay_t const& asset, std::decay_t const& asset2, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMM_CLAWBACK, account, sequence, fee) + { + setHolder(holder); + setAsset(asset); + setAsset2(asset2); + } + + /** + * @brief Construct a AMMClawbackBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AMMClawbackBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMM_CLAWBACK) + { + throw std::runtime_error("Invalid transaction type for AMMClawbackBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfHolder (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMClawbackBuilder& + setHolder(std::decay_t const& value) + { + object_[sfHolder] = value; + return *this; + } + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMClawbackBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAsset2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMClawbackBuilder& + setAsset2(std::decay_t const& value) + { + object_[sfAsset2] = STIssue(sfAsset2, value); + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMClawbackBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Build and return the AMMClawback wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AMMClawback + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AMMClawback{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AMMCreate.h b/include/xrpl/protocol_autogen/transactions/AMMCreate.h new file mode 100644 index 0000000000..311d19a3c4 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AMMCreate.h @@ -0,0 +1,177 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AMMCreateBuilder; + +/** + * @brief Transaction: AMMCreate + * + * Type: ttAMM_CREATE (35) + * Delegable: Delegation::delegable + * Amendment: featureAMM + * Privileges: createPseudoAcct + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AMMCreateBuilder to construct new transactions. + */ +class AMMCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMM_CREATE; + + /** + * @brief Construct a AMMCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AMMCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AMMCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfAmount2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount2() const + { + return this->tx_->at(sfAmount2); + } + + /** + * @brief Get sfTradingFee (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT16::type::value_type + getTradingFee() const + { + return this->tx_->at(sfTradingFee); + } +}; + +/** + * @brief Builder for AMMCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AMMCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AMMCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param amount The sfAmount field value. + * @param amount2 The sfAmount2 field value. + * @param tradingFee The sfTradingFee field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AMMCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& amount, std::decay_t const& amount2, std::decay_t const& tradingFee, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMM_CREATE, account, sequence, fee) + { + setAmount(amount); + setAmount2(amount2); + setTradingFee(tradingFee); + } + + /** + * @brief Construct a AMMCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AMMCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMM_CREATE) + { + throw std::runtime_error("Invalid transaction type for AMMCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMCreateBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfAmount2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMCreateBuilder& + setAmount2(std::decay_t const& value) + { + object_[sfAmount2] = value; + return *this; + } + + /** + * @brief Set sfTradingFee (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMCreateBuilder& + setTradingFee(std::decay_t const& value) + { + object_[sfTradingFee] = value; + return *this; + } + + /** + * @brief Build and return the AMMCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AMMCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AMMCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AMMDelete.h b/include/xrpl/protocol_autogen/transactions/AMMDelete.h new file mode 100644 index 0000000000..bc61434d0b --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AMMDelete.h @@ -0,0 +1,153 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AMMDeleteBuilder; + +/** + * @brief Transaction: AMMDelete + * + * Type: ttAMM_DELETE (40) + * Delegable: Delegation::delegable + * Amendment: featureAMM + * Privileges: mustDeleteAcct + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AMMDeleteBuilder to construct new transactions. + */ +class AMMDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMM_DELETE; + + /** + * @brief Construct a AMMDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AMMDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AMMDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->tx_->at(sfAsset); + } + + /** + * @brief Get sfAsset2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset2() const + { + return this->tx_->at(sfAsset2); + } +}; + +/** + * @brief Builder for AMMDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AMMDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AMMDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param asset The sfAsset field value. + * @param asset2 The sfAsset2 field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AMMDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& asset, std::decay_t const& asset2, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMM_DELETE, account, sequence, fee) + { + setAsset(asset); + setAsset2(asset2); + } + + /** + * @brief Construct a AMMDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AMMDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMM_DELETE) + { + throw std::runtime_error("Invalid transaction type for AMMDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMDeleteBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAsset2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMDeleteBuilder& + setAsset2(std::decay_t const& value) + { + object_[sfAsset2] = STIssue(sfAsset2, value); + return *this; + } + + /** + * @brief Build and return the AMMDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AMMDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AMMDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AMMDeposit.h b/include/xrpl/protocol_autogen/transactions/AMMDeposit.h new file mode 100644 index 0000000000..8e86339b0a --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AMMDeposit.h @@ -0,0 +1,338 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AMMDepositBuilder; + +/** + * @brief Transaction: AMMDeposit + * + * Type: ttAMM_DEPOSIT (36) + * Delegable: Delegation::delegable + * Amendment: featureAMM + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AMMDepositBuilder to construct new transactions. + */ +class AMMDeposit : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMM_DEPOSIT; + + /** + * @brief Construct a AMMDeposit transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AMMDeposit(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AMMDeposit"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->tx_->at(sfAsset); + } + + /** + * @brief Get sfAsset2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset2() const + { + return this->tx_->at(sfAsset2); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } + + /** + * @brief Get sfAmount2 (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount2() const + { + if (hasAmount2()) + { + return this->tx_->at(sfAmount2); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount2 is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount2() const + { + return this->tx_->isFieldPresent(sfAmount2); + } + + /** + * @brief Get sfEPrice (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getEPrice() const + { + if (hasEPrice()) + { + return this->tx_->at(sfEPrice); + } + return std::nullopt; + } + + /** + * @brief Check if sfEPrice is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasEPrice() const + { + return this->tx_->isFieldPresent(sfEPrice); + } + + /** + * @brief Get sfLPTokenOut (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLPTokenOut() const + { + if (hasLPTokenOut()) + { + return this->tx_->at(sfLPTokenOut); + } + return std::nullopt; + } + + /** + * @brief Check if sfLPTokenOut is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLPTokenOut() const + { + return this->tx_->isFieldPresent(sfLPTokenOut); + } + + /** + * @brief Get sfTradingFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTradingFee() const + { + if (hasTradingFee()) + { + return this->tx_->at(sfTradingFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfTradingFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTradingFee() const + { + return this->tx_->isFieldPresent(sfTradingFee); + } +}; + +/** + * @brief Builder for AMMDeposit transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AMMDepositBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AMMDepositBuilder with required fields. + * @param account The account initiating the transaction. + * @param asset The sfAsset field value. + * @param asset2 The sfAsset2 field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AMMDepositBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& asset, std::decay_t const& asset2, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMM_DEPOSIT, account, sequence, fee) + { + setAsset(asset); + setAsset2(asset2); + } + + /** + * @brief Construct a AMMDepositBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AMMDepositBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMM_DEPOSIT) + { + throw std::runtime_error("Invalid transaction type for AMMDepositBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMDepositBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAsset2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMDepositBuilder& + setAsset2(std::decay_t const& value) + { + object_[sfAsset2] = STIssue(sfAsset2, value); + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMDepositBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfAmount2 (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMDepositBuilder& + setAmount2(std::decay_t const& value) + { + object_[sfAmount2] = value; + return *this; + } + + /** + * @brief Set sfEPrice (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMDepositBuilder& + setEPrice(std::decay_t const& value) + { + object_[sfEPrice] = value; + return *this; + } + + /** + * @brief Set sfLPTokenOut (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMDepositBuilder& + setLPTokenOut(std::decay_t const& value) + { + object_[sfLPTokenOut] = value; + return *this; + } + + /** + * @brief Set sfTradingFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMDepositBuilder& + setTradingFee(std::decay_t const& value) + { + object_[sfTradingFee] = value; + return *this; + } + + /** + * @brief Build and return the AMMDeposit wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AMMDeposit + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AMMDeposit{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AMMVote.h b/include/xrpl/protocol_autogen/transactions/AMMVote.h new file mode 100644 index 0000000000..a4e58c9aa4 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AMMVote.h @@ -0,0 +1,177 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AMMVoteBuilder; + +/** + * @brief Transaction: AMMVote + * + * Type: ttAMM_VOTE (38) + * Delegable: Delegation::delegable + * Amendment: featureAMM + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AMMVoteBuilder to construct new transactions. + */ +class AMMVote : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMM_VOTE; + + /** + * @brief Construct a AMMVote transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AMMVote(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AMMVote"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->tx_->at(sfAsset); + } + + /** + * @brief Get sfAsset2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset2() const + { + return this->tx_->at(sfAsset2); + } + + /** + * @brief Get sfTradingFee (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT16::type::value_type + getTradingFee() const + { + return this->tx_->at(sfTradingFee); + } +}; + +/** + * @brief Builder for AMMVote transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AMMVoteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AMMVoteBuilder with required fields. + * @param account The account initiating the transaction. + * @param asset The sfAsset field value. + * @param asset2 The sfAsset2 field value. + * @param tradingFee The sfTradingFee field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AMMVoteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& asset, std::decay_t const& asset2, std::decay_t const& tradingFee, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMM_VOTE, account, sequence, fee) + { + setAsset(asset); + setAsset2(asset2); + setTradingFee(tradingFee); + } + + /** + * @brief Construct a AMMVoteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AMMVoteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMM_VOTE) + { + throw std::runtime_error("Invalid transaction type for AMMVoteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMVoteBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAsset2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMVoteBuilder& + setAsset2(std::decay_t const& value) + { + object_[sfAsset2] = STIssue(sfAsset2, value); + return *this; + } + + /** + * @brief Set sfTradingFee (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMVoteBuilder& + setTradingFee(std::decay_t const& value) + { + object_[sfTradingFee] = value; + return *this; + } + + /** + * @brief Build and return the AMMVote wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AMMVote + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AMMVote{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AMMWithdraw.h b/include/xrpl/protocol_autogen/transactions/AMMWithdraw.h new file mode 100644 index 0000000000..da19c546ee --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AMMWithdraw.h @@ -0,0 +1,301 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AMMWithdrawBuilder; + +/** + * @brief Transaction: AMMWithdraw + * + * Type: ttAMM_WITHDRAW (37) + * Delegable: Delegation::delegable + * Amendment: featureAMM + * Privileges: mayDeleteAcct + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AMMWithdrawBuilder to construct new transactions. + */ +class AMMWithdraw : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMM_WITHDRAW; + + /** + * @brief Construct a AMMWithdraw transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AMMWithdraw(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AMMWithdraw"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAsset (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->tx_->at(sfAsset); + } + + /** + * @brief Get sfAsset2 (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset2() const + { + return this->tx_->at(sfAsset2); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } + + /** + * @brief Get sfAmount2 (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount2() const + { + if (hasAmount2()) + { + return this->tx_->at(sfAmount2); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount2 is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount2() const + { + return this->tx_->isFieldPresent(sfAmount2); + } + + /** + * @brief Get sfEPrice (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getEPrice() const + { + if (hasEPrice()) + { + return this->tx_->at(sfEPrice); + } + return std::nullopt; + } + + /** + * @brief Check if sfEPrice is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasEPrice() const + { + return this->tx_->isFieldPresent(sfEPrice); + } + + /** + * @brief Get sfLPTokenIn (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLPTokenIn() const + { + if (hasLPTokenIn()) + { + return this->tx_->at(sfLPTokenIn); + } + return std::nullopt; + } + + /** + * @brief Check if sfLPTokenIn is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLPTokenIn() const + { + return this->tx_->isFieldPresent(sfLPTokenIn); + } +}; + +/** + * @brief Builder for AMMWithdraw transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AMMWithdrawBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AMMWithdrawBuilder with required fields. + * @param account The account initiating the transaction. + * @param asset The sfAsset field value. + * @param asset2 The sfAsset2 field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AMMWithdrawBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& asset, std::decay_t const& asset2, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMM_WITHDRAW, account, sequence, fee) + { + setAsset(asset); + setAsset2(asset2); + } + + /** + * @brief Construct a AMMWithdrawBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AMMWithdrawBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMM_WITHDRAW) + { + throw std::runtime_error("Invalid transaction type for AMMWithdrawBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAsset (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMWithdrawBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAsset2 (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AMMWithdrawBuilder& + setAsset2(std::decay_t const& value) + { + object_[sfAsset2] = STIssue(sfAsset2, value); + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMWithdrawBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfAmount2 (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMWithdrawBuilder& + setAmount2(std::decay_t const& value) + { + object_[sfAmount2] = value; + return *this; + } + + /** + * @brief Set sfEPrice (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMWithdrawBuilder& + setEPrice(std::decay_t const& value) + { + object_[sfEPrice] = value; + return *this; + } + + /** + * @brief Set sfLPTokenIn (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AMMWithdrawBuilder& + setLPTokenIn(std::decay_t const& value) + { + object_[sfLPTokenIn] = value; + return *this; + } + + /** + * @brief Build and return the AMMWithdraw wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AMMWithdraw + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AMMWithdraw{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AccountDelete.h b/include/xrpl/protocol_autogen/transactions/AccountDelete.h new file mode 100644 index 0000000000..86ae9af546 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AccountDelete.h @@ -0,0 +1,203 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AccountDeleteBuilder; + +/** + * @brief Transaction: AccountDelete + * + * Type: ttACCOUNT_DELETE (21) + * Delegable: Delegation::notDelegable + * Amendment: uint256{} + * Privileges: mustDeleteAcct + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AccountDeleteBuilder to construct new transactions. + */ +class AccountDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttACCOUNT_DELETE; + + /** + * @brief Construct a AccountDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AccountDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AccountDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } + + /** + * @brief Get sfCredentialIDs (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCredentialIDs() const + { + if (hasCredentialIDs()) + { + return this->tx_->at(sfCredentialIDs); + } + return std::nullopt; + } + + /** + * @brief Check if sfCredentialIDs is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCredentialIDs() const + { + return this->tx_->isFieldPresent(sfCredentialIDs); + } +}; + +/** + * @brief Builder for AccountDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AccountDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AccountDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param destination The sfDestination field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AccountDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& destination, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttACCOUNT_DELETE, account, sequence, fee) + { + setDestination(destination); + } + + /** + * @brief Construct a AccountDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AccountDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttACCOUNT_DELETE) + { + throw std::runtime_error("Invalid transaction type for AccountDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + AccountDeleteBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountDeleteBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Set sfCredentialIDs (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountDeleteBuilder& + setCredentialIDs(std::decay_t const& value) + { + object_[sfCredentialIDs] = value; + return *this; + } + + /** + * @brief Build and return the AccountDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AccountDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AccountDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/AccountSet.h b/include/xrpl/protocol_autogen/transactions/AccountSet.h new file mode 100644 index 0000000000..c00142bd1e --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/AccountSet.h @@ -0,0 +1,475 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class AccountSetBuilder; + +/** + * @brief Transaction: AccountSet + * + * Type: ttACCOUNT_SET (3) + * Delegable: Delegation::notDelegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use AccountSetBuilder to construct new transactions. + */ +class AccountSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttACCOUNT_SET; + + /** + * @brief Construct a AccountSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit AccountSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for AccountSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfEmailHash (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getEmailHash() const + { + if (hasEmailHash()) + { + return this->tx_->at(sfEmailHash); + } + return std::nullopt; + } + + /** + * @brief Check if sfEmailHash is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasEmailHash() const + { + return this->tx_->isFieldPresent(sfEmailHash); + } + + /** + * @brief Get sfWalletLocator (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getWalletLocator() const + { + if (hasWalletLocator()) + { + return this->tx_->at(sfWalletLocator); + } + return std::nullopt; + } + + /** + * @brief Check if sfWalletLocator is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasWalletLocator() const + { + return this->tx_->isFieldPresent(sfWalletLocator); + } + + /** + * @brief Get sfWalletSize (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getWalletSize() const + { + if (hasWalletSize()) + { + return this->tx_->at(sfWalletSize); + } + return std::nullopt; + } + + /** + * @brief Check if sfWalletSize is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasWalletSize() const + { + return this->tx_->isFieldPresent(sfWalletSize); + } + + /** + * @brief Get sfMessageKey (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMessageKey() const + { + if (hasMessageKey()) + { + return this->tx_->at(sfMessageKey); + } + return std::nullopt; + } + + /** + * @brief Check if sfMessageKey is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMessageKey() const + { + return this->tx_->isFieldPresent(sfMessageKey); + } + + /** + * @brief Get sfDomain (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomain() const + { + if (hasDomain()) + { + return this->tx_->at(sfDomain); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomain is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomain() const + { + return this->tx_->isFieldPresent(sfDomain); + } + + /** + * @brief Get sfTransferRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTransferRate() const + { + if (hasTransferRate()) + { + return this->tx_->at(sfTransferRate); + } + return std::nullopt; + } + + /** + * @brief Check if sfTransferRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTransferRate() const + { + return this->tx_->isFieldPresent(sfTransferRate); + } + + /** + * @brief Get sfSetFlag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSetFlag() const + { + if (hasSetFlag()) + { + return this->tx_->at(sfSetFlag); + } + return std::nullopt; + } + + /** + * @brief Check if sfSetFlag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSetFlag() const + { + return this->tx_->isFieldPresent(sfSetFlag); + } + + /** + * @brief Get sfClearFlag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getClearFlag() const + { + if (hasClearFlag()) + { + return this->tx_->at(sfClearFlag); + } + return std::nullopt; + } + + /** + * @brief Check if sfClearFlag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasClearFlag() const + { + return this->tx_->isFieldPresent(sfClearFlag); + } + + /** + * @brief Get sfTickSize (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTickSize() const + { + if (hasTickSize()) + { + return this->tx_->at(sfTickSize); + } + return std::nullopt; + } + + /** + * @brief Check if sfTickSize is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTickSize() const + { + return this->tx_->isFieldPresent(sfTickSize); + } + + /** + * @brief Get sfNFTokenMinter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNFTokenMinter() const + { + if (hasNFTokenMinter()) + { + return this->tx_->at(sfNFTokenMinter); + } + return std::nullopt; + } + + /** + * @brief Check if sfNFTokenMinter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNFTokenMinter() const + { + return this->tx_->isFieldPresent(sfNFTokenMinter); + } +}; + +/** + * @brief Builder for AccountSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class AccountSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new AccountSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + AccountSetBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttACCOUNT_SET, account, sequence, fee) + { + } + + /** + * @brief Construct a AccountSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + AccountSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttACCOUNT_SET) + { + throw std::runtime_error("Invalid transaction type for AccountSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfEmailHash (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setEmailHash(std::decay_t const& value) + { + object_[sfEmailHash] = value; + return *this; + } + + /** + * @brief Set sfWalletLocator (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setWalletLocator(std::decay_t const& value) + { + object_[sfWalletLocator] = value; + return *this; + } + + /** + * @brief Set sfWalletSize (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setWalletSize(std::decay_t const& value) + { + object_[sfWalletSize] = value; + return *this; + } + + /** + * @brief Set sfMessageKey (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setMessageKey(std::decay_t const& value) + { + object_[sfMessageKey] = value; + return *this; + } + + /** + * @brief Set sfDomain (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setDomain(std::decay_t const& value) + { + object_[sfDomain] = value; + return *this; + } + + /** + * @brief Set sfTransferRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setTransferRate(std::decay_t const& value) + { + object_[sfTransferRate] = value; + return *this; + } + + /** + * @brief Set sfSetFlag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setSetFlag(std::decay_t const& value) + { + object_[sfSetFlag] = value; + return *this; + } + + /** + * @brief Set sfClearFlag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setClearFlag(std::decay_t const& value) + { + object_[sfClearFlag] = value; + return *this; + } + + /** + * @brief Set sfTickSize (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setTickSize(std::decay_t const& value) + { + object_[sfTickSize] = value; + return *this; + } + + /** + * @brief Set sfNFTokenMinter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + AccountSetBuilder& + setNFTokenMinter(std::decay_t const& value) + { + object_[sfNFTokenMinter] = value; + return *this; + } + + /** + * @brief Build and return the AccountSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + AccountSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return AccountSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/Batch.h b/include/xrpl/protocol_autogen/transactions/Batch.h new file mode 100644 index 0000000000..0bb638435c --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/Batch.h @@ -0,0 +1,164 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class BatchBuilder; + +/** + * @brief Transaction: Batch + * + * Type: ttBATCH (71) + * Delegable: Delegation::notDelegable + * Amendment: featureBatch + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use BatchBuilder to construct new transactions. + */ +class Batch : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttBATCH; + + /** + * @brief Construct a Batch transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit Batch(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for Batch"); + } + } + + // Transaction-specific field getters + /** + * @brief Get sfRawTransactions (soeREQUIRED) + * @note This is an untyped field. + * @return The field value. + */ + [[nodiscard]] + STArray const& + getRawTransactions() const + { + return this->tx_->getFieldArray(sfRawTransactions); + } + /** + * @brief Get sfBatchSigners (soeOPTIONAL) + * @note This is an untyped field. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getBatchSigners() const + { + if (this->tx_->isFieldPresent(sfBatchSigners)) + return this->tx_->getFieldArray(sfBatchSigners); + return std::nullopt; + } + + /** + * @brief Check if sfBatchSigners is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBatchSigners() const + { + return this->tx_->isFieldPresent(sfBatchSigners); + } +}; + +/** + * @brief Builder for Batch transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class BatchBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new BatchBuilder with required fields. + * @param account The account initiating the transaction. + * @param rawTransactions The sfRawTransactions field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + BatchBuilder(SF_ACCOUNT::type::value_type account, + STArray const& rawTransactions, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttBATCH, account, sequence, fee) + { + setRawTransactions(rawTransactions); + } + + /** + * @brief Construct a BatchBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + BatchBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttBATCH) + { + throw std::runtime_error("Invalid transaction type for BatchBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfRawTransactions (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + BatchBuilder& + setRawTransactions(STArray const& value) + { + object_.setFieldArray(sfRawTransactions, value); + return *this; + } + + /** + * @brief Set sfBatchSigners (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + BatchBuilder& + setBatchSigners(STArray const& value) + { + object_.setFieldArray(sfBatchSigners, value); + return *this; + } + + /** + * @brief Build and return the Batch wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + Batch + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return Batch{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/CheckCancel.h b/include/xrpl/protocol_autogen/transactions/CheckCancel.h new file mode 100644 index 0000000000..2409e7064c --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/CheckCancel.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class CheckCancelBuilder; + +/** + * @brief Transaction: CheckCancel + * + * Type: ttCHECK_CANCEL (18) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use CheckCancelBuilder to construct new transactions. + */ +class CheckCancel : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttCHECK_CANCEL; + + /** + * @brief Construct a CheckCancel transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit CheckCancel(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for CheckCancel"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfCheckID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getCheckID() const + { + return this->tx_->at(sfCheckID); + } +}; + +/** + * @brief Builder for CheckCancel transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class CheckCancelBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new CheckCancelBuilder with required fields. + * @param account The account initiating the transaction. + * @param checkID The sfCheckID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + CheckCancelBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& checkID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttCHECK_CANCEL, account, sequence, fee) + { + setCheckID(checkID); + } + + /** + * @brief Construct a CheckCancelBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + CheckCancelBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttCHECK_CANCEL) + { + throw std::runtime_error("Invalid transaction type for CheckCancelBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfCheckID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckCancelBuilder& + setCheckID(std::decay_t const& value) + { + object_[sfCheckID] = value; + return *this; + } + + /** + * @brief Build and return the CheckCancel wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + CheckCancel + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return CheckCancel{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/CheckCash.h b/include/xrpl/protocol_autogen/transactions/CheckCash.h new file mode 100644 index 0000000000..2a2bc9c7af --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/CheckCash.h @@ -0,0 +1,203 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class CheckCashBuilder; + +/** + * @brief Transaction: CheckCash + * + * Type: ttCHECK_CASH (17) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use CheckCashBuilder to construct new transactions. + */ +class CheckCash : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttCHECK_CASH; + + /** + * @brief Construct a CheckCash transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit CheckCash(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for CheckCash"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfCheckID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getCheckID() const + { + return this->tx_->at(sfCheckID); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } + + /** + * @brief Get sfDeliverMin (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDeliverMin() const + { + if (hasDeliverMin()) + { + return this->tx_->at(sfDeliverMin); + } + return std::nullopt; + } + + /** + * @brief Check if sfDeliverMin is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDeliverMin() const + { + return this->tx_->isFieldPresent(sfDeliverMin); + } +}; + +/** + * @brief Builder for CheckCash transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class CheckCashBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new CheckCashBuilder with required fields. + * @param account The account initiating the transaction. + * @param checkID The sfCheckID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + CheckCashBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& checkID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttCHECK_CASH, account, sequence, fee) + { + setCheckID(checkID); + } + + /** + * @brief Construct a CheckCashBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + CheckCashBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttCHECK_CASH) + { + throw std::runtime_error("Invalid transaction type for CheckCashBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfCheckID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckCashBuilder& + setCheckID(std::decay_t const& value) + { + object_[sfCheckID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckCashBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfDeliverMin (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckCashBuilder& + setDeliverMin(std::decay_t const& value) + { + object_[sfDeliverMin] = value; + return *this; + } + + /** + * @brief Build and return the CheckCash wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + CheckCash + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return CheckCash{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/CheckCreate.h b/include/xrpl/protocol_autogen/transactions/CheckCreate.h new file mode 100644 index 0000000000..ba209a7fc4 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/CheckCreate.h @@ -0,0 +1,264 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class CheckCreateBuilder; + +/** + * @brief Transaction: CheckCreate + * + * Type: ttCHECK_CREATE (16) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use CheckCreateBuilder to construct new transactions. + */ +class CheckCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttCHECK_CREATE; + + /** + * @brief Construct a CheckCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit CheckCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for CheckCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfSendMax (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSendMax() const + { + return this->tx_->at(sfSendMax); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + { + return this->tx_->at(sfExpiration); + } + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->tx_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } + + /** + * @brief Get sfInvoiceID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getInvoiceID() const + { + if (hasInvoiceID()) + { + return this->tx_->at(sfInvoiceID); + } + return std::nullopt; + } + + /** + * @brief Check if sfInvoiceID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasInvoiceID() const + { + return this->tx_->isFieldPresent(sfInvoiceID); + } +}; + +/** + * @brief Builder for CheckCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class CheckCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new CheckCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param destination The sfDestination field value. + * @param sendMax The sfSendMax field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + CheckCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& destination, std::decay_t const& sendMax, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttCHECK_CREATE, account, sequence, fee) + { + setDestination(destination); + setSendMax(sendMax); + } + + /** + * @brief Construct a CheckCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + CheckCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttCHECK_CREATE) + { + throw std::runtime_error("Invalid transaction type for CheckCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckCreateBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfSendMax (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CheckCreateBuilder& + setSendMax(std::decay_t const& value) + { + object_[sfSendMax] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckCreateBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckCreateBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Set sfInvoiceID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CheckCreateBuilder& + setInvoiceID(std::decay_t const& value) + { + object_[sfInvoiceID] = value; + return *this; + } + + /** + * @brief Build and return the CheckCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + CheckCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return CheckCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/Clawback.h b/include/xrpl/protocol_autogen/transactions/Clawback.h new file mode 100644 index 0000000000..6c34ceff11 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/Clawback.h @@ -0,0 +1,168 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class ClawbackBuilder; + +/** + * @brief Transaction: Clawback + * + * Type: ttCLAWBACK (30) + * Delegable: Delegation::delegable + * Amendment: featureClawback + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use ClawbackBuilder to construct new transactions. + */ +class Clawback : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttCLAWBACK; + + /** + * @brief Construct a Clawback transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit Clawback(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for Clawback"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfHolder (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getHolder() const + { + if (hasHolder()) + { + return this->tx_->at(sfHolder); + } + return std::nullopt; + } + + /** + * @brief Check if sfHolder is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasHolder() const + { + return this->tx_->isFieldPresent(sfHolder); + } +}; + +/** + * @brief Builder for Clawback transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class ClawbackBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new ClawbackBuilder with required fields. + * @param account The account initiating the transaction. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + ClawbackBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttCLAWBACK, account, sequence, fee) + { + setAmount(amount); + } + + /** + * @brief Construct a ClawbackBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + ClawbackBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttCLAWBACK) + { + throw std::runtime_error("Invalid transaction type for ClawbackBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + ClawbackBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfHolder (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + ClawbackBuilder& + setHolder(std::decay_t const& value) + { + object_[sfHolder] = value; + return *this; + } + + /** + * @brief Build and return the Clawback wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + Clawback + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return Clawback{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/CredentialAccept.h b/include/xrpl/protocol_autogen/transactions/CredentialAccept.h new file mode 100644 index 0000000000..c739e4abcb --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/CredentialAccept.h @@ -0,0 +1,153 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class CredentialAcceptBuilder; + +/** + * @brief Transaction: CredentialAccept + * + * Type: ttCREDENTIAL_ACCEPT (59) + * Delegable: Delegation::delegable + * Amendment: featureCredentials + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use CredentialAcceptBuilder to construct new transactions. + */ +class CredentialAccept : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttCREDENTIAL_ACCEPT; + + /** + * @brief Construct a CredentialAccept transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit CredentialAccept(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for CredentialAccept"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfIssuer (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getIssuer() const + { + return this->tx_->at(sfIssuer); + } + + /** + * @brief Get sfCredentialType (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getCredentialType() const + { + return this->tx_->at(sfCredentialType); + } +}; + +/** + * @brief Builder for CredentialAccept transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class CredentialAcceptBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new CredentialAcceptBuilder with required fields. + * @param account The account initiating the transaction. + * @param issuer The sfIssuer field value. + * @param credentialType The sfCredentialType field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + CredentialAcceptBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& issuer, std::decay_t const& credentialType, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttCREDENTIAL_ACCEPT, account, sequence, fee) + { + setIssuer(issuer); + setCredentialType(credentialType); + } + + /** + * @brief Construct a CredentialAcceptBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + CredentialAcceptBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttCREDENTIAL_ACCEPT) + { + throw std::runtime_error("Invalid transaction type for CredentialAcceptBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfIssuer (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialAcceptBuilder& + setIssuer(std::decay_t const& value) + { + object_[sfIssuer] = value; + return *this; + } + + /** + * @brief Set sfCredentialType (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialAcceptBuilder& + setCredentialType(std::decay_t const& value) + { + object_[sfCredentialType] = value; + return *this; + } + + /** + * @brief Build and return the CredentialAccept wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + CredentialAccept + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return CredentialAccept{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/CredentialCreate.h b/include/xrpl/protocol_autogen/transactions/CredentialCreate.h new file mode 100644 index 0000000000..4da5b3ff47 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/CredentialCreate.h @@ -0,0 +1,227 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class CredentialCreateBuilder; + +/** + * @brief Transaction: CredentialCreate + * + * Type: ttCREDENTIAL_CREATE (58) + * Delegable: Delegation::delegable + * Amendment: featureCredentials + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use CredentialCreateBuilder to construct new transactions. + */ +class CredentialCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttCREDENTIAL_CREATE; + + /** + * @brief Construct a CredentialCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit CredentialCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for CredentialCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfSubject (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getSubject() const + { + return this->tx_->at(sfSubject); + } + + /** + * @brief Get sfCredentialType (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getCredentialType() const + { + return this->tx_->at(sfCredentialType); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + { + return this->tx_->at(sfExpiration); + } + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->tx_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + { + return this->tx_->at(sfURI); + } + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->tx_->isFieldPresent(sfURI); + } +}; + +/** + * @brief Builder for CredentialCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class CredentialCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new CredentialCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param subject The sfSubject field value. + * @param credentialType The sfCredentialType field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + CredentialCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& subject, std::decay_t const& credentialType, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttCREDENTIAL_CREATE, account, sequence, fee) + { + setSubject(subject); + setCredentialType(credentialType); + } + + /** + * @brief Construct a CredentialCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + CredentialCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttCREDENTIAL_CREATE) + { + throw std::runtime_error("Invalid transaction type for CredentialCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfSubject (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialCreateBuilder& + setSubject(std::decay_t const& value) + { + object_[sfSubject] = value; + return *this; + } + + /** + * @brief Set sfCredentialType (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialCreateBuilder& + setCredentialType(std::decay_t const& value) + { + object_[sfCredentialType] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CredentialCreateBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CredentialCreateBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Build and return the CredentialCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + CredentialCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return CredentialCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/CredentialDelete.h b/include/xrpl/protocol_autogen/transactions/CredentialDelete.h new file mode 100644 index 0000000000..bd840ed104 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/CredentialDelete.h @@ -0,0 +1,203 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class CredentialDeleteBuilder; + +/** + * @brief Transaction: CredentialDelete + * + * Type: ttCREDENTIAL_DELETE (60) + * Delegable: Delegation::delegable + * Amendment: featureCredentials + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use CredentialDeleteBuilder to construct new transactions. + */ +class CredentialDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttCREDENTIAL_DELETE; + + /** + * @brief Construct a CredentialDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit CredentialDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for CredentialDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfSubject (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSubject() const + { + if (hasSubject()) + { + return this->tx_->at(sfSubject); + } + return std::nullopt; + } + + /** + * @brief Check if sfSubject is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSubject() const + { + return this->tx_->isFieldPresent(sfSubject); + } + + /** + * @brief Get sfIssuer (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getIssuer() const + { + if (hasIssuer()) + { + return this->tx_->at(sfIssuer); + } + return std::nullopt; + } + + /** + * @brief Check if sfIssuer is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasIssuer() const + { + return this->tx_->isFieldPresent(sfIssuer); + } + + /** + * @brief Get sfCredentialType (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getCredentialType() const + { + return this->tx_->at(sfCredentialType); + } +}; + +/** + * @brief Builder for CredentialDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class CredentialDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new CredentialDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param credentialType The sfCredentialType field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + CredentialDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& credentialType, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttCREDENTIAL_DELETE, account, sequence, fee) + { + setCredentialType(credentialType); + } + + /** + * @brief Construct a CredentialDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + CredentialDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttCREDENTIAL_DELETE) + { + throw std::runtime_error("Invalid transaction type for CredentialDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfSubject (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CredentialDeleteBuilder& + setSubject(std::decay_t const& value) + { + object_[sfSubject] = value; + return *this; + } + + /** + * @brief Set sfIssuer (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + CredentialDeleteBuilder& + setIssuer(std::decay_t const& value) + { + object_[sfIssuer] = value; + return *this; + } + + /** + * @brief Set sfCredentialType (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + CredentialDeleteBuilder& + setCredentialType(std::decay_t const& value) + { + object_[sfCredentialType] = value; + return *this; + } + + /** + * @brief Build and return the CredentialDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + CredentialDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return CredentialDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/DIDDelete.h b/include/xrpl/protocol_autogen/transactions/DIDDelete.h new file mode 100644 index 0000000000..c4e61eb19e --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/DIDDelete.h @@ -0,0 +1,105 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class DIDDeleteBuilder; + +/** + * @brief Transaction: DIDDelete + * + * Type: ttDID_DELETE (50) + * Delegable: Delegation::delegable + * Amendment: featureDID + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use DIDDeleteBuilder to construct new transactions. + */ +class DIDDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttDID_DELETE; + + /** + * @brief Construct a DIDDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit DIDDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for DIDDelete"); + } + } + + // Transaction-specific field getters +}; + +/** + * @brief Builder for DIDDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class DIDDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new DIDDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + DIDDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttDID_DELETE, account, sequence, fee) + { + } + + /** + * @brief Construct a DIDDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + DIDDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttDID_DELETE) + { + throw std::runtime_error("Invalid transaction type for DIDDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Build and return the DIDDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + DIDDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return DIDDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/DIDSet.h b/include/xrpl/protocol_autogen/transactions/DIDSet.h new file mode 100644 index 0000000000..33313d384c --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/DIDSet.h @@ -0,0 +1,216 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class DIDSetBuilder; + +/** + * @brief Transaction: DIDSet + * + * Type: ttDID_SET (49) + * Delegable: Delegation::delegable + * Amendment: featureDID + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use DIDSetBuilder to construct new transactions. + */ +class DIDSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttDID_SET; + + /** + * @brief Construct a DIDSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit DIDSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for DIDSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDIDDocument (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDIDDocument() const + { + if (hasDIDDocument()) + { + return this->tx_->at(sfDIDDocument); + } + return std::nullopt; + } + + /** + * @brief Check if sfDIDDocument is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDIDDocument() const + { + return this->tx_->isFieldPresent(sfDIDDocument); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + { + return this->tx_->at(sfURI); + } + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->tx_->isFieldPresent(sfURI); + } + + /** + * @brief Get sfData (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + { + return this->tx_->at(sfData); + } + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->tx_->isFieldPresent(sfData); + } +}; + +/** + * @brief Builder for DIDSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class DIDSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new DIDSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + DIDSetBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttDID_SET, account, sequence, fee) + { + } + + /** + * @brief Construct a DIDSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + DIDSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttDID_SET) + { + throw std::runtime_error("Invalid transaction type for DIDSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDIDDocument (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DIDSetBuilder& + setDIDDocument(std::decay_t const& value) + { + object_[sfDIDDocument] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DIDSetBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Set sfData (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DIDSetBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Build and return the DIDSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + DIDSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return DIDSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/DelegateSet.h b/include/xrpl/protocol_autogen/transactions/DelegateSet.h new file mode 100644 index 0000000000..cac4b3abef --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/DelegateSet.h @@ -0,0 +1,153 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class DelegateSetBuilder; + +/** + * @brief Transaction: DelegateSet + * + * Type: ttDELEGATE_SET (64) + * Delegable: Delegation::notDelegable + * Amendment: featurePermissionDelegationV1_1 + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use DelegateSetBuilder to construct new transactions. + */ +class DelegateSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttDELEGATE_SET; + + /** + * @brief Construct a DelegateSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit DelegateSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for DelegateSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAuthorize (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAuthorize() const + { + return this->tx_->at(sfAuthorize); + } + /** + * @brief Get sfPermissions (soeREQUIRED) + * @note This is an untyped field. + * @return The field value. + */ + [[nodiscard]] + STArray const& + getPermissions() const + { + return this->tx_->getFieldArray(sfPermissions); + } +}; + +/** + * @brief Builder for DelegateSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class DelegateSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new DelegateSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param authorize The sfAuthorize field value. + * @param permissions The sfPermissions field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + DelegateSetBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& authorize, STArray const& permissions, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttDELEGATE_SET, account, sequence, fee) + { + setAuthorize(authorize); + setPermissions(permissions); + } + + /** + * @brief Construct a DelegateSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + DelegateSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttDELEGATE_SET) + { + throw std::runtime_error("Invalid transaction type for DelegateSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAuthorize (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateSetBuilder& + setAuthorize(std::decay_t const& value) + { + object_[sfAuthorize] = value; + return *this; + } + + /** + * @brief Set sfPermissions (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + DelegateSetBuilder& + setPermissions(STArray const& value) + { + object_.setFieldArray(sfPermissions, value); + return *this; + } + + /** + * @brief Build and return the DelegateSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + DelegateSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return DelegateSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/DepositPreauth.h b/include/xrpl/protocol_autogen/transactions/DepositPreauth.h new file mode 100644 index 0000000000..eae8b113a9 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/DepositPreauth.h @@ -0,0 +1,249 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class DepositPreauthBuilder; + +/** + * @brief Transaction: DepositPreauth + * + * Type: ttDEPOSIT_PREAUTH (19) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use DepositPreauthBuilder to construct new transactions. + */ +class DepositPreauth : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttDEPOSIT_PREAUTH; + + /** + * @brief Construct a DepositPreauth transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit DepositPreauth(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for DepositPreauth"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAuthorize (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAuthorize() const + { + if (hasAuthorize()) + { + return this->tx_->at(sfAuthorize); + } + return std::nullopt; + } + + /** + * @brief Check if sfAuthorize is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAuthorize() const + { + return this->tx_->isFieldPresent(sfAuthorize); + } + + /** + * @brief Get sfUnauthorize (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getUnauthorize() const + { + if (hasUnauthorize()) + { + return this->tx_->at(sfUnauthorize); + } + return std::nullopt; + } + + /** + * @brief Check if sfUnauthorize is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasUnauthorize() const + { + return this->tx_->isFieldPresent(sfUnauthorize); + } + /** + * @brief Get sfAuthorizeCredentials (soeOPTIONAL) + * @note This is an untyped field. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getAuthorizeCredentials() const + { + if (this->tx_->isFieldPresent(sfAuthorizeCredentials)) + return this->tx_->getFieldArray(sfAuthorizeCredentials); + return std::nullopt; + } + + /** + * @brief Check if sfAuthorizeCredentials is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAuthorizeCredentials() const + { + return this->tx_->isFieldPresent(sfAuthorizeCredentials); + } + /** + * @brief Get sfUnauthorizeCredentials (soeOPTIONAL) + * @note This is an untyped field. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getUnauthorizeCredentials() const + { + if (this->tx_->isFieldPresent(sfUnauthorizeCredentials)) + return this->tx_->getFieldArray(sfUnauthorizeCredentials); + return std::nullopt; + } + + /** + * @brief Check if sfUnauthorizeCredentials is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasUnauthorizeCredentials() const + { + return this->tx_->isFieldPresent(sfUnauthorizeCredentials); + } +}; + +/** + * @brief Builder for DepositPreauth transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class DepositPreauthBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new DepositPreauthBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + DepositPreauthBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttDEPOSIT_PREAUTH, account, sequence, fee) + { + } + + /** + * @brief Construct a DepositPreauthBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + DepositPreauthBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttDEPOSIT_PREAUTH) + { + throw std::runtime_error("Invalid transaction type for DepositPreauthBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAuthorize (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setAuthorize(std::decay_t const& value) + { + object_[sfAuthorize] = value; + return *this; + } + + /** + * @brief Set sfUnauthorize (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setUnauthorize(std::decay_t const& value) + { + object_[sfUnauthorize] = value; + return *this; + } + + /** + * @brief Set sfAuthorizeCredentials (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setAuthorizeCredentials(STArray const& value) + { + object_.setFieldArray(sfAuthorizeCredentials, value); + return *this; + } + + /** + * @brief Set sfUnauthorizeCredentials (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + DepositPreauthBuilder& + setUnauthorizeCredentials(STArray const& value) + { + object_.setFieldArray(sfUnauthorizeCredentials, value); + return *this; + } + + /** + * @brief Build and return the DepositPreauth wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + DepositPreauth + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return DepositPreauth{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/EnableAmendment.h b/include/xrpl/protocol_autogen/transactions/EnableAmendment.h new file mode 100644 index 0000000000..0bf3dfd575 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/EnableAmendment.h @@ -0,0 +1,153 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class EnableAmendmentBuilder; + +/** + * @brief Transaction: EnableAmendment + * + * Type: ttAMENDMENT (100) + * Delegable: Delegation::notDelegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use EnableAmendmentBuilder to construct new transactions. + */ +class EnableAmendment : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttAMENDMENT; + + /** + * @brief Construct a EnableAmendment transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit EnableAmendment(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for EnableAmendment"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLedgerSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getLedgerSequence() const + { + return this->tx_->at(sfLedgerSequence); + } + + /** + * @brief Get sfAmendment (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getAmendment() const + { + return this->tx_->at(sfAmendment); + } +}; + +/** + * @brief Builder for EnableAmendment transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class EnableAmendmentBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new EnableAmendmentBuilder with required fields. + * @param account The account initiating the transaction. + * @param ledgerSequence The sfLedgerSequence field value. + * @param amendment The sfAmendment field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + EnableAmendmentBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& ledgerSequence, std::decay_t const& amendment, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttAMENDMENT, account, sequence, fee) + { + setLedgerSequence(ledgerSequence); + setAmendment(amendment); + } + + /** + * @brief Construct a EnableAmendmentBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + EnableAmendmentBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttAMENDMENT) + { + throw std::runtime_error("Invalid transaction type for EnableAmendmentBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLedgerSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EnableAmendmentBuilder& + setLedgerSequence(std::decay_t const& value) + { + object_[sfLedgerSequence] = value; + return *this; + } + + /** + * @brief Set sfAmendment (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EnableAmendmentBuilder& + setAmendment(std::decay_t const& value) + { + object_[sfAmendment] = value; + return *this; + } + + /** + * @brief Build and return the EnableAmendment wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + EnableAmendment + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return EnableAmendment{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/EscrowCancel.h b/include/xrpl/protocol_autogen/transactions/EscrowCancel.h new file mode 100644 index 0000000000..a92d5b10ae --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/EscrowCancel.h @@ -0,0 +1,153 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class EscrowCancelBuilder; + +/** + * @brief Transaction: EscrowCancel + * + * Type: ttESCROW_CANCEL (4) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use EscrowCancelBuilder to construct new transactions. + */ +class EscrowCancel : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttESCROW_CANCEL; + + /** + * @brief Construct a EscrowCancel transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit EscrowCancel(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for EscrowCancel"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfOwner (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOwner() const + { + return this->tx_->at(sfOwner); + } + + /** + * @brief Get sfOfferSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getOfferSequence() const + { + return this->tx_->at(sfOfferSequence); + } +}; + +/** + * @brief Builder for EscrowCancel transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class EscrowCancelBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new EscrowCancelBuilder with required fields. + * @param account The account initiating the transaction. + * @param owner The sfOwner field value. + * @param offerSequence The sfOfferSequence field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + EscrowCancelBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& owner, std::decay_t const& offerSequence, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttESCROW_CANCEL, account, sequence, fee) + { + setOwner(owner); + setOfferSequence(offerSequence); + } + + /** + * @brief Construct a EscrowCancelBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + EscrowCancelBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttESCROW_CANCEL) + { + throw std::runtime_error("Invalid transaction type for EscrowCancelBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfOwner (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowCancelBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfOfferSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowCancelBuilder& + setOfferSequence(std::decay_t const& value) + { + object_[sfOfferSequence] = value; + return *this; + } + + /** + * @brief Build and return the EscrowCancel wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + EscrowCancel + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return EscrowCancel{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/EscrowCreate.h b/include/xrpl/protocol_autogen/transactions/EscrowCreate.h new file mode 100644 index 0000000000..32dae6cc57 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/EscrowCreate.h @@ -0,0 +1,303 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class EscrowCreateBuilder; + +/** + * @brief Transaction: EscrowCreate + * + * Type: ttESCROW_CREATE (1) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use EscrowCreateBuilder to construct new transactions. + */ +class EscrowCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttESCROW_CREATE; + + /** + * @brief Construct a EscrowCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit EscrowCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for EscrowCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfCondition (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCondition() const + { + if (hasCondition()) + { + return this->tx_->at(sfCondition); + } + return std::nullopt; + } + + /** + * @brief Check if sfCondition is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCondition() const + { + return this->tx_->isFieldPresent(sfCondition); + } + + /** + * @brief Get sfCancelAfter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCancelAfter() const + { + if (hasCancelAfter()) + { + return this->tx_->at(sfCancelAfter); + } + return std::nullopt; + } + + /** + * @brief Check if sfCancelAfter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCancelAfter() const + { + return this->tx_->isFieldPresent(sfCancelAfter); + } + + /** + * @brief Get sfFinishAfter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getFinishAfter() const + { + if (hasFinishAfter()) + { + return this->tx_->at(sfFinishAfter); + } + return std::nullopt; + } + + /** + * @brief Check if sfFinishAfter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasFinishAfter() const + { + return this->tx_->isFieldPresent(sfFinishAfter); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } +}; + +/** + * @brief Builder for EscrowCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class EscrowCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new EscrowCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param destination The sfDestination field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + EscrowCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& destination, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttESCROW_CREATE, account, sequence, fee) + { + setDestination(destination); + setAmount(amount); + } + + /** + * @brief Construct a EscrowCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + EscrowCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttESCROW_CREATE) + { + throw std::runtime_error("Invalid transaction type for EscrowCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowCreateBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + EscrowCreateBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfCondition (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowCreateBuilder& + setCondition(std::decay_t const& value) + { + object_[sfCondition] = value; + return *this; + } + + /** + * @brief Set sfCancelAfter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowCreateBuilder& + setCancelAfter(std::decay_t const& value) + { + object_[sfCancelAfter] = value; + return *this; + } + + /** + * @brief Set sfFinishAfter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowCreateBuilder& + setFinishAfter(std::decay_t const& value) + { + object_[sfFinishAfter] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowCreateBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Build and return the EscrowCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + EscrowCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return EscrowCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/EscrowFinish.h b/include/xrpl/protocol_autogen/transactions/EscrowFinish.h new file mode 100644 index 0000000000..20e9a089fb --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/EscrowFinish.h @@ -0,0 +1,264 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class EscrowFinishBuilder; + +/** + * @brief Transaction: EscrowFinish + * + * Type: ttESCROW_FINISH (2) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use EscrowFinishBuilder to construct new transactions. + */ +class EscrowFinish : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttESCROW_FINISH; + + /** + * @brief Construct a EscrowFinish transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit EscrowFinish(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for EscrowFinish"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfOwner (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOwner() const + { + return this->tx_->at(sfOwner); + } + + /** + * @brief Get sfOfferSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getOfferSequence() const + { + return this->tx_->at(sfOfferSequence); + } + + /** + * @brief Get sfFulfillment (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getFulfillment() const + { + if (hasFulfillment()) + { + return this->tx_->at(sfFulfillment); + } + return std::nullopt; + } + + /** + * @brief Check if sfFulfillment is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasFulfillment() const + { + return this->tx_->isFieldPresent(sfFulfillment); + } + + /** + * @brief Get sfCondition (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCondition() const + { + if (hasCondition()) + { + return this->tx_->at(sfCondition); + } + return std::nullopt; + } + + /** + * @brief Check if sfCondition is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCondition() const + { + return this->tx_->isFieldPresent(sfCondition); + } + + /** + * @brief Get sfCredentialIDs (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCredentialIDs() const + { + if (hasCredentialIDs()) + { + return this->tx_->at(sfCredentialIDs); + } + return std::nullopt; + } + + /** + * @brief Check if sfCredentialIDs is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCredentialIDs() const + { + return this->tx_->isFieldPresent(sfCredentialIDs); + } +}; + +/** + * @brief Builder for EscrowFinish transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class EscrowFinishBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new EscrowFinishBuilder with required fields. + * @param account The account initiating the transaction. + * @param owner The sfOwner field value. + * @param offerSequence The sfOfferSequence field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + EscrowFinishBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& owner, std::decay_t const& offerSequence, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttESCROW_FINISH, account, sequence, fee) + { + setOwner(owner); + setOfferSequence(offerSequence); + } + + /** + * @brief Construct a EscrowFinishBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + EscrowFinishBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttESCROW_FINISH) + { + throw std::runtime_error("Invalid transaction type for EscrowFinishBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfOwner (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowFinishBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfOfferSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + EscrowFinishBuilder& + setOfferSequence(std::decay_t const& value) + { + object_[sfOfferSequence] = value; + return *this; + } + + /** + * @brief Set sfFulfillment (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowFinishBuilder& + setFulfillment(std::decay_t const& value) + { + object_[sfFulfillment] = value; + return *this; + } + + /** + * @brief Set sfCondition (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowFinishBuilder& + setCondition(std::decay_t const& value) + { + object_[sfCondition] = value; + return *this; + } + + /** + * @brief Set sfCredentialIDs (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + EscrowFinishBuilder& + setCredentialIDs(std::decay_t const& value) + { + object_[sfCredentialIDs] = value; + return *this; + } + + /** + * @brief Build and return the EscrowFinish wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + EscrowFinish + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return EscrowFinish{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LedgerStateFix.h b/include/xrpl/protocol_autogen/transactions/LedgerStateFix.h new file mode 100644 index 0000000000..6f60b81a04 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LedgerStateFix.h @@ -0,0 +1,166 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LedgerStateFixBuilder; + +/** + * @brief Transaction: LedgerStateFix + * + * Type: ttLEDGER_STATE_FIX (53) + * Delegable: Delegation::delegable + * Amendment: fixNFTokenPageLinks + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LedgerStateFixBuilder to construct new transactions. + */ +class LedgerStateFix : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLEDGER_STATE_FIX; + + /** + * @brief Construct a LedgerStateFix transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LedgerStateFix(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LedgerStateFix"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLedgerFixType (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT16::type::value_type + getLedgerFixType() const + { + return this->tx_->at(sfLedgerFixType); + } + + /** + * @brief Get sfOwner (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOwner() const + { + if (hasOwner()) + { + return this->tx_->at(sfOwner); + } + return std::nullopt; + } + + /** + * @brief Check if sfOwner is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOwner() const + { + return this->tx_->isFieldPresent(sfOwner); + } +}; + +/** + * @brief Builder for LedgerStateFix transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LedgerStateFixBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LedgerStateFixBuilder with required fields. + * @param account The account initiating the transaction. + * @param ledgerFixType The sfLedgerFixType field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LedgerStateFixBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& ledgerFixType, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLEDGER_STATE_FIX, account, sequence, fee) + { + setLedgerFixType(ledgerFixType); + } + + /** + * @brief Construct a LedgerStateFixBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LedgerStateFixBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLEDGER_STATE_FIX) + { + throw std::runtime_error("Invalid transaction type for LedgerStateFixBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLedgerFixType (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LedgerStateFixBuilder& + setLedgerFixType(std::decay_t const& value) + { + object_[sfLedgerFixType] = value; + return *this; + } + + /** + * @brief Set sfOwner (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LedgerStateFixBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Build and return the LedgerStateFix wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LedgerStateFix + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LedgerStateFix{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverClawback.h b/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverClawback.h new file mode 100644 index 0000000000..d8a9d9d52a --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverClawback.h @@ -0,0 +1,181 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanBrokerCoverClawbackBuilder; + +/** + * @brief Transaction: LoanBrokerCoverClawback + * + * Type: ttLOAN_BROKER_COVER_CLAWBACK (78) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanBrokerCoverClawbackBuilder to construct new transactions. + */ +class LoanBrokerCoverClawback : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_BROKER_COVER_CLAWBACK; + + /** + * @brief Construct a LoanBrokerCoverClawback transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanBrokerCoverClawback(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerCoverClawback"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanBrokerID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanBrokerID() const + { + if (hasLoanBrokerID()) + { + return this->tx_->at(sfLoanBrokerID); + } + return std::nullopt; + } + + /** + * @brief Check if sfLoanBrokerID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanBrokerID() const + { + return this->tx_->isFieldPresent(sfLoanBrokerID); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } +}; + +/** + * @brief Builder for LoanBrokerCoverClawback transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanBrokerCoverClawbackBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanBrokerCoverClawbackBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanBrokerCoverClawbackBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_BROKER_COVER_CLAWBACK, account, sequence, fee) + { + } + + /** + * @brief Construct a LoanBrokerCoverClawbackBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanBrokerCoverClawbackBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_BROKER_COVER_CLAWBACK) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerCoverClawbackBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanBrokerID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverClawbackBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverClawbackBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Build and return the LoanBrokerCoverClawback wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanBrokerCoverClawback + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanBrokerCoverClawback{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverDeposit.h b/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverDeposit.h new file mode 100644 index 0000000000..baa567a7ac --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverDeposit.h @@ -0,0 +1,155 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanBrokerCoverDepositBuilder; + +/** + * @brief Transaction: LoanBrokerCoverDeposit + * + * Type: ttLOAN_BROKER_COVER_DEPOSIT (76) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanBrokerCoverDepositBuilder to construct new transactions. + */ +class LoanBrokerCoverDeposit : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_BROKER_COVER_DEPOSIT; + + /** + * @brief Construct a LoanBrokerCoverDeposit transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanBrokerCoverDeposit(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerCoverDeposit"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanBrokerID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanBrokerID() const + { + return this->tx_->at(sfLoanBrokerID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } +}; + +/** + * @brief Builder for LoanBrokerCoverDeposit transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanBrokerCoverDepositBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanBrokerCoverDepositBuilder with required fields. + * @param account The account initiating the transaction. + * @param loanBrokerID The sfLoanBrokerID field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanBrokerCoverDepositBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& loanBrokerID, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_BROKER_COVER_DEPOSIT, account, sequence, fee) + { + setLoanBrokerID(loanBrokerID); + setAmount(amount); + } + + /** + * @brief Construct a LoanBrokerCoverDepositBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanBrokerCoverDepositBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_BROKER_COVER_DEPOSIT) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerCoverDepositBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanBrokerID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverDepositBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverDepositBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Build and return the LoanBrokerCoverDeposit wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanBrokerCoverDeposit + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanBrokerCoverDeposit{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverWithdraw.h b/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverWithdraw.h new file mode 100644 index 0000000000..3690b6a40a --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanBrokerCoverWithdraw.h @@ -0,0 +1,229 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanBrokerCoverWithdrawBuilder; + +/** + * @brief Transaction: LoanBrokerCoverWithdraw + * + * Type: ttLOAN_BROKER_COVER_WITHDRAW (77) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: mayAuthorizeMPT + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanBrokerCoverWithdrawBuilder to construct new transactions. + */ +class LoanBrokerCoverWithdraw : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_BROKER_COVER_WITHDRAW; + + /** + * @brief Construct a LoanBrokerCoverWithdraw transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanBrokerCoverWithdraw(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerCoverWithdraw"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanBrokerID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanBrokerID() const + { + return this->tx_->at(sfLoanBrokerID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfDestination (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestination() const + { + if (hasDestination()) + { + return this->tx_->at(sfDestination); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestination is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestination() const + { + return this->tx_->isFieldPresent(sfDestination); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } +}; + +/** + * @brief Builder for LoanBrokerCoverWithdraw transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanBrokerCoverWithdrawBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanBrokerCoverWithdrawBuilder with required fields. + * @param account The account initiating the transaction. + * @param loanBrokerID The sfLoanBrokerID field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanBrokerCoverWithdrawBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& loanBrokerID, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_BROKER_COVER_WITHDRAW, account, sequence, fee) + { + setLoanBrokerID(loanBrokerID); + setAmount(amount); + } + + /** + * @brief Construct a LoanBrokerCoverWithdrawBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanBrokerCoverWithdrawBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_BROKER_COVER_WITHDRAW) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerCoverWithdrawBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanBrokerID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverWithdrawBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverWithdrawBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverWithdrawBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerCoverWithdrawBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Build and return the LoanBrokerCoverWithdraw wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanBrokerCoverWithdraw + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanBrokerCoverWithdraw{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanBrokerDelete.h b/include/xrpl/protocol_autogen/transactions/LoanBrokerDelete.h new file mode 100644 index 0000000000..2c174ae500 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanBrokerDelete.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanBrokerDeleteBuilder; + +/** + * @brief Transaction: LoanBrokerDelete + * + * Type: ttLOAN_BROKER_DELETE (75) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: mustDeleteAcct | mayAuthorizeMPT + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanBrokerDeleteBuilder to construct new transactions. + */ +class LoanBrokerDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_BROKER_DELETE; + + /** + * @brief Construct a LoanBrokerDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanBrokerDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanBrokerID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanBrokerID() const + { + return this->tx_->at(sfLoanBrokerID); + } +}; + +/** + * @brief Builder for LoanBrokerDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanBrokerDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanBrokerDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param loanBrokerID The sfLoanBrokerID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanBrokerDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& loanBrokerID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_BROKER_DELETE, account, sequence, fee) + { + setLoanBrokerID(loanBrokerID); + } + + /** + * @brief Construct a LoanBrokerDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanBrokerDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_BROKER_DELETE) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanBrokerID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerDeleteBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Build and return the LoanBrokerDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanBrokerDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanBrokerDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanBrokerSet.h b/include/xrpl/protocol_autogen/transactions/LoanBrokerSet.h new file mode 100644 index 0000000000..ba6ca06266 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanBrokerSet.h @@ -0,0 +1,351 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanBrokerSetBuilder; + +/** + * @brief Transaction: LoanBrokerSet + * + * Type: ttLOAN_BROKER_SET (74) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: createPseudoAcct | mayAuthorizeMPT + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanBrokerSetBuilder to construct new transactions. + */ +class LoanBrokerSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_BROKER_SET; + + /** + * @brief Construct a LoanBrokerSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanBrokerSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfVaultID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getVaultID() const + { + return this->tx_->at(sfVaultID); + } + + /** + * @brief Get sfLoanBrokerID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanBrokerID() const + { + if (hasLoanBrokerID()) + { + return this->tx_->at(sfLoanBrokerID); + } + return std::nullopt; + } + + /** + * @brief Check if sfLoanBrokerID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanBrokerID() const + { + return this->tx_->isFieldPresent(sfLoanBrokerID); + } + + /** + * @brief Get sfData (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + { + return this->tx_->at(sfData); + } + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->tx_->isFieldPresent(sfData); + } + + /** + * @brief Get sfManagementFeeRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getManagementFeeRate() const + { + if (hasManagementFeeRate()) + { + return this->tx_->at(sfManagementFeeRate); + } + return std::nullopt; + } + + /** + * @brief Check if sfManagementFeeRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasManagementFeeRate() const + { + return this->tx_->isFieldPresent(sfManagementFeeRate); + } + + /** + * @brief Get sfDebtMaximum (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDebtMaximum() const + { + if (hasDebtMaximum()) + { + return this->tx_->at(sfDebtMaximum); + } + return std::nullopt; + } + + /** + * @brief Check if sfDebtMaximum is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDebtMaximum() const + { + return this->tx_->isFieldPresent(sfDebtMaximum); + } + + /** + * @brief Get sfCoverRateMinimum (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCoverRateMinimum() const + { + if (hasCoverRateMinimum()) + { + return this->tx_->at(sfCoverRateMinimum); + } + return std::nullopt; + } + + /** + * @brief Check if sfCoverRateMinimum is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCoverRateMinimum() const + { + return this->tx_->isFieldPresent(sfCoverRateMinimum); + } + + /** + * @brief Get sfCoverRateLiquidation (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCoverRateLiquidation() const + { + if (hasCoverRateLiquidation()) + { + return this->tx_->at(sfCoverRateLiquidation); + } + return std::nullopt; + } + + /** + * @brief Check if sfCoverRateLiquidation is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCoverRateLiquidation() const + { + return this->tx_->isFieldPresent(sfCoverRateLiquidation); + } +}; + +/** + * @brief Builder for LoanBrokerSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanBrokerSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanBrokerSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param vaultID The sfVaultID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanBrokerSetBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& vaultID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_BROKER_SET, account, sequence, fee) + { + setVaultID(vaultID); + } + + /** + * @brief Construct a LoanBrokerSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanBrokerSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_BROKER_SET) + { + throw std::runtime_error("Invalid transaction type for LoanBrokerSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfVaultID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanBrokerSetBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Set sfLoanBrokerID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerSetBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Set sfData (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerSetBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Set sfManagementFeeRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerSetBuilder& + setManagementFeeRate(std::decay_t const& value) + { + object_[sfManagementFeeRate] = value; + return *this; + } + + /** + * @brief Set sfDebtMaximum (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerSetBuilder& + setDebtMaximum(std::decay_t const& value) + { + object_[sfDebtMaximum] = value; + return *this; + } + + /** + * @brief Set sfCoverRateMinimum (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerSetBuilder& + setCoverRateMinimum(std::decay_t const& value) + { + object_[sfCoverRateMinimum] = value; + return *this; + } + + /** + * @brief Set sfCoverRateLiquidation (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanBrokerSetBuilder& + setCoverRateLiquidation(std::decay_t const& value) + { + object_[sfCoverRateLiquidation] = value; + return *this; + } + + /** + * @brief Build and return the LoanBrokerSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanBrokerSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanBrokerSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanDelete.h b/include/xrpl/protocol_autogen/transactions/LoanDelete.h new file mode 100644 index 0000000000..df1b49d17e --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanDelete.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanDeleteBuilder; + +/** + * @brief Transaction: LoanDelete + * + * Type: ttLOAN_DELETE (81) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanDeleteBuilder to construct new transactions. + */ +class LoanDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_DELETE; + + /** + * @brief Construct a LoanDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanID() const + { + return this->tx_->at(sfLoanID); + } +}; + +/** + * @brief Builder for LoanDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param loanID The sfLoanID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& loanID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_DELETE, account, sequence, fee) + { + setLoanID(loanID); + } + + /** + * @brief Construct a LoanDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_DELETE) + { + throw std::runtime_error("Invalid transaction type for LoanDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanDeleteBuilder& + setLoanID(std::decay_t const& value) + { + object_[sfLoanID] = value; + return *this; + } + + /** + * @brief Build and return the LoanDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanManage.h b/include/xrpl/protocol_autogen/transactions/LoanManage.h new file mode 100644 index 0000000000..3da31e4487 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanManage.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanManageBuilder; + +/** + * @brief Transaction: LoanManage + * + * Type: ttLOAN_MANAGE (82) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: mayModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanManageBuilder to construct new transactions. + */ +class LoanManage : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_MANAGE; + + /** + * @brief Construct a LoanManage transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanManage(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanManage"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanID() const + { + return this->tx_->at(sfLoanID); + } +}; + +/** + * @brief Builder for LoanManage transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanManageBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanManageBuilder with required fields. + * @param account The account initiating the transaction. + * @param loanID The sfLoanID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanManageBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& loanID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_MANAGE, account, sequence, fee) + { + setLoanID(loanID); + } + + /** + * @brief Construct a LoanManageBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanManageBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_MANAGE) + { + throw std::runtime_error("Invalid transaction type for LoanManageBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanManageBuilder& + setLoanID(std::decay_t const& value) + { + object_[sfLoanID] = value; + return *this; + } + + /** + * @brief Build and return the LoanManage wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanManage + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanManage{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanPay.h b/include/xrpl/protocol_autogen/transactions/LoanPay.h new file mode 100644 index 0000000000..e0b4376e18 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanPay.h @@ -0,0 +1,155 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanPayBuilder; + +/** + * @brief Transaction: LoanPay + * + * Type: ttLOAN_PAY (84) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: mayAuthorizeMPT | mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanPayBuilder to construct new transactions. + */ +class LoanPay : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_PAY; + + /** + * @brief Construct a LoanPay transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanPay(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanPay"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanID() const + { + return this->tx_->at(sfLoanID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } +}; + +/** + * @brief Builder for LoanPay transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanPayBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanPayBuilder with required fields. + * @param account The account initiating the transaction. + * @param loanID The sfLoanID field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanPayBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& loanID, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_PAY, account, sequence, fee) + { + setLoanID(loanID); + setAmount(amount); + } + + /** + * @brief Construct a LoanPayBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanPayBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_PAY) + { + throw std::runtime_error("Invalid transaction type for LoanPayBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanPayBuilder& + setLoanID(std::decay_t const& value) + { + object_[sfLoanID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + LoanPayBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Build and return the LoanPay wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanPay + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanPay{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/LoanSet.h b/include/xrpl/protocol_autogen/transactions/LoanSet.h new file mode 100644 index 0000000000..7d6181f517 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/LoanSet.h @@ -0,0 +1,706 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class LoanSetBuilder; + +/** + * @brief Transaction: LoanSet + * + * Type: ttLOAN_SET (80) + * Delegable: Delegation::notDelegable + * Amendment: featureLendingProtocol + * Privileges: mayAuthorizeMPT | mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use LoanSetBuilder to construct new transactions. + */ +class LoanSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttLOAN_SET; + + /** + * @brief Construct a LoanSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit LoanSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for LoanSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLoanBrokerID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getLoanBrokerID() const + { + return this->tx_->at(sfLoanBrokerID); + } + + /** + * @brief Get sfData (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + { + return this->tx_->at(sfData); + } + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->tx_->isFieldPresent(sfData); + } + + /** + * @brief Get sfCounterparty (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCounterparty() const + { + if (hasCounterparty()) + { + return this->tx_->at(sfCounterparty); + } + return std::nullopt; + } + + /** + * @brief Check if sfCounterparty is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCounterparty() const + { + return this->tx_->isFieldPresent(sfCounterparty); + } + /** + * @brief Get sfCounterpartySignature (soeOPTIONAL) + * @note This is an untyped field. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional + getCounterpartySignature() const + { + if (this->tx_->isFieldPresent(sfCounterpartySignature)) + return this->tx_->getFieldObject(sfCounterpartySignature); + return std::nullopt; + } + + /** + * @brief Check if sfCounterpartySignature is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCounterpartySignature() const + { + return this->tx_->isFieldPresent(sfCounterpartySignature); + } + + /** + * @brief Get sfLoanOriginationFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanOriginationFee() const + { + if (hasLoanOriginationFee()) + { + return this->tx_->at(sfLoanOriginationFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfLoanOriginationFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanOriginationFee() const + { + return this->tx_->isFieldPresent(sfLoanOriginationFee); + } + + /** + * @brief Get sfLoanServiceFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLoanServiceFee() const + { + if (hasLoanServiceFee()) + { + return this->tx_->at(sfLoanServiceFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfLoanServiceFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLoanServiceFee() const + { + return this->tx_->isFieldPresent(sfLoanServiceFee); + } + + /** + * @brief Get sfLatePaymentFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLatePaymentFee() const + { + if (hasLatePaymentFee()) + { + return this->tx_->at(sfLatePaymentFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfLatePaymentFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLatePaymentFee() const + { + return this->tx_->isFieldPresent(sfLatePaymentFee); + } + + /** + * @brief Get sfClosePaymentFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getClosePaymentFee() const + { + if (hasClosePaymentFee()) + { + return this->tx_->at(sfClosePaymentFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfClosePaymentFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasClosePaymentFee() const + { + return this->tx_->isFieldPresent(sfClosePaymentFee); + } + + /** + * @brief Get sfOverpaymentFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOverpaymentFee() const + { + if (hasOverpaymentFee()) + { + return this->tx_->at(sfOverpaymentFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfOverpaymentFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOverpaymentFee() const + { + return this->tx_->isFieldPresent(sfOverpaymentFee); + } + + /** + * @brief Get sfInterestRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getInterestRate() const + { + if (hasInterestRate()) + { + return this->tx_->at(sfInterestRate); + } + return std::nullopt; + } + + /** + * @brief Check if sfInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasInterestRate() const + { + return this->tx_->isFieldPresent(sfInterestRate); + } + + /** + * @brief Get sfLateInterestRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLateInterestRate() const + { + if (hasLateInterestRate()) + { + return this->tx_->at(sfLateInterestRate); + } + return std::nullopt; + } + + /** + * @brief Check if sfLateInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLateInterestRate() const + { + return this->tx_->isFieldPresent(sfLateInterestRate); + } + + /** + * @brief Get sfCloseInterestRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCloseInterestRate() const + { + if (hasCloseInterestRate()) + { + return this->tx_->at(sfCloseInterestRate); + } + return std::nullopt; + } + + /** + * @brief Check if sfCloseInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCloseInterestRate() const + { + return this->tx_->isFieldPresent(sfCloseInterestRate); + } + + /** + * @brief Get sfOverpaymentInterestRate (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOverpaymentInterestRate() const + { + if (hasOverpaymentInterestRate()) + { + return this->tx_->at(sfOverpaymentInterestRate); + } + return std::nullopt; + } + + /** + * @brief Check if sfOverpaymentInterestRate is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOverpaymentInterestRate() const + { + return this->tx_->isFieldPresent(sfOverpaymentInterestRate); + } + + /** + * @brief Get sfPrincipalRequested (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_NUMBER::type::value_type + getPrincipalRequested() const + { + return this->tx_->at(sfPrincipalRequested); + } + + /** + * @brief Get sfPaymentTotal (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPaymentTotal() const + { + if (hasPaymentTotal()) + { + return this->tx_->at(sfPaymentTotal); + } + return std::nullopt; + } + + /** + * @brief Check if sfPaymentTotal is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPaymentTotal() const + { + return this->tx_->isFieldPresent(sfPaymentTotal); + } + + /** + * @brief Get sfPaymentInterval (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPaymentInterval() const + { + if (hasPaymentInterval()) + { + return this->tx_->at(sfPaymentInterval); + } + return std::nullopt; + } + + /** + * @brief Check if sfPaymentInterval is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPaymentInterval() const + { + return this->tx_->isFieldPresent(sfPaymentInterval); + } + + /** + * @brief Get sfGracePeriod (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getGracePeriod() const + { + if (hasGracePeriod()) + { + return this->tx_->at(sfGracePeriod); + } + return std::nullopt; + } + + /** + * @brief Check if sfGracePeriod is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasGracePeriod() const + { + return this->tx_->isFieldPresent(sfGracePeriod); + } +}; + +/** + * @brief Builder for LoanSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class LoanSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new LoanSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param loanBrokerID The sfLoanBrokerID field value. + * @param principalRequested The sfPrincipalRequested field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + LoanSetBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& loanBrokerID, std::decay_t const& principalRequested, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttLOAN_SET, account, sequence, fee) + { + setLoanBrokerID(loanBrokerID); + setPrincipalRequested(principalRequested); + } + + /** + * @brief Construct a LoanSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + LoanSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttLOAN_SET) + { + throw std::runtime_error("Invalid transaction type for LoanSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLoanBrokerID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setLoanBrokerID(std::decay_t const& value) + { + object_[sfLoanBrokerID] = value; + return *this; + } + + /** + * @brief Set sfData (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Set sfCounterparty (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setCounterparty(std::decay_t const& value) + { + object_[sfCounterparty] = value; + return *this; + } + + /** + * @brief Set sfCounterpartySignature (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setCounterpartySignature(STObject const& value) + { + object_.setFieldObject(sfCounterpartySignature, value); + return *this; + } + + /** + * @brief Set sfLoanOriginationFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setLoanOriginationFee(std::decay_t const& value) + { + object_[sfLoanOriginationFee] = value; + return *this; + } + + /** + * @brief Set sfLoanServiceFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setLoanServiceFee(std::decay_t const& value) + { + object_[sfLoanServiceFee] = value; + return *this; + } + + /** + * @brief Set sfLatePaymentFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setLatePaymentFee(std::decay_t const& value) + { + object_[sfLatePaymentFee] = value; + return *this; + } + + /** + * @brief Set sfClosePaymentFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setClosePaymentFee(std::decay_t const& value) + { + object_[sfClosePaymentFee] = value; + return *this; + } + + /** + * @brief Set sfOverpaymentFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setOverpaymentFee(std::decay_t const& value) + { + object_[sfOverpaymentFee] = value; + return *this; + } + + /** + * @brief Set sfInterestRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setInterestRate(std::decay_t const& value) + { + object_[sfInterestRate] = value; + return *this; + } + + /** + * @brief Set sfLateInterestRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setLateInterestRate(std::decay_t const& value) + { + object_[sfLateInterestRate] = value; + return *this; + } + + /** + * @brief Set sfCloseInterestRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setCloseInterestRate(std::decay_t const& value) + { + object_[sfCloseInterestRate] = value; + return *this; + } + + /** + * @brief Set sfOverpaymentInterestRate (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setOverpaymentInterestRate(std::decay_t const& value) + { + object_[sfOverpaymentInterestRate] = value; + return *this; + } + + /** + * @brief Set sfPrincipalRequested (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setPrincipalRequested(std::decay_t const& value) + { + object_[sfPrincipalRequested] = value; + return *this; + } + + /** + * @brief Set sfPaymentTotal (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setPaymentTotal(std::decay_t const& value) + { + object_[sfPaymentTotal] = value; + return *this; + } + + /** + * @brief Set sfPaymentInterval (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setPaymentInterval(std::decay_t const& value) + { + object_[sfPaymentInterval] = value; + return *this; + } + + /** + * @brief Set sfGracePeriod (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + LoanSetBuilder& + setGracePeriod(std::decay_t const& value) + { + object_[sfGracePeriod] = value; + return *this; + } + + /** + * @brief Build and return the LoanSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + LoanSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return LoanSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/MPTokenAuthorize.h b/include/xrpl/protocol_autogen/transactions/MPTokenAuthorize.h new file mode 100644 index 0000000000..a4641f5dc0 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/MPTokenAuthorize.h @@ -0,0 +1,166 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class MPTokenAuthorizeBuilder; + +/** + * @brief Transaction: MPTokenAuthorize + * + * Type: ttMPTOKEN_AUTHORIZE (57) + * Delegable: Delegation::delegable + * Amendment: featureMPTokensV1 + * Privileges: mustAuthorizeMPT + * + * Immutable wrapper around STTx providing type-safe field access. + * Use MPTokenAuthorizeBuilder to construct new transactions. + */ +class MPTokenAuthorize : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttMPTOKEN_AUTHORIZE; + + /** + * @brief Construct a MPTokenAuthorize transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit MPTokenAuthorize(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for MPTokenAuthorize"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfMPTokenIssuanceID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT192::type::value_type + getMPTokenIssuanceID() const + { + return this->tx_->at(sfMPTokenIssuanceID); + } + + /** + * @brief Get sfHolder (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getHolder() const + { + if (hasHolder()) + { + return this->tx_->at(sfHolder); + } + return std::nullopt; + } + + /** + * @brief Check if sfHolder is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasHolder() const + { + return this->tx_->isFieldPresent(sfHolder); + } +}; + +/** + * @brief Builder for MPTokenAuthorize transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class MPTokenAuthorizeBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new MPTokenAuthorizeBuilder with required fields. + * @param account The account initiating the transaction. + * @param mPTokenIssuanceID The sfMPTokenIssuanceID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + MPTokenAuthorizeBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& mPTokenIssuanceID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttMPTOKEN_AUTHORIZE, account, sequence, fee) + { + setMPTokenIssuanceID(mPTokenIssuanceID); + } + + /** + * @brief Construct a MPTokenAuthorizeBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + MPTokenAuthorizeBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttMPTOKEN_AUTHORIZE) + { + throw std::runtime_error("Invalid transaction type for MPTokenAuthorizeBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfMPTokenIssuanceID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenAuthorizeBuilder& + setMPTokenIssuanceID(std::decay_t const& value) + { + object_[sfMPTokenIssuanceID] = value; + return *this; + } + + /** + * @brief Set sfHolder (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenAuthorizeBuilder& + setHolder(std::decay_t const& value) + { + object_[sfHolder] = value; + return *this; + } + + /** + * @brief Build and return the MPTokenAuthorize wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + MPTokenAuthorize + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return MPTokenAuthorize{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceCreate.h b/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceCreate.h new file mode 100644 index 0000000000..6f5c50fc4a --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceCreate.h @@ -0,0 +1,327 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class MPTokenIssuanceCreateBuilder; + +/** + * @brief Transaction: MPTokenIssuanceCreate + * + * Type: ttMPTOKEN_ISSUANCE_CREATE (54) + * Delegable: Delegation::delegable + * Amendment: featureMPTokensV1 + * Privileges: createMPTIssuance + * + * Immutable wrapper around STTx providing type-safe field access. + * Use MPTokenIssuanceCreateBuilder to construct new transactions. + */ +class MPTokenIssuanceCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttMPTOKEN_ISSUANCE_CREATE; + + /** + * @brief Construct a MPTokenIssuanceCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit MPTokenIssuanceCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for MPTokenIssuanceCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAssetScale (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetScale() const + { + if (hasAssetScale()) + { + return this->tx_->at(sfAssetScale); + } + return std::nullopt; + } + + /** + * @brief Check if sfAssetScale is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetScale() const + { + return this->tx_->isFieldPresent(sfAssetScale); + } + + /** + * @brief Get sfTransferFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTransferFee() const + { + if (hasTransferFee()) + { + return this->tx_->at(sfTransferFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfTransferFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTransferFee() const + { + return this->tx_->isFieldPresent(sfTransferFee); + } + + /** + * @brief Get sfMaximumAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMaximumAmount() const + { + if (hasMaximumAmount()) + { + return this->tx_->at(sfMaximumAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfMaximumAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMaximumAmount() const + { + return this->tx_->isFieldPresent(sfMaximumAmount); + } + + /** + * @brief Get sfMPTokenMetadata (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMPTokenMetadata() const + { + if (hasMPTokenMetadata()) + { + return this->tx_->at(sfMPTokenMetadata); + } + return std::nullopt; + } + + /** + * @brief Check if sfMPTokenMetadata is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMPTokenMetadata() const + { + return this->tx_->isFieldPresent(sfMPTokenMetadata); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + { + return this->tx_->at(sfDomainID); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->tx_->isFieldPresent(sfDomainID); + } + + /** + * @brief Get sfMutableFlags (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMutableFlags() const + { + if (hasMutableFlags()) + { + return this->tx_->at(sfMutableFlags); + } + return std::nullopt; + } + + /** + * @brief Check if sfMutableFlags is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMutableFlags() const + { + return this->tx_->isFieldPresent(sfMutableFlags); + } +}; + +/** + * @brief Builder for MPTokenIssuanceCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class MPTokenIssuanceCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new MPTokenIssuanceCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + MPTokenIssuanceCreateBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttMPTOKEN_ISSUANCE_CREATE, account, sequence, fee) + { + } + + /** + * @brief Construct a MPTokenIssuanceCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + MPTokenIssuanceCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttMPTOKEN_ISSUANCE_CREATE) + { + throw std::runtime_error("Invalid transaction type for MPTokenIssuanceCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAssetScale (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceCreateBuilder& + setAssetScale(std::decay_t const& value) + { + object_[sfAssetScale] = value; + return *this; + } + + /** + * @brief Set sfTransferFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceCreateBuilder& + setTransferFee(std::decay_t const& value) + { + object_[sfTransferFee] = value; + return *this; + } + + /** + * @brief Set sfMaximumAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceCreateBuilder& + setMaximumAmount(std::decay_t const& value) + { + object_[sfMaximumAmount] = value; + return *this; + } + + /** + * @brief Set sfMPTokenMetadata (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceCreateBuilder& + setMPTokenMetadata(std::decay_t const& value) + { + object_[sfMPTokenMetadata] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceCreateBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Set sfMutableFlags (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceCreateBuilder& + setMutableFlags(std::decay_t const& value) + { + object_[sfMutableFlags] = value; + return *this; + } + + /** + * @brief Build and return the MPTokenIssuanceCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + MPTokenIssuanceCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return MPTokenIssuanceCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceDestroy.h b/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceDestroy.h new file mode 100644 index 0000000000..28d2e49971 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceDestroy.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class MPTokenIssuanceDestroyBuilder; + +/** + * @brief Transaction: MPTokenIssuanceDestroy + * + * Type: ttMPTOKEN_ISSUANCE_DESTROY (55) + * Delegable: Delegation::delegable + * Amendment: featureMPTokensV1 + * Privileges: destroyMPTIssuance + * + * Immutable wrapper around STTx providing type-safe field access. + * Use MPTokenIssuanceDestroyBuilder to construct new transactions. + */ +class MPTokenIssuanceDestroy : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttMPTOKEN_ISSUANCE_DESTROY; + + /** + * @brief Construct a MPTokenIssuanceDestroy transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit MPTokenIssuanceDestroy(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for MPTokenIssuanceDestroy"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfMPTokenIssuanceID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT192::type::value_type + getMPTokenIssuanceID() const + { + return this->tx_->at(sfMPTokenIssuanceID); + } +}; + +/** + * @brief Builder for MPTokenIssuanceDestroy transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class MPTokenIssuanceDestroyBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new MPTokenIssuanceDestroyBuilder with required fields. + * @param account The account initiating the transaction. + * @param mPTokenIssuanceID The sfMPTokenIssuanceID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + MPTokenIssuanceDestroyBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& mPTokenIssuanceID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttMPTOKEN_ISSUANCE_DESTROY, account, sequence, fee) + { + setMPTokenIssuanceID(mPTokenIssuanceID); + } + + /** + * @brief Construct a MPTokenIssuanceDestroyBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + MPTokenIssuanceDestroyBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttMPTOKEN_ISSUANCE_DESTROY) + { + throw std::runtime_error("Invalid transaction type for MPTokenIssuanceDestroyBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfMPTokenIssuanceID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceDestroyBuilder& + setMPTokenIssuanceID(std::decay_t const& value) + { + object_[sfMPTokenIssuanceID] = value; + return *this; + } + + /** + * @brief Build and return the MPTokenIssuanceDestroy wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + MPTokenIssuanceDestroy + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return MPTokenIssuanceDestroy{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceSet.h b/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceSet.h new file mode 100644 index 0000000000..429b252e95 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/MPTokenIssuanceSet.h @@ -0,0 +1,314 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class MPTokenIssuanceSetBuilder; + +/** + * @brief Transaction: MPTokenIssuanceSet + * + * Type: ttMPTOKEN_ISSUANCE_SET (56) + * Delegable: Delegation::delegable + * Amendment: featureMPTokensV1 + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use MPTokenIssuanceSetBuilder to construct new transactions. + */ +class MPTokenIssuanceSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttMPTOKEN_ISSUANCE_SET; + + /** + * @brief Construct a MPTokenIssuanceSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit MPTokenIssuanceSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for MPTokenIssuanceSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfMPTokenIssuanceID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT192::type::value_type + getMPTokenIssuanceID() const + { + return this->tx_->at(sfMPTokenIssuanceID); + } + + /** + * @brief Get sfHolder (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getHolder() const + { + if (hasHolder()) + { + return this->tx_->at(sfHolder); + } + return std::nullopt; + } + + /** + * @brief Check if sfHolder is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasHolder() const + { + return this->tx_->isFieldPresent(sfHolder); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + { + return this->tx_->at(sfDomainID); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->tx_->isFieldPresent(sfDomainID); + } + + /** + * @brief Get sfMPTokenMetadata (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMPTokenMetadata() const + { + if (hasMPTokenMetadata()) + { + return this->tx_->at(sfMPTokenMetadata); + } + return std::nullopt; + } + + /** + * @brief Check if sfMPTokenMetadata is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMPTokenMetadata() const + { + return this->tx_->isFieldPresent(sfMPTokenMetadata); + } + + /** + * @brief Get sfTransferFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTransferFee() const + { + if (hasTransferFee()) + { + return this->tx_->at(sfTransferFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfTransferFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTransferFee() const + { + return this->tx_->isFieldPresent(sfTransferFee); + } + + /** + * @brief Get sfMutableFlags (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMutableFlags() const + { + if (hasMutableFlags()) + { + return this->tx_->at(sfMutableFlags); + } + return std::nullopt; + } + + /** + * @brief Check if sfMutableFlags is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMutableFlags() const + { + return this->tx_->isFieldPresent(sfMutableFlags); + } +}; + +/** + * @brief Builder for MPTokenIssuanceSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class MPTokenIssuanceSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new MPTokenIssuanceSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param mPTokenIssuanceID The sfMPTokenIssuanceID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + MPTokenIssuanceSetBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& mPTokenIssuanceID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttMPTOKEN_ISSUANCE_SET, account, sequence, fee) + { + setMPTokenIssuanceID(mPTokenIssuanceID); + } + + /** + * @brief Construct a MPTokenIssuanceSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + MPTokenIssuanceSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttMPTOKEN_ISSUANCE_SET) + { + throw std::runtime_error("Invalid transaction type for MPTokenIssuanceSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfMPTokenIssuanceID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceSetBuilder& + setMPTokenIssuanceID(std::decay_t const& value) + { + object_[sfMPTokenIssuanceID] = value; + return *this; + } + + /** + * @brief Set sfHolder (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceSetBuilder& + setHolder(std::decay_t const& value) + { + object_[sfHolder] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceSetBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Set sfMPTokenMetadata (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceSetBuilder& + setMPTokenMetadata(std::decay_t const& value) + { + object_[sfMPTokenMetadata] = value; + return *this; + } + + /** + * @brief Set sfTransferFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceSetBuilder& + setTransferFee(std::decay_t const& value) + { + object_[sfTransferFee] = value; + return *this; + } + + /** + * @brief Set sfMutableFlags (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + MPTokenIssuanceSetBuilder& + setMutableFlags(std::decay_t const& value) + { + object_[sfMutableFlags] = value; + return *this; + } + + /** + * @brief Build and return the MPTokenIssuanceSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + MPTokenIssuanceSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return MPTokenIssuanceSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/NFTokenAcceptOffer.h b/include/xrpl/protocol_autogen/transactions/NFTokenAcceptOffer.h new file mode 100644 index 0000000000..53ae614ee4 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/NFTokenAcceptOffer.h @@ -0,0 +1,216 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class NFTokenAcceptOfferBuilder; + +/** + * @brief Transaction: NFTokenAcceptOffer + * + * Type: ttNFTOKEN_ACCEPT_OFFER (29) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use NFTokenAcceptOfferBuilder to construct new transactions. + */ +class NFTokenAcceptOffer : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttNFTOKEN_ACCEPT_OFFER; + + /** + * @brief Construct a NFTokenAcceptOffer transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit NFTokenAcceptOffer(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for NFTokenAcceptOffer"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfNFTokenBuyOffer (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNFTokenBuyOffer() const + { + if (hasNFTokenBuyOffer()) + { + return this->tx_->at(sfNFTokenBuyOffer); + } + return std::nullopt; + } + + /** + * @brief Check if sfNFTokenBuyOffer is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNFTokenBuyOffer() const + { + return this->tx_->isFieldPresent(sfNFTokenBuyOffer); + } + + /** + * @brief Get sfNFTokenSellOffer (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNFTokenSellOffer() const + { + if (hasNFTokenSellOffer()) + { + return this->tx_->at(sfNFTokenSellOffer); + } + return std::nullopt; + } + + /** + * @brief Check if sfNFTokenSellOffer is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNFTokenSellOffer() const + { + return this->tx_->isFieldPresent(sfNFTokenSellOffer); + } + + /** + * @brief Get sfNFTokenBrokerFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getNFTokenBrokerFee() const + { + if (hasNFTokenBrokerFee()) + { + return this->tx_->at(sfNFTokenBrokerFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfNFTokenBrokerFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasNFTokenBrokerFee() const + { + return this->tx_->isFieldPresent(sfNFTokenBrokerFee); + } +}; + +/** + * @brief Builder for NFTokenAcceptOffer transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class NFTokenAcceptOfferBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenAcceptOfferBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + NFTokenAcceptOfferBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttNFTOKEN_ACCEPT_OFFER, account, sequence, fee) + { + } + + /** + * @brief Construct a NFTokenAcceptOfferBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + NFTokenAcceptOfferBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttNFTOKEN_ACCEPT_OFFER) + { + throw std::runtime_error("Invalid transaction type for NFTokenAcceptOfferBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfNFTokenBuyOffer (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenAcceptOfferBuilder& + setNFTokenBuyOffer(std::decay_t const& value) + { + object_[sfNFTokenBuyOffer] = value; + return *this; + } + + /** + * @brief Set sfNFTokenSellOffer (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenAcceptOfferBuilder& + setNFTokenSellOffer(std::decay_t const& value) + { + object_[sfNFTokenSellOffer] = value; + return *this; + } + + /** + * @brief Set sfNFTokenBrokerFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenAcceptOfferBuilder& + setNFTokenBrokerFee(std::decay_t const& value) + { + object_[sfNFTokenBrokerFee] = value; + return *this; + } + + /** + * @brief Build and return the NFTokenAcceptOffer wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + NFTokenAcceptOffer + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return NFTokenAcceptOffer{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/NFTokenBurn.h b/include/xrpl/protocol_autogen/transactions/NFTokenBurn.h new file mode 100644 index 0000000000..123418d00a --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/NFTokenBurn.h @@ -0,0 +1,166 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class NFTokenBurnBuilder; + +/** + * @brief Transaction: NFTokenBurn + * + * Type: ttNFTOKEN_BURN (26) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: changeNFTCounts + * + * Immutable wrapper around STTx providing type-safe field access. + * Use NFTokenBurnBuilder to construct new transactions. + */ +class NFTokenBurn : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttNFTOKEN_BURN; + + /** + * @brief Construct a NFTokenBurn transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit NFTokenBurn(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for NFTokenBurn"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfNFTokenID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getNFTokenID() const + { + return this->tx_->at(sfNFTokenID); + } + + /** + * @brief Get sfOwner (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOwner() const + { + if (hasOwner()) + { + return this->tx_->at(sfOwner); + } + return std::nullopt; + } + + /** + * @brief Check if sfOwner is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOwner() const + { + return this->tx_->isFieldPresent(sfOwner); + } +}; + +/** + * @brief Builder for NFTokenBurn transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class NFTokenBurnBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenBurnBuilder with required fields. + * @param account The account initiating the transaction. + * @param nFTokenID The sfNFTokenID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + NFTokenBurnBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& nFTokenID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttNFTOKEN_BURN, account, sequence, fee) + { + setNFTokenID(nFTokenID); + } + + /** + * @brief Construct a NFTokenBurnBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + NFTokenBurnBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttNFTOKEN_BURN) + { + throw std::runtime_error("Invalid transaction type for NFTokenBurnBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfNFTokenID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenBurnBuilder& + setNFTokenID(std::decay_t const& value) + { + object_[sfNFTokenID] = value; + return *this; + } + + /** + * @brief Set sfOwner (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenBurnBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Build and return the NFTokenBurn wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + NFTokenBurn + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return NFTokenBurn{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/NFTokenCancelOffer.h b/include/xrpl/protocol_autogen/transactions/NFTokenCancelOffer.h new file mode 100644 index 0000000000..5fbbeca96c --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/NFTokenCancelOffer.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class NFTokenCancelOfferBuilder; + +/** + * @brief Transaction: NFTokenCancelOffer + * + * Type: ttNFTOKEN_CANCEL_OFFER (28) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use NFTokenCancelOfferBuilder to construct new transactions. + */ +class NFTokenCancelOffer : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttNFTOKEN_CANCEL_OFFER; + + /** + * @brief Construct a NFTokenCancelOffer transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit NFTokenCancelOffer(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for NFTokenCancelOffer"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfNFTokenOffers (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VECTOR256::type::value_type + getNFTokenOffers() const + { + return this->tx_->at(sfNFTokenOffers); + } +}; + +/** + * @brief Builder for NFTokenCancelOffer transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class NFTokenCancelOfferBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenCancelOfferBuilder with required fields. + * @param account The account initiating the transaction. + * @param nFTokenOffers The sfNFTokenOffers field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + NFTokenCancelOfferBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& nFTokenOffers, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttNFTOKEN_CANCEL_OFFER, account, sequence, fee) + { + setNFTokenOffers(nFTokenOffers); + } + + /** + * @brief Construct a NFTokenCancelOfferBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + NFTokenCancelOfferBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttNFTOKEN_CANCEL_OFFER) + { + throw std::runtime_error("Invalid transaction type for NFTokenCancelOfferBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfNFTokenOffers (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenCancelOfferBuilder& + setNFTokenOffers(std::decay_t const& value) + { + object_[sfNFTokenOffers] = value; + return *this; + } + + /** + * @brief Build and return the NFTokenCancelOffer wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + NFTokenCancelOffer + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return NFTokenCancelOffer{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/NFTokenCreateOffer.h b/include/xrpl/protocol_autogen/transactions/NFTokenCreateOffer.h new file mode 100644 index 0000000000..e820272f83 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/NFTokenCreateOffer.h @@ -0,0 +1,264 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class NFTokenCreateOfferBuilder; + +/** + * @brief Transaction: NFTokenCreateOffer + * + * Type: ttNFTOKEN_CREATE_OFFER (27) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use NFTokenCreateOfferBuilder to construct new transactions. + */ +class NFTokenCreateOffer : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttNFTOKEN_CREATE_OFFER; + + /** + * @brief Construct a NFTokenCreateOffer transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit NFTokenCreateOffer(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for NFTokenCreateOffer"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfNFTokenID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getNFTokenID() const + { + return this->tx_->at(sfNFTokenID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfDestination (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestination() const + { + if (hasDestination()) + { + return this->tx_->at(sfDestination); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestination is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestination() const + { + return this->tx_->isFieldPresent(sfDestination); + } + + /** + * @brief Get sfOwner (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOwner() const + { + if (hasOwner()) + { + return this->tx_->at(sfOwner); + } + return std::nullopt; + } + + /** + * @brief Check if sfOwner is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOwner() const + { + return this->tx_->isFieldPresent(sfOwner); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + { + return this->tx_->at(sfExpiration); + } + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->tx_->isFieldPresent(sfExpiration); + } +}; + +/** + * @brief Builder for NFTokenCreateOffer transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class NFTokenCreateOfferBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenCreateOfferBuilder with required fields. + * @param account The account initiating the transaction. + * @param nFTokenID The sfNFTokenID field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + NFTokenCreateOfferBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& nFTokenID, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttNFTOKEN_CREATE_OFFER, account, sequence, fee) + { + setNFTokenID(nFTokenID); + setAmount(amount); + } + + /** + * @brief Construct a NFTokenCreateOfferBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + NFTokenCreateOfferBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttNFTOKEN_CREATE_OFFER) + { + throw std::runtime_error("Invalid transaction type for NFTokenCreateOfferBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfNFTokenID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenCreateOfferBuilder& + setNFTokenID(std::decay_t const& value) + { + object_[sfNFTokenID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenCreateOfferBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenCreateOfferBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfOwner (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenCreateOfferBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenCreateOfferBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Build and return the NFTokenCreateOffer wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + NFTokenCreateOffer + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return NFTokenCreateOffer{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/NFTokenMint.h b/include/xrpl/protocol_autogen/transactions/NFTokenMint.h new file mode 100644 index 0000000000..9854147570 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/NFTokenMint.h @@ -0,0 +1,351 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class NFTokenMintBuilder; + +/** + * @brief Transaction: NFTokenMint + * + * Type: ttNFTOKEN_MINT (25) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: changeNFTCounts + * + * Immutable wrapper around STTx providing type-safe field access. + * Use NFTokenMintBuilder to construct new transactions. + */ +class NFTokenMint : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttNFTOKEN_MINT; + + /** + * @brief Construct a NFTokenMint transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit NFTokenMint(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for NFTokenMint"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfNFTokenTaxon (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getNFTokenTaxon() const + { + return this->tx_->at(sfNFTokenTaxon); + } + + /** + * @brief Get sfTransferFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getTransferFee() const + { + if (hasTransferFee()) + { + return this->tx_->at(sfTransferFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfTransferFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasTransferFee() const + { + return this->tx_->isFieldPresent(sfTransferFee); + } + + /** + * @brief Get sfIssuer (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getIssuer() const + { + if (hasIssuer()) + { + return this->tx_->at(sfIssuer); + } + return std::nullopt; + } + + /** + * @brief Check if sfIssuer is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasIssuer() const + { + return this->tx_->isFieldPresent(sfIssuer); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + { + return this->tx_->at(sfURI); + } + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->tx_->isFieldPresent(sfURI); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } + + /** + * @brief Get sfDestination (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestination() const + { + if (hasDestination()) + { + return this->tx_->at(sfDestination); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestination is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestination() const + { + return this->tx_->isFieldPresent(sfDestination); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + { + return this->tx_->at(sfExpiration); + } + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->tx_->isFieldPresent(sfExpiration); + } +}; + +/** + * @brief Builder for NFTokenMint transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class NFTokenMintBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenMintBuilder with required fields. + * @param account The account initiating the transaction. + * @param nFTokenTaxon The sfNFTokenTaxon field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + NFTokenMintBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& nFTokenTaxon, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttNFTOKEN_MINT, account, sequence, fee) + { + setNFTokenTaxon(nFTokenTaxon); + } + + /** + * @brief Construct a NFTokenMintBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + NFTokenMintBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttNFTOKEN_MINT) + { + throw std::runtime_error("Invalid transaction type for NFTokenMintBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfNFTokenTaxon (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenMintBuilder& + setNFTokenTaxon(std::decay_t const& value) + { + object_[sfNFTokenTaxon] = value; + return *this; + } + + /** + * @brief Set sfTransferFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenMintBuilder& + setTransferFee(std::decay_t const& value) + { + object_[sfTransferFee] = value; + return *this; + } + + /** + * @brief Set sfIssuer (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenMintBuilder& + setIssuer(std::decay_t const& value) + { + object_[sfIssuer] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenMintBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenMintBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenMintBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenMintBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Build and return the NFTokenMint wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + NFTokenMint + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return NFTokenMint{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/NFTokenModify.h b/include/xrpl/protocol_autogen/transactions/NFTokenModify.h new file mode 100644 index 0000000000..6f9b75532c --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/NFTokenModify.h @@ -0,0 +1,203 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class NFTokenModifyBuilder; + +/** + * @brief Transaction: NFTokenModify + * + * Type: ttNFTOKEN_MODIFY (61) + * Delegable: Delegation::delegable + * Amendment: featureDynamicNFT + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use NFTokenModifyBuilder to construct new transactions. + */ +class NFTokenModify : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttNFTOKEN_MODIFY; + + /** + * @brief Construct a NFTokenModify transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit NFTokenModify(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for NFTokenModify"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfNFTokenID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getNFTokenID() const + { + return this->tx_->at(sfNFTokenID); + } + + /** + * @brief Get sfOwner (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOwner() const + { + if (hasOwner()) + { + return this->tx_->at(sfOwner); + } + return std::nullopt; + } + + /** + * @brief Check if sfOwner is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOwner() const + { + return this->tx_->isFieldPresent(sfOwner); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + { + return this->tx_->at(sfURI); + } + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->tx_->isFieldPresent(sfURI); + } +}; + +/** + * @brief Builder for NFTokenModify transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class NFTokenModifyBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new NFTokenModifyBuilder with required fields. + * @param account The account initiating the transaction. + * @param nFTokenID The sfNFTokenID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + NFTokenModifyBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& nFTokenID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttNFTOKEN_MODIFY, account, sequence, fee) + { + setNFTokenID(nFTokenID); + } + + /** + * @brief Construct a NFTokenModifyBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + NFTokenModifyBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttNFTOKEN_MODIFY) + { + throw std::runtime_error("Invalid transaction type for NFTokenModifyBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfNFTokenID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + NFTokenModifyBuilder& + setNFTokenID(std::decay_t const& value) + { + object_[sfNFTokenID] = value; + return *this; + } + + /** + * @brief Set sfOwner (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenModifyBuilder& + setOwner(std::decay_t const& value) + { + object_[sfOwner] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + NFTokenModifyBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Build and return the NFTokenModify wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + NFTokenModify + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return NFTokenModify{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/OfferCancel.h b/include/xrpl/protocol_autogen/transactions/OfferCancel.h new file mode 100644 index 0000000000..ed2c761c0e --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/OfferCancel.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class OfferCancelBuilder; + +/** + * @brief Transaction: OfferCancel + * + * Type: ttOFFER_CANCEL (8) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use OfferCancelBuilder to construct new transactions. + */ +class OfferCancel : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttOFFER_CANCEL; + + /** + * @brief Construct a OfferCancel transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit OfferCancel(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for OfferCancel"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfOfferSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getOfferSequence() const + { + return this->tx_->at(sfOfferSequence); + } +}; + +/** + * @brief Builder for OfferCancel transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class OfferCancelBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new OfferCancelBuilder with required fields. + * @param account The account initiating the transaction. + * @param offerSequence The sfOfferSequence field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + OfferCancelBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& offerSequence, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttOFFER_CANCEL, account, sequence, fee) + { + setOfferSequence(offerSequence); + } + + /** + * @brief Construct a OfferCancelBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + OfferCancelBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttOFFER_CANCEL) + { + throw std::runtime_error("Invalid transaction type for OfferCancelBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfOfferSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferCancelBuilder& + setOfferSequence(std::decay_t const& value) + { + object_[sfOfferSequence] = value; + return *this; + } + + /** + * @brief Build and return the OfferCancel wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + OfferCancel + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return OfferCancel{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/OfferCreate.h b/include/xrpl/protocol_autogen/transactions/OfferCreate.h new file mode 100644 index 0000000000..a0eff385f6 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/OfferCreate.h @@ -0,0 +1,264 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class OfferCreateBuilder; + +/** + * @brief Transaction: OfferCreate + * + * Type: ttOFFER_CREATE (7) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use OfferCreateBuilder to construct new transactions. + */ +class OfferCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttOFFER_CREATE; + + /** + * @brief Construct a OfferCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit OfferCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for OfferCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfTakerPays (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getTakerPays() const + { + return this->tx_->at(sfTakerPays); + } + + /** + * @brief Get sfTakerGets (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getTakerGets() const + { + return this->tx_->at(sfTakerGets); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + { + return this->tx_->at(sfExpiration); + } + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->tx_->isFieldPresent(sfExpiration); + } + + /** + * @brief Get sfOfferSequence (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOfferSequence() const + { + if (hasOfferSequence()) + { + return this->tx_->at(sfOfferSequence); + } + return std::nullopt; + } + + /** + * @brief Check if sfOfferSequence is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOfferSequence() const + { + return this->tx_->isFieldPresent(sfOfferSequence); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + { + return this->tx_->at(sfDomainID); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->tx_->isFieldPresent(sfDomainID); + } +}; + +/** + * @brief Builder for OfferCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class OfferCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new OfferCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param takerPays The sfTakerPays field value. + * @param takerGets The sfTakerGets field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + OfferCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& takerPays, std::decay_t const& takerGets, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttOFFER_CREATE, account, sequence, fee) + { + setTakerPays(takerPays); + setTakerGets(takerGets); + } + + /** + * @brief Construct a OfferCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + OfferCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttOFFER_CREATE) + { + throw std::runtime_error("Invalid transaction type for OfferCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfTakerPays (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferCreateBuilder& + setTakerPays(std::decay_t const& value) + { + object_[sfTakerPays] = value; + return *this; + } + + /** + * @brief Set sfTakerGets (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OfferCreateBuilder& + setTakerGets(std::decay_t const& value) + { + object_[sfTakerGets] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OfferCreateBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Set sfOfferSequence (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OfferCreateBuilder& + setOfferSequence(std::decay_t const& value) + { + object_[sfOfferSequence] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OfferCreateBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Build and return the OfferCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + OfferCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return OfferCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/OracleDelete.h b/include/xrpl/protocol_autogen/transactions/OracleDelete.h new file mode 100644 index 0000000000..6cafd2b6de --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/OracleDelete.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class OracleDeleteBuilder; + +/** + * @brief Transaction: OracleDelete + * + * Type: ttORACLE_DELETE (52) + * Delegable: Delegation::delegable + * Amendment: featurePriceOracle + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use OracleDeleteBuilder to construct new transactions. + */ +class OracleDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttORACLE_DELETE; + + /** + * @brief Construct a OracleDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit OracleDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for OracleDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfOracleDocumentID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getOracleDocumentID() const + { + return this->tx_->at(sfOracleDocumentID); + } +}; + +/** + * @brief Builder for OracleDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class OracleDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new OracleDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param oracleDocumentID The sfOracleDocumentID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + OracleDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& oracleDocumentID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttORACLE_DELETE, account, sequence, fee) + { + setOracleDocumentID(oracleDocumentID); + } + + /** + * @brief Construct a OracleDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + OracleDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttORACLE_DELETE) + { + throw std::runtime_error("Invalid transaction type for OracleDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfOracleDocumentID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleDeleteBuilder& + setOracleDocumentID(std::decay_t const& value) + { + object_[sfOracleDocumentID] = value; + return *this; + } + + /** + * @brief Build and return the OracleDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + OracleDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return OracleDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/OracleSet.h b/include/xrpl/protocol_autogen/transactions/OracleSet.h new file mode 100644 index 0000000000..8dd0d88865 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/OracleSet.h @@ -0,0 +1,288 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class OracleSetBuilder; + +/** + * @brief Transaction: OracleSet + * + * Type: ttORACLE_SET (51) + * Delegable: Delegation::delegable + * Amendment: featurePriceOracle + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use OracleSetBuilder to construct new transactions. + */ +class OracleSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttORACLE_SET; + + /** + * @brief Construct a OracleSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit OracleSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for OracleSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfOracleDocumentID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getOracleDocumentID() const + { + return this->tx_->at(sfOracleDocumentID); + } + + /** + * @brief Get sfProvider (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getProvider() const + { + if (hasProvider()) + { + return this->tx_->at(sfProvider); + } + return std::nullopt; + } + + /** + * @brief Check if sfProvider is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasProvider() const + { + return this->tx_->isFieldPresent(sfProvider); + } + + /** + * @brief Get sfURI (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getURI() const + { + if (hasURI()) + { + return this->tx_->at(sfURI); + } + return std::nullopt; + } + + /** + * @brief Check if sfURI is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasURI() const + { + return this->tx_->isFieldPresent(sfURI); + } + + /** + * @brief Get sfAssetClass (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetClass() const + { + if (hasAssetClass()) + { + return this->tx_->at(sfAssetClass); + } + return std::nullopt; + } + + /** + * @brief Check if sfAssetClass is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetClass() const + { + return this->tx_->isFieldPresent(sfAssetClass); + } + + /** + * @brief Get sfLastUpdateTime (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getLastUpdateTime() const + { + return this->tx_->at(sfLastUpdateTime); + } + /** + * @brief Get sfPriceDataSeries (soeREQUIRED) + * @note This is an untyped field. + * @return The field value. + */ + [[nodiscard]] + STArray const& + getPriceDataSeries() const + { + return this->tx_->getFieldArray(sfPriceDataSeries); + } +}; + +/** + * @brief Builder for OracleSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class OracleSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new OracleSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param oracleDocumentID The sfOracleDocumentID field value. + * @param lastUpdateTime The sfLastUpdateTime field value. + * @param priceDataSeries The sfPriceDataSeries field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + OracleSetBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& oracleDocumentID, std::decay_t const& lastUpdateTime, STArray const& priceDataSeries, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttORACLE_SET, account, sequence, fee) + { + setOracleDocumentID(oracleDocumentID); + setLastUpdateTime(lastUpdateTime); + setPriceDataSeries(priceDataSeries); + } + + /** + * @brief Construct a OracleSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + OracleSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttORACLE_SET) + { + throw std::runtime_error("Invalid transaction type for OracleSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfOracleDocumentID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleSetBuilder& + setOracleDocumentID(std::decay_t const& value) + { + object_[sfOracleDocumentID] = value; + return *this; + } + + /** + * @brief Set sfProvider (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OracleSetBuilder& + setProvider(std::decay_t const& value) + { + object_[sfProvider] = value; + return *this; + } + + /** + * @brief Set sfURI (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OracleSetBuilder& + setURI(std::decay_t const& value) + { + object_[sfURI] = value; + return *this; + } + + /** + * @brief Set sfAssetClass (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + OracleSetBuilder& + setAssetClass(std::decay_t const& value) + { + object_[sfAssetClass] = value; + return *this; + } + + /** + * @brief Set sfLastUpdateTime (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleSetBuilder& + setLastUpdateTime(std::decay_t const& value) + { + object_[sfLastUpdateTime] = value; + return *this; + } + + /** + * @brief Set sfPriceDataSeries (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + OracleSetBuilder& + setPriceDataSeries(STArray const& value) + { + object_.setFieldArray(sfPriceDataSeries, value); + return *this; + } + + /** + * @brief Build and return the OracleSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + OracleSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return OracleSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/Payment.h b/include/xrpl/protocol_autogen/transactions/Payment.h new file mode 100644 index 0000000000..877286f90e --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/Payment.h @@ -0,0 +1,416 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class PaymentBuilder; + +/** + * @brief Transaction: Payment + * + * Type: ttPAYMENT (0) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: createAcct + * + * Immutable wrapper around STTx providing type-safe field access. + * Use PaymentBuilder to construct new transactions. + */ +class Payment : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttPAYMENT; + + /** + * @brief Construct a Payment transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit Payment(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for Payment"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfSendMax (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSendMax() const + { + if (hasSendMax()) + { + return this->tx_->at(sfSendMax); + } + return std::nullopt; + } + + /** + * @brief Check if sfSendMax is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSendMax() const + { + return this->tx_->isFieldPresent(sfSendMax); + } + /** + * @brief Get sfPaths (soeDEFAULT) + * @note This is an untyped field. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getPaths() const + { + if (this->tx_->isFieldPresent(sfPaths)) + return this->tx_->getFieldPathSet(sfPaths); + return std::nullopt; + } + + /** + * @brief Check if sfPaths is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPaths() const + { + return this->tx_->isFieldPresent(sfPaths); + } + + /** + * @brief Get sfInvoiceID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getInvoiceID() const + { + if (hasInvoiceID()) + { + return this->tx_->at(sfInvoiceID); + } + return std::nullopt; + } + + /** + * @brief Check if sfInvoiceID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasInvoiceID() const + { + return this->tx_->isFieldPresent(sfInvoiceID); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } + + /** + * @brief Get sfDeliverMin (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDeliverMin() const + { + if (hasDeliverMin()) + { + return this->tx_->at(sfDeliverMin); + } + return std::nullopt; + } + + /** + * @brief Check if sfDeliverMin is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDeliverMin() const + { + return this->tx_->isFieldPresent(sfDeliverMin); + } + + /** + * @brief Get sfCredentialIDs (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCredentialIDs() const + { + if (hasCredentialIDs()) + { + return this->tx_->at(sfCredentialIDs); + } + return std::nullopt; + } + + /** + * @brief Check if sfCredentialIDs is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCredentialIDs() const + { + return this->tx_->isFieldPresent(sfCredentialIDs); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + { + return this->tx_->at(sfDomainID); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->tx_->isFieldPresent(sfDomainID); + } +}; + +/** + * @brief Builder for Payment transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class PaymentBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new PaymentBuilder with required fields. + * @param account The account initiating the transaction. + * @param destination The sfDestination field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + PaymentBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& destination, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttPAYMENT, account, sequence, fee) + { + setDestination(destination); + setAmount(amount); + } + + /** + * @brief Construct a PaymentBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + PaymentBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttPAYMENT) + { + throw std::runtime_error("Invalid transaction type for PaymentBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfSendMax (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setSendMax(std::decay_t const& value) + { + object_[sfSendMax] = value; + return *this; + } + + /** + * @brief Set sfPaths (soeDEFAULT) + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setPaths(STPathSet const& value) + { + object_.setFieldPathSet(sfPaths, value); + return *this; + } + + /** + * @brief Set sfInvoiceID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setInvoiceID(std::decay_t const& value) + { + object_[sfInvoiceID] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Set sfDeliverMin (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setDeliverMin(std::decay_t const& value) + { + object_[sfDeliverMin] = value; + return *this; + } + + /** + * @brief Set sfCredentialIDs (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setCredentialIDs(std::decay_t const& value) + { + object_[sfCredentialIDs] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Build and return the Payment wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + Payment + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return Payment{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/PaymentChannelClaim.h b/include/xrpl/protocol_autogen/transactions/PaymentChannelClaim.h new file mode 100644 index 0000000000..1e90c74aa1 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/PaymentChannelClaim.h @@ -0,0 +1,314 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class PaymentChannelClaimBuilder; + +/** + * @brief Transaction: PaymentChannelClaim + * + * Type: ttPAYCHAN_CLAIM (15) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use PaymentChannelClaimBuilder to construct new transactions. + */ +class PaymentChannelClaim : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttPAYCHAN_CLAIM; + + /** + * @brief Construct a PaymentChannelClaim transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit PaymentChannelClaim(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for PaymentChannelClaim"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfChannel (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getChannel() const + { + return this->tx_->at(sfChannel); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } + + /** + * @brief Get sfBalance (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBalance() const + { + if (hasBalance()) + { + return this->tx_->at(sfBalance); + } + return std::nullopt; + } + + /** + * @brief Check if sfBalance is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBalance() const + { + return this->tx_->isFieldPresent(sfBalance); + } + + /** + * @brief Get sfSignature (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSignature() const + { + if (hasSignature()) + { + return this->tx_->at(sfSignature); + } + return std::nullopt; + } + + /** + * @brief Check if sfSignature is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSignature() const + { + return this->tx_->isFieldPresent(sfSignature); + } + + /** + * @brief Get sfPublicKey (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getPublicKey() const + { + if (hasPublicKey()) + { + return this->tx_->at(sfPublicKey); + } + return std::nullopt; + } + + /** + * @brief Check if sfPublicKey is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasPublicKey() const + { + return this->tx_->isFieldPresent(sfPublicKey); + } + + /** + * @brief Get sfCredentialIDs (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCredentialIDs() const + { + if (hasCredentialIDs()) + { + return this->tx_->at(sfCredentialIDs); + } + return std::nullopt; + } + + /** + * @brief Check if sfCredentialIDs is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCredentialIDs() const + { + return this->tx_->isFieldPresent(sfCredentialIDs); + } +}; + +/** + * @brief Builder for PaymentChannelClaim transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class PaymentChannelClaimBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new PaymentChannelClaimBuilder with required fields. + * @param account The account initiating the transaction. + * @param channel The sfChannel field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + PaymentChannelClaimBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& channel, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttPAYCHAN_CLAIM, account, sequence, fee) + { + setChannel(channel); + } + + /** + * @brief Construct a PaymentChannelClaimBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + PaymentChannelClaimBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttPAYCHAN_CLAIM) + { + throw std::runtime_error("Invalid transaction type for PaymentChannelClaimBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfChannel (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentChannelClaimBuilder& + setChannel(std::decay_t const& value) + { + object_[sfChannel] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelClaimBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfBalance (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelClaimBuilder& + setBalance(std::decay_t const& value) + { + object_[sfBalance] = value; + return *this; + } + + /** + * @brief Set sfSignature (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelClaimBuilder& + setSignature(std::decay_t const& value) + { + object_[sfSignature] = value; + return *this; + } + + /** + * @brief Set sfPublicKey (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelClaimBuilder& + setPublicKey(std::decay_t const& value) + { + object_[sfPublicKey] = value; + return *this; + } + + /** + * @brief Set sfCredentialIDs (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelClaimBuilder& + setCredentialIDs(std::decay_t const& value) + { + object_[sfCredentialIDs] = value; + return *this; + } + + /** + * @brief Build and return the PaymentChannelClaim wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + PaymentChannelClaim + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return PaymentChannelClaim{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/PaymentChannelCreate.h b/include/xrpl/protocol_autogen/transactions/PaymentChannelCreate.h new file mode 100644 index 0000000000..4242046114 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/PaymentChannelCreate.h @@ -0,0 +1,275 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class PaymentChannelCreateBuilder; + +/** + * @brief Transaction: PaymentChannelCreate + * + * Type: ttPAYCHAN_CREATE (13) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use PaymentChannelCreateBuilder to construct new transactions. + */ +class PaymentChannelCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttPAYCHAN_CREATE; + + /** + * @brief Construct a PaymentChannelCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit PaymentChannelCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for PaymentChannelCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfSettleDelay (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSettleDelay() const + { + return this->tx_->at(sfSettleDelay); + } + + /** + * @brief Get sfPublicKey (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getPublicKey() const + { + return this->tx_->at(sfPublicKey); + } + + /** + * @brief Get sfCancelAfter (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getCancelAfter() const + { + if (hasCancelAfter()) + { + return this->tx_->at(sfCancelAfter); + } + return std::nullopt; + } + + /** + * @brief Check if sfCancelAfter is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasCancelAfter() const + { + return this->tx_->isFieldPresent(sfCancelAfter); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } +}; + +/** + * @brief Builder for PaymentChannelCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class PaymentChannelCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new PaymentChannelCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param destination The sfDestination field value. + * @param amount The sfAmount field value. + * @param settleDelay The sfSettleDelay field value. + * @param publicKey The sfPublicKey field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + PaymentChannelCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& destination, std::decay_t const& amount, std::decay_t const& settleDelay, std::decay_t const& publicKey, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttPAYCHAN_CREATE, account, sequence, fee) + { + setDestination(destination); + setAmount(amount); + setSettleDelay(settleDelay); + setPublicKey(publicKey); + } + + /** + * @brief Construct a PaymentChannelCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + PaymentChannelCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttPAYCHAN_CREATE) + { + throw std::runtime_error("Invalid transaction type for PaymentChannelCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentChannelCreateBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentChannelCreateBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfSettleDelay (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentChannelCreateBuilder& + setSettleDelay(std::decay_t const& value) + { + object_[sfSettleDelay] = value; + return *this; + } + + /** + * @brief Set sfPublicKey (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentChannelCreateBuilder& + setPublicKey(std::decay_t const& value) + { + object_[sfPublicKey] = value; + return *this; + } + + /** + * @brief Set sfCancelAfter (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelCreateBuilder& + setCancelAfter(std::decay_t const& value) + { + object_[sfCancelAfter] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelCreateBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Build and return the PaymentChannelCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + PaymentChannelCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return PaymentChannelCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/PaymentChannelFund.h b/include/xrpl/protocol_autogen/transactions/PaymentChannelFund.h new file mode 100644 index 0000000000..2fecf21154 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/PaymentChannelFund.h @@ -0,0 +1,190 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class PaymentChannelFundBuilder; + +/** + * @brief Transaction: PaymentChannelFund + * + * Type: ttPAYCHAN_FUND (14) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use PaymentChannelFundBuilder to construct new transactions. + */ +class PaymentChannelFund : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttPAYCHAN_FUND; + + /** + * @brief Construct a PaymentChannelFund transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit PaymentChannelFund(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for PaymentChannelFund"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfChannel (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getChannel() const + { + return this->tx_->at(sfChannel); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfExpiration (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getExpiration() const + { + if (hasExpiration()) + { + return this->tx_->at(sfExpiration); + } + return std::nullopt; + } + + /** + * @brief Check if sfExpiration is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasExpiration() const + { + return this->tx_->isFieldPresent(sfExpiration); + } +}; + +/** + * @brief Builder for PaymentChannelFund transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class PaymentChannelFundBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new PaymentChannelFundBuilder with required fields. + * @param account The account initiating the transaction. + * @param channel The sfChannel field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + PaymentChannelFundBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& channel, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttPAYCHAN_FUND, account, sequence, fee) + { + setChannel(channel); + setAmount(amount); + } + + /** + * @brief Construct a PaymentChannelFundBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + PaymentChannelFundBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttPAYCHAN_FUND) + { + throw std::runtime_error("Invalid transaction type for PaymentChannelFundBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfChannel (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentChannelFundBuilder& + setChannel(std::decay_t const& value) + { + object_[sfChannel] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PaymentChannelFundBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfExpiration (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PaymentChannelFundBuilder& + setExpiration(std::decay_t const& value) + { + object_[sfExpiration] = value; + return *this; + } + + /** + * @brief Build and return the PaymentChannelFund wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + PaymentChannelFund + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return PaymentChannelFund{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/PermissionedDomainDelete.h b/include/xrpl/protocol_autogen/transactions/PermissionedDomainDelete.h new file mode 100644 index 0000000000..c95e0f2e18 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/PermissionedDomainDelete.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class PermissionedDomainDeleteBuilder; + +/** + * @brief Transaction: PermissionedDomainDelete + * + * Type: ttPERMISSIONED_DOMAIN_DELETE (63) + * Delegable: Delegation::delegable + * Amendment: featurePermissionedDomains + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use PermissionedDomainDeleteBuilder to construct new transactions. + */ +class PermissionedDomainDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttPERMISSIONED_DOMAIN_DELETE; + + /** + * @brief Construct a PermissionedDomainDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit PermissionedDomainDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for PermissionedDomainDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDomainID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getDomainID() const + { + return this->tx_->at(sfDomainID); + } +}; + +/** + * @brief Builder for PermissionedDomainDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class PermissionedDomainDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new PermissionedDomainDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param domainID The sfDomainID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + PermissionedDomainDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& domainID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttPERMISSIONED_DOMAIN_DELETE, account, sequence, fee) + { + setDomainID(domainID); + } + + /** + * @brief Construct a PermissionedDomainDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + PermissionedDomainDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttPERMISSIONED_DOMAIN_DELETE) + { + throw std::runtime_error("Invalid transaction type for PermissionedDomainDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDomainID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainDeleteBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Build and return the PermissionedDomainDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + PermissionedDomainDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return PermissionedDomainDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/PermissionedDomainSet.h b/include/xrpl/protocol_autogen/transactions/PermissionedDomainSet.h new file mode 100644 index 0000000000..38df7f4fc7 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/PermissionedDomainSet.h @@ -0,0 +1,166 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class PermissionedDomainSetBuilder; + +/** + * @brief Transaction: PermissionedDomainSet + * + * Type: ttPERMISSIONED_DOMAIN_SET (62) + * Delegable: Delegation::delegable + * Amendment: featurePermissionedDomains + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use PermissionedDomainSetBuilder to construct new transactions. + */ +class PermissionedDomainSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttPERMISSIONED_DOMAIN_SET; + + /** + * @brief Construct a PermissionedDomainSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit PermissionedDomainSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for PermissionedDomainSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + { + return this->tx_->at(sfDomainID); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->tx_->isFieldPresent(sfDomainID); + } + /** + * @brief Get sfAcceptedCredentials (soeREQUIRED) + * @note This is an untyped field. + * @return The field value. + */ + [[nodiscard]] + STArray const& + getAcceptedCredentials() const + { + return this->tx_->getFieldArray(sfAcceptedCredentials); + } +}; + +/** + * @brief Builder for PermissionedDomainSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class PermissionedDomainSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new PermissionedDomainSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param acceptedCredentials The sfAcceptedCredentials field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + PermissionedDomainSetBuilder(SF_ACCOUNT::type::value_type account, + STArray const& acceptedCredentials, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttPERMISSIONED_DOMAIN_SET, account, sequence, fee) + { + setAcceptedCredentials(acceptedCredentials); + } + + /** + * @brief Construct a PermissionedDomainSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + PermissionedDomainSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttPERMISSIONED_DOMAIN_SET) + { + throw std::runtime_error("Invalid transaction type for PermissionedDomainSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainSetBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Set sfAcceptedCredentials (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + PermissionedDomainSetBuilder& + setAcceptedCredentials(STArray const& value) + { + object_.setFieldArray(sfAcceptedCredentials, value); + return *this; + } + + /** + * @brief Build and return the PermissionedDomainSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + PermissionedDomainSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return PermissionedDomainSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/SetFee.h b/include/xrpl/protocol_autogen/transactions/SetFee.h new file mode 100644 index 0000000000..7bf73201b9 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/SetFee.h @@ -0,0 +1,401 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class SetFeeBuilder; + +/** + * @brief Transaction: SetFee + * + * Type: ttFEE (101) + * Delegable: Delegation::notDelegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use SetFeeBuilder to construct new transactions. + */ +class SetFee : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttFEE; + + /** + * @brief Construct a SetFee transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit SetFee(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for SetFee"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLedgerSequence (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLedgerSequence() const + { + if (hasLedgerSequence()) + { + return this->tx_->at(sfLedgerSequence); + } + return std::nullopt; + } + + /** + * @brief Check if sfLedgerSequence is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLedgerSequence() const + { + return this->tx_->isFieldPresent(sfLedgerSequence); + } + + /** + * @brief Get sfBaseFee (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBaseFee() const + { + if (hasBaseFee()) + { + return this->tx_->at(sfBaseFee); + } + return std::nullopt; + } + + /** + * @brief Check if sfBaseFee is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBaseFee() const + { + return this->tx_->isFieldPresent(sfBaseFee); + } + + /** + * @brief Get sfReferenceFeeUnits (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReferenceFeeUnits() const + { + if (hasReferenceFeeUnits()) + { + return this->tx_->at(sfReferenceFeeUnits); + } + return std::nullopt; + } + + /** + * @brief Check if sfReferenceFeeUnits is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReferenceFeeUnits() const + { + return this->tx_->isFieldPresent(sfReferenceFeeUnits); + } + + /** + * @brief Get sfReserveBase (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveBase() const + { + if (hasReserveBase()) + { + return this->tx_->at(sfReserveBase); + } + return std::nullopt; + } + + /** + * @brief Check if sfReserveBase is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveBase() const + { + return this->tx_->isFieldPresent(sfReserveBase); + } + + /** + * @brief Get sfReserveIncrement (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveIncrement() const + { + if (hasReserveIncrement()) + { + return this->tx_->at(sfReserveIncrement); + } + return std::nullopt; + } + + /** + * @brief Check if sfReserveIncrement is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveIncrement() const + { + return this->tx_->isFieldPresent(sfReserveIncrement); + } + + /** + * @brief Get sfBaseFeeDrops (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getBaseFeeDrops() const + { + if (hasBaseFeeDrops()) + { + return this->tx_->at(sfBaseFeeDrops); + } + return std::nullopt; + } + + /** + * @brief Check if sfBaseFeeDrops is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasBaseFeeDrops() const + { + return this->tx_->isFieldPresent(sfBaseFeeDrops); + } + + /** + * @brief Get sfReserveBaseDrops (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveBaseDrops() const + { + if (hasReserveBaseDrops()) + { + return this->tx_->at(sfReserveBaseDrops); + } + return std::nullopt; + } + + /** + * @brief Check if sfReserveBaseDrops is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveBaseDrops() const + { + return this->tx_->isFieldPresent(sfReserveBaseDrops); + } + + /** + * @brief Get sfReserveIncrementDrops (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getReserveIncrementDrops() const + { + if (hasReserveIncrementDrops()) + { + return this->tx_->at(sfReserveIncrementDrops); + } + return std::nullopt; + } + + /** + * @brief Check if sfReserveIncrementDrops is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasReserveIncrementDrops() const + { + return this->tx_->isFieldPresent(sfReserveIncrementDrops); + } +}; + +/** + * @brief Builder for SetFee transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class SetFeeBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new SetFeeBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + SetFeeBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttFEE, account, sequence, fee) + { + } + + /** + * @brief Construct a SetFeeBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + SetFeeBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttFEE) + { + throw std::runtime_error("Invalid transaction type for SetFeeBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLedgerSequence (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setLedgerSequence(std::decay_t const& value) + { + object_[sfLedgerSequence] = value; + return *this; + } + + /** + * @brief Set sfBaseFee (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setBaseFee(std::decay_t const& value) + { + object_[sfBaseFee] = value; + return *this; + } + + /** + * @brief Set sfReferenceFeeUnits (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setReferenceFeeUnits(std::decay_t const& value) + { + object_[sfReferenceFeeUnits] = value; + return *this; + } + + /** + * @brief Set sfReserveBase (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setReserveBase(std::decay_t const& value) + { + object_[sfReserveBase] = value; + return *this; + } + + /** + * @brief Set sfReserveIncrement (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setReserveIncrement(std::decay_t const& value) + { + object_[sfReserveIncrement] = value; + return *this; + } + + /** + * @brief Set sfBaseFeeDrops (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setBaseFeeDrops(std::decay_t const& value) + { + object_[sfBaseFeeDrops] = value; + return *this; + } + + /** + * @brief Set sfReserveBaseDrops (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setReserveBaseDrops(std::decay_t const& value) + { + object_[sfReserveBaseDrops] = value; + return *this; + } + + /** + * @brief Set sfReserveIncrementDrops (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetFeeBuilder& + setReserveIncrementDrops(std::decay_t const& value) + { + object_[sfReserveIncrementDrops] = value; + return *this; + } + + /** + * @brief Build and return the SetFee wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + SetFee + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return SetFee{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/SetRegularKey.h b/include/xrpl/protocol_autogen/transactions/SetRegularKey.h new file mode 100644 index 0000000000..3d70d092c5 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/SetRegularKey.h @@ -0,0 +1,142 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class SetRegularKeyBuilder; + +/** + * @brief Transaction: SetRegularKey + * + * Type: ttREGULAR_KEY_SET (5) + * Delegable: Delegation::notDelegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use SetRegularKeyBuilder to construct new transactions. + */ +class SetRegularKey : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttREGULAR_KEY_SET; + + /** + * @brief Construct a SetRegularKey transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit SetRegularKey(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for SetRegularKey"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfRegularKey (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getRegularKey() const + { + if (hasRegularKey()) + { + return this->tx_->at(sfRegularKey); + } + return std::nullopt; + } + + /** + * @brief Check if sfRegularKey is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasRegularKey() const + { + return this->tx_->isFieldPresent(sfRegularKey); + } +}; + +/** + * @brief Builder for SetRegularKey transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class SetRegularKeyBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new SetRegularKeyBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + SetRegularKeyBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttREGULAR_KEY_SET, account, sequence, fee) + { + } + + /** + * @brief Construct a SetRegularKeyBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + SetRegularKeyBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttREGULAR_KEY_SET) + { + throw std::runtime_error("Invalid transaction type for SetRegularKeyBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfRegularKey (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SetRegularKeyBuilder& + setRegularKey(std::decay_t const& value) + { + object_[sfRegularKey] = value; + return *this; + } + + /** + * @brief Build and return the SetRegularKey wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + SetRegularKey + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return SetRegularKey{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/SignerListSet.h b/include/xrpl/protocol_autogen/transactions/SignerListSet.h new file mode 100644 index 0000000000..ec5330a9cb --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/SignerListSet.h @@ -0,0 +1,164 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class SignerListSetBuilder; + +/** + * @brief Transaction: SignerListSet + * + * Type: ttSIGNER_LIST_SET (12) + * Delegable: Delegation::notDelegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use SignerListSetBuilder to construct new transactions. + */ +class SignerListSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttSIGNER_LIST_SET; + + /** + * @brief Construct a SignerListSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit SignerListSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for SignerListSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfSignerQuorum (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getSignerQuorum() const + { + return this->tx_->at(sfSignerQuorum); + } + /** + * @brief Get sfSignerEntries (soeOPTIONAL) + * @note This is an untyped field. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + std::optional> + getSignerEntries() const + { + if (this->tx_->isFieldPresent(sfSignerEntries)) + return this->tx_->getFieldArray(sfSignerEntries); + return std::nullopt; + } + + /** + * @brief Check if sfSignerEntries is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSignerEntries() const + { + return this->tx_->isFieldPresent(sfSignerEntries); + } +}; + +/** + * @brief Builder for SignerListSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class SignerListSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new SignerListSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param signerQuorum The sfSignerQuorum field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + SignerListSetBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& signerQuorum, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttSIGNER_LIST_SET, account, sequence, fee) + { + setSignerQuorum(signerQuorum); + } + + /** + * @brief Construct a SignerListSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + SignerListSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttSIGNER_LIST_SET) + { + throw std::runtime_error("Invalid transaction type for SignerListSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfSignerQuorum (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + SignerListSetBuilder& + setSignerQuorum(std::decay_t const& value) + { + object_[sfSignerQuorum] = value; + return *this; + } + + /** + * @brief Set sfSignerEntries (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + SignerListSetBuilder& + setSignerEntries(STArray const& value) + { + object_.setFieldArray(sfSignerEntries, value); + return *this; + } + + /** + * @brief Build and return the SignerListSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + SignerListSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return SignerListSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/TicketCreate.h b/include/xrpl/protocol_autogen/transactions/TicketCreate.h new file mode 100644 index 0000000000..842ae93111 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/TicketCreate.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class TicketCreateBuilder; + +/** + * @brief Transaction: TicketCreate + * + * Type: ttTICKET_CREATE (10) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use TicketCreateBuilder to construct new transactions. + */ +class TicketCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttTICKET_CREATE; + + /** + * @brief Construct a TicketCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit TicketCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for TicketCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfTicketCount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getTicketCount() const + { + return this->tx_->at(sfTicketCount); + } +}; + +/** + * @brief Builder for TicketCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class TicketCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new TicketCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param ticketCount The sfTicketCount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + TicketCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& ticketCount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttTICKET_CREATE, account, sequence, fee) + { + setTicketCount(ticketCount); + } + + /** + * @brief Construct a TicketCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + TicketCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttTICKET_CREATE) + { + throw std::runtime_error("Invalid transaction type for TicketCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfTicketCount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + TicketCreateBuilder& + setTicketCount(std::decay_t const& value) + { + object_[sfTicketCount] = value; + return *this; + } + + /** + * @brief Build and return the TicketCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + TicketCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return TicketCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/TrustSet.h b/include/xrpl/protocol_autogen/transactions/TrustSet.h new file mode 100644 index 0000000000..5623311b92 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/TrustSet.h @@ -0,0 +1,216 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class TrustSetBuilder; + +/** + * @brief Transaction: TrustSet + * + * Type: ttTRUST_SET (20) + * Delegable: Delegation::delegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use TrustSetBuilder to construct new transactions. + */ +class TrustSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttTRUST_SET; + + /** + * @brief Construct a TrustSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit TrustSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for TrustSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfLimitAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getLimitAmount() const + { + if (hasLimitAmount()) + { + return this->tx_->at(sfLimitAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfLimitAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasLimitAmount() const + { + return this->tx_->isFieldPresent(sfLimitAmount); + } + + /** + * @brief Get sfQualityIn (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getQualityIn() const + { + if (hasQualityIn()) + { + return this->tx_->at(sfQualityIn); + } + return std::nullopt; + } + + /** + * @brief Check if sfQualityIn is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasQualityIn() const + { + return this->tx_->isFieldPresent(sfQualityIn); + } + + /** + * @brief Get sfQualityOut (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getQualityOut() const + { + if (hasQualityOut()) + { + return this->tx_->at(sfQualityOut); + } + return std::nullopt; + } + + /** + * @brief Check if sfQualityOut is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasQualityOut() const + { + return this->tx_->isFieldPresent(sfQualityOut); + } +}; + +/** + * @brief Builder for TrustSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class TrustSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new TrustSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + TrustSetBuilder(SF_ACCOUNT::type::value_type account, + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttTRUST_SET, account, sequence, fee) + { + } + + /** + * @brief Construct a TrustSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + TrustSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttTRUST_SET) + { + throw std::runtime_error("Invalid transaction type for TrustSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfLimitAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + TrustSetBuilder& + setLimitAmount(std::decay_t const& value) + { + object_[sfLimitAmount] = value; + return *this; + } + + /** + * @brief Set sfQualityIn (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + TrustSetBuilder& + setQualityIn(std::decay_t const& value) + { + object_[sfQualityIn] = value; + return *this; + } + + /** + * @brief Set sfQualityOut (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + TrustSetBuilder& + setQualityOut(std::decay_t const& value) + { + object_[sfQualityOut] = value; + return *this; + } + + /** + * @brief Build and return the TrustSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + TrustSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return TrustSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/UNLModify.h b/include/xrpl/protocol_autogen/transactions/UNLModify.h new file mode 100644 index 0000000000..b5e64f19a0 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/UNLModify.h @@ -0,0 +1,177 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class UNLModifyBuilder; + +/** + * @brief Transaction: UNLModify + * + * Type: ttUNL_MODIFY (102) + * Delegable: Delegation::notDelegable + * Amendment: uint256{} + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use UNLModifyBuilder to construct new transactions. + */ +class UNLModify : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttUNL_MODIFY; + + /** + * @brief Construct a UNLModify transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit UNLModify(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for UNLModify"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfUNLModifyDisabling (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT8::type::value_type + getUNLModifyDisabling() const + { + return this->tx_->at(sfUNLModifyDisabling); + } + + /** + * @brief Get sfLedgerSequence (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT32::type::value_type + getLedgerSequence() const + { + return this->tx_->at(sfLedgerSequence); + } + + /** + * @brief Get sfUNLModifyValidator (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getUNLModifyValidator() const + { + return this->tx_->at(sfUNLModifyValidator); + } +}; + +/** + * @brief Builder for UNLModify transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class UNLModifyBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new UNLModifyBuilder with required fields. + * @param account The account initiating the transaction. + * @param uNLModifyDisabling The sfUNLModifyDisabling field value. + * @param ledgerSequence The sfLedgerSequence field value. + * @param uNLModifyValidator The sfUNLModifyValidator field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + UNLModifyBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& uNLModifyDisabling, std::decay_t const& ledgerSequence, std::decay_t const& uNLModifyValidator, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttUNL_MODIFY, account, sequence, fee) + { + setUNLModifyDisabling(uNLModifyDisabling); + setLedgerSequence(ledgerSequence); + setUNLModifyValidator(uNLModifyValidator); + } + + /** + * @brief Construct a UNLModifyBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + UNLModifyBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttUNL_MODIFY) + { + throw std::runtime_error("Invalid transaction type for UNLModifyBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfUNLModifyDisabling (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + UNLModifyBuilder& + setUNLModifyDisabling(std::decay_t const& value) + { + object_[sfUNLModifyDisabling] = value; + return *this; + } + + /** + * @brief Set sfLedgerSequence (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + UNLModifyBuilder& + setLedgerSequence(std::decay_t const& value) + { + object_[sfLedgerSequence] = value; + return *this; + } + + /** + * @brief Set sfUNLModifyValidator (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + UNLModifyBuilder& + setUNLModifyValidator(std::decay_t const& value) + { + object_[sfUNLModifyValidator] = value; + return *this; + } + + /** + * @brief Build and return the UNLModify wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + UNLModify + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return UNLModify{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/VaultClawback.h b/include/xrpl/protocol_autogen/transactions/VaultClawback.h new file mode 100644 index 0000000000..82b2b32e8d --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/VaultClawback.h @@ -0,0 +1,192 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class VaultClawbackBuilder; + +/** + * @brief Transaction: VaultClawback + * + * Type: ttVAULT_CLAWBACK (70) + * Delegable: Delegation::notDelegable + * Amendment: featureSingleAssetVault + * Privileges: mayDeleteMPT | mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use VaultClawbackBuilder to construct new transactions. + */ +class VaultClawback : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttVAULT_CLAWBACK; + + /** + * @brief Construct a VaultClawback transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit VaultClawback(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for VaultClawback"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfVaultID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getVaultID() const + { + return this->tx_->at(sfVaultID); + } + + /** + * @brief Get sfHolder (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getHolder() const + { + return this->tx_->at(sfHolder); + } + + /** + * @brief Get sfAmount (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAmount() const + { + if (hasAmount()) + { + return this->tx_->at(sfAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAmount() const + { + return this->tx_->isFieldPresent(sfAmount); + } +}; + +/** + * @brief Builder for VaultClawback transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class VaultClawbackBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new VaultClawbackBuilder with required fields. + * @param account The account initiating the transaction. + * @param vaultID The sfVaultID field value. + * @param holder The sfHolder field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + VaultClawbackBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& vaultID, std::decay_t const& holder, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttVAULT_CLAWBACK, account, sequence, fee) + { + setVaultID(vaultID); + setHolder(holder); + } + + /** + * @brief Construct a VaultClawbackBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + VaultClawbackBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttVAULT_CLAWBACK) + { + throw std::runtime_error("Invalid transaction type for VaultClawbackBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfVaultID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultClawbackBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Set sfHolder (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultClawbackBuilder& + setHolder(std::decay_t const& value) + { + object_[sfHolder] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeOPTIONAL) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + VaultClawbackBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Build and return the VaultClawback wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + VaultClawback + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return VaultClawback{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/VaultCreate.h b/include/xrpl/protocol_autogen/transactions/VaultCreate.h new file mode 100644 index 0000000000..03d4d4b88d --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/VaultCreate.h @@ -0,0 +1,353 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class VaultCreateBuilder; + +/** + * @brief Transaction: VaultCreate + * + * Type: ttVAULT_CREATE (65) + * Delegable: Delegation::notDelegable + * Amendment: featureSingleAssetVault + * Privileges: createPseudoAcct | createMPTIssuance | mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use VaultCreateBuilder to construct new transactions. + */ +class VaultCreate : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttVAULT_CREATE; + + /** + * @brief Construct a VaultCreate transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit VaultCreate(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for VaultCreate"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfAsset (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_ISSUE::type::value_type + getAsset() const + { + return this->tx_->at(sfAsset); + } + + /** + * @brief Get sfAssetsMaximum (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetsMaximum() const + { + if (hasAssetsMaximum()) + { + return this->tx_->at(sfAssetsMaximum); + } + return std::nullopt; + } + + /** + * @brief Check if sfAssetsMaximum is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetsMaximum() const + { + return this->tx_->isFieldPresent(sfAssetsMaximum); + } + + /** + * @brief Get sfMPTokenMetadata (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMPTokenMetadata() const + { + if (hasMPTokenMetadata()) + { + return this->tx_->at(sfMPTokenMetadata); + } + return std::nullopt; + } + + /** + * @brief Check if sfMPTokenMetadata is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMPTokenMetadata() const + { + return this->tx_->isFieldPresent(sfMPTokenMetadata); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + { + return this->tx_->at(sfDomainID); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->tx_->isFieldPresent(sfDomainID); + } + + /** + * @brief Get sfWithdrawalPolicy (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getWithdrawalPolicy() const + { + if (hasWithdrawalPolicy()) + { + return this->tx_->at(sfWithdrawalPolicy); + } + return std::nullopt; + } + + /** + * @brief Check if sfWithdrawalPolicy is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasWithdrawalPolicy() const + { + return this->tx_->isFieldPresent(sfWithdrawalPolicy); + } + + /** + * @brief Get sfData (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + { + return this->tx_->at(sfData); + } + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->tx_->isFieldPresent(sfData); + } + + /** + * @brief Get sfScale (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getScale() const + { + if (hasScale()) + { + return this->tx_->at(sfScale); + } + return std::nullopt; + } + + /** + * @brief Check if sfScale is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasScale() const + { + return this->tx_->isFieldPresent(sfScale); + } +}; + +/** + * @brief Builder for VaultCreate transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class VaultCreateBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new VaultCreateBuilder with required fields. + * @param account The account initiating the transaction. + * @param asset The sfAsset field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + VaultCreateBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& asset, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttVAULT_CREATE, account, sequence, fee) + { + setAsset(asset); + } + + /** + * @brief Construct a VaultCreateBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + VaultCreateBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttVAULT_CREATE) + { + throw std::runtime_error("Invalid transaction type for VaultCreateBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfAsset (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + VaultCreateBuilder& + setAsset(std::decay_t const& value) + { + object_[sfAsset] = STIssue(sfAsset, value); + return *this; + } + + /** + * @brief Set sfAssetsMaximum (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultCreateBuilder& + setAssetsMaximum(std::decay_t const& value) + { + object_[sfAssetsMaximum] = value; + return *this; + } + + /** + * @brief Set sfMPTokenMetadata (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultCreateBuilder& + setMPTokenMetadata(std::decay_t const& value) + { + object_[sfMPTokenMetadata] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultCreateBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Set sfWithdrawalPolicy (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultCreateBuilder& + setWithdrawalPolicy(std::decay_t const& value) + { + object_[sfWithdrawalPolicy] = value; + return *this; + } + + /** + * @brief Set sfData (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultCreateBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Set sfScale (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultCreateBuilder& + setScale(std::decay_t const& value) + { + object_[sfScale] = value; + return *this; + } + + /** + * @brief Build and return the VaultCreate wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + VaultCreate + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return VaultCreate{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/VaultDelete.h b/include/xrpl/protocol_autogen/transactions/VaultDelete.h new file mode 100644 index 0000000000..89a4ef2a2f --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/VaultDelete.h @@ -0,0 +1,129 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class VaultDeleteBuilder; + +/** + * @brief Transaction: VaultDelete + * + * Type: ttVAULT_DELETE (67) + * Delegable: Delegation::notDelegable + * Amendment: featureSingleAssetVault + * Privileges: mustDeleteAcct | destroyMPTIssuance | mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use VaultDeleteBuilder to construct new transactions. + */ +class VaultDelete : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttVAULT_DELETE; + + /** + * @brief Construct a VaultDelete transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit VaultDelete(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for VaultDelete"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfVaultID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getVaultID() const + { + return this->tx_->at(sfVaultID); + } +}; + +/** + * @brief Builder for VaultDelete transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class VaultDeleteBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new VaultDeleteBuilder with required fields. + * @param account The account initiating the transaction. + * @param vaultID The sfVaultID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + VaultDeleteBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& vaultID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttVAULT_DELETE, account, sequence, fee) + { + setVaultID(vaultID); + } + + /** + * @brief Construct a VaultDeleteBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + VaultDeleteBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttVAULT_DELETE) + { + throw std::runtime_error("Invalid transaction type for VaultDeleteBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfVaultID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultDeleteBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Build and return the VaultDelete wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + VaultDelete + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return VaultDelete{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/VaultDeposit.h b/include/xrpl/protocol_autogen/transactions/VaultDeposit.h new file mode 100644 index 0000000000..4127638e57 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/VaultDeposit.h @@ -0,0 +1,155 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class VaultDepositBuilder; + +/** + * @brief Transaction: VaultDeposit + * + * Type: ttVAULT_DEPOSIT (68) + * Delegable: Delegation::notDelegable + * Amendment: featureSingleAssetVault + * Privileges: mayAuthorizeMPT | mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use VaultDepositBuilder to construct new transactions. + */ +class VaultDeposit : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttVAULT_DEPOSIT; + + /** + * @brief Construct a VaultDeposit transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit VaultDeposit(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for VaultDeposit"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfVaultID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getVaultID() const + { + return this->tx_->at(sfVaultID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } +}; + +/** + * @brief Builder for VaultDeposit transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class VaultDepositBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new VaultDepositBuilder with required fields. + * @param account The account initiating the transaction. + * @param vaultID The sfVaultID field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + VaultDepositBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& vaultID, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttVAULT_DEPOSIT, account, sequence, fee) + { + setVaultID(vaultID); + setAmount(amount); + } + + /** + * @brief Construct a VaultDepositBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + VaultDepositBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttVAULT_DEPOSIT) + { + throw std::runtime_error("Invalid transaction type for VaultDepositBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfVaultID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultDepositBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + VaultDepositBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Build and return the VaultDeposit wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + VaultDeposit + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return VaultDeposit{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/VaultSet.h b/include/xrpl/protocol_autogen/transactions/VaultSet.h new file mode 100644 index 0000000000..372697b5f7 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/VaultSet.h @@ -0,0 +1,240 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class VaultSetBuilder; + +/** + * @brief Transaction: VaultSet + * + * Type: ttVAULT_SET (66) + * Delegable: Delegation::notDelegable + * Amendment: featureSingleAssetVault + * Privileges: mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use VaultSetBuilder to construct new transactions. + */ +class VaultSet : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttVAULT_SET; + + /** + * @brief Construct a VaultSet transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit VaultSet(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for VaultSet"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfVaultID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getVaultID() const + { + return this->tx_->at(sfVaultID); + } + + /** + * @brief Get sfAssetsMaximum (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getAssetsMaximum() const + { + if (hasAssetsMaximum()) + { + return this->tx_->at(sfAssetsMaximum); + } + return std::nullopt; + } + + /** + * @brief Check if sfAssetsMaximum is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasAssetsMaximum() const + { + return this->tx_->isFieldPresent(sfAssetsMaximum); + } + + /** + * @brief Get sfDomainID (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDomainID() const + { + if (hasDomainID()) + { + return this->tx_->at(sfDomainID); + } + return std::nullopt; + } + + /** + * @brief Check if sfDomainID is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDomainID() const + { + return this->tx_->isFieldPresent(sfDomainID); + } + + /** + * @brief Get sfData (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getData() const + { + if (hasData()) + { + return this->tx_->at(sfData); + } + return std::nullopt; + } + + /** + * @brief Check if sfData is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasData() const + { + return this->tx_->isFieldPresent(sfData); + } +}; + +/** + * @brief Builder for VaultSet transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class VaultSetBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new VaultSetBuilder with required fields. + * @param account The account initiating the transaction. + * @param vaultID The sfVaultID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + VaultSetBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& vaultID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttVAULT_SET, account, sequence, fee) + { + setVaultID(vaultID); + } + + /** + * @brief Construct a VaultSetBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + VaultSetBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttVAULT_SET) + { + throw std::runtime_error("Invalid transaction type for VaultSetBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfVaultID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultSetBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Set sfAssetsMaximum (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultSetBuilder& + setAssetsMaximum(std::decay_t const& value) + { + object_[sfAssetsMaximum] = value; + return *this; + } + + /** + * @brief Set sfDomainID (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultSetBuilder& + setDomainID(std::decay_t const& value) + { + object_[sfDomainID] = value; + return *this; + } + + /** + * @brief Set sfData (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultSetBuilder& + setData(std::decay_t const& value) + { + object_[sfData] = value; + return *this; + } + + /** + * @brief Build and return the VaultSet wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + VaultSet + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return VaultSet{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/VaultWithdraw.h b/include/xrpl/protocol_autogen/transactions/VaultWithdraw.h new file mode 100644 index 0000000000..8b2a6a9a3c --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/VaultWithdraw.h @@ -0,0 +1,229 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class VaultWithdrawBuilder; + +/** + * @brief Transaction: VaultWithdraw + * + * Type: ttVAULT_WITHDRAW (69) + * Delegable: Delegation::notDelegable + * Amendment: featureSingleAssetVault + * Privileges: mayDeleteMPT | mayAuthorizeMPT | mustModifyVault + * + * Immutable wrapper around STTx providing type-safe field access. + * Use VaultWithdrawBuilder to construct new transactions. + */ +class VaultWithdraw : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttVAULT_WITHDRAW; + + /** + * @brief Construct a VaultWithdraw transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit VaultWithdraw(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for VaultWithdraw"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfVaultID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT256::type::value_type + getVaultID() const + { + return this->tx_->at(sfVaultID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfDestination (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestination() const + { + if (hasDestination()) + { + return this->tx_->at(sfDestination); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestination is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestination() const + { + return this->tx_->isFieldPresent(sfDestination); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } +}; + +/** + * @brief Builder for VaultWithdraw transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class VaultWithdrawBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new VaultWithdrawBuilder with required fields. + * @param account The account initiating the transaction. + * @param vaultID The sfVaultID field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + VaultWithdrawBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& vaultID, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttVAULT_WITHDRAW, account, sequence, fee) + { + setVaultID(vaultID); + setAmount(amount); + } + + /** + * @brief Construct a VaultWithdrawBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + VaultWithdrawBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttVAULT_WITHDRAW) + { + throw std::runtime_error("Invalid transaction type for VaultWithdrawBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfVaultID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + VaultWithdrawBuilder& + setVaultID(std::decay_t const& value) + { + object_[sfVaultID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @note This field supports MPT (Multi-Purpose Token) amounts. + * @return Reference to this builder for method chaining. + */ + VaultWithdrawBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultWithdrawBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + VaultWithdrawBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Build and return the VaultWithdraw wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + VaultWithdraw + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return VaultWithdraw{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainAccountCreateCommit.h b/include/xrpl/protocol_autogen/transactions/XChainAccountCreateCommit.h new file mode 100644 index 0000000000..aebfbea5d3 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainAccountCreateCommit.h @@ -0,0 +1,201 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainAccountCreateCommitBuilder; + +/** + * @brief Transaction: XChainAccountCreateCommit + * + * Type: ttXCHAIN_ACCOUNT_CREATE_COMMIT (44) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainAccountCreateCommitBuilder to construct new transactions. + */ +class XChainAccountCreateCommit : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_ACCOUNT_CREATE_COMMIT; + + /** + * @brief Construct a XChainAccountCreateCommit transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainAccountCreateCommit(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainAccountCreateCommit"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfSignatureReward (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSignatureReward() const + { + return this->tx_->at(sfSignatureReward); + } +}; + +/** + * @brief Builder for XChainAccountCreateCommit transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainAccountCreateCommitBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainAccountCreateCommitBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param destination The sfDestination field value. + * @param amount The sfAmount field value. + * @param signatureReward The sfSignatureReward field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainAccountCreateCommitBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::decay_t const& destination, std::decay_t const& amount, std::decay_t const& signatureReward, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_ACCOUNT_CREATE_COMMIT, account, sequence, fee) + { + setXChainBridge(xChainBridge); + setDestination(destination); + setAmount(amount); + setSignatureReward(signatureReward); + } + + /** + * @brief Construct a XChainAccountCreateCommitBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainAccountCreateCommitBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_ACCOUNT_CREATE_COMMIT) + { + throw std::runtime_error("Invalid transaction type for XChainAccountCreateCommitBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAccountCreateCommitBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAccountCreateCommitBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAccountCreateCommitBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfSignatureReward (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAccountCreateCommitBuilder& + setSignatureReward(std::decay_t const& value) + { + object_[sfSignatureReward] = value; + return *this; + } + + /** + * @brief Build and return the XChainAccountCreateCommit wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainAccountCreateCommit + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainAccountCreateCommit{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestation.h b/include/xrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestation.h new file mode 100644 index 0000000000..08dc646470 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestation.h @@ -0,0 +1,369 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainAddAccountCreateAttestationBuilder; + +/** + * @brief Transaction: XChainAddAccountCreateAttestation + * + * Type: ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION (46) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: createAcct + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainAddAccountCreateAttestationBuilder to construct new transactions. + */ +class XChainAddAccountCreateAttestation : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION; + + /** + * @brief Construct a XChainAddAccountCreateAttestation transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainAddAccountCreateAttestation(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainAddAccountCreateAttestation"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfAttestationSignerAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAttestationSignerAccount() const + { + return this->tx_->at(sfAttestationSignerAccount); + } + + /** + * @brief Get sfPublicKey (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getPublicKey() const + { + return this->tx_->at(sfPublicKey); + } + + /** + * @brief Get sfSignature (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getSignature() const + { + return this->tx_->at(sfSignature); + } + + /** + * @brief Get sfOtherChainSource (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOtherChainSource() const + { + return this->tx_->at(sfOtherChainSource); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfAttestationRewardAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAttestationRewardAccount() const + { + return this->tx_->at(sfAttestationRewardAccount); + } + + /** + * @brief Get sfWasLockingChainSend (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT8::type::value_type + getWasLockingChainSend() const + { + return this->tx_->at(sfWasLockingChainSend); + } + + /** + * @brief Get sfXChainAccountCreateCount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainAccountCreateCount() const + { + return this->tx_->at(sfXChainAccountCreateCount); + } + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfSignatureReward (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSignatureReward() const + { + return this->tx_->at(sfSignatureReward); + } +}; + +/** + * @brief Builder for XChainAddAccountCreateAttestation transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainAddAccountCreateAttestationBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainAddAccountCreateAttestationBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param attestationSignerAccount The sfAttestationSignerAccount field value. + * @param publicKey The sfPublicKey field value. + * @param signature The sfSignature field value. + * @param otherChainSource The sfOtherChainSource field value. + * @param amount The sfAmount field value. + * @param attestationRewardAccount The sfAttestationRewardAccount field value. + * @param wasLockingChainSend The sfWasLockingChainSend field value. + * @param xChainAccountCreateCount The sfXChainAccountCreateCount field value. + * @param destination The sfDestination field value. + * @param signatureReward The sfSignatureReward field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainAddAccountCreateAttestationBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::decay_t const& attestationSignerAccount, std::decay_t const& publicKey, std::decay_t const& signature, std::decay_t const& otherChainSource, std::decay_t const& amount, std::decay_t const& attestationRewardAccount, std::decay_t const& wasLockingChainSend, std::decay_t const& xChainAccountCreateCount, std::decay_t const& destination, std::decay_t const& signatureReward, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION, account, sequence, fee) + { + setXChainBridge(xChainBridge); + setAttestationSignerAccount(attestationSignerAccount); + setPublicKey(publicKey); + setSignature(signature); + setOtherChainSource(otherChainSource); + setAmount(amount); + setAttestationRewardAccount(attestationRewardAccount); + setWasLockingChainSend(wasLockingChainSend); + setXChainAccountCreateCount(xChainAccountCreateCount); + setDestination(destination); + setSignatureReward(signatureReward); + } + + /** + * @brief Construct a XChainAddAccountCreateAttestationBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainAddAccountCreateAttestationBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION) + { + throw std::runtime_error("Invalid transaction type for XChainAddAccountCreateAttestationBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfAttestationSignerAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setAttestationSignerAccount(std::decay_t const& value) + { + object_[sfAttestationSignerAccount] = value; + return *this; + } + + /** + * @brief Set sfPublicKey (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setPublicKey(std::decay_t const& value) + { + object_[sfPublicKey] = value; + return *this; + } + + /** + * @brief Set sfSignature (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setSignature(std::decay_t const& value) + { + object_[sfSignature] = value; + return *this; + } + + /** + * @brief Set sfOtherChainSource (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setOtherChainSource(std::decay_t const& value) + { + object_[sfOtherChainSource] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfAttestationRewardAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setAttestationRewardAccount(std::decay_t const& value) + { + object_[sfAttestationRewardAccount] = value; + return *this; + } + + /** + * @brief Set sfWasLockingChainSend (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setWasLockingChainSend(std::decay_t const& value) + { + object_[sfWasLockingChainSend] = value; + return *this; + } + + /** + * @brief Set sfXChainAccountCreateCount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setXChainAccountCreateCount(std::decay_t const& value) + { + object_[sfXChainAccountCreateCount] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfSignatureReward (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddAccountCreateAttestationBuilder& + setSignatureReward(std::decay_t const& value) + { + object_[sfSignatureReward] = value; + return *this; + } + + /** + * @brief Build and return the XChainAddAccountCreateAttestation wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainAddAccountCreateAttestation + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainAddAccountCreateAttestation{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainAddClaimAttestation.h b/include/xrpl/protocol_autogen/transactions/XChainAddClaimAttestation.h new file mode 100644 index 0000000000..100fc855aa --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainAddClaimAttestation.h @@ -0,0 +1,358 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainAddClaimAttestationBuilder; + +/** + * @brief Transaction: XChainAddClaimAttestation + * + * Type: ttXCHAIN_ADD_CLAIM_ATTESTATION (45) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: createAcct + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainAddClaimAttestationBuilder to construct new transactions. + */ +class XChainAddClaimAttestation : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_ADD_CLAIM_ATTESTATION; + + /** + * @brief Construct a XChainAddClaimAttestation transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainAddClaimAttestation(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainAddClaimAttestation"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfAttestationSignerAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAttestationSignerAccount() const + { + return this->tx_->at(sfAttestationSignerAccount); + } + + /** + * @brief Get sfPublicKey (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getPublicKey() const + { + return this->tx_->at(sfPublicKey); + } + + /** + * @brief Get sfSignature (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_VL::type::value_type + getSignature() const + { + return this->tx_->at(sfSignature); + } + + /** + * @brief Get sfOtherChainSource (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOtherChainSource() const + { + return this->tx_->at(sfOtherChainSource); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfAttestationRewardAccount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getAttestationRewardAccount() const + { + return this->tx_->at(sfAttestationRewardAccount); + } + + /** + * @brief Get sfWasLockingChainSend (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT8::type::value_type + getWasLockingChainSend() const + { + return this->tx_->at(sfWasLockingChainSend); + } + + /** + * @brief Get sfXChainClaimID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainClaimID() const + { + return this->tx_->at(sfXChainClaimID); + } + + /** + * @brief Get sfDestination (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestination() const + { + if (hasDestination()) + { + return this->tx_->at(sfDestination); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestination is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestination() const + { + return this->tx_->isFieldPresent(sfDestination); + } +}; + +/** + * @brief Builder for XChainAddClaimAttestation transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainAddClaimAttestationBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainAddClaimAttestationBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param attestationSignerAccount The sfAttestationSignerAccount field value. + * @param publicKey The sfPublicKey field value. + * @param signature The sfSignature field value. + * @param otherChainSource The sfOtherChainSource field value. + * @param amount The sfAmount field value. + * @param attestationRewardAccount The sfAttestationRewardAccount field value. + * @param wasLockingChainSend The sfWasLockingChainSend field value. + * @param xChainClaimID The sfXChainClaimID field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainAddClaimAttestationBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::decay_t const& attestationSignerAccount, std::decay_t const& publicKey, std::decay_t const& signature, std::decay_t const& otherChainSource, std::decay_t const& amount, std::decay_t const& attestationRewardAccount, std::decay_t const& wasLockingChainSend, std::decay_t const& xChainClaimID, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_ADD_CLAIM_ATTESTATION, account, sequence, fee) + { + setXChainBridge(xChainBridge); + setAttestationSignerAccount(attestationSignerAccount); + setPublicKey(publicKey); + setSignature(signature); + setOtherChainSource(otherChainSource); + setAmount(amount); + setAttestationRewardAccount(attestationRewardAccount); + setWasLockingChainSend(wasLockingChainSend); + setXChainClaimID(xChainClaimID); + } + + /** + * @brief Construct a XChainAddClaimAttestationBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainAddClaimAttestationBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_ADD_CLAIM_ATTESTATION) + { + throw std::runtime_error("Invalid transaction type for XChainAddClaimAttestationBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfAttestationSignerAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setAttestationSignerAccount(std::decay_t const& value) + { + object_[sfAttestationSignerAccount] = value; + return *this; + } + + /** + * @brief Set sfPublicKey (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setPublicKey(std::decay_t const& value) + { + object_[sfPublicKey] = value; + return *this; + } + + /** + * @brief Set sfSignature (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setSignature(std::decay_t const& value) + { + object_[sfSignature] = value; + return *this; + } + + /** + * @brief Set sfOtherChainSource (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setOtherChainSource(std::decay_t const& value) + { + object_[sfOtherChainSource] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfAttestationRewardAccount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setAttestationRewardAccount(std::decay_t const& value) + { + object_[sfAttestationRewardAccount] = value; + return *this; + } + + /** + * @brief Set sfWasLockingChainSend (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setWasLockingChainSend(std::decay_t const& value) + { + object_[sfWasLockingChainSend] = value; + return *this; + } + + /** + * @brief Set sfXChainClaimID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setXChainClaimID(std::decay_t const& value) + { + object_[sfXChainClaimID] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + XChainAddClaimAttestationBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Build and return the XChainAddClaimAttestation wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainAddClaimAttestation + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainAddClaimAttestation{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainClaim.h b/include/xrpl/protocol_autogen/transactions/XChainClaim.h new file mode 100644 index 0000000000..6b1b748677 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainClaim.h @@ -0,0 +1,238 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainClaimBuilder; + +/** + * @brief Transaction: XChainClaim + * + * Type: ttXCHAIN_CLAIM (43) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainClaimBuilder to construct new transactions. + */ +class XChainClaim : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_CLAIM; + + /** + * @brief Construct a XChainClaim transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainClaim(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainClaim"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfXChainClaimID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainClaimID() const + { + return this->tx_->at(sfXChainClaimID); + } + + /** + * @brief Get sfDestination (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getDestination() const + { + return this->tx_->at(sfDestination); + } + + /** + * @brief Get sfDestinationTag (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getDestinationTag() const + { + if (hasDestinationTag()) + { + return this->tx_->at(sfDestinationTag); + } + return std::nullopt; + } + + /** + * @brief Check if sfDestinationTag is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasDestinationTag() const + { + return this->tx_->isFieldPresent(sfDestinationTag); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } +}; + +/** + * @brief Builder for XChainClaim transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainClaimBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainClaimBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param xChainClaimID The sfXChainClaimID field value. + * @param destination The sfDestination field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainClaimBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::decay_t const& xChainClaimID, std::decay_t const& destination, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_CLAIM, account, sequence, fee) + { + setXChainBridge(xChainBridge); + setXChainClaimID(xChainClaimID); + setDestination(destination); + setAmount(amount); + } + + /** + * @brief Construct a XChainClaimBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainClaimBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_CLAIM) + { + throw std::runtime_error("Invalid transaction type for XChainClaimBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainClaimBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfXChainClaimID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainClaimBuilder& + setXChainClaimID(std::decay_t const& value) + { + object_[sfXChainClaimID] = value; + return *this; + } + + /** + * @brief Set sfDestination (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainClaimBuilder& + setDestination(std::decay_t const& value) + { + object_[sfDestination] = value; + return *this; + } + + /** + * @brief Set sfDestinationTag (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + XChainClaimBuilder& + setDestinationTag(std::decay_t const& value) + { + object_[sfDestinationTag] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainClaimBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Build and return the XChainClaim wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainClaim + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainClaim{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainCommit.h b/include/xrpl/protocol_autogen/transactions/XChainCommit.h new file mode 100644 index 0000000000..879c76f180 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainCommit.h @@ -0,0 +1,214 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainCommitBuilder; + +/** + * @brief Transaction: XChainCommit + * + * Type: ttXCHAIN_COMMIT (42) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainCommitBuilder to construct new transactions. + */ +class XChainCommit : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_COMMIT; + + /** + * @brief Construct a XChainCommit transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainCommit(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainCommit"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfXChainClaimID (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_UINT64::type::value_type + getXChainClaimID() const + { + return this->tx_->at(sfXChainClaimID); + } + + /** + * @brief Get sfAmount (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getAmount() const + { + return this->tx_->at(sfAmount); + } + + /** + * @brief Get sfOtherChainDestination (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getOtherChainDestination() const + { + if (hasOtherChainDestination()) + { + return this->tx_->at(sfOtherChainDestination); + } + return std::nullopt; + } + + /** + * @brief Check if sfOtherChainDestination is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasOtherChainDestination() const + { + return this->tx_->isFieldPresent(sfOtherChainDestination); + } +}; + +/** + * @brief Builder for XChainCommit transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainCommitBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainCommitBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param xChainClaimID The sfXChainClaimID field value. + * @param amount The sfAmount field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainCommitBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::decay_t const& xChainClaimID, std::decay_t const& amount, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_COMMIT, account, sequence, fee) + { + setXChainBridge(xChainBridge); + setXChainClaimID(xChainClaimID); + setAmount(amount); + } + + /** + * @brief Construct a XChainCommitBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainCommitBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_COMMIT) + { + throw std::runtime_error("Invalid transaction type for XChainCommitBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCommitBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfXChainClaimID (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCommitBuilder& + setXChainClaimID(std::decay_t const& value) + { + object_[sfXChainClaimID] = value; + return *this; + } + + /** + * @brief Set sfAmount (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCommitBuilder& + setAmount(std::decay_t const& value) + { + object_[sfAmount] = value; + return *this; + } + + /** + * @brief Set sfOtherChainDestination (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + XChainCommitBuilder& + setOtherChainDestination(std::decay_t const& value) + { + object_[sfOtherChainDestination] = value; + return *this; + } + + /** + * @brief Build and return the XChainCommit wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainCommit + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainCommit{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainCreateBridge.h b/include/xrpl/protocol_autogen/transactions/XChainCreateBridge.h new file mode 100644 index 0000000000..6ec22dd9fc --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainCreateBridge.h @@ -0,0 +1,190 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainCreateBridgeBuilder; + +/** + * @brief Transaction: XChainCreateBridge + * + * Type: ttXCHAIN_CREATE_BRIDGE (48) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainCreateBridgeBuilder to construct new transactions. + */ +class XChainCreateBridge : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_CREATE_BRIDGE; + + /** + * @brief Construct a XChainCreateBridge transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainCreateBridge(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainCreateBridge"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfSignatureReward (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSignatureReward() const + { + return this->tx_->at(sfSignatureReward); + } + + /** + * @brief Get sfMinAccountCreateAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMinAccountCreateAmount() const + { + if (hasMinAccountCreateAmount()) + { + return this->tx_->at(sfMinAccountCreateAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfMinAccountCreateAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMinAccountCreateAmount() const + { + return this->tx_->isFieldPresent(sfMinAccountCreateAmount); + } +}; + +/** + * @brief Builder for XChainCreateBridge transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainCreateBridgeBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainCreateBridgeBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param signatureReward The sfSignatureReward field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainCreateBridgeBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::decay_t const& signatureReward, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_CREATE_BRIDGE, account, sequence, fee) + { + setXChainBridge(xChainBridge); + setSignatureReward(signatureReward); + } + + /** + * @brief Construct a XChainCreateBridgeBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainCreateBridgeBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_CREATE_BRIDGE) + { + throw std::runtime_error("Invalid transaction type for XChainCreateBridgeBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCreateBridgeBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfSignatureReward (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCreateBridgeBuilder& + setSignatureReward(std::decay_t const& value) + { + object_[sfSignatureReward] = value; + return *this; + } + + /** + * @brief Set sfMinAccountCreateAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + XChainCreateBridgeBuilder& + setMinAccountCreateAmount(std::decay_t const& value) + { + object_[sfMinAccountCreateAmount] = value; + return *this; + } + + /** + * @brief Build and return the XChainCreateBridge wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainCreateBridge + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainCreateBridge{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainCreateClaimID.h b/include/xrpl/protocol_autogen/transactions/XChainCreateClaimID.h new file mode 100644 index 0000000000..ab76ee0e77 --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainCreateClaimID.h @@ -0,0 +1,177 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainCreateClaimIDBuilder; + +/** + * @brief Transaction: XChainCreateClaimID + * + * Type: ttXCHAIN_CREATE_CLAIM_ID (41) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainCreateClaimIDBuilder to construct new transactions. + */ +class XChainCreateClaimID : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_CREATE_CLAIM_ID; + + /** + * @brief Construct a XChainCreateClaimID transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainCreateClaimID(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainCreateClaimID"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfSignatureReward (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_AMOUNT::type::value_type + getSignatureReward() const + { + return this->tx_->at(sfSignatureReward); + } + + /** + * @brief Get sfOtherChainSource (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_ACCOUNT::type::value_type + getOtherChainSource() const + { + return this->tx_->at(sfOtherChainSource); + } +}; + +/** + * @brief Builder for XChainCreateClaimID transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainCreateClaimIDBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainCreateClaimIDBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param signatureReward The sfSignatureReward field value. + * @param otherChainSource The sfOtherChainSource field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainCreateClaimIDBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::decay_t const& signatureReward, std::decay_t const& otherChainSource, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_CREATE_CLAIM_ID, account, sequence, fee) + { + setXChainBridge(xChainBridge); + setSignatureReward(signatureReward); + setOtherChainSource(otherChainSource); + } + + /** + * @brief Construct a XChainCreateClaimIDBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainCreateClaimIDBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_CREATE_CLAIM_ID) + { + throw std::runtime_error("Invalid transaction type for XChainCreateClaimIDBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCreateClaimIDBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfSignatureReward (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCreateClaimIDBuilder& + setSignatureReward(std::decay_t const& value) + { + object_[sfSignatureReward] = value; + return *this; + } + + /** + * @brief Set sfOtherChainSource (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainCreateClaimIDBuilder& + setOtherChainSource(std::decay_t const& value) + { + object_[sfOtherChainSource] = value; + return *this; + } + + /** + * @brief Build and return the XChainCreateClaimID wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainCreateClaimID + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainCreateClaimID{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/include/xrpl/protocol_autogen/transactions/XChainModifyBridge.h b/include/xrpl/protocol_autogen/transactions/XChainModifyBridge.h new file mode 100644 index 0000000000..b57e0fdbdc --- /dev/null +++ b/include/xrpl/protocol_autogen/transactions/XChainModifyBridge.h @@ -0,0 +1,203 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class XChainModifyBridgeBuilder; + +/** + * @brief Transaction: XChainModifyBridge + * + * Type: ttXCHAIN_MODIFY_BRIDGE (47) + * Delegable: Delegation::delegable + * Amendment: featureXChainBridge + * Privileges: noPriv + * + * Immutable wrapper around STTx providing type-safe field access. + * Use XChainModifyBridgeBuilder to construct new transactions. + */ +class XChainModifyBridge : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ttXCHAIN_MODIFY_BRIDGE; + + /** + * @brief Construct a XChainModifyBridge transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit XChainModifyBridge(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for XChainModifyBridge"); + } + } + + // Transaction-specific field getters + + /** + * @brief Get sfXChainBridge (soeREQUIRED) + * @return The field value. + */ + [[nodiscard]] + SF_XCHAIN_BRIDGE::type::value_type + getXChainBridge() const + { + return this->tx_->at(sfXChainBridge); + } + + /** + * @brief Get sfSignatureReward (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getSignatureReward() const + { + if (hasSignatureReward()) + { + return this->tx_->at(sfSignatureReward); + } + return std::nullopt; + } + + /** + * @brief Check if sfSignatureReward is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasSignatureReward() const + { + return this->tx_->isFieldPresent(sfSignatureReward); + } + + /** + * @brief Get sfMinAccountCreateAmount (soeOPTIONAL) + * @return The field value, or std::nullopt if not present. + */ + [[nodiscard]] + protocol_autogen::Optional + getMinAccountCreateAmount() const + { + if (hasMinAccountCreateAmount()) + { + return this->tx_->at(sfMinAccountCreateAmount); + } + return std::nullopt; + } + + /** + * @brief Check if sfMinAccountCreateAmount is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + hasMinAccountCreateAmount() const + { + return this->tx_->isFieldPresent(sfMinAccountCreateAmount); + } +}; + +/** + * @brief Builder for XChainModifyBridge transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class XChainModifyBridgeBuilder : public TransactionBuilderBase +{ +public: + /** + * @brief Construct a new XChainModifyBridgeBuilder with required fields. + * @param account The account initiating the transaction. + * @param xChainBridge The sfXChainBridge field value. + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + XChainModifyBridgeBuilder(SF_ACCOUNT::type::value_type account, + std::decay_t const& xChainBridge, std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase(ttXCHAIN_MODIFY_BRIDGE, account, sequence, fee) + { + setXChainBridge(xChainBridge); + } + + /** + * @brief Construct a XChainModifyBridgeBuilder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + XChainModifyBridgeBuilder(std::shared_ptr tx) + { + if (tx->getTxnType() != ttXCHAIN_MODIFY_BRIDGE) + { + throw std::runtime_error("Invalid transaction type for XChainModifyBridgeBuilder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ + + /** + * @brief Set sfXChainBridge (soeREQUIRED) + * @return Reference to this builder for method chaining. + */ + XChainModifyBridgeBuilder& + setXChainBridge(std::decay_t const& value) + { + object_[sfXChainBridge] = value; + return *this; + } + + /** + * @brief Set sfSignatureReward (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + XChainModifyBridgeBuilder& + setSignatureReward(std::decay_t const& value) + { + object_[sfSignatureReward] = value; + return *this; + } + + /** + * @brief Set sfMinAccountCreateAmount (soeOPTIONAL) + * @return Reference to this builder for method chaining. + */ + XChainModifyBridgeBuilder& + setMinAccountCreateAmount(std::decay_t const& value) + { + object_[sfMinAccountCreateAmount] = value; + return *this; + } + + /** + * @brief Build and return the XChainModifyBridge wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + XChainModifyBridge + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return XChainModifyBridge{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/scripts/generate_ledger_classes.py b/scripts/generate_ledger_classes.py new file mode 100644 index 0000000000..ad773ab9af --- /dev/null +++ b/scripts/generate_ledger_classes.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python3 +""" +Generate C++ wrapper classes for XRP Ledger entry types from ledger_entries.macro. + +This script parses the ledger_entries.macro file and generates type-safe wrapper +classes for each ledger entry type, similar to the transaction wrapper classes. + +Uses pcpp to preprocess the macro file and pyparsing to parse the DSL. +""" + +import io +import argparse +from pathlib import Path +import pyparsing as pp + +# Import common utilities +from macro_parser_common import ( + CppCleaner, + parse_sfields_macro, + parse_field_list, + generate_cpp_class, + generate_from_template, + clear_output_directory, +) + + +def create_ledger_entry_parser(): + """Create a pyparsing parser for LEDGER_ENTRY macros. + + This parser extracts the full LEDGER_ENTRY macro call and parses its arguments + using pyparsing's nesting-aware delimited list parsing. + """ + # Match the exact words + ledger_entry = pp.Keyword("LEDGER_ENTRY") | pp.Keyword("LEDGER_ENTRY_DUPLICATE") + + # Define nested structures so pyparsing protects them + nested_braces = pp.original_text_for(pp.nested_expr("{", "}")) + nested_parens = pp.original_text_for(pp.nested_expr("(", ")")) + + # Define standard text (anything that isn't a comma, parens, or braces) + plain_text = pp.Word(pp.printables + " \t\n", exclude_chars=",{}()") + + # A single argument is any combination of the above + single_arg = pp.Combine(pp.OneOrMore(nested_braces | nested_parens | plain_text)) + single_arg.set_parse_action(lambda t: t[0].strip()) + + # The arguments are a delimited list + args_list = pp.DelimitedList(single_arg) + + # The full macro: LEDGER_ENTRY(args) or LEDGER_ENTRY_DUPLICATE(args) + macro_parser = ( + ledger_entry + pp.Suppress("(") + pp.Group(args_list)("args") + pp.Suppress(")") + ) + + return macro_parser + + +def parse_ledger_entry_args(args_list): + """Parse the arguments of a LEDGER_ENTRY macro call. + + Args: + args_list: A list of parsed arguments from pyparsing, e.g., + ['ltACCOUNT_ROOT', '0x0061', 'AccountRoot', 'account', '({...})'] + + Returns: + A dict with parsed ledger entry information. + """ + if len(args_list) < 5: + raise ValueError( + f"Expected at least 5 parts in LEDGER_ENTRY, got {len(args_list)}: {args_list}" + ) + + tag = args_list[0] + value = args_list[1] + name = args_list[2] + rpc_name = args_list[3] + fields_str = args_list[-1] + + # Parse fields: ({field1, field2, ...}) + fields = parse_field_list(fields_str) + + return { + "tag": tag, + "value": value, + "name": name, + "rpc_name": rpc_name, + "fields": fields, + } + + +def parse_macro_file(file_path): + """Parse the ledger_entries.macro file and return a list of ledger entry definitions. + + Uses pcpp to preprocess the file and pyparsing to parse the LEDGER_ENTRY macros. + """ + with open(file_path, "r") as f: + c_code = f.read() + + # Step 1: Clean the C++ code using pcpp + cleaner = CppCleaner("LEDGER_ENTRY_INCLUDE", "LEDGER_ENTRY") + cleaner.parse(c_code) + + out = io.StringIO() + cleaner.write(out) + clean_text = out.getvalue() + + # Step 2: Parse the clean text using pyparsing + parser = create_ledger_entry_parser() + entries = [] + + for match, _, _ in parser.scan_string(clean_text): + # Extract the macro name and arguments + raw_args = match.args + + # Parse the arguments + entry_data = parse_ledger_entry_args(raw_args) + entries.append(entry_data) + + return entries + + +def main(): + parser = argparse.ArgumentParser( + description="Generate C++ ledger entry classes from ledger_entries.macro" + ) + parser.add_argument("macro_path", help="Path to ledger_entries.macro") + parser.add_argument( + "--header-dir", + help="Output directory for header files", + default="include/xrpl/protocol_autogen/ledger_entries", + ) + parser.add_argument( + "--test-dir", + help="Output directory for test files (optional)", + default=None, + ) + parser.add_argument( + "--sfields-macro", + help="Path to sfields.macro (default: auto-detect from macro_path)", + ) + parser.add_argument( + "--list-outputs", + action="store_true", + help="List output files without generating (one per line)", + ) + + args = parser.parse_args() + + # Parse the macro file to get ledger entry names + entries = parse_macro_file(args.macro_path) + + # If --list-outputs, just print the output file paths and exit + if args.list_outputs: + header_dir = Path(args.header_dir) + for entry in entries: + print(header_dir / f"{entry['name']}.h") + if args.test_dir: + test_dir = Path(args.test_dir) + for entry in entries: + print(test_dir / f"{entry['name']}Tests.cpp") + return + + # Auto-detect sfields.macro path if not provided + if args.sfields_macro: + sfields_path = Path(args.sfields_macro) + else: + # Assume sfields.macro is in the same directory as ledger_entries.macro + macro_path = Path(args.macro_path) + sfields_path = macro_path.parent / "sfields.macro" + + # Parse sfields.macro to get field type information + print(f"Parsing {sfields_path}...") + field_types = parse_sfields_macro(sfields_path) + print( + f"Found {len(field_types)} field definitions ({sum(1 for f in field_types.values() if f['typed'])} typed, {sum(1 for f in field_types.values() if not f['typed'])} untyped)\n" + ) + + print(f"Found {len(entries)} ledger entries\n") + + for entry in entries: + print(f"Ledger Entry: {entry['name']}") + print(f" Tag: {entry['tag']}") + print(f" Value: {entry['value']}") + print(f" RPC Name: {entry['rpc_name']}") + print(f" Fields: {len(entry['fields'])}") + for field in entry["fields"]: + mpt_info = f" ({field['mpt_support']})" if "mpt_support" in field else "" + print(f" - {field['name']}: {field['requirement']}{mpt_info}") + print() + + # Set up template directory + script_dir = Path(__file__).parent + template_dir = script_dir / "templates" + + # Generate C++ classes + header_dir = Path(args.header_dir) + header_dir.mkdir(parents=True, exist_ok=True) + + # Clear existing generated files before regenerating + clear_output_directory(header_dir) + + for entry in entries: + generate_cpp_class( + entry, header_dir, template_dir, field_types, "LedgerEntry.h.mako" + ) + + print(f"\nGenerated {len(entries)} ledger entry classes") + + # Generate unit tests if --test-dir is provided + if args.test_dir: + test_dir = Path(args.test_dir) + test_dir.mkdir(parents=True, exist_ok=True) + + # Clear existing generated test files before regenerating + clear_output_directory(test_dir) + + for entry in entries: + # Fields are already enriched from generate_cpp_class above + generate_from_template( + entry, test_dir, template_dir, "LedgerEntryTests.cpp.mako", "Tests.cpp" + ) + + print(f"\nGenerated {len(entries)} ledger entry test files") + + +if __name__ == "__main__": + main() diff --git a/scripts/generate_tx_classes.py b/scripts/generate_tx_classes.py new file mode 100644 index 0000000000..f21b7101df --- /dev/null +++ b/scripts/generate_tx_classes.py @@ -0,0 +1,247 @@ +#!/usr/bin/env python3 +""" +Parse transactions.macro file to extract transaction information +and generate C++ classes for each transaction type. + +Uses pcpp to preprocess the macro file and pyparsing to parse the DSL. +""" + +import io +import argparse +from pathlib import Path +import pyparsing as pp + +# Import common utilities +from macro_parser_common import ( + CppCleaner, + parse_sfields_macro, + parse_field_list, + generate_cpp_class, + generate_from_template, + clear_output_directory, +) + + +def create_transaction_parser(): + """Create a pyparsing parser for TRANSACTION macros. + + This parser extracts the full TRANSACTION macro call and parses its arguments + using pyparsing's nesting-aware delimited list parsing. + """ + # Define nested structures so pyparsing protects them + nested_braces = pp.original_text_for(pp.nested_expr("{", "}")) + nested_parens = pp.original_text_for(pp.nested_expr("(", ")")) + + # Define standard text (anything that isn't a comma, parens, or braces) + plain_text = pp.Word(pp.printables + " \t\n", exclude_chars=",{}()") + + # A single argument is any combination of the above + single_arg = pp.Combine(pp.OneOrMore(nested_braces | nested_parens | plain_text)) + single_arg.set_parse_action(lambda t: t[0].strip()) + + # The arguments are a delimited list + args_list = pp.DelimitedList(single_arg) + + # The full macro: TRANSACTION(args) + macro_parser = ( + pp.Keyword("TRANSACTION") + + pp.Suppress("(") + + pp.Group(args_list)("args") + + pp.Suppress(")") + ) + + return macro_parser + + +def parse_transaction_args(args_list): + """Parse the arguments of a TRANSACTION macro call. + + Args: + args_list: A list of parsed arguments from pyparsing, e.g., + ['ttPAYMENT', '0', 'Payment', 'Delegation::delegable', + 'uint256{}', 'createAcct', '({...})'] + + Returns: + A dict with parsed transaction information. + """ + if len(args_list) < 7: + raise ValueError( + f"Expected at least 7 parts in TRANSACTION, got {len(args_list)}: {args_list}" + ) + + tag = args_list[0] + value = args_list[1] + name = args_list[2] + delegable = args_list[3] + amendments = args_list[4] + privileges = args_list[5] + fields_str = args_list[-1] + + # Parse fields: ({field1, field2, ...}) + fields = parse_field_list(fields_str) + + return { + "tag": tag, + "value": value, + "name": name, + "delegable": delegable, + "amendments": amendments, + "privileges": privileges, + "fields": fields, + } + + +def parse_macro_file(filepath): + """Parse the transactions.macro file. + + Uses pcpp to preprocess the file and pyparsing to parse the TRANSACTION macros. + """ + with open(filepath, "r") as f: + c_code = f.read() + + # Step 1: Clean the C++ code using pcpp + cleaner = CppCleaner("TRANSACTION_INCLUDE", "TRANSACTION") + cleaner.parse(c_code) + + out = io.StringIO() + cleaner.write(out) + clean_text = out.getvalue() + + # Step 2: Parse the clean text using pyparsing + parser = create_transaction_parser() + transactions = [] + + for match, _, _ in parser.scan_string(clean_text): + # Extract the macro name and arguments + raw_args = match.args + + # Parse the arguments + tx_data = parse_transaction_args(raw_args) + transactions.append(tx_data) + + return transactions + + +# TransactionBase is a static file in the repository at: +# - include/xrpl/protocol/TransactionBase.h +# - src/libxrpl/protocol/TransactionBase.cpp +# It is NOT generated by this script. + + +def main(): + parser = argparse.ArgumentParser( + description="Generate C++ transaction classes from transactions.macro" + ) + parser.add_argument("macro_path", help="Path to transactions.macro") + parser.add_argument( + "--header-dir", + help="Output directory for header files", + default="include/xrpl/protocol_autogen/transactions", + ) + parser.add_argument( + "--test-dir", + help="Output directory for test files (optional)", + default=None, + ) + parser.add_argument( + "--sfields-macro", + help="Path to sfields.macro (default: auto-detect from macro_path)", + ) + parser.add_argument( + "--list-outputs", + action="store_true", + help="List output files without generating (one per line)", + ) + + args = parser.parse_args() + + # Parse the macro file to get transaction names + transactions = parse_macro_file(args.macro_path) + + # If --list-outputs, just print the output file paths and exit + if args.list_outputs: + header_dir = Path(args.header_dir) + for tx in transactions: + print(header_dir / f"{tx['name']}.h") + if args.test_dir: + test_dir = Path(args.test_dir) + for tx in transactions: + print(test_dir / f"{tx['name']}Tests.cpp") + return + + # Auto-detect sfields.macro path if not provided + if args.sfields_macro: + sfields_path = Path(args.sfields_macro) + else: + # Assume sfields.macro is in the same directory as transactions.macro + macro_path = Path(args.macro_path) + sfields_path = macro_path.parent / "sfields.macro" + + # Parse sfields.macro to get field type information + print(f"Parsing {sfields_path}...") + field_types = parse_sfields_macro(sfields_path) + print( + f"Found {len(field_types)} field definitions ({sum(1 for f in field_types.values() if f['typed'])} typed, {sum(1 for f in field_types.values() if not f['typed'])} untyped)\n" + ) + + print(f"Found {len(transactions)} transactions\n") + + for tx in transactions: + print(f"Transaction: {tx['name']}") + print(f" Tag: {tx['tag']}") + print(f" Value: {tx['value']}") + print(f" Fields: {len(tx['fields'])}") + for field in tx["fields"]: + print(f" - {field['name']}: {field['requirement']}") + print() + + # Set up output directory + header_dir = Path(args.header_dir) + header_dir.mkdir(parents=True, exist_ok=True) + + # Clear existing generated files before regenerating + clear_output_directory(header_dir) + + print(f"\nGenerating header-only template classes...") + print(f" Headers: {header_dir}\n") + + # Set up template directory + script_dir = Path(__file__).parent + template_dir = script_dir / "templates" + + generated_files = [] + for tx_info in transactions: + header_path = generate_cpp_class( + tx_info, header_dir, template_dir, field_types, "Transaction.h.mako" + ) + generated_files.append(header_path) + print(f" Generated: {tx_info['name']}.h") + + print( + f"\nGenerated {len(transactions)} transaction classes ({len(generated_files)} header files)" + ) + print(f" Headers: {header_dir.absolute()}") + + # Generate unit tests if --test-dir is provided + if args.test_dir: + test_dir = Path(args.test_dir) + test_dir.mkdir(parents=True, exist_ok=True) + + # Clear existing generated test files before regenerating + clear_output_directory(test_dir) + + for tx_info in transactions: + # Fields are already enriched from generate_cpp_class above + generate_from_template( + tx_info, + test_dir, + template_dir, + "TransactionTests.cpp.mako", + "Tests.cpp", + ) + + print(f"\nGenerated {len(transactions)} transaction test files") + + +if __name__ == "__main__": + main() diff --git a/scripts/macro_parser_common.py b/scripts/macro_parser_common.py new file mode 100644 index 0000000000..eae4df39db --- /dev/null +++ b/scripts/macro_parser_common.py @@ -0,0 +1,297 @@ +#!/usr/bin/env python3 +""" +Common utilities for parsing XRP Ledger macro files. + +This module provides shared functionality for parsing transactions.macro +and ledger_entries.macro files using pcpp and pyparsing. +""" + +import re +import shutil +from pathlib import Path +import pyparsing as pp +from pcpp import Preprocessor + + +def clear_output_directory(directory): + """Clear all generated files from an output directory. + + Removes all .h and .cpp files from the directory, but preserves + the directory itself and any subdirectories. + + Args: + directory: Path to the directory to clear + """ + dir_path = Path(directory) + if not dir_path.exists(): + return + + # Remove generated files (headers and source files) + for pattern in ["*.h", "*.cpp"]: + for file_path in dir_path.glob(pattern): + file_path.unlink() + + print(f"Cleared output directory: {dir_path}") + + +class CppCleaner(Preprocessor): + """C preprocessor that removes C++ noise while preserving macro calls.""" + + def __init__(self, macro_include_name, macro_name): + """ + Initialize the preprocessor. + + Args: + macro_include_name: The name of the include flag to set to 0 + (e.g., "TRANSACTION_INCLUDE" or "LEDGER_ENTRY_INCLUDE") + macro_name: The name of the macro to define so #if !defined() checks pass + (e.g., "TRANSACTION" or "LEDGER_ENTRY") + """ + super(CppCleaner, self).__init__() + # Define flags so #if blocks evaluate correctly + # We set the include flag to 0 so includes are skipped + self.define(f"{macro_include_name} 0") + # Define the macro so #if !defined(MACRO) / #error checks pass + # We define it to expand to itself so the macro calls remain in the output + # for pyparsing to find and parse + self.define(f"{macro_name}(...) {macro_name}(__VA_ARGS__)") + # Suppress line directives + self.line_directive = None + + def on_error(self, file, line, msg): + # Ignore #error directives + pass + + def on_include_not_found( + self, is_malformed, is_system_include, curdir, includepath + ): + # Ignore missing headers + pass + + +def parse_sfields_macro(sfields_path): + """ + Parse sfields.macro to determine which fields are typed vs untyped. + + Returns a dict mapping field names to their type information: + { + 'sfMemos': {'typed': False, 'stiSuffix': 'ARRAY', 'typeData': {...}}, + 'sfAmount': {'typed': True, 'stiSuffix': 'AMOUNT', 'typeData': {...}}, + ... + } + """ + # Mapping from STI suffix to C++ type for untyped fields + UNTYPED_TYPE_MAP = { + "ARRAY": { + "getter_method": "getFieldArray", + "setter_method": "setFieldArray", + "setter_use_brackets": False, + "setter_type": "STArray const&", + "return_type": "STArray const&", + "return_type_optional": "std::optional>", + }, + "OBJECT": { + "getter_method": "getFieldObject", + "setter_method": "setFieldObject", + "setter_use_brackets": False, + "setter_type": "STObject const&", + "return_type": "STObject", + "return_type_optional": "std::optional", + }, + "PATHSET": { + "getter_method": "getFieldPathSet", + "setter_method": "setFieldPathSet", + "setter_use_brackets": False, + "setter_type": "STPathSet const&", + "return_type": "STPathSet const&", + "return_type_optional": "std::optional>", + }, + } + + field_info = {} + + with open(sfields_path, "r") as f: + content = f.read() + + # Parse TYPED_SFIELD entries + # Format: TYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) + typed_pattern = r"TYPED_SFIELD\s*\(\s*(\w+)\s*,\s*(\w+)\s*," + for match in re.finditer(typed_pattern, content): + field_name = match.group(1) + sti_suffix = match.group(2) + field_info[field_name] = { + "typed": True, + "stiSuffix": sti_suffix, + "typeData": { + "getter_method": "at", + "setter_method": "", + "setter_use_brackets": True, + "setter_type": f"std::decay_t const&", + "return_type": f"SF_{sti_suffix}::type::value_type", + "return_type_optional": f"protocol_autogen::Optional", + }, + } + + # Parse UNTYPED_SFIELD entries + # Format: UNTYPED_SFIELD(sfName, stiSuffix, fieldValue, ...) + untyped_pattern = r"UNTYPED_SFIELD\s*\(\s*(\w+)\s*,\s*(\w+)\s*," + for match in re.finditer(untyped_pattern, content): + field_name = match.group(1) + sti_suffix = match.group(2) + type_data = UNTYPED_TYPE_MAP.get( + sti_suffix, UNTYPED_TYPE_MAP.get("OBJECT") + ) # Default to OBJECT + field_info[field_name] = { + "typed": False, + "stiSuffix": sti_suffix, + "typeData": type_data, + } + + return field_info + + +def create_field_list_parser(): + """Create a pyparsing parser for field lists like '({...})'.""" + # A field identifier (e.g., sfDestination, soeREQUIRED, soeMPTSupported) + field_identifier = pp.Word(pp.alphas + "_", pp.alphanums + "_") + + # A single field definition: {sfName, soeREQUIRED, ...} + # Allow optional trailing comma inside the braces + field_def = ( + pp.Suppress("{") + + pp.Group(pp.DelimitedList(field_identifier) + pp.Optional(pp.Suppress(",")))( + "parts" + ) + + pp.Suppress("}") + ) + + # The field list: ({field1, field2, ...}) or ({}) for empty lists + # Allow optional trailing comma after the last field definition + field_list = ( + pp.Suppress("(") + + pp.Suppress("{") + + pp.Group( + pp.Optional(pp.DelimitedList(field_def) + pp.Optional(pp.Suppress(","))) + )("fields") + + pp.Suppress("}") + + pp.Suppress(")") + ) + + return field_list + + +def parse_field_list(fields_str): + """Parse a field list string like '({...})' using pyparsing. + + Args: + fields_str: A string like '({ + {sfDestination, soeREQUIRED}, + {sfAmount, soeREQUIRED, soeMPTSupported} + })' + + Returns: + A list of field dicts with 'name', 'requirement', 'flags', and 'supports_mpt'. + """ + parser = create_field_list_parser() + + try: + result = parser.parse_string(fields_str, parse_all=True) + fields = [] + + for field_parts in result.fields: + if len(field_parts) < 2: + continue + + field_name = field_parts[0] + requirement = field_parts[1] + flags = list(field_parts[2:]) if len(field_parts) > 2 else [] + supports_mpt = "soeMPTSupported" in flags + + fields.append( + { + "name": field_name, + "requirement": requirement, + "flags": flags, + "supports_mpt": supports_mpt, + } + ) + + return fields + except pp.ParseException as e: + raise ValueError(f"Failed to parse field list: {e}") + + +def enrich_fields_with_type_data(entry_info, field_types): + """Enrich field information with type data from sfields.macro. + + Args: + entry_info: Dict containing entry information (name, fields, etc.) + field_types: Dict mapping field names to type information + + Modifies entry_info["fields"] in place. + """ + for field in entry_info["fields"]: + field_name = field["name"] + if field_name in field_types: + field["typed"] = field_types[field_name]["typed"] + field["paramName"] = field_name[2].lower() + field_name[3:] + field["stiSuffix"] = field_types[field_name]["stiSuffix"] + field["typeData"] = field_types[field_name]["typeData"] + else: + # Unknown field - assume typed for safety + field["typed"] = True + field["paramName"] = "" + field["stiSuffix"] = None + field["typeData"] = None + + +def generate_from_template( + entry_info, output_dir, template_dir, template_name, output_suffix +): + """Generate a file from a Mako template. + + Args: + entry_info: Dict containing entry information (name, fields, etc.) + Fields should already be enriched with type data. + output_dir: Output directory for generated files + template_dir: Directory containing Mako templates + template_name: Name of the Mako template file to use + output_suffix: Suffix for the output file (e.g., ".h" or "Tests.cpp") + + Returns: + Path to the generated file + """ + from mako.template import Template + + template_path = Path(template_dir) / template_name + template = Template(filename=str(template_path)) + + # Render the template - pass entry_info directly so templates can access any field + content = template.render(**entry_info) + + # Write output file in binary mode to avoid any line ending conversion + output_path = Path(output_dir) / f"{entry_info['name']}{output_suffix}" + with open(output_path, "wb") as f: + f.write(content.encode("utf-8")) + + print(f"Generated {output_path}") + return output_path + + +def generate_cpp_class( + entry_info, header_dir, template_dir, field_types, template_name +): + """Generate C++ header file from a Mako template. + + Args: + entry_info: Dict containing entry information (name, fields, etc.) + header_dir: Output directory for generated header files + template_dir: Directory containing Mako templates + field_types: Dict mapping field names to type information + template_name: Name of the Mako template file to use + """ + # Enrich field information with type data + enrich_fields_with_type_data(entry_info, field_types) + + # Generate the header file + generate_from_template(entry_info, header_dir, template_dir, template_name, ".h") diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 0000000000..40b472078d --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1,13 @@ +# Python dependencies for XRP Ledger code generation scripts +# +# These packages are required to run the code generation scripts that +# parse macro files and generate C++ wrapper classes. + +# C preprocessor for Python - used to preprocess macro files +pcpp>=1.30 + +# Parser combinator library - used to parse the macro DSL +pyparsing>=3.0.0 + +# Template engine - used to generate C++ code from templates +Mako>=1.2.0 diff --git a/scripts/templates/LedgerEntry.h.mako b/scripts/templates/LedgerEntry.h.mako new file mode 100644 index 0000000000..fdb55a973a --- /dev/null +++ b/scripts/templates/LedgerEntry.h.mako @@ -0,0 +1,216 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::ledger_entries { + +class ${name}Builder; + +/** + * @brief Ledger Entry: ${name} + * + * Type: ${tag} (${value}) + * RPC Name: ${rpc_name} + * + * Immutable wrapper around SLE providing type-safe field access. + * Use ${name}Builder to construct new ledger entries. + */ +class ${name} : public LedgerEntryBase +{ +public: + static constexpr LedgerEntryType entryType = ${tag}; + + /** + * @brief Construct a ${name} ledger entry wrapper from an existing SLE object. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + explicit ${name}(std::shared_ptr sle) + : LedgerEntryBase(std::move(sle)) + { + // Verify ledger entry type + if (sle_->getType() != entryType) + { + throw std::runtime_error("Invalid ledger entry type for ${name}"); + } + } + + // Ledger entry-specific field getters +% for field in fields: +% if field['typed']: + + /** + * @brief Get ${field['name']} (${field['requirement']}) +% if field.get('mpt_support'): + * MPT Support: ${field['mpt_support']} +% endif +% if field['requirement'] == 'soeREQUIRED': + * @return The field value. +% else: + * @return The field value, or std::nullopt if not present. +% endif + */ +% if field['requirement'] == 'soeREQUIRED': + [[nodiscard]] + ${field['typeData']['return_type']} + get${field['name'][2:]}() const + { + return this->sle_->${field['typeData']['getter_method']}(${field['name']}); + } +% else: + [[nodiscard]] + ${field['typeData']['return_type_optional']} + get${field['name'][2:]}() const + { + if (has${field['name'][2:]}()) + return this->sle_->${field['typeData']['getter_method']}(${field['name']}); + return std::nullopt; + } + + /** + * @brief Check if ${field['name']} is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + has${field['name'][2:]}() const + { + return this->sle_->isFieldPresent(${field['name']}); + } +% endif +% else: + + /** + * @brief Get ${field['name']} (${field['requirement']}) +% if field.get('mpt_support'): + * MPT Support: ${field['mpt_support']} +% endif + * @note This is an untyped field (${field.get('cppType', 'unknown')}). +% if field['requirement'] == 'soeREQUIRED': + * @return The field value. +% else: + * @return The field value, or std::nullopt if not present. +% endif + */ +% if field['requirement'] == 'soeREQUIRED': + [[nodiscard]] + ${field['typeData']['return_type']} + get${field['name'][2:]}() const + { + return this->sle_->${field['typeData']['getter_method']}(${field['name']}); + } +% else: + [[nodiscard]] + ${field['typeData']['return_type_optional']} + get${field['name'][2:]}() const + { + if (this->sle_->isFieldPresent(${field['name']})) + return this->sle_->${field['typeData']['getter_method']}(${field['name']}); + return std::nullopt; + } + + /** + * @brief Check if ${field['name']} is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + has${field['name'][2:]}() const + { + return this->sle_->isFieldPresent(${field['name']}); + } +% endif +% endif +% endfor +}; + +<% + required_fields = [f for f in fields if f['requirement'] == 'soeREQUIRED'] +%>\ +/** + * @brief Builder for ${name} ledger entries. + * + * Provides a fluent interface for constructing ledger entries with method chaining. + * Uses Json::Value internally for flexible ledger entry construction. + * Inherits common field setters from LedgerEntryBuilderBase. + */ +class ${name}Builder : public LedgerEntryBuilderBase<${name}Builder> +{ +public: + /** + * @brief Construct a new ${name}Builder with required fields. +% for field in required_fields: + * @param ${field['paramName']} The ${field['name']} field value. +% endfor + */ + ${name}Builder(\ +% for i, field in enumerate(required_fields): +${field['typeData']['setter_type']} ${field['paramName']}${',' if i < len(required_fields) - 1 else ''}\ +% endfor +) + : LedgerEntryBuilderBase<${name}Builder>(${tag}) + { +% for field in required_fields: + set${field['name'][2:]}(${field['paramName']}); +% endfor + } + + /** + * @brief Construct a ${name}Builder from an existing SLE object. + * @param sle The existing ledger entry to copy from. + * @throws std::runtime_error if the ledger entry type doesn't match. + */ + ${name}Builder(std::shared_ptr sle) + { + if (sle->at(sfLedgerEntryType) != ${tag}) + { + throw std::runtime_error("Invalid ledger entry type for ${name}"); + } + object_ = *sle; + } + + /** @brief Ledger entry-specific field setters */ +% for field in fields: + + /** + * @brief Set ${field['name']} (${field['requirement']}) +% if field.get('mpt_support'): + * MPT Support: ${field['mpt_support']} +% endif + * @return Reference to this builder for method chaining. + */ + ${name}Builder& + set${field['name'][2:]}(${field['typeData']['setter_type']} value) + { +% if field.get('stiSuffix') == 'ISSUE': + object_[${field['name']}] = STIssue(${field['name']}, value); +% elif field['typeData'].get('setter_use_brackets'): + object_[${field['name']}] = value; +% else: + object_.${field['typeData']['setter_method']}(${field['name']}, value); +% endif + return *this; + } +% endfor + + /** + * @brief Build and return the completed ${name} wrapper. + * @param index The ledger entry index. + * @return The constructed ledger entry wrapper. + */ + ${name} + build(uint256 const& index) + { + return ${name}{std::make_shared(std::move(object_), index)}; + } +}; + +} // namespace xrpl::ledger_entries diff --git a/scripts/templates/LedgerEntryTests.cpp.mako b/scripts/templates/LedgerEntryTests.cpp.mako new file mode 100644 index 0000000000..35ce57f17b --- /dev/null +++ b/scripts/templates/LedgerEntryTests.cpp.mako @@ -0,0 +1,231 @@ +// Auto-generated unit tests for ledger entry ${name} +<% + required_fields = [f for f in fields if f["requirement"] == "soeREQUIRED"] + optional_fields = [f for f in fields if f["requirement"] != "soeREQUIRED"] + + def canonical_expr(field): + return f"canonical_{field['stiSuffix']}()" + + # Pick a wrong ledger entry to test type mismatch + # Use Ticket as it has minimal required fields (just Account) + if name != "Ticket": + wrong_le_include = "Ticket" + else: + wrong_le_include = "Check" +%> + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(${name}Tests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + +% for field in fields: + auto const ${field["paramName"]}Value = ${canonical_expr(field)}; +% endfor + + ${name}Builder builder{ +% for i, field in enumerate(required_fields): + ${field["paramName"]}Value${"," if i < len(required_fields) - 1 else ""} +% endfor + }; + +% for field in optional_fields: + builder.set${field["name"][2:]}(${field["paramName"]}Value); +% endfor + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + +% for field in required_fields: + { + auto const& expected = ${field["paramName"]}Value; + auto const actual = entry.get${field["name"][2:]}(); + expectEqualField(expected, actual, "${field["name"]}"); + } + +% endfor +% for field in optional_fields: + { + auto const& expected = ${field["paramName"]}Value; + auto const actualOpt = entry.get${field["name"][2:]}(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "${field["name"]}"); + EXPECT_TRUE(entry.has${field["name"][2:]}()); + } + +% endfor + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(${name}Tests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + +% for field in fields: + auto const ${field["paramName"]}Value = ${canonical_expr(field)}; +% endfor + + auto sle = std::make_shared(${name}::entryType, index); + +% for field in fields: +% if field.get("stiSuffix") == "ISSUE": + sle->at(${field["name"]}) = STIssue(${field["name"]}, ${field["paramName"]}Value); +% elif field["typeData"].get("setter_use_brackets"): + sle->at(${field["name"]}) = ${field["paramName"]}Value; +% else: + sle->${field["typeData"]["setter_method"]}(${field["name"]}, ${field["paramName"]}Value); +% endif +% endfor + + ${name}Builder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + ${name} entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + +% for field in required_fields: + { + auto const& expected = ${field["paramName"]}Value; + + auto const fromSle = entryFromSle.get${field["name"][2:]}(); + auto const fromBuilder = entryFromBuilder.get${field["name"][2:]}(); + + expectEqualField(expected, fromSle, "${field["name"]}"); + expectEqualField(expected, fromBuilder, "${field["name"]}"); + } + +% endfor +% for field in optional_fields: + { + auto const& expected = ${field["paramName"]}Value; + + auto const fromSleOpt = entryFromSle.get${field["name"][2:]}(); + auto const fromBuilderOpt = entryFromBuilder.get${field["name"][2:]}(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "${field["name"]}"); + expectEqualField(expected, *fromBuilderOpt, "${field["name"]}"); + } + +% endfor + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(${name}Tests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq +% if wrong_le_include == "Ticket": + ${wrong_le_include}Builder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; +% else: + ${wrong_le_include}Builder wrongBuilder{ + canonical_ACCOUNT(), + canonical_ACCOUNT(), + canonical_AMOUNT(), + canonical_UINT32(), + canonical_UINT64(), + canonical_UINT64(), + canonical_UINT256(), + canonical_UINT32()}; +% endif + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(${name}{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(${name}Tests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type +% if wrong_le_include == "Ticket": + ${wrong_le_include}Builder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; +% else: + ${wrong_le_include}Builder wrongBuilder{ + canonical_ACCOUNT(), + canonical_ACCOUNT(), + canonical_AMOUNT(), + canonical_UINT32(), + canonical_UINT64(), + canonical_UINT64(), + canonical_UINT256(), + canonical_UINT32()}; +% endif + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(${name}Builder{wrongEntry.getSle()}, std::runtime_error); +} + +% if optional_fields: +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(${name}Tests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + +% for field in required_fields: + auto const ${field["paramName"]}Value = ${canonical_expr(field)}; +% endfor + + ${name}Builder builder{ +% for i, field in enumerate(required_fields): + ${field["paramName"]}Value${"," if i < len(required_fields) - 1 else ""} +% endfor + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present +% for field in optional_fields: + EXPECT_FALSE(entry.has${field["name"][2:]}()); + EXPECT_FALSE(entry.get${field["name"][2:]}().has_value()); +% endfor +} +% endif +} diff --git a/scripts/templates/Transaction.h.mako b/scripts/templates/Transaction.h.mako new file mode 100644 index 0000000000..62c51a5c97 --- /dev/null +++ b/scripts/templates/Transaction.h.mako @@ -0,0 +1,226 @@ +// This file is auto-generated. Do not edit. +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace xrpl::transactions { + +class ${name}Builder; + +/** + * @brief Transaction: ${name} + * + * Type: ${tag} (${value}) + * Delegable: ${delegable} + * Amendment: ${amendments} + * Privileges: ${privileges} + * + * Immutable wrapper around STTx providing type-safe field access. + * Use ${name}Builder to construct new transactions. + */ +class ${name} : public TransactionBase +{ +public: + static constexpr xrpl::TxType txType = ${tag}; + + /** + * @brief Construct a ${name} transaction wrapper from an existing STTx object. + * @throws std::runtime_error if the transaction type doesn't match. + */ + explicit ${name}(std::shared_ptr tx) + : TransactionBase(std::move(tx)) + { + // Verify transaction type + if (tx_->getTxnType() != txType) + { + throw std::runtime_error("Invalid transaction type for ${name}"); + } + } + + // Transaction-specific field getters +% for field in fields: +% if field['typed']: + + /** + * @brief Get ${field['name']} (${field['requirement']}) +% if field.get('supports_mpt'): + * @note This field supports MPT (Multi-Purpose Token) amounts. +% endif +% if field['requirement'] == 'soeREQUIRED': + * @return The field value. +% else: + * @return The field value, or std::nullopt if not present. +% endif + */ +% if field['requirement'] == 'soeREQUIRED': + [[nodiscard]] + ${field['typeData']['return_type']} + get${field['name'][2:]}() const + { + return this->tx_->${field['typeData']['getter_method']}(${field['name']}); + } +% else: + [[nodiscard]] + ${field['typeData']['return_type_optional']} + get${field['name'][2:]}() const + { + if (has${field['name'][2:]}()) + { + return this->tx_->${field['typeData']['getter_method']}(${field['name']}); + } + return std::nullopt; + } + + /** + * @brief Check if ${field['name']} is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + has${field['name'][2:]}() const + { + return this->tx_->isFieldPresent(${field['name']}); + } +% endif +% else: + /** + * @brief Get ${field['name']} (${field['requirement']}) +% if field.get('supports_mpt'): + * @note This field supports MPT (Multi-Purpose Token) amounts. +% endif + * @note This is an untyped field. +% if field['requirement'] == 'soeREQUIRED': + * @return The field value. +% else: + * @return The field value, or std::nullopt if not present. +% endif + */ +% if field['requirement'] == 'soeREQUIRED': + [[nodiscard]] + ${field['typeData']['return_type']} + get${field['name'][2:]}() const + { + return this->tx_->${field['typeData']['getter_method']}(${field['name']}); + } +% else: + [[nodiscard]] + ${field['typeData']['return_type_optional']} + get${field['name'][2:]}() const + { + if (this->tx_->isFieldPresent(${field['name']})) + return this->tx_->${field['typeData']['getter_method']}(${field['name']}); + return std::nullopt; + } + + /** + * @brief Check if ${field['name']} is present. + * @return True if the field is present, false otherwise. + */ + [[nodiscard]] + bool + has${field['name'][2:]}() const + { + return this->tx_->isFieldPresent(${field['name']}); + } +% endif +% endif +% endfor +}; + +<% + required_fields = [f for f in fields if f['requirement'] == 'soeREQUIRED'] +%>\ +/** + * @brief Builder for ${name} transactions. + * + * Provides a fluent interface for constructing transactions with method chaining. + * Uses Json::Value internally for flexible transaction construction. + * Inherits common field setters from TransactionBuilderBase. + */ +class ${name}Builder : public TransactionBuilderBase<${name}Builder> +{ +public: + /** + * @brief Construct a new ${name}Builder with required fields. + * @param account The account initiating the transaction. +% for field in required_fields: + * @param ${field['paramName']} The ${field['name']} field value. +% endfor + * @param sequence Optional sequence number for the transaction. + * @param fee Optional fee for the transaction. + */ + ${name}Builder(SF_ACCOUNT::type::value_type account, +% for i, field in enumerate(required_fields): + ${field['typeData']['setter_type']} ${field['paramName']},\ +% endfor + std::optional sequence = std::nullopt, + std::optional fee = std::nullopt +) + : TransactionBuilderBase<${name}Builder>(${tag}, account, sequence, fee) + { +% for field in required_fields: + set${field['name'][2:]}(${field['paramName']}); +% endfor + } + + /** + * @brief Construct a ${name}Builder from an existing STTx object. + * @param tx The existing transaction to copy from. + * @throws std::runtime_error if the transaction type doesn't match. + */ + ${name}Builder(std::shared_ptr tx) + { + if (tx->getTxnType() != ${tag}) + { + throw std::runtime_error("Invalid transaction type for ${name}Builder"); + } + object_ = *tx; + } + + /** @brief Transaction-specific field setters */ +% for field in fields: + + /** + * @brief Set ${field['name']} (${field['requirement']}) +% if field.get('supports_mpt'): + * @note This field supports MPT (Multi-Purpose Token) amounts. +% endif + * @return Reference to this builder for method chaining. + */ + ${name}Builder& + set${field['name'][2:]}(${field['typeData']['setter_type']} value) + { +% if field.get('stiSuffix') == 'ISSUE': + object_[${field['name']}] = STIssue(${field['name']}, value); +% elif field['typeData'].get('setter_use_brackets'): + object_[${field['name']}] = value; +% else: + object_.${field['typeData']['setter_method']}(${field['name']}, value); +% endif + return *this; + } +% endfor + + /** + * @brief Build and return the ${name} wrapper. + * @param publicKey The public key for signing. + * @param secretKey The secret key for signing. + * @return The constructed transaction wrapper. + */ + ${name} + build(PublicKey const& publicKey, SecretKey const& secretKey) + { + sign(publicKey, secretKey); + return ${name}{std::make_shared(std::move(object_))}; + } +}; + +} // namespace xrpl::transactions diff --git a/scripts/templates/TransactionTests.cpp.mako b/scripts/templates/TransactionTests.cpp.mako new file mode 100644 index 0000000000..b6bd5cd831 --- /dev/null +++ b/scripts/templates/TransactionTests.cpp.mako @@ -0,0 +1,241 @@ +// Auto-generated unit tests for transaction ${name} +<% + required_fields = [f for f in fields if f["requirement"] == "soeREQUIRED"] + optional_fields = [f for f in fields if f["requirement"] != "soeREQUIRED"] + + def canonical_expr(field): + return f"canonical_{field['stiSuffix']}()" + + # Pick a wrong transaction to test type mismatch + if name != "AccountSet": + wrong_tx_include = "AccountSet" + else: + wrong_tx_include = "OfferCancel" +%> + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(Transactions${name}Tests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("test${name}")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values +% for field in fields: + auto const ${field["paramName"]}Value = ${canonical_expr(field)}; +% endfor + + ${name}Builder builder{ + accountValue, +% for field in required_fields: + ${field["paramName"]}Value, +% endfor + sequenceValue, + feeValue + }; + + // Set optional fields +% for field in optional_fields: + builder.set${field["name"][2:]}(${field["paramName"]}Value); +% endfor + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields +% for field in required_fields: + { + auto const& expected = ${field["paramName"]}Value; + auto const actual = tx.get${field["name"][2:]}(); + expectEqualField(expected, actual, "${field["name"]}"); + } + +% endfor + // Verify optional fields +% for field in optional_fields: + { + auto const& expected = ${field["paramName"]}Value; + auto const actualOpt = tx.get${field["name"][2:]}(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field ${field["name"]} should be present"; + expectEqualField(expected, *actualOpt, "${field["name"]}"); + EXPECT_TRUE(tx.has${field["name"][2:]}()); + } + +% endfor +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(Transactions${name}Tests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("test${name}FromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values +% for field in fields: + auto const ${field["paramName"]}Value = ${canonical_expr(field)}; +% endfor + + // Build an initial transaction + ${name}Builder initialBuilder{ + accountValue, +% for field in required_fields: + ${field["paramName"]}Value, +% endfor + sequenceValue, + feeValue + }; + +% for field in optional_fields: + initialBuilder.set${field["name"][2:]}(${field["paramName"]}Value); +% endfor + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + ${name}Builder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields +% for field in required_fields: + { + auto const& expected = ${field["paramName"]}Value; + auto const actual = rebuiltTx.get${field["name"][2:]}(); + expectEqualField(expected, actual, "${field["name"]}"); + } + +% endfor + // Verify optional fields +% for field in optional_fields: + { + auto const& expected = ${field["paramName"]}Value; + auto const actualOpt = rebuiltTx.get${field["name"][2:]}(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field ${field["name"]} should be present"; + expectEqualField(expected, *actualOpt, "${field["name"]}"); + } + +% endfor +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(Transactions${name}Tests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + +% if wrong_tx_include == "AccountSet": + ${wrong_tx_include}Builder wrongBuilder{account, 1, canonical_AMOUNT()}; +% else: + ${wrong_tx_include}Builder wrongBuilder{account, canonical_UINT32(), 1, canonical_AMOUNT()}; +% endif + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(${name}{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(Transactions${name}Tests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + +% if wrong_tx_include == "AccountSet": + ${wrong_tx_include}Builder wrongBuilder{account, 1, canonical_AMOUNT()}; +% else: + ${wrong_tx_include}Builder wrongBuilder{account, canonical_UINT32(), 1, canonical_AMOUNT()}; +% endif + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(${name}Builder{wrongTx.getSTTx()}, std::runtime_error); +} + +% if optional_fields: +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(Transactions${name}Tests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("test${name}Nullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values +% for field in required_fields: + auto const ${field["paramName"]}Value = ${canonical_expr(field)}; +% endfor + + ${name}Builder builder{ + accountValue, +% for field in required_fields: + ${field["paramName"]}Value, +% endfor + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present +% for field in optional_fields: + EXPECT_FALSE(tx.has${field["name"][2:]}()); + EXPECT_FALSE(tx.get${field["name"][2:]}().has_value()); +% endfor +} +% endif + +} diff --git a/src/libxrpl/protocol_autogen/placeholder.cpp b/src/libxrpl/protocol_autogen/placeholder.cpp new file mode 100644 index 0000000000..b48581e5b8 --- /dev/null +++ b/src/libxrpl/protocol_autogen/placeholder.cpp @@ -0,0 +1,5 @@ +// This file is a placeholder to ensure the protocol_autogen module can be built. +#include +#include +#include +#include diff --git a/src/tests/libxrpl/CMakeLists.txt b/src/tests/libxrpl/CMakeLists.txt index 6bcb6aff89..a82ed1472f 100644 --- a/src/tests/libxrpl/CMakeLists.txt +++ b/src/tests/libxrpl/CMakeLists.txt @@ -32,6 +32,21 @@ xrpl_add_test(json) target_link_libraries(xrpl.test.json PRIVATE xrpl.imports.test) add_dependencies(xrpl.tests xrpl.test.json) +# protocol_autogen tests use explicit source list (not GLOB) because sources are generated +# Mark generated sources so CMake knows they'll be created at build time +set_source_files_properties( + ${PROTOCOL_AUTOGEN_TEST_SOURCES} + PROPERTIES GENERATED TRUE +) +add_executable(xrpl.test.protocol_autogen ${PROTOCOL_AUTOGEN_TEST_SOURCES}) +target_link_libraries(xrpl.test.protocol_autogen PRIVATE xrpl.imports.test) +add_dependencies(xrpl.tests xrpl.test.protocol_autogen) +add_test(NAME xrpl.test.protocol_autogen COMMAND xrpl.test.protocol_autogen) +# Ensure code generation runs before compiling tests +if(TARGET protocol_autogen_generate) + add_dependencies(xrpl.test.protocol_autogen protocol_autogen_generate) +endif() + # Network unit tests are currently not supported on Windows if(NOT WIN32) xrpl_add_test(net) diff --git a/src/tests/libxrpl/protocol_autogen/STObjectValidation.cpp b/src/tests/libxrpl/protocol_autogen/STObjectValidation.cpp new file mode 100644 index 0000000000..5c100364dc --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/STObjectValidation.cpp @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +#include + +namespace xrpl { +TEST(STObjectValidation, validate_required_field) +{ + SOTemplate format{{sfFlags, soeREQUIRED}}; + STObject obj(sfGeneric); + obj.setFieldU32(sfFlags, 0); + EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format)); +} + +TEST(STObjectValidation, validate_missing_required_field) +{ + SOTemplate format{{sfFlags, soeREQUIRED}}; + STObject obj(sfGeneric); + EXPECT_FALSE(protocol_autogen::validateSTObject(obj, format)); +} + +TEST(STObjectValidation, validate_optional_field) +{ + SOTemplate format{{sfFlags, soeOPTIONAL}}; + STObject obj(sfGeneric); + obj.setFieldU32(sfFlags, 0); + EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format)); +} + +TEST(STObjectValidation, validate_missing_optional_field) +{ + SOTemplate format{{sfFlags, soeOPTIONAL}}; + STObject obj(sfGeneric); + EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format)); +} + +TEST(STObjectValidation, validate_mpt_amount_supported) +{ + SOTemplate format{{sfAmount, soeREQUIRED, soeMPTSupported}}; + STObject obj(sfGeneric); + obj.setFieldAmount(sfAmount, STAmount{MPTAmount{Number{1}}, MPTIssue{}}); + EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format)); +} + +TEST(STObjectValidation, validate_mpt_amount_not_supported) +{ + SOTemplate format{{sfAmount, soeREQUIRED, soeMPTNotSupported}}; + STObject obj(sfGeneric); + obj.setFieldAmount(sfAmount, STAmount{MPTAmount{Number{1}}, MPTIssue{}}); + EXPECT_FALSE(protocol_autogen::validateSTObject(obj, format)); +} + +TEST(STObjectValidation, validate_mpt_issue_supported) +{ + SOTemplate format{{sfAsset, soeREQUIRED, soeMPTSupported}}; + STObject obj(sfGeneric); + obj.setFieldIssue(sfAsset, STIssue{sfAsset, MPTIssue{}}); + EXPECT_TRUE(protocol_autogen::validateSTObject(obj, format)); +} + +TEST(STObjectValidation, validate_mpt_issue_not_supported) +{ + SOTemplate format{{sfAsset, soeREQUIRED, soeMPTNotSupported}}; + STObject obj(sfGeneric); + obj.setFieldIssue(sfAsset, STIssue{sfAsset, MPTIssue{}}); + EXPECT_FALSE(protocol_autogen::validateSTObject(obj, format)); +} +} // namespace xrpl diff --git a/src/tests/libxrpl/protocol_autogen/TestHelpers.h b/src/tests/libxrpl/protocol_autogen/TestHelpers.h new file mode 100644 index 0000000000..cf2d7ffe6a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/TestHelpers.h @@ -0,0 +1,209 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace xrpl { + +// Typed field canonical values + +using Uint8Value = std::decay_t; +inline Uint8Value +canonical_UINT8() +{ + return Uint8Value{1}; +} + +using Uint16Value = std::decay_t; +inline Uint16Value +canonical_UINT16() +{ + return Uint16Value{1}; +} + +using Uint32Value = std::decay_t; +inline Uint32Value +canonical_UINT32() +{ + return Uint32Value{1}; +} + +using Uint64Value = std::decay_t; +inline Uint64Value +canonical_UINT64() +{ + return Uint64Value{1}; +} + +using Uint128Value = std::decay_t; +inline Uint128Value +canonical_UINT128() +{ + return Uint128Value{1}; +} + +using Uint160Value = std::decay_t; +inline Uint160Value +canonical_UINT160() +{ + return Uint160Value{1}; +} + +using Uint192Value = std::decay_t; +inline Uint192Value +canonical_UINT192() +{ + return Uint192Value{1}; +} + +using Uint256Value = std::decay_t; +inline Uint256Value +canonical_UINT256() +{ + return Uint256Value{1}; +} + +using Int32Value = std::decay_t; +inline Int32Value +canonical_INT32() +{ + return Int32Value{42}; +} + +using NumberValue = std::decay_t; +inline NumberValue +canonical_NUMBER() +{ + return NumberValue{123}; +} + +using AmountValue = std::decay_t; +inline AmountValue +canonical_AMOUNT() +{ + return AmountValue{XRPAmount{1}}; +} + +using AccountValue = std::decay_t; +inline AccountValue +canonical_ACCOUNT() +{ + return xrpAccount(); +} + +using CurrencyValue = std::decay_t; +inline CurrencyValue +canonical_CURRENCY() +{ + return xrpCurrency(); +} + +using IssueValue = std::decay_t; +inline IssueValue +canonical_ISSUE() +{ + return IssueValue{xrpIssue()}; +} + +using Vector256Value = std::decay_t; +inline Vector256Value +canonical_VECTOR256() +{ + return Vector256Value{uint256{1}}; +} + +using BlobValue = std::decay_t; +inline BlobValue +canonical_VL() +{ + static constexpr std::array data{{'a', 'b', 'c'}}; + return BlobValue{data.data(), data.size()}; +} + +using XChainBridgeValue = std::decay_t; +inline XChainBridgeValue +canonical_XCHAIN_BRIDGE() +{ + return XChainBridgeValue{xrpAccount(), xrpIssue(), xrpAccount(), xrpIssue()}; +} + +// Untyped field canonical values + +inline STArray +canonical_ARRAY() +{ + return STArray{}; +} + +inline STObject +canonical_OBJECT() +{ + return STObject{sfGeneric}; +} + +inline STPathSet +canonical_PATHSET() +{ + STPathSet result{}; + result.push_back(STPath{}); + return result; +} + +// Field comparison helpers for generated tests + +template +void +expectEqualField(T const& expected, T const& actual, char const* fieldName) +{ + EXPECT_EQ(expected, actual) << "Field " << fieldName << " mismatch"; +} + +// Specialization for STObject (no operator==, use isEquivalent) +template <> +inline void +expectEqualField(STObject const& expected, STObject const& actual, char const* fieldName) +{ + EXPECT_TRUE(expected.isEquivalent(actual)) << "Field " << fieldName << " mismatch"; +} + +// Specialization for STPathSet (no operator==, use isEquivalent) +template <> +inline void +expectEqualField( + STPathSet const& expected, + STPathSet const& actual, + char const* fieldName) +{ + EXPECT_TRUE(expected.isEquivalent(actual)) << "Field " << fieldName << " mismatch"; +} + +// Overloads for std::reference_wrapper (used by optional ARRAY/PATHSET fields) +template +void +expectEqualField(T const& expected, std::reference_wrapper actual, char const* fieldName) +{ + expectEqualField(expected, actual.get(), fieldName); +} + +} // namespace xrpl diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/AMMTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/AMMTests.cpp new file mode 100644 index 0000000000..0bb80c41e6 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/AMMTests.cpp @@ -0,0 +1,361 @@ +// Auto-generated unit tests for ledger entry AMM + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(AMMTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const tradingFeeValue = canonical_UINT16(); + auto const voteSlotsValue = canonical_ARRAY(); + auto const auctionSlotValue = canonical_OBJECT(); + auto const lPTokenBalanceValue = canonical_AMOUNT(); + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + AMMBuilder builder{ + accountValue, + lPTokenBalanceValue, + assetValue, + asset2Value, + ownerNodeValue + }; + + builder.setTradingFee(tradingFeeValue); + builder.setVoteSlots(voteSlotsValue); + builder.setAuctionSlot(auctionSlotValue); + builder.setPreviousTxnID(previousTxnIDValue); + builder.setPreviousTxnLgrSeq(previousTxnLgrSeqValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = lPTokenBalanceValue; + auto const actual = entry.getLPTokenBalance(); + expectEqualField(expected, actual, "sfLPTokenBalance"); + } + + { + auto const& expected = assetValue; + auto const actual = entry.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = entry.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = tradingFeeValue; + auto const actualOpt = entry.getTradingFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTradingFee"); + EXPECT_TRUE(entry.hasTradingFee()); + } + + { + auto const& expected = voteSlotsValue; + auto const actualOpt = entry.getVoteSlots(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfVoteSlots"); + EXPECT_TRUE(entry.hasVoteSlots()); + } + + { + auto const& expected = auctionSlotValue; + auto const actualOpt = entry.getAuctionSlot(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAuctionSlot"); + EXPECT_TRUE(entry.hasAuctionSlot()); + } + + { + auto const& expected = previousTxnIDValue; + auto const actualOpt = entry.getPreviousTxnID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnID"); + EXPECT_TRUE(entry.hasPreviousTxnID()); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actualOpt = entry.getPreviousTxnLgrSeq(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnLgrSeq"); + EXPECT_TRUE(entry.hasPreviousTxnLgrSeq()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(AMMTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const tradingFeeValue = canonical_UINT16(); + auto const voteSlotsValue = canonical_ARRAY(); + auto const auctionSlotValue = canonical_OBJECT(); + auto const lPTokenBalanceValue = canonical_AMOUNT(); + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(AMM::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfTradingFee) = tradingFeeValue; + sle->setFieldArray(sfVoteSlots, voteSlotsValue); + sle->setFieldObject(sfAuctionSlot, auctionSlotValue); + sle->at(sfLPTokenBalance) = lPTokenBalanceValue; + sle->at(sfAsset) = STIssue(sfAsset, assetValue); + sle->at(sfAsset2) = STIssue(sfAsset2, asset2Value); + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + AMMBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + AMM entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = lPTokenBalanceValue; + + auto const fromSle = entryFromSle.getLPTokenBalance(); + auto const fromBuilder = entryFromBuilder.getLPTokenBalance(); + + expectEqualField(expected, fromSle, "sfLPTokenBalance"); + expectEqualField(expected, fromBuilder, "sfLPTokenBalance"); + } + + { + auto const& expected = assetValue; + + auto const fromSle = entryFromSle.getAsset(); + auto const fromBuilder = entryFromBuilder.getAsset(); + + expectEqualField(expected, fromSle, "sfAsset"); + expectEqualField(expected, fromBuilder, "sfAsset"); + } + + { + auto const& expected = asset2Value; + + auto const fromSle = entryFromSle.getAsset2(); + auto const fromBuilder = entryFromBuilder.getAsset2(); + + expectEqualField(expected, fromSle, "sfAsset2"); + expectEqualField(expected, fromBuilder, "sfAsset2"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = tradingFeeValue; + + auto const fromSleOpt = entryFromSle.getTradingFee(); + auto const fromBuilderOpt = entryFromBuilder.getTradingFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTradingFee"); + expectEqualField(expected, *fromBuilderOpt, "sfTradingFee"); + } + + { + auto const& expected = voteSlotsValue; + + auto const fromSleOpt = entryFromSle.getVoteSlots(); + auto const fromBuilderOpt = entryFromBuilder.getVoteSlots(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfVoteSlots"); + expectEqualField(expected, *fromBuilderOpt, "sfVoteSlots"); + } + + { + auto const& expected = auctionSlotValue; + + auto const fromSleOpt = entryFromSle.getAuctionSlot(); + auto const fromBuilderOpt = entryFromBuilder.getAuctionSlot(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAuctionSlot"); + expectEqualField(expected, *fromBuilderOpt, "sfAuctionSlot"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnID(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnID"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnLgrSeq(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(AMMTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(AMM{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(AMMTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(AMMBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(AMMTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const lPTokenBalanceValue = canonical_AMOUNT(); + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const ownerNodeValue = canonical_UINT64(); + + AMMBuilder builder{ + accountValue, + lPTokenBalanceValue, + assetValue, + asset2Value, + ownerNodeValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasTradingFee()); + EXPECT_FALSE(entry.getTradingFee().has_value()); + EXPECT_FALSE(entry.hasVoteSlots()); + EXPECT_FALSE(entry.getVoteSlots().has_value()); + EXPECT_FALSE(entry.hasAuctionSlot()); + EXPECT_FALSE(entry.getAuctionSlot().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnID()); + EXPECT_FALSE(entry.getPreviousTxnID().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnLgrSeq()); + EXPECT_FALSE(entry.getPreviousTxnLgrSeq().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/AccountRootTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/AccountRootTests.cpp new file mode 100644 index 0000000000..e967b614b7 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/AccountRootTests.cpp @@ -0,0 +1,707 @@ +// Auto-generated unit tests for ledger entry AccountRoot + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(AccountRootTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const balanceValue = canonical_AMOUNT(); + auto const ownerCountValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const accountTxnIDValue = canonical_UINT256(); + auto const regularKeyValue = canonical_ACCOUNT(); + auto const emailHashValue = canonical_UINT128(); + auto const walletLocatorValue = canonical_UINT256(); + auto const walletSizeValue = canonical_UINT32(); + auto const messageKeyValue = canonical_VL(); + auto const transferRateValue = canonical_UINT32(); + auto const domainValue = canonical_VL(); + auto const tickSizeValue = canonical_UINT8(); + auto const ticketCountValue = canonical_UINT32(); + auto const nFTokenMinterValue = canonical_ACCOUNT(); + auto const mintedNFTokensValue = canonical_UINT32(); + auto const burnedNFTokensValue = canonical_UINT32(); + auto const firstNFTokenSequenceValue = canonical_UINT32(); + auto const aMMIDValue = canonical_UINT256(); + auto const vaultIDValue = canonical_UINT256(); + auto const loanBrokerIDValue = canonical_UINT256(); + + AccountRootBuilder builder{ + accountValue, + sequenceValue, + balanceValue, + ownerCountValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setAccountTxnID(accountTxnIDValue); + builder.setRegularKey(regularKeyValue); + builder.setEmailHash(emailHashValue); + builder.setWalletLocator(walletLocatorValue); + builder.setWalletSize(walletSizeValue); + builder.setMessageKey(messageKeyValue); + builder.setTransferRate(transferRateValue); + builder.setDomain(domainValue); + builder.setTickSize(tickSizeValue); + builder.setTicketCount(ticketCountValue); + builder.setNFTokenMinter(nFTokenMinterValue); + builder.setMintedNFTokens(mintedNFTokensValue); + builder.setBurnedNFTokens(burnedNFTokensValue); + builder.setFirstNFTokenSequence(firstNFTokenSequenceValue); + builder.setAMMID(aMMIDValue); + builder.setVaultID(vaultIDValue); + builder.setLoanBrokerID(loanBrokerIDValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = sequenceValue; + auto const actual = entry.getSequence(); + expectEqualField(expected, actual, "sfSequence"); + } + + { + auto const& expected = balanceValue; + auto const actual = entry.getBalance(); + expectEqualField(expected, actual, "sfBalance"); + } + + { + auto const& expected = ownerCountValue; + auto const actual = entry.getOwnerCount(); + expectEqualField(expected, actual, "sfOwnerCount"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = accountTxnIDValue; + auto const actualOpt = entry.getAccountTxnID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAccountTxnID"); + EXPECT_TRUE(entry.hasAccountTxnID()); + } + + { + auto const& expected = regularKeyValue; + auto const actualOpt = entry.getRegularKey(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfRegularKey"); + EXPECT_TRUE(entry.hasRegularKey()); + } + + { + auto const& expected = emailHashValue; + auto const actualOpt = entry.getEmailHash(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfEmailHash"); + EXPECT_TRUE(entry.hasEmailHash()); + } + + { + auto const& expected = walletLocatorValue; + auto const actualOpt = entry.getWalletLocator(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfWalletLocator"); + EXPECT_TRUE(entry.hasWalletLocator()); + } + + { + auto const& expected = walletSizeValue; + auto const actualOpt = entry.getWalletSize(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfWalletSize"); + EXPECT_TRUE(entry.hasWalletSize()); + } + + { + auto const& expected = messageKeyValue; + auto const actualOpt = entry.getMessageKey(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMessageKey"); + EXPECT_TRUE(entry.hasMessageKey()); + } + + { + auto const& expected = transferRateValue; + auto const actualOpt = entry.getTransferRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTransferRate"); + EXPECT_TRUE(entry.hasTransferRate()); + } + + { + auto const& expected = domainValue; + auto const actualOpt = entry.getDomain(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDomain"); + EXPECT_TRUE(entry.hasDomain()); + } + + { + auto const& expected = tickSizeValue; + auto const actualOpt = entry.getTickSize(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTickSize"); + EXPECT_TRUE(entry.hasTickSize()); + } + + { + auto const& expected = ticketCountValue; + auto const actualOpt = entry.getTicketCount(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTicketCount"); + EXPECT_TRUE(entry.hasTicketCount()); + } + + { + auto const& expected = nFTokenMinterValue; + auto const actualOpt = entry.getNFTokenMinter(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfNFTokenMinter"); + EXPECT_TRUE(entry.hasNFTokenMinter()); + } + + { + auto const& expected = mintedNFTokensValue; + auto const actualOpt = entry.getMintedNFTokens(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMintedNFTokens"); + EXPECT_TRUE(entry.hasMintedNFTokens()); + } + + { + auto const& expected = burnedNFTokensValue; + auto const actualOpt = entry.getBurnedNFTokens(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfBurnedNFTokens"); + EXPECT_TRUE(entry.hasBurnedNFTokens()); + } + + { + auto const& expected = firstNFTokenSequenceValue; + auto const actualOpt = entry.getFirstNFTokenSequence(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfFirstNFTokenSequence"); + EXPECT_TRUE(entry.hasFirstNFTokenSequence()); + } + + { + auto const& expected = aMMIDValue; + auto const actualOpt = entry.getAMMID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAMMID"); + EXPECT_TRUE(entry.hasAMMID()); + } + + { + auto const& expected = vaultIDValue; + auto const actualOpt = entry.getVaultID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfVaultID"); + EXPECT_TRUE(entry.hasVaultID()); + } + + { + auto const& expected = loanBrokerIDValue; + auto const actualOpt = entry.getLoanBrokerID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLoanBrokerID"); + EXPECT_TRUE(entry.hasLoanBrokerID()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(AccountRootTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const balanceValue = canonical_AMOUNT(); + auto const ownerCountValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const accountTxnIDValue = canonical_UINT256(); + auto const regularKeyValue = canonical_ACCOUNT(); + auto const emailHashValue = canonical_UINT128(); + auto const walletLocatorValue = canonical_UINT256(); + auto const walletSizeValue = canonical_UINT32(); + auto const messageKeyValue = canonical_VL(); + auto const transferRateValue = canonical_UINT32(); + auto const domainValue = canonical_VL(); + auto const tickSizeValue = canonical_UINT8(); + auto const ticketCountValue = canonical_UINT32(); + auto const nFTokenMinterValue = canonical_ACCOUNT(); + auto const mintedNFTokensValue = canonical_UINT32(); + auto const burnedNFTokensValue = canonical_UINT32(); + auto const firstNFTokenSequenceValue = canonical_UINT32(); + auto const aMMIDValue = canonical_UINT256(); + auto const vaultIDValue = canonical_UINT256(); + auto const loanBrokerIDValue = canonical_UINT256(); + + auto sle = std::make_shared(AccountRoot::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfBalance) = balanceValue; + sle->at(sfOwnerCount) = ownerCountValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfAccountTxnID) = accountTxnIDValue; + sle->at(sfRegularKey) = regularKeyValue; + sle->at(sfEmailHash) = emailHashValue; + sle->at(sfWalletLocator) = walletLocatorValue; + sle->at(sfWalletSize) = walletSizeValue; + sle->at(sfMessageKey) = messageKeyValue; + sle->at(sfTransferRate) = transferRateValue; + sle->at(sfDomain) = domainValue; + sle->at(sfTickSize) = tickSizeValue; + sle->at(sfTicketCount) = ticketCountValue; + sle->at(sfNFTokenMinter) = nFTokenMinterValue; + sle->at(sfMintedNFTokens) = mintedNFTokensValue; + sle->at(sfBurnedNFTokens) = burnedNFTokensValue; + sle->at(sfFirstNFTokenSequence) = firstNFTokenSequenceValue; + sle->at(sfAMMID) = aMMIDValue; + sle->at(sfVaultID) = vaultIDValue; + sle->at(sfLoanBrokerID) = loanBrokerIDValue; + + AccountRootBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + AccountRoot entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSle = entryFromSle.getSequence(); + auto const fromBuilder = entryFromBuilder.getSequence(); + + expectEqualField(expected, fromSle, "sfSequence"); + expectEqualField(expected, fromBuilder, "sfSequence"); + } + + { + auto const& expected = balanceValue; + + auto const fromSle = entryFromSle.getBalance(); + auto const fromBuilder = entryFromBuilder.getBalance(); + + expectEqualField(expected, fromSle, "sfBalance"); + expectEqualField(expected, fromBuilder, "sfBalance"); + } + + { + auto const& expected = ownerCountValue; + + auto const fromSle = entryFromSle.getOwnerCount(); + auto const fromBuilder = entryFromBuilder.getOwnerCount(); + + expectEqualField(expected, fromSle, "sfOwnerCount"); + expectEqualField(expected, fromBuilder, "sfOwnerCount"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = accountTxnIDValue; + + auto const fromSleOpt = entryFromSle.getAccountTxnID(); + auto const fromBuilderOpt = entryFromBuilder.getAccountTxnID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAccountTxnID"); + expectEqualField(expected, *fromBuilderOpt, "sfAccountTxnID"); + } + + { + auto const& expected = regularKeyValue; + + auto const fromSleOpt = entryFromSle.getRegularKey(); + auto const fromBuilderOpt = entryFromBuilder.getRegularKey(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfRegularKey"); + expectEqualField(expected, *fromBuilderOpt, "sfRegularKey"); + } + + { + auto const& expected = emailHashValue; + + auto const fromSleOpt = entryFromSle.getEmailHash(); + auto const fromBuilderOpt = entryFromBuilder.getEmailHash(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfEmailHash"); + expectEqualField(expected, *fromBuilderOpt, "sfEmailHash"); + } + + { + auto const& expected = walletLocatorValue; + + auto const fromSleOpt = entryFromSle.getWalletLocator(); + auto const fromBuilderOpt = entryFromBuilder.getWalletLocator(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfWalletLocator"); + expectEqualField(expected, *fromBuilderOpt, "sfWalletLocator"); + } + + { + auto const& expected = walletSizeValue; + + auto const fromSleOpt = entryFromSle.getWalletSize(); + auto const fromBuilderOpt = entryFromBuilder.getWalletSize(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfWalletSize"); + expectEqualField(expected, *fromBuilderOpt, "sfWalletSize"); + } + + { + auto const& expected = messageKeyValue; + + auto const fromSleOpt = entryFromSle.getMessageKey(); + auto const fromBuilderOpt = entryFromBuilder.getMessageKey(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMessageKey"); + expectEqualField(expected, *fromBuilderOpt, "sfMessageKey"); + } + + { + auto const& expected = transferRateValue; + + auto const fromSleOpt = entryFromSle.getTransferRate(); + auto const fromBuilderOpt = entryFromBuilder.getTransferRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTransferRate"); + expectEqualField(expected, *fromBuilderOpt, "sfTransferRate"); + } + + { + auto const& expected = domainValue; + + auto const fromSleOpt = entryFromSle.getDomain(); + auto const fromBuilderOpt = entryFromBuilder.getDomain(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDomain"); + expectEqualField(expected, *fromBuilderOpt, "sfDomain"); + } + + { + auto const& expected = tickSizeValue; + + auto const fromSleOpt = entryFromSle.getTickSize(); + auto const fromBuilderOpt = entryFromBuilder.getTickSize(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTickSize"); + expectEqualField(expected, *fromBuilderOpt, "sfTickSize"); + } + + { + auto const& expected = ticketCountValue; + + auto const fromSleOpt = entryFromSle.getTicketCount(); + auto const fromBuilderOpt = entryFromBuilder.getTicketCount(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTicketCount"); + expectEqualField(expected, *fromBuilderOpt, "sfTicketCount"); + } + + { + auto const& expected = nFTokenMinterValue; + + auto const fromSleOpt = entryFromSle.getNFTokenMinter(); + auto const fromBuilderOpt = entryFromBuilder.getNFTokenMinter(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfNFTokenMinter"); + expectEqualField(expected, *fromBuilderOpt, "sfNFTokenMinter"); + } + + { + auto const& expected = mintedNFTokensValue; + + auto const fromSleOpt = entryFromSle.getMintedNFTokens(); + auto const fromBuilderOpt = entryFromBuilder.getMintedNFTokens(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMintedNFTokens"); + expectEqualField(expected, *fromBuilderOpt, "sfMintedNFTokens"); + } + + { + auto const& expected = burnedNFTokensValue; + + auto const fromSleOpt = entryFromSle.getBurnedNFTokens(); + auto const fromBuilderOpt = entryFromBuilder.getBurnedNFTokens(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfBurnedNFTokens"); + expectEqualField(expected, *fromBuilderOpt, "sfBurnedNFTokens"); + } + + { + auto const& expected = firstNFTokenSequenceValue; + + auto const fromSleOpt = entryFromSle.getFirstNFTokenSequence(); + auto const fromBuilderOpt = entryFromBuilder.getFirstNFTokenSequence(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfFirstNFTokenSequence"); + expectEqualField(expected, *fromBuilderOpt, "sfFirstNFTokenSequence"); + } + + { + auto const& expected = aMMIDValue; + + auto const fromSleOpt = entryFromSle.getAMMID(); + auto const fromBuilderOpt = entryFromBuilder.getAMMID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAMMID"); + expectEqualField(expected, *fromBuilderOpt, "sfAMMID"); + } + + { + auto const& expected = vaultIDValue; + + auto const fromSleOpt = entryFromSle.getVaultID(); + auto const fromBuilderOpt = entryFromBuilder.getVaultID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfVaultID"); + expectEqualField(expected, *fromBuilderOpt, "sfVaultID"); + } + + { + auto const& expected = loanBrokerIDValue; + + auto const fromSleOpt = entryFromSle.getLoanBrokerID(); + auto const fromBuilderOpt = entryFromBuilder.getLoanBrokerID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLoanBrokerID"); + expectEqualField(expected, *fromBuilderOpt, "sfLoanBrokerID"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(AccountRootTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(AccountRoot{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(AccountRootTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(AccountRootBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(AccountRootTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const balanceValue = canonical_AMOUNT(); + auto const ownerCountValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + AccountRootBuilder builder{ + accountValue, + sequenceValue, + balanceValue, + ownerCountValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasAccountTxnID()); + EXPECT_FALSE(entry.getAccountTxnID().has_value()); + EXPECT_FALSE(entry.hasRegularKey()); + EXPECT_FALSE(entry.getRegularKey().has_value()); + EXPECT_FALSE(entry.hasEmailHash()); + EXPECT_FALSE(entry.getEmailHash().has_value()); + EXPECT_FALSE(entry.hasWalletLocator()); + EXPECT_FALSE(entry.getWalletLocator().has_value()); + EXPECT_FALSE(entry.hasWalletSize()); + EXPECT_FALSE(entry.getWalletSize().has_value()); + EXPECT_FALSE(entry.hasMessageKey()); + EXPECT_FALSE(entry.getMessageKey().has_value()); + EXPECT_FALSE(entry.hasTransferRate()); + EXPECT_FALSE(entry.getTransferRate().has_value()); + EXPECT_FALSE(entry.hasDomain()); + EXPECT_FALSE(entry.getDomain().has_value()); + EXPECT_FALSE(entry.hasTickSize()); + EXPECT_FALSE(entry.getTickSize().has_value()); + EXPECT_FALSE(entry.hasTicketCount()); + EXPECT_FALSE(entry.getTicketCount().has_value()); + EXPECT_FALSE(entry.hasNFTokenMinter()); + EXPECT_FALSE(entry.getNFTokenMinter().has_value()); + EXPECT_FALSE(entry.hasMintedNFTokens()); + EXPECT_FALSE(entry.getMintedNFTokens().has_value()); + EXPECT_FALSE(entry.hasBurnedNFTokens()); + EXPECT_FALSE(entry.getBurnedNFTokens().has_value()); + EXPECT_FALSE(entry.hasFirstNFTokenSequence()); + EXPECT_FALSE(entry.getFirstNFTokenSequence().has_value()); + EXPECT_FALSE(entry.hasAMMID()); + EXPECT_FALSE(entry.getAMMID().has_value()); + EXPECT_FALSE(entry.hasVaultID()); + EXPECT_FALSE(entry.getVaultID().has_value()); + EXPECT_FALSE(entry.hasLoanBrokerID()); + EXPECT_FALSE(entry.getLoanBrokerID().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/AmendmentsTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/AmendmentsTests.cpp new file mode 100644 index 0000000000..17da755a3d --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/AmendmentsTests.cpp @@ -0,0 +1,224 @@ +// Auto-generated unit tests for ledger entry Amendments + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(AmendmentsTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const amendmentsValue = canonical_VECTOR256(); + auto const majoritiesValue = canonical_ARRAY(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + AmendmentsBuilder builder{ + }; + + builder.setAmendments(amendmentsValue); + builder.setMajorities(majoritiesValue); + builder.setPreviousTxnID(previousTxnIDValue); + builder.setPreviousTxnLgrSeq(previousTxnLgrSeqValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = amendmentsValue; + auto const actualOpt = entry.getAmendments(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAmendments"); + EXPECT_TRUE(entry.hasAmendments()); + } + + { + auto const& expected = majoritiesValue; + auto const actualOpt = entry.getMajorities(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMajorities"); + EXPECT_TRUE(entry.hasMajorities()); + } + + { + auto const& expected = previousTxnIDValue; + auto const actualOpt = entry.getPreviousTxnID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnID"); + EXPECT_TRUE(entry.hasPreviousTxnID()); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actualOpt = entry.getPreviousTxnLgrSeq(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnLgrSeq"); + EXPECT_TRUE(entry.hasPreviousTxnLgrSeq()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(AmendmentsTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const amendmentsValue = canonical_VECTOR256(); + auto const majoritiesValue = canonical_ARRAY(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(Amendments::entryType, index); + + sle->at(sfAmendments) = amendmentsValue; + sle->setFieldArray(sfMajorities, majoritiesValue); + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + AmendmentsBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Amendments entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = amendmentsValue; + + auto const fromSleOpt = entryFromSle.getAmendments(); + auto const fromBuilderOpt = entryFromBuilder.getAmendments(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAmendments"); + expectEqualField(expected, *fromBuilderOpt, "sfAmendments"); + } + + { + auto const& expected = majoritiesValue; + + auto const fromSleOpt = entryFromSle.getMajorities(); + auto const fromBuilderOpt = entryFromBuilder.getMajorities(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMajorities"); + expectEqualField(expected, *fromBuilderOpt, "sfMajorities"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnID(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnID"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnLgrSeq(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(AmendmentsTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Amendments{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(AmendmentsTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(AmendmentsBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(AmendmentsTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + + AmendmentsBuilder builder{ + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasAmendments()); + EXPECT_FALSE(entry.getAmendments().has_value()); + EXPECT_FALSE(entry.hasMajorities()); + EXPECT_FALSE(entry.getMajorities().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnID()); + EXPECT_FALSE(entry.getPreviousTxnID().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnLgrSeq()); + EXPECT_FALSE(entry.getPreviousTxnLgrSeq().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/BridgeTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/BridgeTests.cpp new file mode 100644 index 0000000000..1d4cfc00b9 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/BridgeTests.cpp @@ -0,0 +1,341 @@ +// Auto-generated unit tests for ledger entry Bridge + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(BridgeTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const minAccountCreateAmountValue = canonical_AMOUNT(); + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const xChainAccountCreateCountValue = canonical_UINT64(); + auto const xChainAccountClaimCountValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + BridgeBuilder builder{ + accountValue, + signatureRewardValue, + xChainBridgeValue, + xChainClaimIDValue, + xChainAccountCreateCountValue, + xChainAccountClaimCountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setMinAccountCreateAmount(minAccountCreateAmountValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = entry.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + { + auto const& expected = xChainBridgeValue; + auto const actual = entry.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = entry.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + { + auto const& expected = xChainAccountCreateCountValue; + auto const actual = entry.getXChainAccountCreateCount(); + expectEqualField(expected, actual, "sfXChainAccountCreateCount"); + } + + { + auto const& expected = xChainAccountClaimCountValue; + auto const actual = entry.getXChainAccountClaimCount(); + expectEqualField(expected, actual, "sfXChainAccountClaimCount"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = minAccountCreateAmountValue; + auto const actualOpt = entry.getMinAccountCreateAmount(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMinAccountCreateAmount"); + EXPECT_TRUE(entry.hasMinAccountCreateAmount()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(BridgeTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const minAccountCreateAmountValue = canonical_AMOUNT(); + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const xChainAccountCreateCountValue = canonical_UINT64(); + auto const xChainAccountClaimCountValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(Bridge::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfSignatureReward) = signatureRewardValue; + sle->at(sfMinAccountCreateAmount) = minAccountCreateAmountValue; + sle->at(sfXChainBridge) = xChainBridgeValue; + sle->at(sfXChainClaimID) = xChainClaimIDValue; + sle->at(sfXChainAccountCreateCount) = xChainAccountCreateCountValue; + sle->at(sfXChainAccountClaimCount) = xChainAccountClaimCountValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + BridgeBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Bridge entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = signatureRewardValue; + + auto const fromSle = entryFromSle.getSignatureReward(); + auto const fromBuilder = entryFromBuilder.getSignatureReward(); + + expectEqualField(expected, fromSle, "sfSignatureReward"); + expectEqualField(expected, fromBuilder, "sfSignatureReward"); + } + + { + auto const& expected = xChainBridgeValue; + + auto const fromSle = entryFromSle.getXChainBridge(); + auto const fromBuilder = entryFromBuilder.getXChainBridge(); + + expectEqualField(expected, fromSle, "sfXChainBridge"); + expectEqualField(expected, fromBuilder, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + + auto const fromSle = entryFromSle.getXChainClaimID(); + auto const fromBuilder = entryFromBuilder.getXChainClaimID(); + + expectEqualField(expected, fromSle, "sfXChainClaimID"); + expectEqualField(expected, fromBuilder, "sfXChainClaimID"); + } + + { + auto const& expected = xChainAccountCreateCountValue; + + auto const fromSle = entryFromSle.getXChainAccountCreateCount(); + auto const fromBuilder = entryFromBuilder.getXChainAccountCreateCount(); + + expectEqualField(expected, fromSle, "sfXChainAccountCreateCount"); + expectEqualField(expected, fromBuilder, "sfXChainAccountCreateCount"); + } + + { + auto const& expected = xChainAccountClaimCountValue; + + auto const fromSle = entryFromSle.getXChainAccountClaimCount(); + auto const fromBuilder = entryFromBuilder.getXChainAccountClaimCount(); + + expectEqualField(expected, fromSle, "sfXChainAccountClaimCount"); + expectEqualField(expected, fromBuilder, "sfXChainAccountClaimCount"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = minAccountCreateAmountValue; + + auto const fromSleOpt = entryFromSle.getMinAccountCreateAmount(); + auto const fromBuilderOpt = entryFromBuilder.getMinAccountCreateAmount(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMinAccountCreateAmount"); + expectEqualField(expected, *fromBuilderOpt, "sfMinAccountCreateAmount"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(BridgeTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Bridge{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(BridgeTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(BridgeBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(BridgeTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const xChainAccountCreateCountValue = canonical_UINT64(); + auto const xChainAccountClaimCountValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + BridgeBuilder builder{ + accountValue, + signatureRewardValue, + xChainBridgeValue, + xChainClaimIDValue, + xChainAccountCreateCountValue, + xChainAccountClaimCountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasMinAccountCreateAmount()); + EXPECT_FALSE(entry.getMinAccountCreateAmount().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/CheckTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/CheckTests.cpp new file mode 100644 index 0000000000..f14b4fb4e4 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/CheckTests.cpp @@ -0,0 +1,400 @@ +// Auto-generated unit tests for ledger entry Check + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(CheckTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const destinationNodeValue = canonical_UINT64(); + auto const expirationValue = canonical_UINT32(); + auto const invoiceIDValue = canonical_UINT256(); + auto const sourceTagValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + CheckBuilder builder{ + accountValue, + destinationValue, + sendMaxValue, + sequenceValue, + ownerNodeValue, + destinationNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setExpiration(expirationValue); + builder.setInvoiceID(invoiceIDValue); + builder.setSourceTag(sourceTagValue); + builder.setDestinationTag(destinationTagValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = destinationValue; + auto const actual = entry.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = sendMaxValue; + auto const actual = entry.getSendMax(); + expectEqualField(expected, actual, "sfSendMax"); + } + + { + auto const& expected = sequenceValue; + auto const actual = entry.getSequence(); + expectEqualField(expected, actual, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = destinationNodeValue; + auto const actual = entry.getDestinationNode(); + expectEqualField(expected, actual, "sfDestinationNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = entry.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(entry.hasExpiration()); + } + + { + auto const& expected = invoiceIDValue; + auto const actualOpt = entry.getInvoiceID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfInvoiceID"); + EXPECT_TRUE(entry.hasInvoiceID()); + } + + { + auto const& expected = sourceTagValue; + auto const actualOpt = entry.getSourceTag(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfSourceTag"); + EXPECT_TRUE(entry.hasSourceTag()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = entry.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(entry.hasDestinationTag()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(CheckTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const destinationNodeValue = canonical_UINT64(); + auto const expirationValue = canonical_UINT32(); + auto const invoiceIDValue = canonical_UINT256(); + auto const sourceTagValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(Check::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfDestination) = destinationValue; + sle->at(sfSendMax) = sendMaxValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfDestinationNode) = destinationNodeValue; + sle->at(sfExpiration) = expirationValue; + sle->at(sfInvoiceID) = invoiceIDValue; + sle->at(sfSourceTag) = sourceTagValue; + sle->at(sfDestinationTag) = destinationTagValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + CheckBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Check entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = destinationValue; + + auto const fromSle = entryFromSle.getDestination(); + auto const fromBuilder = entryFromBuilder.getDestination(); + + expectEqualField(expected, fromSle, "sfDestination"); + expectEqualField(expected, fromBuilder, "sfDestination"); + } + + { + auto const& expected = sendMaxValue; + + auto const fromSle = entryFromSle.getSendMax(); + auto const fromBuilder = entryFromBuilder.getSendMax(); + + expectEqualField(expected, fromSle, "sfSendMax"); + expectEqualField(expected, fromBuilder, "sfSendMax"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSle = entryFromSle.getSequence(); + auto const fromBuilder = entryFromBuilder.getSequence(); + + expectEqualField(expected, fromSle, "sfSequence"); + expectEqualField(expected, fromBuilder, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = destinationNodeValue; + + auto const fromSle = entryFromSle.getDestinationNode(); + auto const fromBuilder = entryFromBuilder.getDestinationNode(); + + expectEqualField(expected, fromSle, "sfDestinationNode"); + expectEqualField(expected, fromBuilder, "sfDestinationNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = expirationValue; + + auto const fromSleOpt = entryFromSle.getExpiration(); + auto const fromBuilderOpt = entryFromBuilder.getExpiration(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfExpiration"); + expectEqualField(expected, *fromBuilderOpt, "sfExpiration"); + } + + { + auto const& expected = invoiceIDValue; + + auto const fromSleOpt = entryFromSle.getInvoiceID(); + auto const fromBuilderOpt = entryFromBuilder.getInvoiceID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfInvoiceID"); + expectEqualField(expected, *fromBuilderOpt, "sfInvoiceID"); + } + + { + auto const& expected = sourceTagValue; + + auto const fromSleOpt = entryFromSle.getSourceTag(); + auto const fromBuilderOpt = entryFromBuilder.getSourceTag(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfSourceTag"); + expectEqualField(expected, *fromBuilderOpt, "sfSourceTag"); + } + + { + auto const& expected = destinationTagValue; + + auto const fromSleOpt = entryFromSle.getDestinationTag(); + auto const fromBuilderOpt = entryFromBuilder.getDestinationTag(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDestinationTag"); + expectEqualField(expected, *fromBuilderOpt, "sfDestinationTag"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(CheckTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Check{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(CheckTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(CheckBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(CheckTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const destinationNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + CheckBuilder builder{ + accountValue, + destinationValue, + sendMaxValue, + sequenceValue, + ownerNodeValue, + destinationNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasExpiration()); + EXPECT_FALSE(entry.getExpiration().has_value()); + EXPECT_FALSE(entry.hasInvoiceID()); + EXPECT_FALSE(entry.getInvoiceID().has_value()); + EXPECT_FALSE(entry.hasSourceTag()); + EXPECT_FALSE(entry.getSourceTag().has_value()); + EXPECT_FALSE(entry.hasDestinationTag()); + EXPECT_FALSE(entry.getDestinationTag().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/CredentialTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/CredentialTests.cpp new file mode 100644 index 0000000000..4fbf6d2a26 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/CredentialTests.cpp @@ -0,0 +1,329 @@ +// Auto-generated unit tests for ledger entry Credential + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(CredentialTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const subjectValue = canonical_ACCOUNT(); + auto const issuerValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + auto const expirationValue = canonical_UINT32(); + auto const uRIValue = canonical_VL(); + auto const issuerNodeValue = canonical_UINT64(); + auto const subjectNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + CredentialBuilder builder{ + subjectValue, + issuerValue, + credentialTypeValue, + issuerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setExpiration(expirationValue); + builder.setURI(uRIValue); + builder.setSubjectNode(subjectNodeValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = subjectValue; + auto const actual = entry.getSubject(); + expectEqualField(expected, actual, "sfSubject"); + } + + { + auto const& expected = issuerValue; + auto const actual = entry.getIssuer(); + expectEqualField(expected, actual, "sfIssuer"); + } + + { + auto const& expected = credentialTypeValue; + auto const actual = entry.getCredentialType(); + expectEqualField(expected, actual, "sfCredentialType"); + } + + { + auto const& expected = issuerNodeValue; + auto const actual = entry.getIssuerNode(); + expectEqualField(expected, actual, "sfIssuerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = entry.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(entry.hasExpiration()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = entry.getURI(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(entry.hasURI()); + } + + { + auto const& expected = subjectNodeValue; + auto const actualOpt = entry.getSubjectNode(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfSubjectNode"); + EXPECT_TRUE(entry.hasSubjectNode()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(CredentialTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const subjectValue = canonical_ACCOUNT(); + auto const issuerValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + auto const expirationValue = canonical_UINT32(); + auto const uRIValue = canonical_VL(); + auto const issuerNodeValue = canonical_UINT64(); + auto const subjectNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(Credential::entryType, index); + + sle->at(sfSubject) = subjectValue; + sle->at(sfIssuer) = issuerValue; + sle->at(sfCredentialType) = credentialTypeValue; + sle->at(sfExpiration) = expirationValue; + sle->at(sfURI) = uRIValue; + sle->at(sfIssuerNode) = issuerNodeValue; + sle->at(sfSubjectNode) = subjectNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + CredentialBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Credential entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = subjectValue; + + auto const fromSle = entryFromSle.getSubject(); + auto const fromBuilder = entryFromBuilder.getSubject(); + + expectEqualField(expected, fromSle, "sfSubject"); + expectEqualField(expected, fromBuilder, "sfSubject"); + } + + { + auto const& expected = issuerValue; + + auto const fromSle = entryFromSle.getIssuer(); + auto const fromBuilder = entryFromBuilder.getIssuer(); + + expectEqualField(expected, fromSle, "sfIssuer"); + expectEqualField(expected, fromBuilder, "sfIssuer"); + } + + { + auto const& expected = credentialTypeValue; + + auto const fromSle = entryFromSle.getCredentialType(); + auto const fromBuilder = entryFromBuilder.getCredentialType(); + + expectEqualField(expected, fromSle, "sfCredentialType"); + expectEqualField(expected, fromBuilder, "sfCredentialType"); + } + + { + auto const& expected = issuerNodeValue; + + auto const fromSle = entryFromSle.getIssuerNode(); + auto const fromBuilder = entryFromBuilder.getIssuerNode(); + + expectEqualField(expected, fromSle, "sfIssuerNode"); + expectEqualField(expected, fromBuilder, "sfIssuerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = expirationValue; + + auto const fromSleOpt = entryFromSle.getExpiration(); + auto const fromBuilderOpt = entryFromBuilder.getExpiration(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfExpiration"); + expectEqualField(expected, *fromBuilderOpt, "sfExpiration"); + } + + { + auto const& expected = uRIValue; + + auto const fromSleOpt = entryFromSle.getURI(); + auto const fromBuilderOpt = entryFromBuilder.getURI(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfURI"); + expectEqualField(expected, *fromBuilderOpt, "sfURI"); + } + + { + auto const& expected = subjectNodeValue; + + auto const fromSleOpt = entryFromSle.getSubjectNode(); + auto const fromBuilderOpt = entryFromBuilder.getSubjectNode(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfSubjectNode"); + expectEqualField(expected, *fromBuilderOpt, "sfSubjectNode"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(CredentialTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Credential{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(CredentialTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(CredentialBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(CredentialTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const subjectValue = canonical_ACCOUNT(); + auto const issuerValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + auto const issuerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + CredentialBuilder builder{ + subjectValue, + issuerValue, + credentialTypeValue, + issuerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasExpiration()); + EXPECT_FALSE(entry.getExpiration().has_value()); + EXPECT_FALSE(entry.hasURI()); + EXPECT_FALSE(entry.getURI().has_value()); + EXPECT_FALSE(entry.hasSubjectNode()); + EXPECT_FALSE(entry.getSubjectNode().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/DIDTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/DIDTests.cpp new file mode 100644 index 0000000000..29d49a47f2 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/DIDTests.cpp @@ -0,0 +1,285 @@ +// Auto-generated unit tests for ledger entry DID + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(DIDTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const dIDDocumentValue = canonical_VL(); + auto const uRIValue = canonical_VL(); + auto const dataValue = canonical_VL(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + DIDBuilder builder{ + accountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setDIDDocument(dIDDocumentValue); + builder.setURI(uRIValue); + builder.setData(dataValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = dIDDocumentValue; + auto const actualOpt = entry.getDIDDocument(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDIDDocument"); + EXPECT_TRUE(entry.hasDIDDocument()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = entry.getURI(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(entry.hasURI()); + } + + { + auto const& expected = dataValue; + auto const actualOpt = entry.getData(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(entry.hasData()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(DIDTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const dIDDocumentValue = canonical_VL(); + auto const uRIValue = canonical_VL(); + auto const dataValue = canonical_VL(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(DID::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfDIDDocument) = dIDDocumentValue; + sle->at(sfURI) = uRIValue; + sle->at(sfData) = dataValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + DIDBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + DID entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = dIDDocumentValue; + + auto const fromSleOpt = entryFromSle.getDIDDocument(); + auto const fromBuilderOpt = entryFromBuilder.getDIDDocument(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDIDDocument"); + expectEqualField(expected, *fromBuilderOpt, "sfDIDDocument"); + } + + { + auto const& expected = uRIValue; + + auto const fromSleOpt = entryFromSle.getURI(); + auto const fromBuilderOpt = entryFromBuilder.getURI(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfURI"); + expectEqualField(expected, *fromBuilderOpt, "sfURI"); + } + + { + auto const& expected = dataValue; + + auto const fromSleOpt = entryFromSle.getData(); + auto const fromBuilderOpt = entryFromBuilder.getData(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfData"); + expectEqualField(expected, *fromBuilderOpt, "sfData"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(DIDTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(DID{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(DIDTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(DIDBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(DIDTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + DIDBuilder builder{ + accountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasDIDDocument()); + EXPECT_FALSE(entry.getDIDDocument().has_value()); + EXPECT_FALSE(entry.hasURI()); + EXPECT_FALSE(entry.getURI().has_value()); + EXPECT_FALSE(entry.hasData()); + EXPECT_FALSE(entry.getData().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/DelegateTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/DelegateTests.cpp new file mode 100644 index 0000000000..68d0e6c08e --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/DelegateTests.cpp @@ -0,0 +1,223 @@ +// Auto-generated unit tests for ledger entry Delegate + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(DelegateTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const authorizeValue = canonical_ACCOUNT(); + auto const permissionsValue = canonical_ARRAY(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + DelegateBuilder builder{ + accountValue, + authorizeValue, + permissionsValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = authorizeValue; + auto const actual = entry.getAuthorize(); + expectEqualField(expected, actual, "sfAuthorize"); + } + + { + auto const& expected = permissionsValue; + auto const actual = entry.getPermissions(); + expectEqualField(expected, actual, "sfPermissions"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(DelegateTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const authorizeValue = canonical_ACCOUNT(); + auto const permissionsValue = canonical_ARRAY(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(Delegate::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfAuthorize) = authorizeValue; + sle->setFieldArray(sfPermissions, permissionsValue); + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + DelegateBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Delegate entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = authorizeValue; + + auto const fromSle = entryFromSle.getAuthorize(); + auto const fromBuilder = entryFromBuilder.getAuthorize(); + + expectEqualField(expected, fromSle, "sfAuthorize"); + expectEqualField(expected, fromBuilder, "sfAuthorize"); + } + + { + auto const& expected = permissionsValue; + + auto const fromSle = entryFromSle.getPermissions(); + auto const fromBuilder = entryFromBuilder.getPermissions(); + + expectEqualField(expected, fromSle, "sfPermissions"); + expectEqualField(expected, fromBuilder, "sfPermissions"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(DelegateTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Delegate{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(DelegateTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(DelegateBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/DepositPreauthTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/DepositPreauthTests.cpp new file mode 100644 index 0000000000..9e6144d5b9 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/DepositPreauthTests.cpp @@ -0,0 +1,258 @@ +// Auto-generated unit tests for ledger entry DepositPreauth + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(DepositPreauthTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const authorizeValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const authorizeCredentialsValue = canonical_ARRAY(); + + DepositPreauthBuilder builder{ + accountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setAuthorize(authorizeValue); + builder.setAuthorizeCredentials(authorizeCredentialsValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = authorizeValue; + auto const actualOpt = entry.getAuthorize(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAuthorize"); + EXPECT_TRUE(entry.hasAuthorize()); + } + + { + auto const& expected = authorizeCredentialsValue; + auto const actualOpt = entry.getAuthorizeCredentials(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAuthorizeCredentials"); + EXPECT_TRUE(entry.hasAuthorizeCredentials()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(DepositPreauthTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const authorizeValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const authorizeCredentialsValue = canonical_ARRAY(); + + auto sle = std::make_shared(DepositPreauth::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfAuthorize) = authorizeValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->setFieldArray(sfAuthorizeCredentials, authorizeCredentialsValue); + + DepositPreauthBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + DepositPreauth entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = authorizeValue; + + auto const fromSleOpt = entryFromSle.getAuthorize(); + auto const fromBuilderOpt = entryFromBuilder.getAuthorize(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAuthorize"); + expectEqualField(expected, *fromBuilderOpt, "sfAuthorize"); + } + + { + auto const& expected = authorizeCredentialsValue; + + auto const fromSleOpt = entryFromSle.getAuthorizeCredentials(); + auto const fromBuilderOpt = entryFromBuilder.getAuthorizeCredentials(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAuthorizeCredentials"); + expectEqualField(expected, *fromBuilderOpt, "sfAuthorizeCredentials"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(DepositPreauthTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(DepositPreauth{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(DepositPreauthTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(DepositPreauthBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(DepositPreauthTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + DepositPreauthBuilder builder{ + accountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasAuthorize()); + EXPECT_FALSE(entry.getAuthorize().has_value()); + EXPECT_FALSE(entry.hasAuthorizeCredentials()); + EXPECT_FALSE(entry.getAuthorizeCredentials().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/DirectoryNodeTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/DirectoryNodeTests.cpp new file mode 100644 index 0000000000..d1b6edc704 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/DirectoryNodeTests.cpp @@ -0,0 +1,484 @@ +// Auto-generated unit tests for ledger entry DirectoryNode + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(DirectoryNodeTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const takerPaysCurrencyValue = canonical_UINT160(); + auto const takerPaysIssuerValue = canonical_UINT160(); + auto const takerGetsCurrencyValue = canonical_UINT160(); + auto const takerGetsIssuerValue = canonical_UINT160(); + auto const exchangeRateValue = canonical_UINT64(); + auto const indexesValue = canonical_VECTOR256(); + auto const rootIndexValue = canonical_UINT256(); + auto const indexNextValue = canonical_UINT64(); + auto const indexPreviousValue = canonical_UINT64(); + auto const nFTokenIDValue = canonical_UINT256(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + + DirectoryNodeBuilder builder{ + indexesValue, + rootIndexValue + }; + + builder.setOwner(ownerValue); + builder.setTakerPaysCurrency(takerPaysCurrencyValue); + builder.setTakerPaysIssuer(takerPaysIssuerValue); + builder.setTakerGetsCurrency(takerGetsCurrencyValue); + builder.setTakerGetsIssuer(takerGetsIssuerValue); + builder.setExchangeRate(exchangeRateValue); + builder.setIndexNext(indexNextValue); + builder.setIndexPrevious(indexPreviousValue); + builder.setNFTokenID(nFTokenIDValue); + builder.setPreviousTxnID(previousTxnIDValue); + builder.setPreviousTxnLgrSeq(previousTxnLgrSeqValue); + builder.setDomainID(domainIDValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = indexesValue; + auto const actual = entry.getIndexes(); + expectEqualField(expected, actual, "sfIndexes"); + } + + { + auto const& expected = rootIndexValue; + auto const actual = entry.getRootIndex(); + expectEqualField(expected, actual, "sfRootIndex"); + } + + { + auto const& expected = ownerValue; + auto const actualOpt = entry.getOwner(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfOwner"); + EXPECT_TRUE(entry.hasOwner()); + } + + { + auto const& expected = takerPaysCurrencyValue; + auto const actualOpt = entry.getTakerPaysCurrency(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTakerPaysCurrency"); + EXPECT_TRUE(entry.hasTakerPaysCurrency()); + } + + { + auto const& expected = takerPaysIssuerValue; + auto const actualOpt = entry.getTakerPaysIssuer(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTakerPaysIssuer"); + EXPECT_TRUE(entry.hasTakerPaysIssuer()); + } + + { + auto const& expected = takerGetsCurrencyValue; + auto const actualOpt = entry.getTakerGetsCurrency(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTakerGetsCurrency"); + EXPECT_TRUE(entry.hasTakerGetsCurrency()); + } + + { + auto const& expected = takerGetsIssuerValue; + auto const actualOpt = entry.getTakerGetsIssuer(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTakerGetsIssuer"); + EXPECT_TRUE(entry.hasTakerGetsIssuer()); + } + + { + auto const& expected = exchangeRateValue; + auto const actualOpt = entry.getExchangeRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfExchangeRate"); + EXPECT_TRUE(entry.hasExchangeRate()); + } + + { + auto const& expected = indexNextValue; + auto const actualOpt = entry.getIndexNext(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfIndexNext"); + EXPECT_TRUE(entry.hasIndexNext()); + } + + { + auto const& expected = indexPreviousValue; + auto const actualOpt = entry.getIndexPrevious(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfIndexPrevious"); + EXPECT_TRUE(entry.hasIndexPrevious()); + } + + { + auto const& expected = nFTokenIDValue; + auto const actualOpt = entry.getNFTokenID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfNFTokenID"); + EXPECT_TRUE(entry.hasNFTokenID()); + } + + { + auto const& expected = previousTxnIDValue; + auto const actualOpt = entry.getPreviousTxnID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnID"); + EXPECT_TRUE(entry.hasPreviousTxnID()); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actualOpt = entry.getPreviousTxnLgrSeq(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnLgrSeq"); + EXPECT_TRUE(entry.hasPreviousTxnLgrSeq()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = entry.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(entry.hasDomainID()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(DirectoryNodeTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const takerPaysCurrencyValue = canonical_UINT160(); + auto const takerPaysIssuerValue = canonical_UINT160(); + auto const takerGetsCurrencyValue = canonical_UINT160(); + auto const takerGetsIssuerValue = canonical_UINT160(); + auto const exchangeRateValue = canonical_UINT64(); + auto const indexesValue = canonical_VECTOR256(); + auto const rootIndexValue = canonical_UINT256(); + auto const indexNextValue = canonical_UINT64(); + auto const indexPreviousValue = canonical_UINT64(); + auto const nFTokenIDValue = canonical_UINT256(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + + auto sle = std::make_shared(DirectoryNode::entryType, index); + + sle->at(sfOwner) = ownerValue; + sle->at(sfTakerPaysCurrency) = takerPaysCurrencyValue; + sle->at(sfTakerPaysIssuer) = takerPaysIssuerValue; + sle->at(sfTakerGetsCurrency) = takerGetsCurrencyValue; + sle->at(sfTakerGetsIssuer) = takerGetsIssuerValue; + sle->at(sfExchangeRate) = exchangeRateValue; + sle->at(sfIndexes) = indexesValue; + sle->at(sfRootIndex) = rootIndexValue; + sle->at(sfIndexNext) = indexNextValue; + sle->at(sfIndexPrevious) = indexPreviousValue; + sle->at(sfNFTokenID) = nFTokenIDValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfDomainID) = domainIDValue; + + DirectoryNodeBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + DirectoryNode entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = indexesValue; + + auto const fromSle = entryFromSle.getIndexes(); + auto const fromBuilder = entryFromBuilder.getIndexes(); + + expectEqualField(expected, fromSle, "sfIndexes"); + expectEqualField(expected, fromBuilder, "sfIndexes"); + } + + { + auto const& expected = rootIndexValue; + + auto const fromSle = entryFromSle.getRootIndex(); + auto const fromBuilder = entryFromBuilder.getRootIndex(); + + expectEqualField(expected, fromSle, "sfRootIndex"); + expectEqualField(expected, fromBuilder, "sfRootIndex"); + } + + { + auto const& expected = ownerValue; + + auto const fromSleOpt = entryFromSle.getOwner(); + auto const fromBuilderOpt = entryFromBuilder.getOwner(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfOwner"); + expectEqualField(expected, *fromBuilderOpt, "sfOwner"); + } + + { + auto const& expected = takerPaysCurrencyValue; + + auto const fromSleOpt = entryFromSle.getTakerPaysCurrency(); + auto const fromBuilderOpt = entryFromBuilder.getTakerPaysCurrency(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTakerPaysCurrency"); + expectEqualField(expected, *fromBuilderOpt, "sfTakerPaysCurrency"); + } + + { + auto const& expected = takerPaysIssuerValue; + + auto const fromSleOpt = entryFromSle.getTakerPaysIssuer(); + auto const fromBuilderOpt = entryFromBuilder.getTakerPaysIssuer(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTakerPaysIssuer"); + expectEqualField(expected, *fromBuilderOpt, "sfTakerPaysIssuer"); + } + + { + auto const& expected = takerGetsCurrencyValue; + + auto const fromSleOpt = entryFromSle.getTakerGetsCurrency(); + auto const fromBuilderOpt = entryFromBuilder.getTakerGetsCurrency(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTakerGetsCurrency"); + expectEqualField(expected, *fromBuilderOpt, "sfTakerGetsCurrency"); + } + + { + auto const& expected = takerGetsIssuerValue; + + auto const fromSleOpt = entryFromSle.getTakerGetsIssuer(); + auto const fromBuilderOpt = entryFromBuilder.getTakerGetsIssuer(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTakerGetsIssuer"); + expectEqualField(expected, *fromBuilderOpt, "sfTakerGetsIssuer"); + } + + { + auto const& expected = exchangeRateValue; + + auto const fromSleOpt = entryFromSle.getExchangeRate(); + auto const fromBuilderOpt = entryFromBuilder.getExchangeRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfExchangeRate"); + expectEqualField(expected, *fromBuilderOpt, "sfExchangeRate"); + } + + { + auto const& expected = indexNextValue; + + auto const fromSleOpt = entryFromSle.getIndexNext(); + auto const fromBuilderOpt = entryFromBuilder.getIndexNext(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfIndexNext"); + expectEqualField(expected, *fromBuilderOpt, "sfIndexNext"); + } + + { + auto const& expected = indexPreviousValue; + + auto const fromSleOpt = entryFromSle.getIndexPrevious(); + auto const fromBuilderOpt = entryFromBuilder.getIndexPrevious(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfIndexPrevious"); + expectEqualField(expected, *fromBuilderOpt, "sfIndexPrevious"); + } + + { + auto const& expected = nFTokenIDValue; + + auto const fromSleOpt = entryFromSle.getNFTokenID(); + auto const fromBuilderOpt = entryFromBuilder.getNFTokenID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfNFTokenID"); + expectEqualField(expected, *fromBuilderOpt, "sfNFTokenID"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnID(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnID"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnLgrSeq(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = domainIDValue; + + auto const fromSleOpt = entryFromSle.getDomainID(); + auto const fromBuilderOpt = entryFromBuilder.getDomainID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDomainID"); + expectEqualField(expected, *fromBuilderOpt, "sfDomainID"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(DirectoryNodeTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(DirectoryNode{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(DirectoryNodeTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(DirectoryNodeBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(DirectoryNodeTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const indexesValue = canonical_VECTOR256(); + auto const rootIndexValue = canonical_UINT256(); + + DirectoryNodeBuilder builder{ + indexesValue, + rootIndexValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasOwner()); + EXPECT_FALSE(entry.getOwner().has_value()); + EXPECT_FALSE(entry.hasTakerPaysCurrency()); + EXPECT_FALSE(entry.getTakerPaysCurrency().has_value()); + EXPECT_FALSE(entry.hasTakerPaysIssuer()); + EXPECT_FALSE(entry.getTakerPaysIssuer().has_value()); + EXPECT_FALSE(entry.hasTakerGetsCurrency()); + EXPECT_FALSE(entry.getTakerGetsCurrency().has_value()); + EXPECT_FALSE(entry.hasTakerGetsIssuer()); + EXPECT_FALSE(entry.getTakerGetsIssuer().has_value()); + EXPECT_FALSE(entry.hasExchangeRate()); + EXPECT_FALSE(entry.getExchangeRate().has_value()); + EXPECT_FALSE(entry.hasIndexNext()); + EXPECT_FALSE(entry.getIndexNext().has_value()); + EXPECT_FALSE(entry.hasIndexPrevious()); + EXPECT_FALSE(entry.getIndexPrevious().has_value()); + EXPECT_FALSE(entry.hasNFTokenID()); + EXPECT_FALSE(entry.getNFTokenID().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnID()); + EXPECT_FALSE(entry.getPreviousTxnID().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnLgrSeq()); + EXPECT_FALSE(entry.getPreviousTxnLgrSeq().has_value()); + EXPECT_FALSE(entry.hasDomainID()); + EXPECT_FALSE(entry.getDomainID().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/EscrowTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/EscrowTests.cpp new file mode 100644 index 0000000000..2dbb450e28 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/EscrowTests.cpp @@ -0,0 +1,491 @@ +// Auto-generated unit tests for ledger entry Escrow + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(EscrowTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const conditionValue = canonical_VL(); + auto const cancelAfterValue = canonical_UINT32(); + auto const finishAfterValue = canonical_UINT32(); + auto const sourceTagValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const destinationNodeValue = canonical_UINT64(); + auto const transferRateValue = canonical_UINT32(); + auto const issuerNodeValue = canonical_UINT64(); + + EscrowBuilder builder{ + accountValue, + destinationValue, + amountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setSequence(sequenceValue); + builder.setCondition(conditionValue); + builder.setCancelAfter(cancelAfterValue); + builder.setFinishAfter(finishAfterValue); + builder.setSourceTag(sourceTagValue); + builder.setDestinationTag(destinationTagValue); + builder.setDestinationNode(destinationNodeValue); + builder.setTransferRate(transferRateValue); + builder.setIssuerNode(issuerNodeValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = destinationValue; + auto const actual = entry.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = entry.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + auto const actualOpt = entry.getSequence(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfSequence"); + EXPECT_TRUE(entry.hasSequence()); + } + + { + auto const& expected = conditionValue; + auto const actualOpt = entry.getCondition(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfCondition"); + EXPECT_TRUE(entry.hasCondition()); + } + + { + auto const& expected = cancelAfterValue; + auto const actualOpt = entry.getCancelAfter(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfCancelAfter"); + EXPECT_TRUE(entry.hasCancelAfter()); + } + + { + auto const& expected = finishAfterValue; + auto const actualOpt = entry.getFinishAfter(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfFinishAfter"); + EXPECT_TRUE(entry.hasFinishAfter()); + } + + { + auto const& expected = sourceTagValue; + auto const actualOpt = entry.getSourceTag(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfSourceTag"); + EXPECT_TRUE(entry.hasSourceTag()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = entry.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(entry.hasDestinationTag()); + } + + { + auto const& expected = destinationNodeValue; + auto const actualOpt = entry.getDestinationNode(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDestinationNode"); + EXPECT_TRUE(entry.hasDestinationNode()); + } + + { + auto const& expected = transferRateValue; + auto const actualOpt = entry.getTransferRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTransferRate"); + EXPECT_TRUE(entry.hasTransferRate()); + } + + { + auto const& expected = issuerNodeValue; + auto const actualOpt = entry.getIssuerNode(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfIssuerNode"); + EXPECT_TRUE(entry.hasIssuerNode()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(EscrowTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const conditionValue = canonical_VL(); + auto const cancelAfterValue = canonical_UINT32(); + auto const finishAfterValue = canonical_UINT32(); + auto const sourceTagValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const destinationNodeValue = canonical_UINT64(); + auto const transferRateValue = canonical_UINT32(); + auto const issuerNodeValue = canonical_UINT64(); + + auto sle = std::make_shared(Escrow::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfDestination) = destinationValue; + sle->at(sfAmount) = amountValue; + sle->at(sfCondition) = conditionValue; + sle->at(sfCancelAfter) = cancelAfterValue; + sle->at(sfFinishAfter) = finishAfterValue; + sle->at(sfSourceTag) = sourceTagValue; + sle->at(sfDestinationTag) = destinationTagValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfDestinationNode) = destinationNodeValue; + sle->at(sfTransferRate) = transferRateValue; + sle->at(sfIssuerNode) = issuerNodeValue; + + EscrowBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Escrow entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = destinationValue; + + auto const fromSle = entryFromSle.getDestination(); + auto const fromBuilder = entryFromBuilder.getDestination(); + + expectEqualField(expected, fromSle, "sfDestination"); + expectEqualField(expected, fromBuilder, "sfDestination"); + } + + { + auto const& expected = amountValue; + + auto const fromSle = entryFromSle.getAmount(); + auto const fromBuilder = entryFromBuilder.getAmount(); + + expectEqualField(expected, fromSle, "sfAmount"); + expectEqualField(expected, fromBuilder, "sfAmount"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSleOpt = entryFromSle.getSequence(); + auto const fromBuilderOpt = entryFromBuilder.getSequence(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfSequence"); + expectEqualField(expected, *fromBuilderOpt, "sfSequence"); + } + + { + auto const& expected = conditionValue; + + auto const fromSleOpt = entryFromSle.getCondition(); + auto const fromBuilderOpt = entryFromBuilder.getCondition(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfCondition"); + expectEqualField(expected, *fromBuilderOpt, "sfCondition"); + } + + { + auto const& expected = cancelAfterValue; + + auto const fromSleOpt = entryFromSle.getCancelAfter(); + auto const fromBuilderOpt = entryFromBuilder.getCancelAfter(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfCancelAfter"); + expectEqualField(expected, *fromBuilderOpt, "sfCancelAfter"); + } + + { + auto const& expected = finishAfterValue; + + auto const fromSleOpt = entryFromSle.getFinishAfter(); + auto const fromBuilderOpt = entryFromBuilder.getFinishAfter(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfFinishAfter"); + expectEqualField(expected, *fromBuilderOpt, "sfFinishAfter"); + } + + { + auto const& expected = sourceTagValue; + + auto const fromSleOpt = entryFromSle.getSourceTag(); + auto const fromBuilderOpt = entryFromBuilder.getSourceTag(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfSourceTag"); + expectEqualField(expected, *fromBuilderOpt, "sfSourceTag"); + } + + { + auto const& expected = destinationTagValue; + + auto const fromSleOpt = entryFromSle.getDestinationTag(); + auto const fromBuilderOpt = entryFromBuilder.getDestinationTag(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDestinationTag"); + expectEqualField(expected, *fromBuilderOpt, "sfDestinationTag"); + } + + { + auto const& expected = destinationNodeValue; + + auto const fromSleOpt = entryFromSle.getDestinationNode(); + auto const fromBuilderOpt = entryFromBuilder.getDestinationNode(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDestinationNode"); + expectEqualField(expected, *fromBuilderOpt, "sfDestinationNode"); + } + + { + auto const& expected = transferRateValue; + + auto const fromSleOpt = entryFromSle.getTransferRate(); + auto const fromBuilderOpt = entryFromBuilder.getTransferRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTransferRate"); + expectEqualField(expected, *fromBuilderOpt, "sfTransferRate"); + } + + { + auto const& expected = issuerNodeValue; + + auto const fromSleOpt = entryFromSle.getIssuerNode(); + auto const fromBuilderOpt = entryFromBuilder.getIssuerNode(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfIssuerNode"); + expectEqualField(expected, *fromBuilderOpt, "sfIssuerNode"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(EscrowTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Escrow{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(EscrowTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(EscrowBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(EscrowTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + EscrowBuilder builder{ + accountValue, + destinationValue, + amountValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasSequence()); + EXPECT_FALSE(entry.getSequence().has_value()); + EXPECT_FALSE(entry.hasCondition()); + EXPECT_FALSE(entry.getCondition().has_value()); + EXPECT_FALSE(entry.hasCancelAfter()); + EXPECT_FALSE(entry.getCancelAfter().has_value()); + EXPECT_FALSE(entry.hasFinishAfter()); + EXPECT_FALSE(entry.getFinishAfter().has_value()); + EXPECT_FALSE(entry.hasSourceTag()); + EXPECT_FALSE(entry.getSourceTag().has_value()); + EXPECT_FALSE(entry.hasDestinationTag()); + EXPECT_FALSE(entry.getDestinationTag().has_value()); + EXPECT_FALSE(entry.hasDestinationNode()); + EXPECT_FALSE(entry.getDestinationNode().has_value()); + EXPECT_FALSE(entry.hasTransferRate()); + EXPECT_FALSE(entry.getTransferRate().has_value()); + EXPECT_FALSE(entry.hasIssuerNode()); + EXPECT_FALSE(entry.getIssuerNode().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/FeeSettingsTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/FeeSettingsTests.cpp new file mode 100644 index 0000000000..479d0c56c6 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/FeeSettingsTests.cpp @@ -0,0 +1,359 @@ +// Auto-generated unit tests for ledger entry FeeSettings + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(FeeSettingsTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const baseFeeValue = canonical_UINT64(); + auto const referenceFeeUnitsValue = canonical_UINT32(); + auto const reserveBaseValue = canonical_UINT32(); + auto const reserveIncrementValue = canonical_UINT32(); + auto const baseFeeDropsValue = canonical_AMOUNT(); + auto const reserveBaseDropsValue = canonical_AMOUNT(); + auto const reserveIncrementDropsValue = canonical_AMOUNT(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + FeeSettingsBuilder builder{ + }; + + builder.setBaseFee(baseFeeValue); + builder.setReferenceFeeUnits(referenceFeeUnitsValue); + builder.setReserveBase(reserveBaseValue); + builder.setReserveIncrement(reserveIncrementValue); + builder.setBaseFeeDrops(baseFeeDropsValue); + builder.setReserveBaseDrops(reserveBaseDropsValue); + builder.setReserveIncrementDrops(reserveIncrementDropsValue); + builder.setPreviousTxnID(previousTxnIDValue); + builder.setPreviousTxnLgrSeq(previousTxnLgrSeqValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = baseFeeValue; + auto const actualOpt = entry.getBaseFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfBaseFee"); + EXPECT_TRUE(entry.hasBaseFee()); + } + + { + auto const& expected = referenceFeeUnitsValue; + auto const actualOpt = entry.getReferenceFeeUnits(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfReferenceFeeUnits"); + EXPECT_TRUE(entry.hasReferenceFeeUnits()); + } + + { + auto const& expected = reserveBaseValue; + auto const actualOpt = entry.getReserveBase(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfReserveBase"); + EXPECT_TRUE(entry.hasReserveBase()); + } + + { + auto const& expected = reserveIncrementValue; + auto const actualOpt = entry.getReserveIncrement(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfReserveIncrement"); + EXPECT_TRUE(entry.hasReserveIncrement()); + } + + { + auto const& expected = baseFeeDropsValue; + auto const actualOpt = entry.getBaseFeeDrops(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfBaseFeeDrops"); + EXPECT_TRUE(entry.hasBaseFeeDrops()); + } + + { + auto const& expected = reserveBaseDropsValue; + auto const actualOpt = entry.getReserveBaseDrops(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfReserveBaseDrops"); + EXPECT_TRUE(entry.hasReserveBaseDrops()); + } + + { + auto const& expected = reserveIncrementDropsValue; + auto const actualOpt = entry.getReserveIncrementDrops(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfReserveIncrementDrops"); + EXPECT_TRUE(entry.hasReserveIncrementDrops()); + } + + { + auto const& expected = previousTxnIDValue; + auto const actualOpt = entry.getPreviousTxnID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnID"); + EXPECT_TRUE(entry.hasPreviousTxnID()); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actualOpt = entry.getPreviousTxnLgrSeq(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnLgrSeq"); + EXPECT_TRUE(entry.hasPreviousTxnLgrSeq()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(FeeSettingsTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const baseFeeValue = canonical_UINT64(); + auto const referenceFeeUnitsValue = canonical_UINT32(); + auto const reserveBaseValue = canonical_UINT32(); + auto const reserveIncrementValue = canonical_UINT32(); + auto const baseFeeDropsValue = canonical_AMOUNT(); + auto const reserveBaseDropsValue = canonical_AMOUNT(); + auto const reserveIncrementDropsValue = canonical_AMOUNT(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(FeeSettings::entryType, index); + + sle->at(sfBaseFee) = baseFeeValue; + sle->at(sfReferenceFeeUnits) = referenceFeeUnitsValue; + sle->at(sfReserveBase) = reserveBaseValue; + sle->at(sfReserveIncrement) = reserveIncrementValue; + sle->at(sfBaseFeeDrops) = baseFeeDropsValue; + sle->at(sfReserveBaseDrops) = reserveBaseDropsValue; + sle->at(sfReserveIncrementDrops) = reserveIncrementDropsValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + FeeSettingsBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + FeeSettings entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = baseFeeValue; + + auto const fromSleOpt = entryFromSle.getBaseFee(); + auto const fromBuilderOpt = entryFromBuilder.getBaseFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfBaseFee"); + expectEqualField(expected, *fromBuilderOpt, "sfBaseFee"); + } + + { + auto const& expected = referenceFeeUnitsValue; + + auto const fromSleOpt = entryFromSle.getReferenceFeeUnits(); + auto const fromBuilderOpt = entryFromBuilder.getReferenceFeeUnits(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfReferenceFeeUnits"); + expectEqualField(expected, *fromBuilderOpt, "sfReferenceFeeUnits"); + } + + { + auto const& expected = reserveBaseValue; + + auto const fromSleOpt = entryFromSle.getReserveBase(); + auto const fromBuilderOpt = entryFromBuilder.getReserveBase(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfReserveBase"); + expectEqualField(expected, *fromBuilderOpt, "sfReserveBase"); + } + + { + auto const& expected = reserveIncrementValue; + + auto const fromSleOpt = entryFromSle.getReserveIncrement(); + auto const fromBuilderOpt = entryFromBuilder.getReserveIncrement(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfReserveIncrement"); + expectEqualField(expected, *fromBuilderOpt, "sfReserveIncrement"); + } + + { + auto const& expected = baseFeeDropsValue; + + auto const fromSleOpt = entryFromSle.getBaseFeeDrops(); + auto const fromBuilderOpt = entryFromBuilder.getBaseFeeDrops(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfBaseFeeDrops"); + expectEqualField(expected, *fromBuilderOpt, "sfBaseFeeDrops"); + } + + { + auto const& expected = reserveBaseDropsValue; + + auto const fromSleOpt = entryFromSle.getReserveBaseDrops(); + auto const fromBuilderOpt = entryFromBuilder.getReserveBaseDrops(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfReserveBaseDrops"); + expectEqualField(expected, *fromBuilderOpt, "sfReserveBaseDrops"); + } + + { + auto const& expected = reserveIncrementDropsValue; + + auto const fromSleOpt = entryFromSle.getReserveIncrementDrops(); + auto const fromBuilderOpt = entryFromBuilder.getReserveIncrementDrops(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfReserveIncrementDrops"); + expectEqualField(expected, *fromBuilderOpt, "sfReserveIncrementDrops"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnID(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnID"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnLgrSeq(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(FeeSettingsTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(FeeSettings{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(FeeSettingsTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(FeeSettingsBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(FeeSettingsTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + + FeeSettingsBuilder builder{ + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasBaseFee()); + EXPECT_FALSE(entry.getBaseFee().has_value()); + EXPECT_FALSE(entry.hasReferenceFeeUnits()); + EXPECT_FALSE(entry.getReferenceFeeUnits().has_value()); + EXPECT_FALSE(entry.hasReserveBase()); + EXPECT_FALSE(entry.getReserveBase().has_value()); + EXPECT_FALSE(entry.hasReserveIncrement()); + EXPECT_FALSE(entry.getReserveIncrement().has_value()); + EXPECT_FALSE(entry.hasBaseFeeDrops()); + EXPECT_FALSE(entry.getBaseFeeDrops().has_value()); + EXPECT_FALSE(entry.hasReserveBaseDrops()); + EXPECT_FALSE(entry.getReserveBaseDrops().has_value()); + EXPECT_FALSE(entry.hasReserveIncrementDrops()); + EXPECT_FALSE(entry.getReserveIncrementDrops().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnID()); + EXPECT_FALSE(entry.getPreviousTxnID().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnLgrSeq()); + EXPECT_FALSE(entry.getPreviousTxnLgrSeq().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/LedgerHashesTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/LedgerHashesTests.cpp new file mode 100644 index 0000000000..8a7ae38749 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/LedgerHashesTests.cpp @@ -0,0 +1,192 @@ +// Auto-generated unit tests for ledger entry LedgerHashes + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(LedgerHashesTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const firstLedgerSequenceValue = canonical_UINT32(); + auto const lastLedgerSequenceValue = canonical_UINT32(); + auto const hashesValue = canonical_VECTOR256(); + + LedgerHashesBuilder builder{ + hashesValue + }; + + builder.setFirstLedgerSequence(firstLedgerSequenceValue); + builder.setLastLedgerSequence(lastLedgerSequenceValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = hashesValue; + auto const actual = entry.getHashes(); + expectEqualField(expected, actual, "sfHashes"); + } + + { + auto const& expected = firstLedgerSequenceValue; + auto const actualOpt = entry.getFirstLedgerSequence(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfFirstLedgerSequence"); + EXPECT_TRUE(entry.hasFirstLedgerSequence()); + } + + { + auto const& expected = lastLedgerSequenceValue; + auto const actualOpt = entry.getLastLedgerSequence(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLastLedgerSequence"); + EXPECT_TRUE(entry.hasLastLedgerSequence()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(LedgerHashesTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const firstLedgerSequenceValue = canonical_UINT32(); + auto const lastLedgerSequenceValue = canonical_UINT32(); + auto const hashesValue = canonical_VECTOR256(); + + auto sle = std::make_shared(LedgerHashes::entryType, index); + + sle->at(sfFirstLedgerSequence) = firstLedgerSequenceValue; + sle->at(sfLastLedgerSequence) = lastLedgerSequenceValue; + sle->at(sfHashes) = hashesValue; + + LedgerHashesBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + LedgerHashes entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = hashesValue; + + auto const fromSle = entryFromSle.getHashes(); + auto const fromBuilder = entryFromBuilder.getHashes(); + + expectEqualField(expected, fromSle, "sfHashes"); + expectEqualField(expected, fromBuilder, "sfHashes"); + } + + { + auto const& expected = firstLedgerSequenceValue; + + auto const fromSleOpt = entryFromSle.getFirstLedgerSequence(); + auto const fromBuilderOpt = entryFromBuilder.getFirstLedgerSequence(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfFirstLedgerSequence"); + expectEqualField(expected, *fromBuilderOpt, "sfFirstLedgerSequence"); + } + + { + auto const& expected = lastLedgerSequenceValue; + + auto const fromSleOpt = entryFromSle.getLastLedgerSequence(); + auto const fromBuilderOpt = entryFromBuilder.getLastLedgerSequence(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLastLedgerSequence"); + expectEqualField(expected, *fromBuilderOpt, "sfLastLedgerSequence"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(LedgerHashesTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(LedgerHashes{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(LedgerHashesTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(LedgerHashesBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(LedgerHashesTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const hashesValue = canonical_VECTOR256(); + + LedgerHashesBuilder builder{ + hashesValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasFirstLedgerSequence()); + EXPECT_FALSE(entry.getFirstLedgerSequence().has_value()); + EXPECT_FALSE(entry.hasLastLedgerSequence()); + EXPECT_FALSE(entry.getLastLedgerSequence().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/LoanBrokerTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/LoanBrokerTests.cpp new file mode 100644 index 0000000000..fba8c539d2 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/LoanBrokerTests.cpp @@ -0,0 +1,530 @@ +// Auto-generated unit tests for ledger entry LoanBroker + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(LoanBrokerTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const vaultNodeValue = canonical_UINT64(); + auto const vaultIDValue = canonical_UINT256(); + auto const accountValue = canonical_ACCOUNT(); + auto const ownerValue = canonical_ACCOUNT(); + auto const loanSequenceValue = canonical_UINT32(); + auto const dataValue = canonical_VL(); + auto const managementFeeRateValue = canonical_UINT16(); + auto const ownerCountValue = canonical_UINT32(); + auto const debtTotalValue = canonical_NUMBER(); + auto const debtMaximumValue = canonical_NUMBER(); + auto const coverAvailableValue = canonical_NUMBER(); + auto const coverRateMinimumValue = canonical_UINT32(); + auto const coverRateLiquidationValue = canonical_UINT32(); + + LoanBrokerBuilder builder{ + previousTxnIDValue, + previousTxnLgrSeqValue, + sequenceValue, + ownerNodeValue, + vaultNodeValue, + vaultIDValue, + accountValue, + ownerValue, + loanSequenceValue + }; + + builder.setData(dataValue); + builder.setManagementFeeRate(managementFeeRateValue); + builder.setOwnerCount(ownerCountValue); + builder.setDebtTotal(debtTotalValue); + builder.setDebtMaximum(debtMaximumValue); + builder.setCoverAvailable(coverAvailableValue); + builder.setCoverRateMinimum(coverRateMinimumValue); + builder.setCoverRateLiquidation(coverRateLiquidationValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + auto const actual = entry.getSequence(); + expectEqualField(expected, actual, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = vaultNodeValue; + auto const actual = entry.getVaultNode(); + expectEqualField(expected, actual, "sfVaultNode"); + } + + { + auto const& expected = vaultIDValue; + auto const actual = entry.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = ownerValue; + auto const actual = entry.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = loanSequenceValue; + auto const actual = entry.getLoanSequence(); + expectEqualField(expected, actual, "sfLoanSequence"); + } + + { + auto const& expected = dataValue; + auto const actualOpt = entry.getData(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(entry.hasData()); + } + + { + auto const& expected = managementFeeRateValue; + auto const actualOpt = entry.getManagementFeeRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfManagementFeeRate"); + EXPECT_TRUE(entry.hasManagementFeeRate()); + } + + { + auto const& expected = ownerCountValue; + auto const actualOpt = entry.getOwnerCount(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfOwnerCount"); + EXPECT_TRUE(entry.hasOwnerCount()); + } + + { + auto const& expected = debtTotalValue; + auto const actualOpt = entry.getDebtTotal(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDebtTotal"); + EXPECT_TRUE(entry.hasDebtTotal()); + } + + { + auto const& expected = debtMaximumValue; + auto const actualOpt = entry.getDebtMaximum(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDebtMaximum"); + EXPECT_TRUE(entry.hasDebtMaximum()); + } + + { + auto const& expected = coverAvailableValue; + auto const actualOpt = entry.getCoverAvailable(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfCoverAvailable"); + EXPECT_TRUE(entry.hasCoverAvailable()); + } + + { + auto const& expected = coverRateMinimumValue; + auto const actualOpt = entry.getCoverRateMinimum(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfCoverRateMinimum"); + EXPECT_TRUE(entry.hasCoverRateMinimum()); + } + + { + auto const& expected = coverRateLiquidationValue; + auto const actualOpt = entry.getCoverRateLiquidation(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfCoverRateLiquidation"); + EXPECT_TRUE(entry.hasCoverRateLiquidation()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(LoanBrokerTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const vaultNodeValue = canonical_UINT64(); + auto const vaultIDValue = canonical_UINT256(); + auto const accountValue = canonical_ACCOUNT(); + auto const ownerValue = canonical_ACCOUNT(); + auto const loanSequenceValue = canonical_UINT32(); + auto const dataValue = canonical_VL(); + auto const managementFeeRateValue = canonical_UINT16(); + auto const ownerCountValue = canonical_UINT32(); + auto const debtTotalValue = canonical_NUMBER(); + auto const debtMaximumValue = canonical_NUMBER(); + auto const coverAvailableValue = canonical_NUMBER(); + auto const coverRateMinimumValue = canonical_UINT32(); + auto const coverRateLiquidationValue = canonical_UINT32(); + + auto sle = std::make_shared(LoanBroker::entryType, index); + + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfVaultNode) = vaultNodeValue; + sle->at(sfVaultID) = vaultIDValue; + sle->at(sfAccount) = accountValue; + sle->at(sfOwner) = ownerValue; + sle->at(sfLoanSequence) = loanSequenceValue; + sle->at(sfData) = dataValue; + sle->at(sfManagementFeeRate) = managementFeeRateValue; + sle->at(sfOwnerCount) = ownerCountValue; + sle->at(sfDebtTotal) = debtTotalValue; + sle->at(sfDebtMaximum) = debtMaximumValue; + sle->at(sfCoverAvailable) = coverAvailableValue; + sle->at(sfCoverRateMinimum) = coverRateMinimumValue; + sle->at(sfCoverRateLiquidation) = coverRateLiquidationValue; + + LoanBrokerBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + LoanBroker entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSle = entryFromSle.getSequence(); + auto const fromBuilder = entryFromBuilder.getSequence(); + + expectEqualField(expected, fromSle, "sfSequence"); + expectEqualField(expected, fromBuilder, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = vaultNodeValue; + + auto const fromSle = entryFromSle.getVaultNode(); + auto const fromBuilder = entryFromBuilder.getVaultNode(); + + expectEqualField(expected, fromSle, "sfVaultNode"); + expectEqualField(expected, fromBuilder, "sfVaultNode"); + } + + { + auto const& expected = vaultIDValue; + + auto const fromSle = entryFromSle.getVaultID(); + auto const fromBuilder = entryFromBuilder.getVaultID(); + + expectEqualField(expected, fromSle, "sfVaultID"); + expectEqualField(expected, fromBuilder, "sfVaultID"); + } + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = ownerValue; + + auto const fromSle = entryFromSle.getOwner(); + auto const fromBuilder = entryFromBuilder.getOwner(); + + expectEqualField(expected, fromSle, "sfOwner"); + expectEqualField(expected, fromBuilder, "sfOwner"); + } + + { + auto const& expected = loanSequenceValue; + + auto const fromSle = entryFromSle.getLoanSequence(); + auto const fromBuilder = entryFromBuilder.getLoanSequence(); + + expectEqualField(expected, fromSle, "sfLoanSequence"); + expectEqualField(expected, fromBuilder, "sfLoanSequence"); + } + + { + auto const& expected = dataValue; + + auto const fromSleOpt = entryFromSle.getData(); + auto const fromBuilderOpt = entryFromBuilder.getData(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfData"); + expectEqualField(expected, *fromBuilderOpt, "sfData"); + } + + { + auto const& expected = managementFeeRateValue; + + auto const fromSleOpt = entryFromSle.getManagementFeeRate(); + auto const fromBuilderOpt = entryFromBuilder.getManagementFeeRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfManagementFeeRate"); + expectEqualField(expected, *fromBuilderOpt, "sfManagementFeeRate"); + } + + { + auto const& expected = ownerCountValue; + + auto const fromSleOpt = entryFromSle.getOwnerCount(); + auto const fromBuilderOpt = entryFromBuilder.getOwnerCount(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfOwnerCount"); + expectEqualField(expected, *fromBuilderOpt, "sfOwnerCount"); + } + + { + auto const& expected = debtTotalValue; + + auto const fromSleOpt = entryFromSle.getDebtTotal(); + auto const fromBuilderOpt = entryFromBuilder.getDebtTotal(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDebtTotal"); + expectEqualField(expected, *fromBuilderOpt, "sfDebtTotal"); + } + + { + auto const& expected = debtMaximumValue; + + auto const fromSleOpt = entryFromSle.getDebtMaximum(); + auto const fromBuilderOpt = entryFromBuilder.getDebtMaximum(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDebtMaximum"); + expectEqualField(expected, *fromBuilderOpt, "sfDebtMaximum"); + } + + { + auto const& expected = coverAvailableValue; + + auto const fromSleOpt = entryFromSle.getCoverAvailable(); + auto const fromBuilderOpt = entryFromBuilder.getCoverAvailable(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfCoverAvailable"); + expectEqualField(expected, *fromBuilderOpt, "sfCoverAvailable"); + } + + { + auto const& expected = coverRateMinimumValue; + + auto const fromSleOpt = entryFromSle.getCoverRateMinimum(); + auto const fromBuilderOpt = entryFromBuilder.getCoverRateMinimum(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfCoverRateMinimum"); + expectEqualField(expected, *fromBuilderOpt, "sfCoverRateMinimum"); + } + + { + auto const& expected = coverRateLiquidationValue; + + auto const fromSleOpt = entryFromSle.getCoverRateLiquidation(); + auto const fromBuilderOpt = entryFromBuilder.getCoverRateLiquidation(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfCoverRateLiquidation"); + expectEqualField(expected, *fromBuilderOpt, "sfCoverRateLiquidation"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(LoanBrokerTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(LoanBroker{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(LoanBrokerTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(LoanBrokerBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(LoanBrokerTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const vaultNodeValue = canonical_UINT64(); + auto const vaultIDValue = canonical_UINT256(); + auto const accountValue = canonical_ACCOUNT(); + auto const ownerValue = canonical_ACCOUNT(); + auto const loanSequenceValue = canonical_UINT32(); + + LoanBrokerBuilder builder{ + previousTxnIDValue, + previousTxnLgrSeqValue, + sequenceValue, + ownerNodeValue, + vaultNodeValue, + vaultIDValue, + accountValue, + ownerValue, + loanSequenceValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasData()); + EXPECT_FALSE(entry.getData().has_value()); + EXPECT_FALSE(entry.hasManagementFeeRate()); + EXPECT_FALSE(entry.getManagementFeeRate().has_value()); + EXPECT_FALSE(entry.hasOwnerCount()); + EXPECT_FALSE(entry.getOwnerCount().has_value()); + EXPECT_FALSE(entry.hasDebtTotal()); + EXPECT_FALSE(entry.getDebtTotal().has_value()); + EXPECT_FALSE(entry.hasDebtMaximum()); + EXPECT_FALSE(entry.getDebtMaximum().has_value()); + EXPECT_FALSE(entry.hasCoverAvailable()); + EXPECT_FALSE(entry.getCoverAvailable().has_value()); + EXPECT_FALSE(entry.hasCoverRateMinimum()); + EXPECT_FALSE(entry.getCoverRateMinimum().has_value()); + EXPECT_FALSE(entry.hasCoverRateLiquidation()); + EXPECT_FALSE(entry.getCoverRateLiquidation().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/LoanTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/LoanTests.cpp new file mode 100644 index 0000000000..845a8337b9 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/LoanTests.cpp @@ -0,0 +1,795 @@ +// Auto-generated unit tests for ledger entry Loan + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(LoanTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const loanBrokerNodeValue = canonical_UINT64(); + auto const loanBrokerIDValue = canonical_UINT256(); + auto const loanSequenceValue = canonical_UINT32(); + auto const borrowerValue = canonical_ACCOUNT(); + auto const loanOriginationFeeValue = canonical_NUMBER(); + auto const loanServiceFeeValue = canonical_NUMBER(); + auto const latePaymentFeeValue = canonical_NUMBER(); + auto const closePaymentFeeValue = canonical_NUMBER(); + auto const overpaymentFeeValue = canonical_UINT32(); + auto const interestRateValue = canonical_UINT32(); + auto const lateInterestRateValue = canonical_UINT32(); + auto const closeInterestRateValue = canonical_UINT32(); + auto const overpaymentInterestRateValue = canonical_UINT32(); + auto const startDateValue = canonical_UINT32(); + auto const paymentIntervalValue = canonical_UINT32(); + auto const gracePeriodValue = canonical_UINT32(); + auto const previousPaymentDueDateValue = canonical_UINT32(); + auto const nextPaymentDueDateValue = canonical_UINT32(); + auto const paymentRemainingValue = canonical_UINT32(); + auto const periodicPaymentValue = canonical_NUMBER(); + auto const principalOutstandingValue = canonical_NUMBER(); + auto const totalValueOutstandingValue = canonical_NUMBER(); + auto const managementFeeOutstandingValue = canonical_NUMBER(); + auto const loanScaleValue = canonical_INT32(); + + LoanBuilder builder{ + previousTxnIDValue, + previousTxnLgrSeqValue, + ownerNodeValue, + loanBrokerNodeValue, + loanBrokerIDValue, + loanSequenceValue, + borrowerValue, + startDateValue, + paymentIntervalValue, + periodicPaymentValue + }; + + builder.setLoanOriginationFee(loanOriginationFeeValue); + builder.setLoanServiceFee(loanServiceFeeValue); + builder.setLatePaymentFee(latePaymentFeeValue); + builder.setClosePaymentFee(closePaymentFeeValue); + builder.setOverpaymentFee(overpaymentFeeValue); + builder.setInterestRate(interestRateValue); + builder.setLateInterestRate(lateInterestRateValue); + builder.setCloseInterestRate(closeInterestRateValue); + builder.setOverpaymentInterestRate(overpaymentInterestRateValue); + builder.setGracePeriod(gracePeriodValue); + builder.setPreviousPaymentDueDate(previousPaymentDueDateValue); + builder.setNextPaymentDueDate(nextPaymentDueDateValue); + builder.setPaymentRemaining(paymentRemainingValue); + builder.setPrincipalOutstanding(principalOutstandingValue); + builder.setTotalValueOutstanding(totalValueOutstandingValue); + builder.setManagementFeeOutstanding(managementFeeOutstandingValue); + builder.setLoanScale(loanScaleValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = loanBrokerNodeValue; + auto const actual = entry.getLoanBrokerNode(); + expectEqualField(expected, actual, "sfLoanBrokerNode"); + } + + { + auto const& expected = loanBrokerIDValue; + auto const actual = entry.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + { + auto const& expected = loanSequenceValue; + auto const actual = entry.getLoanSequence(); + expectEqualField(expected, actual, "sfLoanSequence"); + } + + { + auto const& expected = borrowerValue; + auto const actual = entry.getBorrower(); + expectEqualField(expected, actual, "sfBorrower"); + } + + { + auto const& expected = startDateValue; + auto const actual = entry.getStartDate(); + expectEqualField(expected, actual, "sfStartDate"); + } + + { + auto const& expected = paymentIntervalValue; + auto const actual = entry.getPaymentInterval(); + expectEqualField(expected, actual, "sfPaymentInterval"); + } + + { + auto const& expected = periodicPaymentValue; + auto const actual = entry.getPeriodicPayment(); + expectEqualField(expected, actual, "sfPeriodicPayment"); + } + + { + auto const& expected = loanOriginationFeeValue; + auto const actualOpt = entry.getLoanOriginationFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLoanOriginationFee"); + EXPECT_TRUE(entry.hasLoanOriginationFee()); + } + + { + auto const& expected = loanServiceFeeValue; + auto const actualOpt = entry.getLoanServiceFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLoanServiceFee"); + EXPECT_TRUE(entry.hasLoanServiceFee()); + } + + { + auto const& expected = latePaymentFeeValue; + auto const actualOpt = entry.getLatePaymentFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLatePaymentFee"); + EXPECT_TRUE(entry.hasLatePaymentFee()); + } + + { + auto const& expected = closePaymentFeeValue; + auto const actualOpt = entry.getClosePaymentFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfClosePaymentFee"); + EXPECT_TRUE(entry.hasClosePaymentFee()); + } + + { + auto const& expected = overpaymentFeeValue; + auto const actualOpt = entry.getOverpaymentFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfOverpaymentFee"); + EXPECT_TRUE(entry.hasOverpaymentFee()); + } + + { + auto const& expected = interestRateValue; + auto const actualOpt = entry.getInterestRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfInterestRate"); + EXPECT_TRUE(entry.hasInterestRate()); + } + + { + auto const& expected = lateInterestRateValue; + auto const actualOpt = entry.getLateInterestRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLateInterestRate"); + EXPECT_TRUE(entry.hasLateInterestRate()); + } + + { + auto const& expected = closeInterestRateValue; + auto const actualOpt = entry.getCloseInterestRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfCloseInterestRate"); + EXPECT_TRUE(entry.hasCloseInterestRate()); + } + + { + auto const& expected = overpaymentInterestRateValue; + auto const actualOpt = entry.getOverpaymentInterestRate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfOverpaymentInterestRate"); + EXPECT_TRUE(entry.hasOverpaymentInterestRate()); + } + + { + auto const& expected = gracePeriodValue; + auto const actualOpt = entry.getGracePeriod(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfGracePeriod"); + EXPECT_TRUE(entry.hasGracePeriod()); + } + + { + auto const& expected = previousPaymentDueDateValue; + auto const actualOpt = entry.getPreviousPaymentDueDate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousPaymentDueDate"); + EXPECT_TRUE(entry.hasPreviousPaymentDueDate()); + } + + { + auto const& expected = nextPaymentDueDateValue; + auto const actualOpt = entry.getNextPaymentDueDate(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfNextPaymentDueDate"); + EXPECT_TRUE(entry.hasNextPaymentDueDate()); + } + + { + auto const& expected = paymentRemainingValue; + auto const actualOpt = entry.getPaymentRemaining(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPaymentRemaining"); + EXPECT_TRUE(entry.hasPaymentRemaining()); + } + + { + auto const& expected = principalOutstandingValue; + auto const actualOpt = entry.getPrincipalOutstanding(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPrincipalOutstanding"); + EXPECT_TRUE(entry.hasPrincipalOutstanding()); + } + + { + auto const& expected = totalValueOutstandingValue; + auto const actualOpt = entry.getTotalValueOutstanding(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTotalValueOutstanding"); + EXPECT_TRUE(entry.hasTotalValueOutstanding()); + } + + { + auto const& expected = managementFeeOutstandingValue; + auto const actualOpt = entry.getManagementFeeOutstanding(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfManagementFeeOutstanding"); + EXPECT_TRUE(entry.hasManagementFeeOutstanding()); + } + + { + auto const& expected = loanScaleValue; + auto const actualOpt = entry.getLoanScale(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLoanScale"); + EXPECT_TRUE(entry.hasLoanScale()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(LoanTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const loanBrokerNodeValue = canonical_UINT64(); + auto const loanBrokerIDValue = canonical_UINT256(); + auto const loanSequenceValue = canonical_UINT32(); + auto const borrowerValue = canonical_ACCOUNT(); + auto const loanOriginationFeeValue = canonical_NUMBER(); + auto const loanServiceFeeValue = canonical_NUMBER(); + auto const latePaymentFeeValue = canonical_NUMBER(); + auto const closePaymentFeeValue = canonical_NUMBER(); + auto const overpaymentFeeValue = canonical_UINT32(); + auto const interestRateValue = canonical_UINT32(); + auto const lateInterestRateValue = canonical_UINT32(); + auto const closeInterestRateValue = canonical_UINT32(); + auto const overpaymentInterestRateValue = canonical_UINT32(); + auto const startDateValue = canonical_UINT32(); + auto const paymentIntervalValue = canonical_UINT32(); + auto const gracePeriodValue = canonical_UINT32(); + auto const previousPaymentDueDateValue = canonical_UINT32(); + auto const nextPaymentDueDateValue = canonical_UINT32(); + auto const paymentRemainingValue = canonical_UINT32(); + auto const periodicPaymentValue = canonical_NUMBER(); + auto const principalOutstandingValue = canonical_NUMBER(); + auto const totalValueOutstandingValue = canonical_NUMBER(); + auto const managementFeeOutstandingValue = canonical_NUMBER(); + auto const loanScaleValue = canonical_INT32(); + + auto sle = std::make_shared(Loan::entryType, index); + + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfLoanBrokerNode) = loanBrokerNodeValue; + sle->at(sfLoanBrokerID) = loanBrokerIDValue; + sle->at(sfLoanSequence) = loanSequenceValue; + sle->at(sfBorrower) = borrowerValue; + sle->at(sfLoanOriginationFee) = loanOriginationFeeValue; + sle->at(sfLoanServiceFee) = loanServiceFeeValue; + sle->at(sfLatePaymentFee) = latePaymentFeeValue; + sle->at(sfClosePaymentFee) = closePaymentFeeValue; + sle->at(sfOverpaymentFee) = overpaymentFeeValue; + sle->at(sfInterestRate) = interestRateValue; + sle->at(sfLateInterestRate) = lateInterestRateValue; + sle->at(sfCloseInterestRate) = closeInterestRateValue; + sle->at(sfOverpaymentInterestRate) = overpaymentInterestRateValue; + sle->at(sfStartDate) = startDateValue; + sle->at(sfPaymentInterval) = paymentIntervalValue; + sle->at(sfGracePeriod) = gracePeriodValue; + sle->at(sfPreviousPaymentDueDate) = previousPaymentDueDateValue; + sle->at(sfNextPaymentDueDate) = nextPaymentDueDateValue; + sle->at(sfPaymentRemaining) = paymentRemainingValue; + sle->at(sfPeriodicPayment) = periodicPaymentValue; + sle->at(sfPrincipalOutstanding) = principalOutstandingValue; + sle->at(sfTotalValueOutstanding) = totalValueOutstandingValue; + sle->at(sfManagementFeeOutstanding) = managementFeeOutstandingValue; + sle->at(sfLoanScale) = loanScaleValue; + + LoanBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Loan entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = loanBrokerNodeValue; + + auto const fromSle = entryFromSle.getLoanBrokerNode(); + auto const fromBuilder = entryFromBuilder.getLoanBrokerNode(); + + expectEqualField(expected, fromSle, "sfLoanBrokerNode"); + expectEqualField(expected, fromBuilder, "sfLoanBrokerNode"); + } + + { + auto const& expected = loanBrokerIDValue; + + auto const fromSle = entryFromSle.getLoanBrokerID(); + auto const fromBuilder = entryFromBuilder.getLoanBrokerID(); + + expectEqualField(expected, fromSle, "sfLoanBrokerID"); + expectEqualField(expected, fromBuilder, "sfLoanBrokerID"); + } + + { + auto const& expected = loanSequenceValue; + + auto const fromSle = entryFromSle.getLoanSequence(); + auto const fromBuilder = entryFromBuilder.getLoanSequence(); + + expectEqualField(expected, fromSle, "sfLoanSequence"); + expectEqualField(expected, fromBuilder, "sfLoanSequence"); + } + + { + auto const& expected = borrowerValue; + + auto const fromSle = entryFromSle.getBorrower(); + auto const fromBuilder = entryFromBuilder.getBorrower(); + + expectEqualField(expected, fromSle, "sfBorrower"); + expectEqualField(expected, fromBuilder, "sfBorrower"); + } + + { + auto const& expected = startDateValue; + + auto const fromSle = entryFromSle.getStartDate(); + auto const fromBuilder = entryFromBuilder.getStartDate(); + + expectEqualField(expected, fromSle, "sfStartDate"); + expectEqualField(expected, fromBuilder, "sfStartDate"); + } + + { + auto const& expected = paymentIntervalValue; + + auto const fromSle = entryFromSle.getPaymentInterval(); + auto const fromBuilder = entryFromBuilder.getPaymentInterval(); + + expectEqualField(expected, fromSle, "sfPaymentInterval"); + expectEqualField(expected, fromBuilder, "sfPaymentInterval"); + } + + { + auto const& expected = periodicPaymentValue; + + auto const fromSle = entryFromSle.getPeriodicPayment(); + auto const fromBuilder = entryFromBuilder.getPeriodicPayment(); + + expectEqualField(expected, fromSle, "sfPeriodicPayment"); + expectEqualField(expected, fromBuilder, "sfPeriodicPayment"); + } + + { + auto const& expected = loanOriginationFeeValue; + + auto const fromSleOpt = entryFromSle.getLoanOriginationFee(); + auto const fromBuilderOpt = entryFromBuilder.getLoanOriginationFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLoanOriginationFee"); + expectEqualField(expected, *fromBuilderOpt, "sfLoanOriginationFee"); + } + + { + auto const& expected = loanServiceFeeValue; + + auto const fromSleOpt = entryFromSle.getLoanServiceFee(); + auto const fromBuilderOpt = entryFromBuilder.getLoanServiceFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLoanServiceFee"); + expectEqualField(expected, *fromBuilderOpt, "sfLoanServiceFee"); + } + + { + auto const& expected = latePaymentFeeValue; + + auto const fromSleOpt = entryFromSle.getLatePaymentFee(); + auto const fromBuilderOpt = entryFromBuilder.getLatePaymentFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLatePaymentFee"); + expectEqualField(expected, *fromBuilderOpt, "sfLatePaymentFee"); + } + + { + auto const& expected = closePaymentFeeValue; + + auto const fromSleOpt = entryFromSle.getClosePaymentFee(); + auto const fromBuilderOpt = entryFromBuilder.getClosePaymentFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfClosePaymentFee"); + expectEqualField(expected, *fromBuilderOpt, "sfClosePaymentFee"); + } + + { + auto const& expected = overpaymentFeeValue; + + auto const fromSleOpt = entryFromSle.getOverpaymentFee(); + auto const fromBuilderOpt = entryFromBuilder.getOverpaymentFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfOverpaymentFee"); + expectEqualField(expected, *fromBuilderOpt, "sfOverpaymentFee"); + } + + { + auto const& expected = interestRateValue; + + auto const fromSleOpt = entryFromSle.getInterestRate(); + auto const fromBuilderOpt = entryFromBuilder.getInterestRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfInterestRate"); + expectEqualField(expected, *fromBuilderOpt, "sfInterestRate"); + } + + { + auto const& expected = lateInterestRateValue; + + auto const fromSleOpt = entryFromSle.getLateInterestRate(); + auto const fromBuilderOpt = entryFromBuilder.getLateInterestRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLateInterestRate"); + expectEqualField(expected, *fromBuilderOpt, "sfLateInterestRate"); + } + + { + auto const& expected = closeInterestRateValue; + + auto const fromSleOpt = entryFromSle.getCloseInterestRate(); + auto const fromBuilderOpt = entryFromBuilder.getCloseInterestRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfCloseInterestRate"); + expectEqualField(expected, *fromBuilderOpt, "sfCloseInterestRate"); + } + + { + auto const& expected = overpaymentInterestRateValue; + + auto const fromSleOpt = entryFromSle.getOverpaymentInterestRate(); + auto const fromBuilderOpt = entryFromBuilder.getOverpaymentInterestRate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfOverpaymentInterestRate"); + expectEqualField(expected, *fromBuilderOpt, "sfOverpaymentInterestRate"); + } + + { + auto const& expected = gracePeriodValue; + + auto const fromSleOpt = entryFromSle.getGracePeriod(); + auto const fromBuilderOpt = entryFromBuilder.getGracePeriod(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfGracePeriod"); + expectEqualField(expected, *fromBuilderOpt, "sfGracePeriod"); + } + + { + auto const& expected = previousPaymentDueDateValue; + + auto const fromSleOpt = entryFromSle.getPreviousPaymentDueDate(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousPaymentDueDate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousPaymentDueDate"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousPaymentDueDate"); + } + + { + auto const& expected = nextPaymentDueDateValue; + + auto const fromSleOpt = entryFromSle.getNextPaymentDueDate(); + auto const fromBuilderOpt = entryFromBuilder.getNextPaymentDueDate(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfNextPaymentDueDate"); + expectEqualField(expected, *fromBuilderOpt, "sfNextPaymentDueDate"); + } + + { + auto const& expected = paymentRemainingValue; + + auto const fromSleOpt = entryFromSle.getPaymentRemaining(); + auto const fromBuilderOpt = entryFromBuilder.getPaymentRemaining(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPaymentRemaining"); + expectEqualField(expected, *fromBuilderOpt, "sfPaymentRemaining"); + } + + { + auto const& expected = principalOutstandingValue; + + auto const fromSleOpt = entryFromSle.getPrincipalOutstanding(); + auto const fromBuilderOpt = entryFromBuilder.getPrincipalOutstanding(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPrincipalOutstanding"); + expectEqualField(expected, *fromBuilderOpt, "sfPrincipalOutstanding"); + } + + { + auto const& expected = totalValueOutstandingValue; + + auto const fromSleOpt = entryFromSle.getTotalValueOutstanding(); + auto const fromBuilderOpt = entryFromBuilder.getTotalValueOutstanding(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTotalValueOutstanding"); + expectEqualField(expected, *fromBuilderOpt, "sfTotalValueOutstanding"); + } + + { + auto const& expected = managementFeeOutstandingValue; + + auto const fromSleOpt = entryFromSle.getManagementFeeOutstanding(); + auto const fromBuilderOpt = entryFromBuilder.getManagementFeeOutstanding(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfManagementFeeOutstanding"); + expectEqualField(expected, *fromBuilderOpt, "sfManagementFeeOutstanding"); + } + + { + auto const& expected = loanScaleValue; + + auto const fromSleOpt = entryFromSle.getLoanScale(); + auto const fromBuilderOpt = entryFromBuilder.getLoanScale(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLoanScale"); + expectEqualField(expected, *fromBuilderOpt, "sfLoanScale"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(LoanTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Loan{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(LoanTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(LoanBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(LoanTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const loanBrokerNodeValue = canonical_UINT64(); + auto const loanBrokerIDValue = canonical_UINT256(); + auto const loanSequenceValue = canonical_UINT32(); + auto const borrowerValue = canonical_ACCOUNT(); + auto const startDateValue = canonical_UINT32(); + auto const paymentIntervalValue = canonical_UINT32(); + auto const periodicPaymentValue = canonical_NUMBER(); + + LoanBuilder builder{ + previousTxnIDValue, + previousTxnLgrSeqValue, + ownerNodeValue, + loanBrokerNodeValue, + loanBrokerIDValue, + loanSequenceValue, + borrowerValue, + startDateValue, + paymentIntervalValue, + periodicPaymentValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasLoanOriginationFee()); + EXPECT_FALSE(entry.getLoanOriginationFee().has_value()); + EXPECT_FALSE(entry.hasLoanServiceFee()); + EXPECT_FALSE(entry.getLoanServiceFee().has_value()); + EXPECT_FALSE(entry.hasLatePaymentFee()); + EXPECT_FALSE(entry.getLatePaymentFee().has_value()); + EXPECT_FALSE(entry.hasClosePaymentFee()); + EXPECT_FALSE(entry.getClosePaymentFee().has_value()); + EXPECT_FALSE(entry.hasOverpaymentFee()); + EXPECT_FALSE(entry.getOverpaymentFee().has_value()); + EXPECT_FALSE(entry.hasInterestRate()); + EXPECT_FALSE(entry.getInterestRate().has_value()); + EXPECT_FALSE(entry.hasLateInterestRate()); + EXPECT_FALSE(entry.getLateInterestRate().has_value()); + EXPECT_FALSE(entry.hasCloseInterestRate()); + EXPECT_FALSE(entry.getCloseInterestRate().has_value()); + EXPECT_FALSE(entry.hasOverpaymentInterestRate()); + EXPECT_FALSE(entry.getOverpaymentInterestRate().has_value()); + EXPECT_FALSE(entry.hasGracePeriod()); + EXPECT_FALSE(entry.getGracePeriod().has_value()); + EXPECT_FALSE(entry.hasPreviousPaymentDueDate()); + EXPECT_FALSE(entry.getPreviousPaymentDueDate().has_value()); + EXPECT_FALSE(entry.hasNextPaymentDueDate()); + EXPECT_FALSE(entry.getNextPaymentDueDate().has_value()); + EXPECT_FALSE(entry.hasPaymentRemaining()); + EXPECT_FALSE(entry.getPaymentRemaining().has_value()); + EXPECT_FALSE(entry.hasPrincipalOutstanding()); + EXPECT_FALSE(entry.getPrincipalOutstanding().has_value()); + EXPECT_FALSE(entry.hasTotalValueOutstanding()); + EXPECT_FALSE(entry.getTotalValueOutstanding().has_value()); + EXPECT_FALSE(entry.hasManagementFeeOutstanding()); + EXPECT_FALSE(entry.getManagementFeeOutstanding().has_value()); + EXPECT_FALSE(entry.hasLoanScale()); + EXPECT_FALSE(entry.getLoanScale().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenIssuanceTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenIssuanceTests.cpp new file mode 100644 index 0000000000..e74af94a5f --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenIssuanceTests.cpp @@ -0,0 +1,437 @@ +// Auto-generated unit tests for ledger entry MPTokenIssuance + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(MPTokenIssuanceTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const issuerValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const transferFeeValue = canonical_UINT16(); + auto const ownerNodeValue = canonical_UINT64(); + auto const assetScaleValue = canonical_UINT8(); + auto const maximumAmountValue = canonical_UINT64(); + auto const outstandingAmountValue = canonical_UINT64(); + auto const lockedAmountValue = canonical_UINT64(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + auto const mutableFlagsValue = canonical_UINT32(); + + MPTokenIssuanceBuilder builder{ + issuerValue, + sequenceValue, + ownerNodeValue, + outstandingAmountValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setTransferFee(transferFeeValue); + builder.setAssetScale(assetScaleValue); + builder.setMaximumAmount(maximumAmountValue); + builder.setLockedAmount(lockedAmountValue); + builder.setMPTokenMetadata(mPTokenMetadataValue); + builder.setDomainID(domainIDValue); + builder.setMutableFlags(mutableFlagsValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = issuerValue; + auto const actual = entry.getIssuer(); + expectEqualField(expected, actual, "sfIssuer"); + } + + { + auto const& expected = sequenceValue; + auto const actual = entry.getSequence(); + expectEqualField(expected, actual, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = outstandingAmountValue; + auto const actual = entry.getOutstandingAmount(); + expectEqualField(expected, actual, "sfOutstandingAmount"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = transferFeeValue; + auto const actualOpt = entry.getTransferFee(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfTransferFee"); + EXPECT_TRUE(entry.hasTransferFee()); + } + + { + auto const& expected = assetScaleValue; + auto const actualOpt = entry.getAssetScale(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAssetScale"); + EXPECT_TRUE(entry.hasAssetScale()); + } + + { + auto const& expected = maximumAmountValue; + auto const actualOpt = entry.getMaximumAmount(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMaximumAmount"); + EXPECT_TRUE(entry.hasMaximumAmount()); + } + + { + auto const& expected = lockedAmountValue; + auto const actualOpt = entry.getLockedAmount(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLockedAmount"); + EXPECT_TRUE(entry.hasLockedAmount()); + } + + { + auto const& expected = mPTokenMetadataValue; + auto const actualOpt = entry.getMPTokenMetadata(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMPTokenMetadata"); + EXPECT_TRUE(entry.hasMPTokenMetadata()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = entry.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(entry.hasDomainID()); + } + + { + auto const& expected = mutableFlagsValue; + auto const actualOpt = entry.getMutableFlags(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMutableFlags"); + EXPECT_TRUE(entry.hasMutableFlags()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(MPTokenIssuanceTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const issuerValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const transferFeeValue = canonical_UINT16(); + auto const ownerNodeValue = canonical_UINT64(); + auto const assetScaleValue = canonical_UINT8(); + auto const maximumAmountValue = canonical_UINT64(); + auto const outstandingAmountValue = canonical_UINT64(); + auto const lockedAmountValue = canonical_UINT64(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + auto const mutableFlagsValue = canonical_UINT32(); + + auto sle = std::make_shared(MPTokenIssuance::entryType, index); + + sle->at(sfIssuer) = issuerValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfTransferFee) = transferFeeValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfAssetScale) = assetScaleValue; + sle->at(sfMaximumAmount) = maximumAmountValue; + sle->at(sfOutstandingAmount) = outstandingAmountValue; + sle->at(sfLockedAmount) = lockedAmountValue; + sle->at(sfMPTokenMetadata) = mPTokenMetadataValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfDomainID) = domainIDValue; + sle->at(sfMutableFlags) = mutableFlagsValue; + + MPTokenIssuanceBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + MPTokenIssuance entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = issuerValue; + + auto const fromSle = entryFromSle.getIssuer(); + auto const fromBuilder = entryFromBuilder.getIssuer(); + + expectEqualField(expected, fromSle, "sfIssuer"); + expectEqualField(expected, fromBuilder, "sfIssuer"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSle = entryFromSle.getSequence(); + auto const fromBuilder = entryFromBuilder.getSequence(); + + expectEqualField(expected, fromSle, "sfSequence"); + expectEqualField(expected, fromBuilder, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = outstandingAmountValue; + + auto const fromSle = entryFromSle.getOutstandingAmount(); + auto const fromBuilder = entryFromBuilder.getOutstandingAmount(); + + expectEqualField(expected, fromSle, "sfOutstandingAmount"); + expectEqualField(expected, fromBuilder, "sfOutstandingAmount"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = transferFeeValue; + + auto const fromSleOpt = entryFromSle.getTransferFee(); + auto const fromBuilderOpt = entryFromBuilder.getTransferFee(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfTransferFee"); + expectEqualField(expected, *fromBuilderOpt, "sfTransferFee"); + } + + { + auto const& expected = assetScaleValue; + + auto const fromSleOpt = entryFromSle.getAssetScale(); + auto const fromBuilderOpt = entryFromBuilder.getAssetScale(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAssetScale"); + expectEqualField(expected, *fromBuilderOpt, "sfAssetScale"); + } + + { + auto const& expected = maximumAmountValue; + + auto const fromSleOpt = entryFromSle.getMaximumAmount(); + auto const fromBuilderOpt = entryFromBuilder.getMaximumAmount(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMaximumAmount"); + expectEqualField(expected, *fromBuilderOpt, "sfMaximumAmount"); + } + + { + auto const& expected = lockedAmountValue; + + auto const fromSleOpt = entryFromSle.getLockedAmount(); + auto const fromBuilderOpt = entryFromBuilder.getLockedAmount(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLockedAmount"); + expectEqualField(expected, *fromBuilderOpt, "sfLockedAmount"); + } + + { + auto const& expected = mPTokenMetadataValue; + + auto const fromSleOpt = entryFromSle.getMPTokenMetadata(); + auto const fromBuilderOpt = entryFromBuilder.getMPTokenMetadata(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMPTokenMetadata"); + expectEqualField(expected, *fromBuilderOpt, "sfMPTokenMetadata"); + } + + { + auto const& expected = domainIDValue; + + auto const fromSleOpt = entryFromSle.getDomainID(); + auto const fromBuilderOpt = entryFromBuilder.getDomainID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDomainID"); + expectEqualField(expected, *fromBuilderOpt, "sfDomainID"); + } + + { + auto const& expected = mutableFlagsValue; + + auto const fromSleOpt = entryFromSle.getMutableFlags(); + auto const fromBuilderOpt = entryFromBuilder.getMutableFlags(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMutableFlags"); + expectEqualField(expected, *fromBuilderOpt, "sfMutableFlags"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(MPTokenIssuanceTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(MPTokenIssuance{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(MPTokenIssuanceTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(MPTokenIssuanceBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(MPTokenIssuanceTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const issuerValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const outstandingAmountValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + MPTokenIssuanceBuilder builder{ + issuerValue, + sequenceValue, + ownerNodeValue, + outstandingAmountValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasTransferFee()); + EXPECT_FALSE(entry.getTransferFee().has_value()); + EXPECT_FALSE(entry.hasAssetScale()); + EXPECT_FALSE(entry.getAssetScale().has_value()); + EXPECT_FALSE(entry.hasMaximumAmount()); + EXPECT_FALSE(entry.getMaximumAmount().has_value()); + EXPECT_FALSE(entry.hasLockedAmount()); + EXPECT_FALSE(entry.getLockedAmount().has_value()); + EXPECT_FALSE(entry.hasMPTokenMetadata()); + EXPECT_FALSE(entry.getMPTokenMetadata().has_value()); + EXPECT_FALSE(entry.hasDomainID()); + EXPECT_FALSE(entry.getDomainID().has_value()); + EXPECT_FALSE(entry.hasMutableFlags()); + EXPECT_FALSE(entry.getMutableFlags().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenTests.cpp new file mode 100644 index 0000000000..c104e7b365 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/MPTokenTests.cpp @@ -0,0 +1,280 @@ +// Auto-generated unit tests for ledger entry MPToken + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(MPTokenTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + auto const mPTAmountValue = canonical_UINT64(); + auto const lockedAmountValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + MPTokenBuilder builder{ + accountValue, + mPTokenIssuanceIDValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setMPTAmount(mPTAmountValue); + builder.setLockedAmount(lockedAmountValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = mPTokenIssuanceIDValue; + auto const actual = entry.getMPTokenIssuanceID(); + expectEqualField(expected, actual, "sfMPTokenIssuanceID"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = mPTAmountValue; + auto const actualOpt = entry.getMPTAmount(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfMPTAmount"); + EXPECT_TRUE(entry.hasMPTAmount()); + } + + { + auto const& expected = lockedAmountValue; + auto const actualOpt = entry.getLockedAmount(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLockedAmount"); + EXPECT_TRUE(entry.hasLockedAmount()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(MPTokenTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + auto const mPTAmountValue = canonical_UINT64(); + auto const lockedAmountValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(MPToken::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfMPTokenIssuanceID) = mPTokenIssuanceIDValue; + sle->at(sfMPTAmount) = mPTAmountValue; + sle->at(sfLockedAmount) = lockedAmountValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + MPTokenBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + MPToken entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = mPTokenIssuanceIDValue; + + auto const fromSle = entryFromSle.getMPTokenIssuanceID(); + auto const fromBuilder = entryFromBuilder.getMPTokenIssuanceID(); + + expectEqualField(expected, fromSle, "sfMPTokenIssuanceID"); + expectEqualField(expected, fromBuilder, "sfMPTokenIssuanceID"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = mPTAmountValue; + + auto const fromSleOpt = entryFromSle.getMPTAmount(); + auto const fromBuilderOpt = entryFromBuilder.getMPTAmount(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfMPTAmount"); + expectEqualField(expected, *fromBuilderOpt, "sfMPTAmount"); + } + + { + auto const& expected = lockedAmountValue; + + auto const fromSleOpt = entryFromSle.getLockedAmount(); + auto const fromBuilderOpt = entryFromBuilder.getLockedAmount(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLockedAmount"); + expectEqualField(expected, *fromBuilderOpt, "sfLockedAmount"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(MPTokenTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(MPToken{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(MPTokenTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(MPTokenBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(MPTokenTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + MPTokenBuilder builder{ + accountValue, + mPTokenIssuanceIDValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasMPTAmount()); + EXPECT_FALSE(entry.getMPTAmount().has_value()); + EXPECT_FALSE(entry.hasLockedAmount()); + EXPECT_FALSE(entry.getLockedAmount().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenOfferTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenOfferTests.cpp new file mode 100644 index 0000000000..9d039b2c38 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenOfferTests.cpp @@ -0,0 +1,324 @@ +// Auto-generated unit tests for ledger entry NFTokenOffer + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(NFTokenOfferTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const nFTokenIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const nFTokenOfferNodeValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + auto const expirationValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + NFTokenOfferBuilder builder{ + ownerValue, + nFTokenIDValue, + amountValue, + ownerNodeValue, + nFTokenOfferNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setDestination(destinationValue); + builder.setExpiration(expirationValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = ownerValue; + auto const actual = entry.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = nFTokenIDValue; + auto const actual = entry.getNFTokenID(); + expectEqualField(expected, actual, "sfNFTokenID"); + } + + { + auto const& expected = amountValue; + auto const actual = entry.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = nFTokenOfferNodeValue; + auto const actual = entry.getNFTokenOfferNode(); + expectEqualField(expected, actual, "sfNFTokenOfferNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = destinationValue; + auto const actualOpt = entry.getDestination(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDestination"); + EXPECT_TRUE(entry.hasDestination()); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = entry.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(entry.hasExpiration()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(NFTokenOfferTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const nFTokenIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const nFTokenOfferNodeValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + auto const expirationValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(NFTokenOffer::entryType, index); + + sle->at(sfOwner) = ownerValue; + sle->at(sfNFTokenID) = nFTokenIDValue; + sle->at(sfAmount) = amountValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfNFTokenOfferNode) = nFTokenOfferNodeValue; + sle->at(sfDestination) = destinationValue; + sle->at(sfExpiration) = expirationValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + NFTokenOfferBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + NFTokenOffer entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = ownerValue; + + auto const fromSle = entryFromSle.getOwner(); + auto const fromBuilder = entryFromBuilder.getOwner(); + + expectEqualField(expected, fromSle, "sfOwner"); + expectEqualField(expected, fromBuilder, "sfOwner"); + } + + { + auto const& expected = nFTokenIDValue; + + auto const fromSle = entryFromSle.getNFTokenID(); + auto const fromBuilder = entryFromBuilder.getNFTokenID(); + + expectEqualField(expected, fromSle, "sfNFTokenID"); + expectEqualField(expected, fromBuilder, "sfNFTokenID"); + } + + { + auto const& expected = amountValue; + + auto const fromSle = entryFromSle.getAmount(); + auto const fromBuilder = entryFromBuilder.getAmount(); + + expectEqualField(expected, fromSle, "sfAmount"); + expectEqualField(expected, fromBuilder, "sfAmount"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = nFTokenOfferNodeValue; + + auto const fromSle = entryFromSle.getNFTokenOfferNode(); + auto const fromBuilder = entryFromBuilder.getNFTokenOfferNode(); + + expectEqualField(expected, fromSle, "sfNFTokenOfferNode"); + expectEqualField(expected, fromBuilder, "sfNFTokenOfferNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = destinationValue; + + auto const fromSleOpt = entryFromSle.getDestination(); + auto const fromBuilderOpt = entryFromBuilder.getDestination(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDestination"); + expectEqualField(expected, *fromBuilderOpt, "sfDestination"); + } + + { + auto const& expected = expirationValue; + + auto const fromSleOpt = entryFromSle.getExpiration(); + auto const fromBuilderOpt = entryFromBuilder.getExpiration(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfExpiration"); + expectEqualField(expected, *fromBuilderOpt, "sfExpiration"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(NFTokenOfferTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(NFTokenOffer{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(NFTokenOfferTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(NFTokenOfferBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(NFTokenOfferTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const nFTokenIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const nFTokenOfferNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + NFTokenOfferBuilder builder{ + ownerValue, + nFTokenIDValue, + amountValue, + ownerNodeValue, + nFTokenOfferNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasDestination()); + EXPECT_FALSE(entry.getDestination().has_value()); + EXPECT_FALSE(entry.hasExpiration()); + EXPECT_FALSE(entry.getExpiration().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenPageTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenPageTests.cpp new file mode 100644 index 0000000000..5909050169 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/NFTokenPageTests.cpp @@ -0,0 +1,236 @@ +// Auto-generated unit tests for ledger entry NFTokenPage + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(NFTokenPageTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const previousPageMinValue = canonical_UINT256(); + auto const nextPageMinValue = canonical_UINT256(); + auto const nFTokensValue = canonical_ARRAY(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + NFTokenPageBuilder builder{ + nFTokensValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setPreviousPageMin(previousPageMinValue); + builder.setNextPageMin(nextPageMinValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = nFTokensValue; + auto const actual = entry.getNFTokens(); + expectEqualField(expected, actual, "sfNFTokens"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = previousPageMinValue; + auto const actualOpt = entry.getPreviousPageMin(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousPageMin"); + EXPECT_TRUE(entry.hasPreviousPageMin()); + } + + { + auto const& expected = nextPageMinValue; + auto const actualOpt = entry.getNextPageMin(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfNextPageMin"); + EXPECT_TRUE(entry.hasNextPageMin()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(NFTokenPageTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const previousPageMinValue = canonical_UINT256(); + auto const nextPageMinValue = canonical_UINT256(); + auto const nFTokensValue = canonical_ARRAY(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(NFTokenPage::entryType, index); + + sle->at(sfPreviousPageMin) = previousPageMinValue; + sle->at(sfNextPageMin) = nextPageMinValue; + sle->setFieldArray(sfNFTokens, nFTokensValue); + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + NFTokenPageBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + NFTokenPage entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = nFTokensValue; + + auto const fromSle = entryFromSle.getNFTokens(); + auto const fromBuilder = entryFromBuilder.getNFTokens(); + + expectEqualField(expected, fromSle, "sfNFTokens"); + expectEqualField(expected, fromBuilder, "sfNFTokens"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = previousPageMinValue; + + auto const fromSleOpt = entryFromSle.getPreviousPageMin(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousPageMin(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousPageMin"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousPageMin"); + } + + { + auto const& expected = nextPageMinValue; + + auto const fromSleOpt = entryFromSle.getNextPageMin(); + auto const fromBuilderOpt = entryFromBuilder.getNextPageMin(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfNextPageMin"); + expectEqualField(expected, *fromBuilderOpt, "sfNextPageMin"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(NFTokenPageTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(NFTokenPage{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(NFTokenPageTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(NFTokenPageBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(NFTokenPageTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const nFTokensValue = canonical_ARRAY(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + NFTokenPageBuilder builder{ + nFTokensValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasPreviousPageMin()); + EXPECT_FALSE(entry.getPreviousPageMin().has_value()); + EXPECT_FALSE(entry.hasNextPageMin()); + EXPECT_FALSE(entry.getNextPageMin().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/NegativeUNLTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/NegativeUNLTests.cpp new file mode 100644 index 0000000000..48ff060c11 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/NegativeUNLTests.cpp @@ -0,0 +1,251 @@ +// Auto-generated unit tests for ledger entry NegativeUNL + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(NegativeUNLTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const disabledValidatorsValue = canonical_ARRAY(); + auto const validatorToDisableValue = canonical_VL(); + auto const validatorToReEnableValue = canonical_VL(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + NegativeUNLBuilder builder{ + }; + + builder.setDisabledValidators(disabledValidatorsValue); + builder.setValidatorToDisable(validatorToDisableValue); + builder.setValidatorToReEnable(validatorToReEnableValue); + builder.setPreviousTxnID(previousTxnIDValue); + builder.setPreviousTxnLgrSeq(previousTxnLgrSeqValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = disabledValidatorsValue; + auto const actualOpt = entry.getDisabledValidators(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDisabledValidators"); + EXPECT_TRUE(entry.hasDisabledValidators()); + } + + { + auto const& expected = validatorToDisableValue; + auto const actualOpt = entry.getValidatorToDisable(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfValidatorToDisable"); + EXPECT_TRUE(entry.hasValidatorToDisable()); + } + + { + auto const& expected = validatorToReEnableValue; + auto const actualOpt = entry.getValidatorToReEnable(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfValidatorToReEnable"); + EXPECT_TRUE(entry.hasValidatorToReEnable()); + } + + { + auto const& expected = previousTxnIDValue; + auto const actualOpt = entry.getPreviousTxnID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnID"); + EXPECT_TRUE(entry.hasPreviousTxnID()); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actualOpt = entry.getPreviousTxnLgrSeq(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfPreviousTxnLgrSeq"); + EXPECT_TRUE(entry.hasPreviousTxnLgrSeq()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(NegativeUNLTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const disabledValidatorsValue = canonical_ARRAY(); + auto const validatorToDisableValue = canonical_VL(); + auto const validatorToReEnableValue = canonical_VL(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(NegativeUNL::entryType, index); + + sle->setFieldArray(sfDisabledValidators, disabledValidatorsValue); + sle->at(sfValidatorToDisable) = validatorToDisableValue; + sle->at(sfValidatorToReEnable) = validatorToReEnableValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + NegativeUNLBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + NegativeUNL entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = disabledValidatorsValue; + + auto const fromSleOpt = entryFromSle.getDisabledValidators(); + auto const fromBuilderOpt = entryFromBuilder.getDisabledValidators(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDisabledValidators"); + expectEqualField(expected, *fromBuilderOpt, "sfDisabledValidators"); + } + + { + auto const& expected = validatorToDisableValue; + + auto const fromSleOpt = entryFromSle.getValidatorToDisable(); + auto const fromBuilderOpt = entryFromBuilder.getValidatorToDisable(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfValidatorToDisable"); + expectEqualField(expected, *fromBuilderOpt, "sfValidatorToDisable"); + } + + { + auto const& expected = validatorToReEnableValue; + + auto const fromSleOpt = entryFromSle.getValidatorToReEnable(); + auto const fromBuilderOpt = entryFromBuilder.getValidatorToReEnable(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfValidatorToReEnable"); + expectEqualField(expected, *fromBuilderOpt, "sfValidatorToReEnable"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnID(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnID"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSleOpt = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilderOpt = entryFromBuilder.getPreviousTxnLgrSeq(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, *fromBuilderOpt, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(NegativeUNLTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(NegativeUNL{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(NegativeUNLTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(NegativeUNLBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(NegativeUNLTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + + NegativeUNLBuilder builder{ + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasDisabledValidators()); + EXPECT_FALSE(entry.getDisabledValidators().has_value()); + EXPECT_FALSE(entry.hasValidatorToDisable()); + EXPECT_FALSE(entry.getValidatorToDisable().has_value()); + EXPECT_FALSE(entry.hasValidatorToReEnable()); + EXPECT_FALSE(entry.getValidatorToReEnable().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnID()); + EXPECT_FALSE(entry.getPreviousTxnID().has_value()); + EXPECT_FALSE(entry.hasPreviousTxnLgrSeq()); + EXPECT_FALSE(entry.getPreviousTxnLgrSeq().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/OfferTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/OfferTests.cpp new file mode 100644 index 0000000000..5cb1bbd804 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/OfferTests.cpp @@ -0,0 +1,395 @@ +// Auto-generated unit tests for ledger entry Offer + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(OfferTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const takerPaysValue = canonical_AMOUNT(); + auto const takerGetsValue = canonical_AMOUNT(); + auto const bookDirectoryValue = canonical_UINT256(); + auto const bookNodeValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const expirationValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + auto const additionalBooksValue = canonical_ARRAY(); + + OfferBuilder builder{ + accountValue, + sequenceValue, + takerPaysValue, + takerGetsValue, + bookDirectoryValue, + bookNodeValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setExpiration(expirationValue); + builder.setDomainID(domainIDValue); + builder.setAdditionalBooks(additionalBooksValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = sequenceValue; + auto const actual = entry.getSequence(); + expectEqualField(expected, actual, "sfSequence"); + } + + { + auto const& expected = takerPaysValue; + auto const actual = entry.getTakerPays(); + expectEqualField(expected, actual, "sfTakerPays"); + } + + { + auto const& expected = takerGetsValue; + auto const actual = entry.getTakerGets(); + expectEqualField(expected, actual, "sfTakerGets"); + } + + { + auto const& expected = bookDirectoryValue; + auto const actual = entry.getBookDirectory(); + expectEqualField(expected, actual, "sfBookDirectory"); + } + + { + auto const& expected = bookNodeValue; + auto const actual = entry.getBookNode(); + expectEqualField(expected, actual, "sfBookNode"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = entry.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(entry.hasExpiration()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = entry.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(entry.hasDomainID()); + } + + { + auto const& expected = additionalBooksValue; + auto const actualOpt = entry.getAdditionalBooks(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAdditionalBooks"); + EXPECT_TRUE(entry.hasAdditionalBooks()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(OfferTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const takerPaysValue = canonical_AMOUNT(); + auto const takerGetsValue = canonical_AMOUNT(); + auto const bookDirectoryValue = canonical_UINT256(); + auto const bookNodeValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const expirationValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + auto const additionalBooksValue = canonical_ARRAY(); + + auto sle = std::make_shared(Offer::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfTakerPays) = takerPaysValue; + sle->at(sfTakerGets) = takerGetsValue; + sle->at(sfBookDirectory) = bookDirectoryValue; + sle->at(sfBookNode) = bookNodeValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfExpiration) = expirationValue; + sle->at(sfDomainID) = domainIDValue; + sle->setFieldArray(sfAdditionalBooks, additionalBooksValue); + + OfferBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Offer entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSle = entryFromSle.getSequence(); + auto const fromBuilder = entryFromBuilder.getSequence(); + + expectEqualField(expected, fromSle, "sfSequence"); + expectEqualField(expected, fromBuilder, "sfSequence"); + } + + { + auto const& expected = takerPaysValue; + + auto const fromSle = entryFromSle.getTakerPays(); + auto const fromBuilder = entryFromBuilder.getTakerPays(); + + expectEqualField(expected, fromSle, "sfTakerPays"); + expectEqualField(expected, fromBuilder, "sfTakerPays"); + } + + { + auto const& expected = takerGetsValue; + + auto const fromSle = entryFromSle.getTakerGets(); + auto const fromBuilder = entryFromBuilder.getTakerGets(); + + expectEqualField(expected, fromSle, "sfTakerGets"); + expectEqualField(expected, fromBuilder, "sfTakerGets"); + } + + { + auto const& expected = bookDirectoryValue; + + auto const fromSle = entryFromSle.getBookDirectory(); + auto const fromBuilder = entryFromBuilder.getBookDirectory(); + + expectEqualField(expected, fromSle, "sfBookDirectory"); + expectEqualField(expected, fromBuilder, "sfBookDirectory"); + } + + { + auto const& expected = bookNodeValue; + + auto const fromSle = entryFromSle.getBookNode(); + auto const fromBuilder = entryFromBuilder.getBookNode(); + + expectEqualField(expected, fromSle, "sfBookNode"); + expectEqualField(expected, fromBuilder, "sfBookNode"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = expirationValue; + + auto const fromSleOpt = entryFromSle.getExpiration(); + auto const fromBuilderOpt = entryFromBuilder.getExpiration(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfExpiration"); + expectEqualField(expected, *fromBuilderOpt, "sfExpiration"); + } + + { + auto const& expected = domainIDValue; + + auto const fromSleOpt = entryFromSle.getDomainID(); + auto const fromBuilderOpt = entryFromBuilder.getDomainID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDomainID"); + expectEqualField(expected, *fromBuilderOpt, "sfDomainID"); + } + + { + auto const& expected = additionalBooksValue; + + auto const fromSleOpt = entryFromSle.getAdditionalBooks(); + auto const fromBuilderOpt = entryFromBuilder.getAdditionalBooks(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAdditionalBooks"); + expectEqualField(expected, *fromBuilderOpt, "sfAdditionalBooks"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(OfferTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Offer{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(OfferTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(OfferBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(OfferTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const takerPaysValue = canonical_AMOUNT(); + auto const takerGetsValue = canonical_AMOUNT(); + auto const bookDirectoryValue = canonical_UINT256(); + auto const bookNodeValue = canonical_UINT64(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + OfferBuilder builder{ + accountValue, + sequenceValue, + takerPaysValue, + takerGetsValue, + bookDirectoryValue, + bookNodeValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasExpiration()); + EXPECT_FALSE(entry.getExpiration().has_value()); + EXPECT_FALSE(entry.hasDomainID()); + EXPECT_FALSE(entry.getDomainID().has_value()); + EXPECT_FALSE(entry.hasAdditionalBooks()); + EXPECT_FALSE(entry.getAdditionalBooks().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/OracleTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/OracleTests.cpp new file mode 100644 index 0000000000..837fd576bf --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/OracleTests.cpp @@ -0,0 +1,346 @@ +// Auto-generated unit tests for ledger entry Oracle + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(OracleTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const oracleDocumentIDValue = canonical_UINT32(); + auto const providerValue = canonical_VL(); + auto const priceDataSeriesValue = canonical_ARRAY(); + auto const assetClassValue = canonical_VL(); + auto const lastUpdateTimeValue = canonical_UINT32(); + auto const uRIValue = canonical_VL(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + OracleBuilder builder{ + ownerValue, + providerValue, + priceDataSeriesValue, + assetClassValue, + lastUpdateTimeValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setOracleDocumentID(oracleDocumentIDValue); + builder.setURI(uRIValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = ownerValue; + auto const actual = entry.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = providerValue; + auto const actual = entry.getProvider(); + expectEqualField(expected, actual, "sfProvider"); + } + + { + auto const& expected = priceDataSeriesValue; + auto const actual = entry.getPriceDataSeries(); + expectEqualField(expected, actual, "sfPriceDataSeries"); + } + + { + auto const& expected = assetClassValue; + auto const actual = entry.getAssetClass(); + expectEqualField(expected, actual, "sfAssetClass"); + } + + { + auto const& expected = lastUpdateTimeValue; + auto const actual = entry.getLastUpdateTime(); + expectEqualField(expected, actual, "sfLastUpdateTime"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = oracleDocumentIDValue; + auto const actualOpt = entry.getOracleDocumentID(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfOracleDocumentID"); + EXPECT_TRUE(entry.hasOracleDocumentID()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = entry.getURI(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(entry.hasURI()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(OracleTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const oracleDocumentIDValue = canonical_UINT32(); + auto const providerValue = canonical_VL(); + auto const priceDataSeriesValue = canonical_ARRAY(); + auto const assetClassValue = canonical_VL(); + auto const lastUpdateTimeValue = canonical_UINT32(); + auto const uRIValue = canonical_VL(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(Oracle::entryType, index); + + sle->at(sfOwner) = ownerValue; + sle->at(sfOracleDocumentID) = oracleDocumentIDValue; + sle->at(sfProvider) = providerValue; + sle->setFieldArray(sfPriceDataSeries, priceDataSeriesValue); + sle->at(sfAssetClass) = assetClassValue; + sle->at(sfLastUpdateTime) = lastUpdateTimeValue; + sle->at(sfURI) = uRIValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + OracleBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Oracle entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = ownerValue; + + auto const fromSle = entryFromSle.getOwner(); + auto const fromBuilder = entryFromBuilder.getOwner(); + + expectEqualField(expected, fromSle, "sfOwner"); + expectEqualField(expected, fromBuilder, "sfOwner"); + } + + { + auto const& expected = providerValue; + + auto const fromSle = entryFromSle.getProvider(); + auto const fromBuilder = entryFromBuilder.getProvider(); + + expectEqualField(expected, fromSle, "sfProvider"); + expectEqualField(expected, fromBuilder, "sfProvider"); + } + + { + auto const& expected = priceDataSeriesValue; + + auto const fromSle = entryFromSle.getPriceDataSeries(); + auto const fromBuilder = entryFromBuilder.getPriceDataSeries(); + + expectEqualField(expected, fromSle, "sfPriceDataSeries"); + expectEqualField(expected, fromBuilder, "sfPriceDataSeries"); + } + + { + auto const& expected = assetClassValue; + + auto const fromSle = entryFromSle.getAssetClass(); + auto const fromBuilder = entryFromBuilder.getAssetClass(); + + expectEqualField(expected, fromSle, "sfAssetClass"); + expectEqualField(expected, fromBuilder, "sfAssetClass"); + } + + { + auto const& expected = lastUpdateTimeValue; + + auto const fromSle = entryFromSle.getLastUpdateTime(); + auto const fromBuilder = entryFromBuilder.getLastUpdateTime(); + + expectEqualField(expected, fromSle, "sfLastUpdateTime"); + expectEqualField(expected, fromBuilder, "sfLastUpdateTime"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = oracleDocumentIDValue; + + auto const fromSleOpt = entryFromSle.getOracleDocumentID(); + auto const fromBuilderOpt = entryFromBuilder.getOracleDocumentID(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfOracleDocumentID"); + expectEqualField(expected, *fromBuilderOpt, "sfOracleDocumentID"); + } + + { + auto const& expected = uRIValue; + + auto const fromSleOpt = entryFromSle.getURI(); + auto const fromBuilderOpt = entryFromBuilder.getURI(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfURI"); + expectEqualField(expected, *fromBuilderOpt, "sfURI"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(OracleTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Oracle{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(OracleTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(OracleBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(OracleTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const providerValue = canonical_VL(); + auto const priceDataSeriesValue = canonical_ARRAY(); + auto const assetClassValue = canonical_VL(); + auto const lastUpdateTimeValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + OracleBuilder builder{ + ownerValue, + providerValue, + priceDataSeriesValue, + assetClassValue, + lastUpdateTimeValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasOracleDocumentID()); + EXPECT_FALSE(entry.getOracleDocumentID().has_value()); + EXPECT_FALSE(entry.hasURI()); + EXPECT_FALSE(entry.getURI().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/PayChannelTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/PayChannelTests.cpp new file mode 100644 index 0000000000..7c31252369 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/PayChannelTests.cpp @@ -0,0 +1,476 @@ +// Auto-generated unit tests for ledger entry PayChannel + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(PayChannelTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const amountValue = canonical_AMOUNT(); + auto const balanceValue = canonical_AMOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const settleDelayValue = canonical_UINT32(); + auto const expirationValue = canonical_UINT32(); + auto const cancelAfterValue = canonical_UINT32(); + auto const sourceTagValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const destinationNodeValue = canonical_UINT64(); + + PayChannelBuilder builder{ + accountValue, + destinationValue, + amountValue, + balanceValue, + publicKeyValue, + settleDelayValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setSequence(sequenceValue); + builder.setExpiration(expirationValue); + builder.setCancelAfter(cancelAfterValue); + builder.setSourceTag(sourceTagValue); + builder.setDestinationTag(destinationTagValue); + builder.setDestinationNode(destinationNodeValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = destinationValue; + auto const actual = entry.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = entry.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = balanceValue; + auto const actual = entry.getBalance(); + expectEqualField(expected, actual, "sfBalance"); + } + + { + auto const& expected = publicKeyValue; + auto const actual = entry.getPublicKey(); + expectEqualField(expected, actual, "sfPublicKey"); + } + + { + auto const& expected = settleDelayValue; + auto const actual = entry.getSettleDelay(); + expectEqualField(expected, actual, "sfSettleDelay"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + auto const actualOpt = entry.getSequence(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfSequence"); + EXPECT_TRUE(entry.hasSequence()); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = entry.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(entry.hasExpiration()); + } + + { + auto const& expected = cancelAfterValue; + auto const actualOpt = entry.getCancelAfter(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfCancelAfter"); + EXPECT_TRUE(entry.hasCancelAfter()); + } + + { + auto const& expected = sourceTagValue; + auto const actualOpt = entry.getSourceTag(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfSourceTag"); + EXPECT_TRUE(entry.hasSourceTag()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = entry.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(entry.hasDestinationTag()); + } + + { + auto const& expected = destinationNodeValue; + auto const actualOpt = entry.getDestinationNode(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfDestinationNode"); + EXPECT_TRUE(entry.hasDestinationNode()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(PayChannelTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const amountValue = canonical_AMOUNT(); + auto const balanceValue = canonical_AMOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const settleDelayValue = canonical_UINT32(); + auto const expirationValue = canonical_UINT32(); + auto const cancelAfterValue = canonical_UINT32(); + auto const sourceTagValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const destinationNodeValue = canonical_UINT64(); + + auto sle = std::make_shared(PayChannel::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfDestination) = destinationValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfAmount) = amountValue; + sle->at(sfBalance) = balanceValue; + sle->at(sfPublicKey) = publicKeyValue; + sle->at(sfSettleDelay) = settleDelayValue; + sle->at(sfExpiration) = expirationValue; + sle->at(sfCancelAfter) = cancelAfterValue; + sle->at(sfSourceTag) = sourceTagValue; + sle->at(sfDestinationTag) = destinationTagValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfDestinationNode) = destinationNodeValue; + + PayChannelBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + PayChannel entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = destinationValue; + + auto const fromSle = entryFromSle.getDestination(); + auto const fromBuilder = entryFromBuilder.getDestination(); + + expectEqualField(expected, fromSle, "sfDestination"); + expectEqualField(expected, fromBuilder, "sfDestination"); + } + + { + auto const& expected = amountValue; + + auto const fromSle = entryFromSle.getAmount(); + auto const fromBuilder = entryFromBuilder.getAmount(); + + expectEqualField(expected, fromSle, "sfAmount"); + expectEqualField(expected, fromBuilder, "sfAmount"); + } + + { + auto const& expected = balanceValue; + + auto const fromSle = entryFromSle.getBalance(); + auto const fromBuilder = entryFromBuilder.getBalance(); + + expectEqualField(expected, fromSle, "sfBalance"); + expectEqualField(expected, fromBuilder, "sfBalance"); + } + + { + auto const& expected = publicKeyValue; + + auto const fromSle = entryFromSle.getPublicKey(); + auto const fromBuilder = entryFromBuilder.getPublicKey(); + + expectEqualField(expected, fromSle, "sfPublicKey"); + expectEqualField(expected, fromBuilder, "sfPublicKey"); + } + + { + auto const& expected = settleDelayValue; + + auto const fromSle = entryFromSle.getSettleDelay(); + auto const fromBuilder = entryFromBuilder.getSettleDelay(); + + expectEqualField(expected, fromSle, "sfSettleDelay"); + expectEqualField(expected, fromBuilder, "sfSettleDelay"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSleOpt = entryFromSle.getSequence(); + auto const fromBuilderOpt = entryFromBuilder.getSequence(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfSequence"); + expectEqualField(expected, *fromBuilderOpt, "sfSequence"); + } + + { + auto const& expected = expirationValue; + + auto const fromSleOpt = entryFromSle.getExpiration(); + auto const fromBuilderOpt = entryFromBuilder.getExpiration(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfExpiration"); + expectEqualField(expected, *fromBuilderOpt, "sfExpiration"); + } + + { + auto const& expected = cancelAfterValue; + + auto const fromSleOpt = entryFromSle.getCancelAfter(); + auto const fromBuilderOpt = entryFromBuilder.getCancelAfter(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfCancelAfter"); + expectEqualField(expected, *fromBuilderOpt, "sfCancelAfter"); + } + + { + auto const& expected = sourceTagValue; + + auto const fromSleOpt = entryFromSle.getSourceTag(); + auto const fromBuilderOpt = entryFromBuilder.getSourceTag(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfSourceTag"); + expectEqualField(expected, *fromBuilderOpt, "sfSourceTag"); + } + + { + auto const& expected = destinationTagValue; + + auto const fromSleOpt = entryFromSle.getDestinationTag(); + auto const fromBuilderOpt = entryFromBuilder.getDestinationTag(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDestinationTag"); + expectEqualField(expected, *fromBuilderOpt, "sfDestinationTag"); + } + + { + auto const& expected = destinationNodeValue; + + auto const fromSleOpt = entryFromSle.getDestinationNode(); + auto const fromBuilderOpt = entryFromBuilder.getDestinationNode(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfDestinationNode"); + expectEqualField(expected, *fromBuilderOpt, "sfDestinationNode"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(PayChannelTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(PayChannel{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(PayChannelTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(PayChannelBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(PayChannelTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const balanceValue = canonical_AMOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const settleDelayValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + PayChannelBuilder builder{ + accountValue, + destinationValue, + amountValue, + balanceValue, + publicKeyValue, + settleDelayValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasSequence()); + EXPECT_FALSE(entry.getSequence().has_value()); + EXPECT_FALSE(entry.hasExpiration()); + EXPECT_FALSE(entry.getExpiration().has_value()); + EXPECT_FALSE(entry.hasCancelAfter()); + EXPECT_FALSE(entry.getCancelAfter().has_value()); + EXPECT_FALSE(entry.hasSourceTag()); + EXPECT_FALSE(entry.getSourceTag().has_value()); + EXPECT_FALSE(entry.hasDestinationTag()); + EXPECT_FALSE(entry.getDestinationTag().has_value()); + EXPECT_FALSE(entry.hasDestinationNode()); + EXPECT_FALSE(entry.getDestinationNode().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/PermissionedDomainTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/PermissionedDomainTests.cpp new file mode 100644 index 0000000000..c448d064cf --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/PermissionedDomainTests.cpp @@ -0,0 +1,223 @@ +// Auto-generated unit tests for ledger entry PermissionedDomain + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(PermissionedDomainTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const acceptedCredentialsValue = canonical_ARRAY(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + PermissionedDomainBuilder builder{ + ownerValue, + sequenceValue, + acceptedCredentialsValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = ownerValue; + auto const actual = entry.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = sequenceValue; + auto const actual = entry.getSequence(); + expectEqualField(expected, actual, "sfSequence"); + } + + { + auto const& expected = acceptedCredentialsValue; + auto const actual = entry.getAcceptedCredentials(); + expectEqualField(expected, actual, "sfAcceptedCredentials"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(PermissionedDomainTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const sequenceValue = canonical_UINT32(); + auto const acceptedCredentialsValue = canonical_ARRAY(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(PermissionedDomain::entryType, index); + + sle->at(sfOwner) = ownerValue; + sle->at(sfSequence) = sequenceValue; + sle->setFieldArray(sfAcceptedCredentials, acceptedCredentialsValue); + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + PermissionedDomainBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + PermissionedDomain entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = ownerValue; + + auto const fromSle = entryFromSle.getOwner(); + auto const fromBuilder = entryFromBuilder.getOwner(); + + expectEqualField(expected, fromSle, "sfOwner"); + expectEqualField(expected, fromBuilder, "sfOwner"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSle = entryFromSle.getSequence(); + auto const fromBuilder = entryFromBuilder.getSequence(); + + expectEqualField(expected, fromSle, "sfSequence"); + expectEqualField(expected, fromBuilder, "sfSequence"); + } + + { + auto const& expected = acceptedCredentialsValue; + + auto const fromSle = entryFromSle.getAcceptedCredentials(); + auto const fromBuilder = entryFromBuilder.getAcceptedCredentials(); + + expectEqualField(expected, fromSle, "sfAcceptedCredentials"); + expectEqualField(expected, fromBuilder, "sfAcceptedCredentials"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(PermissionedDomainTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(PermissionedDomain{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(PermissionedDomainTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(PermissionedDomainBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/RippleStateTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/RippleStateTests.cpp new file mode 100644 index 0000000000..a51ce55f6f --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/RippleStateTests.cpp @@ -0,0 +1,388 @@ +// Auto-generated unit tests for ledger entry RippleState + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(RippleStateTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const balanceValue = canonical_AMOUNT(); + auto const lowLimitValue = canonical_AMOUNT(); + auto const highLimitValue = canonical_AMOUNT(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const lowNodeValue = canonical_UINT64(); + auto const lowQualityInValue = canonical_UINT32(); + auto const lowQualityOutValue = canonical_UINT32(); + auto const highNodeValue = canonical_UINT64(); + auto const highQualityInValue = canonical_UINT32(); + auto const highQualityOutValue = canonical_UINT32(); + + RippleStateBuilder builder{ + balanceValue, + lowLimitValue, + highLimitValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setLowNode(lowNodeValue); + builder.setLowQualityIn(lowQualityInValue); + builder.setLowQualityOut(lowQualityOutValue); + builder.setHighNode(highNodeValue); + builder.setHighQualityIn(highQualityInValue); + builder.setHighQualityOut(highQualityOutValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = balanceValue; + auto const actual = entry.getBalance(); + expectEqualField(expected, actual, "sfBalance"); + } + + { + auto const& expected = lowLimitValue; + auto const actual = entry.getLowLimit(); + expectEqualField(expected, actual, "sfLowLimit"); + } + + { + auto const& expected = highLimitValue; + auto const actual = entry.getHighLimit(); + expectEqualField(expected, actual, "sfHighLimit"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = lowNodeValue; + auto const actualOpt = entry.getLowNode(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLowNode"); + EXPECT_TRUE(entry.hasLowNode()); + } + + { + auto const& expected = lowQualityInValue; + auto const actualOpt = entry.getLowQualityIn(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLowQualityIn"); + EXPECT_TRUE(entry.hasLowQualityIn()); + } + + { + auto const& expected = lowQualityOutValue; + auto const actualOpt = entry.getLowQualityOut(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLowQualityOut"); + EXPECT_TRUE(entry.hasLowQualityOut()); + } + + { + auto const& expected = highNodeValue; + auto const actualOpt = entry.getHighNode(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfHighNode"); + EXPECT_TRUE(entry.hasHighNode()); + } + + { + auto const& expected = highQualityInValue; + auto const actualOpt = entry.getHighQualityIn(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfHighQualityIn"); + EXPECT_TRUE(entry.hasHighQualityIn()); + } + + { + auto const& expected = highQualityOutValue; + auto const actualOpt = entry.getHighQualityOut(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfHighQualityOut"); + EXPECT_TRUE(entry.hasHighQualityOut()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(RippleStateTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const balanceValue = canonical_AMOUNT(); + auto const lowLimitValue = canonical_AMOUNT(); + auto const highLimitValue = canonical_AMOUNT(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const lowNodeValue = canonical_UINT64(); + auto const lowQualityInValue = canonical_UINT32(); + auto const lowQualityOutValue = canonical_UINT32(); + auto const highNodeValue = canonical_UINT64(); + auto const highQualityInValue = canonical_UINT32(); + auto const highQualityOutValue = canonical_UINT32(); + + auto sle = std::make_shared(RippleState::entryType, index); + + sle->at(sfBalance) = balanceValue; + sle->at(sfLowLimit) = lowLimitValue; + sle->at(sfHighLimit) = highLimitValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfLowNode) = lowNodeValue; + sle->at(sfLowQualityIn) = lowQualityInValue; + sle->at(sfLowQualityOut) = lowQualityOutValue; + sle->at(sfHighNode) = highNodeValue; + sle->at(sfHighQualityIn) = highQualityInValue; + sle->at(sfHighQualityOut) = highQualityOutValue; + + RippleStateBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + RippleState entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = balanceValue; + + auto const fromSle = entryFromSle.getBalance(); + auto const fromBuilder = entryFromBuilder.getBalance(); + + expectEqualField(expected, fromSle, "sfBalance"); + expectEqualField(expected, fromBuilder, "sfBalance"); + } + + { + auto const& expected = lowLimitValue; + + auto const fromSle = entryFromSle.getLowLimit(); + auto const fromBuilder = entryFromBuilder.getLowLimit(); + + expectEqualField(expected, fromSle, "sfLowLimit"); + expectEqualField(expected, fromBuilder, "sfLowLimit"); + } + + { + auto const& expected = highLimitValue; + + auto const fromSle = entryFromSle.getHighLimit(); + auto const fromBuilder = entryFromBuilder.getHighLimit(); + + expectEqualField(expected, fromSle, "sfHighLimit"); + expectEqualField(expected, fromBuilder, "sfHighLimit"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = lowNodeValue; + + auto const fromSleOpt = entryFromSle.getLowNode(); + auto const fromBuilderOpt = entryFromBuilder.getLowNode(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLowNode"); + expectEqualField(expected, *fromBuilderOpt, "sfLowNode"); + } + + { + auto const& expected = lowQualityInValue; + + auto const fromSleOpt = entryFromSle.getLowQualityIn(); + auto const fromBuilderOpt = entryFromBuilder.getLowQualityIn(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLowQualityIn"); + expectEqualField(expected, *fromBuilderOpt, "sfLowQualityIn"); + } + + { + auto const& expected = lowQualityOutValue; + + auto const fromSleOpt = entryFromSle.getLowQualityOut(); + auto const fromBuilderOpt = entryFromBuilder.getLowQualityOut(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLowQualityOut"); + expectEqualField(expected, *fromBuilderOpt, "sfLowQualityOut"); + } + + { + auto const& expected = highNodeValue; + + auto const fromSleOpt = entryFromSle.getHighNode(); + auto const fromBuilderOpt = entryFromBuilder.getHighNode(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfHighNode"); + expectEqualField(expected, *fromBuilderOpt, "sfHighNode"); + } + + { + auto const& expected = highQualityInValue; + + auto const fromSleOpt = entryFromSle.getHighQualityIn(); + auto const fromBuilderOpt = entryFromBuilder.getHighQualityIn(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfHighQualityIn"); + expectEqualField(expected, *fromBuilderOpt, "sfHighQualityIn"); + } + + { + auto const& expected = highQualityOutValue; + + auto const fromSleOpt = entryFromSle.getHighQualityOut(); + auto const fromBuilderOpt = entryFromBuilder.getHighQualityOut(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfHighQualityOut"); + expectEqualField(expected, *fromBuilderOpt, "sfHighQualityOut"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(RippleStateTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(RippleState{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(RippleStateTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(RippleStateBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(RippleStateTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const balanceValue = canonical_AMOUNT(); + auto const lowLimitValue = canonical_AMOUNT(); + auto const highLimitValue = canonical_AMOUNT(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + RippleStateBuilder builder{ + balanceValue, + lowLimitValue, + highLimitValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasLowNode()); + EXPECT_FALSE(entry.getLowNode().has_value()); + EXPECT_FALSE(entry.hasLowQualityIn()); + EXPECT_FALSE(entry.getLowQualityIn().has_value()); + EXPECT_FALSE(entry.hasLowQualityOut()); + EXPECT_FALSE(entry.getLowQualityOut().has_value()); + EXPECT_FALSE(entry.hasHighNode()); + EXPECT_FALSE(entry.getHighNode().has_value()); + EXPECT_FALSE(entry.hasHighQualityIn()); + EXPECT_FALSE(entry.getHighQualityIn().has_value()); + EXPECT_FALSE(entry.hasHighQualityOut()); + EXPECT_FALSE(entry.getHighQualityOut().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/SignerListTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/SignerListTests.cpp new file mode 100644 index 0000000000..5ec2c4e10d --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/SignerListTests.cpp @@ -0,0 +1,275 @@ +// Auto-generated unit tests for ledger entry SignerList + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(SignerListTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const signerQuorumValue = canonical_UINT32(); + auto const signerEntriesValue = canonical_ARRAY(); + auto const signerListIDValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + SignerListBuilder builder{ + ownerNodeValue, + signerQuorumValue, + signerEntriesValue, + signerListIDValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + builder.setOwner(ownerValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = signerQuorumValue; + auto const actual = entry.getSignerQuorum(); + expectEqualField(expected, actual, "sfSignerQuorum"); + } + + { + auto const& expected = signerEntriesValue; + auto const actual = entry.getSignerEntries(); + expectEqualField(expected, actual, "sfSignerEntries"); + } + + { + auto const& expected = signerListIDValue; + auto const actual = entry.getSignerListID(); + expectEqualField(expected, actual, "sfSignerListID"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = ownerValue; + auto const actualOpt = entry.getOwner(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfOwner"); + EXPECT_TRUE(entry.hasOwner()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(SignerListTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const ownerValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const signerQuorumValue = canonical_UINT32(); + auto const signerEntriesValue = canonical_ARRAY(); + auto const signerListIDValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(SignerList::entryType, index); + + sle->at(sfOwner) = ownerValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfSignerQuorum) = signerQuorumValue; + sle->setFieldArray(sfSignerEntries, signerEntriesValue); + sle->at(sfSignerListID) = signerListIDValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + SignerListBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + SignerList entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = signerQuorumValue; + + auto const fromSle = entryFromSle.getSignerQuorum(); + auto const fromBuilder = entryFromBuilder.getSignerQuorum(); + + expectEqualField(expected, fromSle, "sfSignerQuorum"); + expectEqualField(expected, fromBuilder, "sfSignerQuorum"); + } + + { + auto const& expected = signerEntriesValue; + + auto const fromSle = entryFromSle.getSignerEntries(); + auto const fromBuilder = entryFromBuilder.getSignerEntries(); + + expectEqualField(expected, fromSle, "sfSignerEntries"); + expectEqualField(expected, fromBuilder, "sfSignerEntries"); + } + + { + auto const& expected = signerListIDValue; + + auto const fromSle = entryFromSle.getSignerListID(); + auto const fromBuilder = entryFromBuilder.getSignerListID(); + + expectEqualField(expected, fromSle, "sfSignerListID"); + expectEqualField(expected, fromBuilder, "sfSignerListID"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = ownerValue; + + auto const fromSleOpt = entryFromSle.getOwner(); + auto const fromBuilderOpt = entryFromBuilder.getOwner(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfOwner"); + expectEqualField(expected, *fromBuilderOpt, "sfOwner"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(SignerListTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(SignerList{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(SignerListTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(SignerListBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(SignerListTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const ownerNodeValue = canonical_UINT64(); + auto const signerQuorumValue = canonical_UINT32(); + auto const signerEntriesValue = canonical_ARRAY(); + auto const signerListIDValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + SignerListBuilder builder{ + ownerNodeValue, + signerQuorumValue, + signerEntriesValue, + signerListIDValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasOwner()); + EXPECT_FALSE(entry.getOwner().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/TicketTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/TicketTests.cpp new file mode 100644 index 0000000000..1ac00288f0 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/TicketTests.cpp @@ -0,0 +1,209 @@ +// Auto-generated unit tests for ledger entry Ticket + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(TicketTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const ticketSequenceValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + TicketBuilder builder{ + accountValue, + ownerNodeValue, + ticketSequenceValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = ticketSequenceValue; + auto const actual = entry.getTicketSequence(); + expectEqualField(expected, actual, "sfTicketSequence"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(TicketTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const ticketSequenceValue = canonical_UINT32(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(Ticket::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfTicketSequence) = ticketSequenceValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + TicketBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Ticket entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = ticketSequenceValue; + + auto const fromSle = entryFromSle.getTicketSequence(); + auto const fromBuilder = entryFromBuilder.getTicketSequence(); + + expectEqualField(expected, fromSle, "sfTicketSequence"); + expectEqualField(expected, fromBuilder, "sfTicketSequence"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(TicketTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + CheckBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_ACCOUNT(), + canonical_AMOUNT(), + canonical_UINT32(), + canonical_UINT64(), + canonical_UINT64(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Ticket{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(TicketTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + CheckBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_ACCOUNT(), + canonical_AMOUNT(), + canonical_UINT32(), + canonical_UINT64(), + canonical_UINT64(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(TicketBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/VaultTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/VaultTests.cpp new file mode 100644 index 0000000000..2697924d37 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/VaultTests.cpp @@ -0,0 +1,476 @@ +// Auto-generated unit tests for ledger entry Vault + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(VaultTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const ownerValue = canonical_ACCOUNT(); + auto const accountValue = canonical_ACCOUNT(); + auto const dataValue = canonical_VL(); + auto const assetValue = canonical_ISSUE(); + auto const assetsTotalValue = canonical_NUMBER(); + auto const assetsAvailableValue = canonical_NUMBER(); + auto const assetsMaximumValue = canonical_NUMBER(); + auto const lossUnrealizedValue = canonical_NUMBER(); + auto const shareMPTIDValue = canonical_UINT192(); + auto const withdrawalPolicyValue = canonical_UINT8(); + auto const scaleValue = canonical_UINT8(); + + VaultBuilder builder{ + previousTxnIDValue, + previousTxnLgrSeqValue, + sequenceValue, + ownerNodeValue, + ownerValue, + accountValue, + assetValue, + shareMPTIDValue, + withdrawalPolicyValue + }; + + builder.setData(dataValue); + builder.setAssetsTotal(assetsTotalValue); + builder.setAssetsAvailable(assetsAvailableValue); + builder.setAssetsMaximum(assetsMaximumValue); + builder.setLossUnrealized(lossUnrealizedValue); + builder.setScale(scaleValue); + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + auto const actual = entry.getSequence(); + expectEqualField(expected, actual, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = ownerValue; + auto const actual = entry.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = assetValue; + auto const actual = entry.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = shareMPTIDValue; + auto const actual = entry.getShareMPTID(); + expectEqualField(expected, actual, "sfShareMPTID"); + } + + { + auto const& expected = withdrawalPolicyValue; + auto const actual = entry.getWithdrawalPolicy(); + expectEqualField(expected, actual, "sfWithdrawalPolicy"); + } + + { + auto const& expected = dataValue; + auto const actualOpt = entry.getData(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(entry.hasData()); + } + + { + auto const& expected = assetsTotalValue; + auto const actualOpt = entry.getAssetsTotal(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAssetsTotal"); + EXPECT_TRUE(entry.hasAssetsTotal()); + } + + { + auto const& expected = assetsAvailableValue; + auto const actualOpt = entry.getAssetsAvailable(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAssetsAvailable"); + EXPECT_TRUE(entry.hasAssetsAvailable()); + } + + { + auto const& expected = assetsMaximumValue; + auto const actualOpt = entry.getAssetsMaximum(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfAssetsMaximum"); + EXPECT_TRUE(entry.hasAssetsMaximum()); + } + + { + auto const& expected = lossUnrealizedValue; + auto const actualOpt = entry.getLossUnrealized(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfLossUnrealized"); + EXPECT_TRUE(entry.hasLossUnrealized()); + } + + { + auto const& expected = scaleValue; + auto const actualOpt = entry.getScale(); + ASSERT_TRUE(actualOpt.has_value()); + expectEqualField(expected, *actualOpt, "sfScale"); + EXPECT_TRUE(entry.hasScale()); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(VaultTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const ownerValue = canonical_ACCOUNT(); + auto const accountValue = canonical_ACCOUNT(); + auto const dataValue = canonical_VL(); + auto const assetValue = canonical_ISSUE(); + auto const assetsTotalValue = canonical_NUMBER(); + auto const assetsAvailableValue = canonical_NUMBER(); + auto const assetsMaximumValue = canonical_NUMBER(); + auto const lossUnrealizedValue = canonical_NUMBER(); + auto const shareMPTIDValue = canonical_UINT192(); + auto const withdrawalPolicyValue = canonical_UINT8(); + auto const scaleValue = canonical_UINT8(); + + auto sle = std::make_shared(Vault::entryType, index); + + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + sle->at(sfSequence) = sequenceValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfOwner) = ownerValue; + sle->at(sfAccount) = accountValue; + sle->at(sfData) = dataValue; + sle->at(sfAsset) = STIssue(sfAsset, assetValue); + sle->at(sfAssetsTotal) = assetsTotalValue; + sle->at(sfAssetsAvailable) = assetsAvailableValue; + sle->at(sfAssetsMaximum) = assetsMaximumValue; + sle->at(sfLossUnrealized) = lossUnrealizedValue; + sle->at(sfShareMPTID) = shareMPTIDValue; + sle->at(sfWithdrawalPolicy) = withdrawalPolicyValue; + sle->at(sfScale) = scaleValue; + + VaultBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + Vault entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + { + auto const& expected = sequenceValue; + + auto const fromSle = entryFromSle.getSequence(); + auto const fromBuilder = entryFromBuilder.getSequence(); + + expectEqualField(expected, fromSle, "sfSequence"); + expectEqualField(expected, fromBuilder, "sfSequence"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = ownerValue; + + auto const fromSle = entryFromSle.getOwner(); + auto const fromBuilder = entryFromBuilder.getOwner(); + + expectEqualField(expected, fromSle, "sfOwner"); + expectEqualField(expected, fromBuilder, "sfOwner"); + } + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = assetValue; + + auto const fromSle = entryFromSle.getAsset(); + auto const fromBuilder = entryFromBuilder.getAsset(); + + expectEqualField(expected, fromSle, "sfAsset"); + expectEqualField(expected, fromBuilder, "sfAsset"); + } + + { + auto const& expected = shareMPTIDValue; + + auto const fromSle = entryFromSle.getShareMPTID(); + auto const fromBuilder = entryFromBuilder.getShareMPTID(); + + expectEqualField(expected, fromSle, "sfShareMPTID"); + expectEqualField(expected, fromBuilder, "sfShareMPTID"); + } + + { + auto const& expected = withdrawalPolicyValue; + + auto const fromSle = entryFromSle.getWithdrawalPolicy(); + auto const fromBuilder = entryFromBuilder.getWithdrawalPolicy(); + + expectEqualField(expected, fromSle, "sfWithdrawalPolicy"); + expectEqualField(expected, fromBuilder, "sfWithdrawalPolicy"); + } + + { + auto const& expected = dataValue; + + auto const fromSleOpt = entryFromSle.getData(); + auto const fromBuilderOpt = entryFromBuilder.getData(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfData"); + expectEqualField(expected, *fromBuilderOpt, "sfData"); + } + + { + auto const& expected = assetsTotalValue; + + auto const fromSleOpt = entryFromSle.getAssetsTotal(); + auto const fromBuilderOpt = entryFromBuilder.getAssetsTotal(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAssetsTotal"); + expectEqualField(expected, *fromBuilderOpt, "sfAssetsTotal"); + } + + { + auto const& expected = assetsAvailableValue; + + auto const fromSleOpt = entryFromSle.getAssetsAvailable(); + auto const fromBuilderOpt = entryFromBuilder.getAssetsAvailable(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAssetsAvailable"); + expectEqualField(expected, *fromBuilderOpt, "sfAssetsAvailable"); + } + + { + auto const& expected = assetsMaximumValue; + + auto const fromSleOpt = entryFromSle.getAssetsMaximum(); + auto const fromBuilderOpt = entryFromBuilder.getAssetsMaximum(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfAssetsMaximum"); + expectEqualField(expected, *fromBuilderOpt, "sfAssetsMaximum"); + } + + { + auto const& expected = lossUnrealizedValue; + + auto const fromSleOpt = entryFromSle.getLossUnrealized(); + auto const fromBuilderOpt = entryFromBuilder.getLossUnrealized(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfLossUnrealized"); + expectEqualField(expected, *fromBuilderOpt, "sfLossUnrealized"); + } + + { + auto const& expected = scaleValue; + + auto const fromSleOpt = entryFromSle.getScale(); + auto const fromBuilderOpt = entryFromBuilder.getScale(); + + ASSERT_TRUE(fromSleOpt.has_value()); + ASSERT_TRUE(fromBuilderOpt.has_value()); + + expectEqualField(expected, *fromSleOpt, "sfScale"); + expectEqualField(expected, *fromBuilderOpt, "sfScale"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(VaultTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(Vault{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(VaultTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(VaultBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(VaultTests, OptionalFieldsReturnNullopt) +{ + uint256 const index{3u}; + + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + auto const sequenceValue = canonical_UINT32(); + auto const ownerNodeValue = canonical_UINT64(); + auto const ownerValue = canonical_ACCOUNT(); + auto const accountValue = canonical_ACCOUNT(); + auto const assetValue = canonical_ISSUE(); + auto const shareMPTIDValue = canonical_UINT192(); + auto const withdrawalPolicyValue = canonical_UINT8(); + + VaultBuilder builder{ + previousTxnIDValue, + previousTxnLgrSeqValue, + sequenceValue, + ownerNodeValue, + ownerValue, + accountValue, + assetValue, + shareMPTIDValue, + withdrawalPolicyValue + }; + + auto const entry = builder.build(index); + + // Verify optional fields are not present + EXPECT_FALSE(entry.hasData()); + EXPECT_FALSE(entry.getData().has_value()); + EXPECT_FALSE(entry.hasAssetsTotal()); + EXPECT_FALSE(entry.getAssetsTotal().has_value()); + EXPECT_FALSE(entry.hasAssetsAvailable()); + EXPECT_FALSE(entry.getAssetsAvailable().has_value()); + EXPECT_FALSE(entry.hasAssetsMaximum()); + EXPECT_FALSE(entry.getAssetsMaximum().has_value()); + EXPECT_FALSE(entry.hasLossUnrealized()); + EXPECT_FALSE(entry.getLossUnrealized().has_value()); + EXPECT_FALSE(entry.hasScale()); + EXPECT_FALSE(entry.getScale().has_value()); +} +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedClaimIDTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedClaimIDTests.cpp new file mode 100644 index 0000000000..4b6979b86a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedClaimIDTests.cpp @@ -0,0 +1,283 @@ +// Auto-generated unit tests for ledger entry XChainOwnedClaimID + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(XChainOwnedClaimIDTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + auto const xChainClaimAttestationsValue = canonical_ARRAY(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + XChainOwnedClaimIDBuilder builder{ + accountValue, + xChainBridgeValue, + xChainClaimIDValue, + otherChainSourceValue, + xChainClaimAttestationsValue, + signatureRewardValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = xChainBridgeValue; + auto const actual = entry.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = entry.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + { + auto const& expected = otherChainSourceValue; + auto const actual = entry.getOtherChainSource(); + expectEqualField(expected, actual, "sfOtherChainSource"); + } + + { + auto const& expected = xChainClaimAttestationsValue; + auto const actual = entry.getXChainClaimAttestations(); + expectEqualField(expected, actual, "sfXChainClaimAttestations"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = entry.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(XChainOwnedClaimIDTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + auto const xChainClaimAttestationsValue = canonical_ARRAY(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(XChainOwnedClaimID::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfXChainBridge) = xChainBridgeValue; + sle->at(sfXChainClaimID) = xChainClaimIDValue; + sle->at(sfOtherChainSource) = otherChainSourceValue; + sle->setFieldArray(sfXChainClaimAttestations, xChainClaimAttestationsValue); + sle->at(sfSignatureReward) = signatureRewardValue; + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + XChainOwnedClaimIDBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + XChainOwnedClaimID entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = xChainBridgeValue; + + auto const fromSle = entryFromSle.getXChainBridge(); + auto const fromBuilder = entryFromBuilder.getXChainBridge(); + + expectEqualField(expected, fromSle, "sfXChainBridge"); + expectEqualField(expected, fromBuilder, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + + auto const fromSle = entryFromSle.getXChainClaimID(); + auto const fromBuilder = entryFromBuilder.getXChainClaimID(); + + expectEqualField(expected, fromSle, "sfXChainClaimID"); + expectEqualField(expected, fromBuilder, "sfXChainClaimID"); + } + + { + auto const& expected = otherChainSourceValue; + + auto const fromSle = entryFromSle.getOtherChainSource(); + auto const fromBuilder = entryFromBuilder.getOtherChainSource(); + + expectEqualField(expected, fromSle, "sfOtherChainSource"); + expectEqualField(expected, fromBuilder, "sfOtherChainSource"); + } + + { + auto const& expected = xChainClaimAttestationsValue; + + auto const fromSle = entryFromSle.getXChainClaimAttestations(); + auto const fromBuilder = entryFromBuilder.getXChainClaimAttestations(); + + expectEqualField(expected, fromSle, "sfXChainClaimAttestations"); + expectEqualField(expected, fromBuilder, "sfXChainClaimAttestations"); + } + + { + auto const& expected = signatureRewardValue; + + auto const fromSle = entryFromSle.getSignatureReward(); + auto const fromBuilder = entryFromBuilder.getSignatureReward(); + + expectEqualField(expected, fromSle, "sfSignatureReward"); + expectEqualField(expected, fromBuilder, "sfSignatureReward"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(XChainOwnedClaimIDTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(XChainOwnedClaimID{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(XChainOwnedClaimIDTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(XChainOwnedClaimIDBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimIDTests.cpp b/src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimIDTests.cpp new file mode 100644 index 0000000000..0e4e1fb977 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/ledger_entries/XChainOwnedCreateAccountClaimIDTests.cpp @@ -0,0 +1,243 @@ +// Auto-generated unit tests for ledger entry XChainOwnedCreateAccountClaimID + + +#include + +#include + +#include +#include +#include + +#include + +namespace xrpl::ledger_entries { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed for both the +// builder's STObject and the wrapper's SLE. +TEST(XChainOwnedCreateAccountClaimIDTests, BuilderSettersRoundTrip) +{ + uint256 const index{1u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainAccountCreateCountValue = canonical_UINT64(); + auto const xChainCreateAccountAttestationsValue = canonical_ARRAY(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + XChainOwnedCreateAccountClaimIDBuilder builder{ + accountValue, + xChainBridgeValue, + xChainAccountCreateCountValue, + xChainCreateAccountAttestationsValue, + ownerNodeValue, + previousTxnIDValue, + previousTxnLgrSeqValue + }; + + + builder.setLedgerIndex(index); + builder.setFlags(0x1u); + + EXPECT_TRUE(builder.validate()); + + auto const entry = builder.build(index); + + EXPECT_TRUE(entry.validate()); + + { + auto const& expected = accountValue; + auto const actual = entry.getAccount(); + expectEqualField(expected, actual, "sfAccount"); + } + + { + auto const& expected = xChainBridgeValue; + auto const actual = entry.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = xChainAccountCreateCountValue; + auto const actual = entry.getXChainAccountCreateCount(); + expectEqualField(expected, actual, "sfXChainAccountCreateCount"); + } + + { + auto const& expected = xChainCreateAccountAttestationsValue; + auto const actual = entry.getXChainCreateAccountAttestations(); + expectEqualField(expected, actual, "sfXChainCreateAccountAttestations"); + } + + { + auto const& expected = ownerNodeValue; + auto const actual = entry.getOwnerNode(); + expectEqualField(expected, actual, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + auto const actual = entry.getPreviousTxnID(); + expectEqualField(expected, actual, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + auto const actual = entry.getPreviousTxnLgrSeq(); + expectEqualField(expected, actual, "sfPreviousTxnLgrSeq"); + } + + EXPECT_TRUE(entry.hasLedgerIndex()); + auto const ledgerIndex = entry.getLedgerIndex(); + ASSERT_TRUE(ledgerIndex.has_value()); + EXPECT_EQ(*ledgerIndex, index); + EXPECT_EQ(entry.getKey(), index); +} + +// 2 & 4) Start from an SLE, set fields directly on it, construct a builder +// from that SLE, build a new wrapper, and verify all fields (and validate()). +TEST(XChainOwnedCreateAccountClaimIDTests, BuilderFromSleRoundTrip) +{ + uint256 const index{2u}; + + auto const accountValue = canonical_ACCOUNT(); + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainAccountCreateCountValue = canonical_UINT64(); + auto const xChainCreateAccountAttestationsValue = canonical_ARRAY(); + auto const ownerNodeValue = canonical_UINT64(); + auto const previousTxnIDValue = canonical_UINT256(); + auto const previousTxnLgrSeqValue = canonical_UINT32(); + + auto sle = std::make_shared(XChainOwnedCreateAccountClaimID::entryType, index); + + sle->at(sfAccount) = accountValue; + sle->at(sfXChainBridge) = xChainBridgeValue; + sle->at(sfXChainAccountCreateCount) = xChainAccountCreateCountValue; + sle->setFieldArray(sfXChainCreateAccountAttestations, xChainCreateAccountAttestationsValue); + sle->at(sfOwnerNode) = ownerNodeValue; + sle->at(sfPreviousTxnID) = previousTxnIDValue; + sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue; + + XChainOwnedCreateAccountClaimIDBuilder builderFromSle{sle}; + EXPECT_TRUE(builderFromSle.validate()); + + auto const entryFromBuilder = builderFromSle.build(index); + + XChainOwnedCreateAccountClaimID entryFromSle{sle}; + EXPECT_TRUE(entryFromBuilder.validate()); + EXPECT_TRUE(entryFromSle.validate()); + + { + auto const& expected = accountValue; + + auto const fromSle = entryFromSle.getAccount(); + auto const fromBuilder = entryFromBuilder.getAccount(); + + expectEqualField(expected, fromSle, "sfAccount"); + expectEqualField(expected, fromBuilder, "sfAccount"); + } + + { + auto const& expected = xChainBridgeValue; + + auto const fromSle = entryFromSle.getXChainBridge(); + auto const fromBuilder = entryFromBuilder.getXChainBridge(); + + expectEqualField(expected, fromSle, "sfXChainBridge"); + expectEqualField(expected, fromBuilder, "sfXChainBridge"); + } + + { + auto const& expected = xChainAccountCreateCountValue; + + auto const fromSle = entryFromSle.getXChainAccountCreateCount(); + auto const fromBuilder = entryFromBuilder.getXChainAccountCreateCount(); + + expectEqualField(expected, fromSle, "sfXChainAccountCreateCount"); + expectEqualField(expected, fromBuilder, "sfXChainAccountCreateCount"); + } + + { + auto const& expected = xChainCreateAccountAttestationsValue; + + auto const fromSle = entryFromSle.getXChainCreateAccountAttestations(); + auto const fromBuilder = entryFromBuilder.getXChainCreateAccountAttestations(); + + expectEqualField(expected, fromSle, "sfXChainCreateAccountAttestations"); + expectEqualField(expected, fromBuilder, "sfXChainCreateAccountAttestations"); + } + + { + auto const& expected = ownerNodeValue; + + auto const fromSle = entryFromSle.getOwnerNode(); + auto const fromBuilder = entryFromBuilder.getOwnerNode(); + + expectEqualField(expected, fromSle, "sfOwnerNode"); + expectEqualField(expected, fromBuilder, "sfOwnerNode"); + } + + { + auto const& expected = previousTxnIDValue; + + auto const fromSle = entryFromSle.getPreviousTxnID(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnID(); + + expectEqualField(expected, fromSle, "sfPreviousTxnID"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnID"); + } + + { + auto const& expected = previousTxnLgrSeqValue; + + auto const fromSle = entryFromSle.getPreviousTxnLgrSeq(); + auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq(); + + expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq"); + expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq"); + } + + EXPECT_EQ(entryFromSle.getKey(), index); + EXPECT_EQ(entryFromBuilder.getKey(), index); +} + +// 3) Verify wrapper throws when constructed from wrong ledger entry type. +TEST(XChainOwnedCreateAccountClaimIDTests, WrapperThrowsOnWrongEntryType) +{ + uint256 const index{3u}; + + // Build a valid ledger entry of a different type + // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq + // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(XChainOwnedCreateAccountClaimID{wrongEntry.getSle()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong ledger entry type. +TEST(XChainOwnedCreateAccountClaimIDTests, BuilderThrowsOnWrongEntryType) +{ + uint256 const index{4u}; + + // Build a valid ledger entry of a different type + TicketBuilder wrongBuilder{ + canonical_ACCOUNT(), + canonical_UINT64(), + canonical_UINT32(), + canonical_UINT256(), + canonical_UINT32()}; + auto wrongEntry = wrongBuilder.build(index); + + EXPECT_THROW(XChainOwnedCreateAccountClaimIDBuilder{wrongEntry.getSle()}, std::runtime_error); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/main.cpp b/src/tests/libxrpl/protocol_autogen/main.cpp new file mode 100644 index 0000000000..5142bbe08a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/main.cpp @@ -0,0 +1,8 @@ +#include + +int +main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AMMBidTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AMMBidTests.cpp new file mode 100644 index 0000000000..c9db0cabcf --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AMMBidTests.cpp @@ -0,0 +1,255 @@ +// Auto-generated unit tests for transaction AMMBid + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAMMBidTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMBid")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const bidMinValue = canonical_AMOUNT(); + auto const bidMaxValue = canonical_AMOUNT(); + auto const authAccountsValue = canonical_ARRAY(); + + AMMBidBuilder builder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setBidMin(bidMinValue); + builder.setBidMax(bidMaxValue); + builder.setAuthAccounts(authAccountsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = tx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = tx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = bidMinValue; + auto const actualOpt = tx.getBidMin(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBidMin should be present"; + expectEqualField(expected, *actualOpt, "sfBidMin"); + EXPECT_TRUE(tx.hasBidMin()); + } + + { + auto const& expected = bidMaxValue; + auto const actualOpt = tx.getBidMax(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBidMax should be present"; + expectEqualField(expected, *actualOpt, "sfBidMax"); + EXPECT_TRUE(tx.hasBidMax()); + } + + { + auto const& expected = authAccountsValue; + auto const actualOpt = tx.getAuthAccounts(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuthAccounts should be present"; + expectEqualField(expected, *actualOpt, "sfAuthAccounts"); + EXPECT_TRUE(tx.hasAuthAccounts()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAMMBidTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMBidFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const bidMinValue = canonical_AMOUNT(); + auto const bidMaxValue = canonical_AMOUNT(); + auto const authAccountsValue = canonical_ARRAY(); + + // Build an initial transaction + AMMBidBuilder initialBuilder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + initialBuilder.setBidMin(bidMinValue); + initialBuilder.setBidMax(bidMaxValue); + initialBuilder.setAuthAccounts(authAccountsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AMMBidBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = rebuiltTx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = rebuiltTx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = bidMinValue; + auto const actualOpt = rebuiltTx.getBidMin(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBidMin should be present"; + expectEqualField(expected, *actualOpt, "sfBidMin"); + } + + { + auto const& expected = bidMaxValue; + auto const actualOpt = rebuiltTx.getBidMax(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBidMax should be present"; + expectEqualField(expected, *actualOpt, "sfBidMax"); + } + + { + auto const& expected = authAccountsValue; + auto const actualOpt = rebuiltTx.getAuthAccounts(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuthAccounts should be present"; + expectEqualField(expected, *actualOpt, "sfAuthAccounts"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAMMBidTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMBid{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAMMBidTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMBidBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsAMMBidTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMBidNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + + AMMBidBuilder builder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasBidMin()); + EXPECT_FALSE(tx.getBidMin().has_value()); + EXPECT_FALSE(tx.hasBidMax()); + EXPECT_FALSE(tx.getBidMax().has_value()); + EXPECT_FALSE(tx.hasAuthAccounts()); + EXPECT_FALSE(tx.getAuthAccounts().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AMMClawbackTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AMMClawbackTests.cpp new file mode 100644 index 0000000000..d01e840ce5 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AMMClawbackTests.cpp @@ -0,0 +1,231 @@ +// Auto-generated unit tests for transaction AMMClawback + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAMMClawbackTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMClawback")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const holderValue = canonical_ACCOUNT(); + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const amountValue = canonical_AMOUNT(); + + AMMClawbackBuilder builder{ + accountValue, + holderValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAmount(amountValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = holderValue; + auto const actual = tx.getHolder(); + expectEqualField(expected, actual, "sfHolder"); + } + + { + auto const& expected = assetValue; + auto const actual = tx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = tx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAMMClawbackTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMClawbackFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const holderValue = canonical_ACCOUNT(); + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const amountValue = canonical_AMOUNT(); + + // Build an initial transaction + AMMClawbackBuilder initialBuilder{ + accountValue, + holderValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + initialBuilder.setAmount(amountValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AMMClawbackBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = holderValue; + auto const actual = rebuiltTx.getHolder(); + expectEqualField(expected, actual, "sfHolder"); + } + + { + auto const& expected = assetValue; + auto const actual = rebuiltTx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = rebuiltTx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAMMClawbackTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMClawback{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAMMClawbackTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMClawbackBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsAMMClawbackTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMClawbackNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const holderValue = canonical_ACCOUNT(); + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + + AMMClawbackBuilder builder{ + accountValue, + holderValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AMMCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AMMCreateTests.cpp new file mode 100644 index 0000000000..b55c9f377e --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AMMCreateTests.cpp @@ -0,0 +1,178 @@ +// Auto-generated unit tests for transaction AMMCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAMMCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const amountValue = canonical_AMOUNT(); + auto const amount2Value = canonical_AMOUNT(); + auto const tradingFeeValue = canonical_UINT16(); + + AMMCreateBuilder builder{ + accountValue, + amountValue, + amount2Value, + tradingFeeValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = amount2Value; + auto const actual = tx.getAmount2(); + expectEqualField(expected, actual, "sfAmount2"); + } + + { + auto const& expected = tradingFeeValue; + auto const actual = tx.getTradingFee(); + expectEqualField(expected, actual, "sfTradingFee"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAMMCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const amountValue = canonical_AMOUNT(); + auto const amount2Value = canonical_AMOUNT(); + auto const tradingFeeValue = canonical_UINT16(); + + // Build an initial transaction + AMMCreateBuilder initialBuilder{ + accountValue, + amountValue, + amount2Value, + tradingFeeValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AMMCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = amount2Value; + auto const actual = rebuiltTx.getAmount2(); + expectEqualField(expected, actual, "sfAmount2"); + } + + { + auto const& expected = tradingFeeValue; + auto const actual = rebuiltTx.getTradingFee(); + expectEqualField(expected, actual, "sfTradingFee"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAMMCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAMMCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AMMDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AMMDeleteTests.cpp new file mode 100644 index 0000000000..774d993a1a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AMMDeleteTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction AMMDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAMMDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + + AMMDeleteBuilder builder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = tx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = tx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAMMDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + + // Build an initial transaction + AMMDeleteBuilder initialBuilder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AMMDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = rebuiltTx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = rebuiltTx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAMMDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAMMDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AMMDepositTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AMMDepositTests.cpp new file mode 100644 index 0000000000..9917848f0a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AMMDepositTests.cpp @@ -0,0 +1,297 @@ +// Auto-generated unit tests for transaction AMMDeposit + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAMMDepositTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMDeposit")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const amountValue = canonical_AMOUNT(); + auto const amount2Value = canonical_AMOUNT(); + auto const ePriceValue = canonical_AMOUNT(); + auto const lPTokenOutValue = canonical_AMOUNT(); + auto const tradingFeeValue = canonical_UINT16(); + + AMMDepositBuilder builder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAmount(amountValue); + builder.setAmount2(amount2Value); + builder.setEPrice(ePriceValue); + builder.setLPTokenOut(lPTokenOutValue); + builder.setTradingFee(tradingFeeValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = tx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = tx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + + { + auto const& expected = amount2Value; + auto const actualOpt = tx.getAmount2(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount2 should be present"; + expectEqualField(expected, *actualOpt, "sfAmount2"); + EXPECT_TRUE(tx.hasAmount2()); + } + + { + auto const& expected = ePriceValue; + auto const actualOpt = tx.getEPrice(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfEPrice should be present"; + expectEqualField(expected, *actualOpt, "sfEPrice"); + EXPECT_TRUE(tx.hasEPrice()); + } + + { + auto const& expected = lPTokenOutValue; + auto const actualOpt = tx.getLPTokenOut(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLPTokenOut should be present"; + expectEqualField(expected, *actualOpt, "sfLPTokenOut"); + EXPECT_TRUE(tx.hasLPTokenOut()); + } + + { + auto const& expected = tradingFeeValue; + auto const actualOpt = tx.getTradingFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTradingFee should be present"; + expectEqualField(expected, *actualOpt, "sfTradingFee"); + EXPECT_TRUE(tx.hasTradingFee()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAMMDepositTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMDepositFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const amountValue = canonical_AMOUNT(); + auto const amount2Value = canonical_AMOUNT(); + auto const ePriceValue = canonical_AMOUNT(); + auto const lPTokenOutValue = canonical_AMOUNT(); + auto const tradingFeeValue = canonical_UINT16(); + + // Build an initial transaction + AMMDepositBuilder initialBuilder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + initialBuilder.setAmount(amountValue); + initialBuilder.setAmount2(amount2Value); + initialBuilder.setEPrice(ePriceValue); + initialBuilder.setLPTokenOut(lPTokenOutValue); + initialBuilder.setTradingFee(tradingFeeValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AMMDepositBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = rebuiltTx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = rebuiltTx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + + { + auto const& expected = amount2Value; + auto const actualOpt = rebuiltTx.getAmount2(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount2 should be present"; + expectEqualField(expected, *actualOpt, "sfAmount2"); + } + + { + auto const& expected = ePriceValue; + auto const actualOpt = rebuiltTx.getEPrice(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfEPrice should be present"; + expectEqualField(expected, *actualOpt, "sfEPrice"); + } + + { + auto const& expected = lPTokenOutValue; + auto const actualOpt = rebuiltTx.getLPTokenOut(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLPTokenOut should be present"; + expectEqualField(expected, *actualOpt, "sfLPTokenOut"); + } + + { + auto const& expected = tradingFeeValue; + auto const actualOpt = rebuiltTx.getTradingFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTradingFee should be present"; + expectEqualField(expected, *actualOpt, "sfTradingFee"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAMMDepositTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMDeposit{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAMMDepositTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMDepositBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsAMMDepositTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMDepositNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + + AMMDepositBuilder builder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); + EXPECT_FALSE(tx.hasAmount2()); + EXPECT_FALSE(tx.getAmount2().has_value()); + EXPECT_FALSE(tx.hasEPrice()); + EXPECT_FALSE(tx.getEPrice().has_value()); + EXPECT_FALSE(tx.hasLPTokenOut()); + EXPECT_FALSE(tx.getLPTokenOut().has_value()); + EXPECT_FALSE(tx.hasTradingFee()); + EXPECT_FALSE(tx.getTradingFee().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AMMVoteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AMMVoteTests.cpp new file mode 100644 index 0000000000..6a47b7613e --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AMMVoteTests.cpp @@ -0,0 +1,178 @@ +// Auto-generated unit tests for transaction AMMVote + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAMMVoteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMVote")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const tradingFeeValue = canonical_UINT16(); + + AMMVoteBuilder builder{ + accountValue, + assetValue, + asset2Value, + tradingFeeValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = tx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = tx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + { + auto const& expected = tradingFeeValue; + auto const actual = tx.getTradingFee(); + expectEqualField(expected, actual, "sfTradingFee"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAMMVoteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMVoteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const tradingFeeValue = canonical_UINT16(); + + // Build an initial transaction + AMMVoteBuilder initialBuilder{ + accountValue, + assetValue, + asset2Value, + tradingFeeValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AMMVoteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = rebuiltTx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = rebuiltTx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + { + auto const& expected = tradingFeeValue; + auto const actual = rebuiltTx.getTradingFee(); + expectEqualField(expected, actual, "sfTradingFee"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAMMVoteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMVote{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAMMVoteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMVoteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AMMWithdrawTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AMMWithdrawTests.cpp new file mode 100644 index 0000000000..0fd529c282 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AMMWithdrawTests.cpp @@ -0,0 +1,276 @@ +// Auto-generated unit tests for transaction AMMWithdraw + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAMMWithdrawTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMWithdraw")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const amountValue = canonical_AMOUNT(); + auto const amount2Value = canonical_AMOUNT(); + auto const ePriceValue = canonical_AMOUNT(); + auto const lPTokenInValue = canonical_AMOUNT(); + + AMMWithdrawBuilder builder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAmount(amountValue); + builder.setAmount2(amount2Value); + builder.setEPrice(ePriceValue); + builder.setLPTokenIn(lPTokenInValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = tx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = tx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + + { + auto const& expected = amount2Value; + auto const actualOpt = tx.getAmount2(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount2 should be present"; + expectEqualField(expected, *actualOpt, "sfAmount2"); + EXPECT_TRUE(tx.hasAmount2()); + } + + { + auto const& expected = ePriceValue; + auto const actualOpt = tx.getEPrice(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfEPrice should be present"; + expectEqualField(expected, *actualOpt, "sfEPrice"); + EXPECT_TRUE(tx.hasEPrice()); + } + + { + auto const& expected = lPTokenInValue; + auto const actualOpt = tx.getLPTokenIn(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLPTokenIn should be present"; + expectEqualField(expected, *actualOpt, "sfLPTokenIn"); + EXPECT_TRUE(tx.hasLPTokenIn()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAMMWithdrawTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMWithdrawFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + auto const amountValue = canonical_AMOUNT(); + auto const amount2Value = canonical_AMOUNT(); + auto const ePriceValue = canonical_AMOUNT(); + auto const lPTokenInValue = canonical_AMOUNT(); + + // Build an initial transaction + AMMWithdrawBuilder initialBuilder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + initialBuilder.setAmount(amountValue); + initialBuilder.setAmount2(amount2Value); + initialBuilder.setEPrice(ePriceValue); + initialBuilder.setLPTokenIn(lPTokenInValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AMMWithdrawBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = rebuiltTx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + { + auto const& expected = asset2Value; + auto const actual = rebuiltTx.getAsset2(); + expectEqualField(expected, actual, "sfAsset2"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + + { + auto const& expected = amount2Value; + auto const actualOpt = rebuiltTx.getAmount2(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount2 should be present"; + expectEqualField(expected, *actualOpt, "sfAmount2"); + } + + { + auto const& expected = ePriceValue; + auto const actualOpt = rebuiltTx.getEPrice(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfEPrice should be present"; + expectEqualField(expected, *actualOpt, "sfEPrice"); + } + + { + auto const& expected = lPTokenInValue; + auto const actualOpt = rebuiltTx.getLPTokenIn(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLPTokenIn should be present"; + expectEqualField(expected, *actualOpt, "sfLPTokenIn"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAMMWithdrawTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMWithdraw{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAMMWithdrawTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AMMWithdrawBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsAMMWithdrawTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAMMWithdrawNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const assetValue = canonical_ISSUE(); + auto const asset2Value = canonical_ISSUE(); + + AMMWithdrawBuilder builder{ + accountValue, + assetValue, + asset2Value, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); + EXPECT_FALSE(tx.hasAmount2()); + EXPECT_FALSE(tx.getAmount2().has_value()); + EXPECT_FALSE(tx.hasEPrice()); + EXPECT_FALSE(tx.getEPrice().has_value()); + EXPECT_FALSE(tx.hasLPTokenIn()); + EXPECT_FALSE(tx.getLPTokenIn().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AccountDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AccountDeleteTests.cpp new file mode 100644 index 0000000000..0fb951221b --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AccountDeleteTests.cpp @@ -0,0 +1,216 @@ +// Auto-generated unit tests for transaction AccountDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAccountDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAccountDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + auto const credentialIDsValue = canonical_VECTOR256(); + + AccountDeleteBuilder builder{ + accountValue, + destinationValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDestinationTag(destinationTagValue); + builder.setCredentialIDs(credentialIDsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + // Verify optional fields + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = tx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + EXPECT_TRUE(tx.hasCredentialIDs()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAccountDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAccountDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + auto const credentialIDsValue = canonical_VECTOR256(); + + // Build an initial transaction + AccountDeleteBuilder initialBuilder{ + accountValue, + destinationValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDestinationTag(destinationTagValue); + initialBuilder.setCredentialIDs(credentialIDsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AccountDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + // Verify optional fields + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = rebuiltTx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAccountDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AccountDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAccountDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AccountDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsAccountDeleteTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAccountDeleteNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const destinationValue = canonical_ACCOUNT(); + + AccountDeleteBuilder builder{ + accountValue, + destinationValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); + EXPECT_FALSE(tx.hasCredentialIDs()); + EXPECT_FALSE(tx.getCredentialIDs().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/AccountSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/AccountSetTests.cpp new file mode 100644 index 0000000000..993fe55742 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/AccountSetTests.cpp @@ -0,0 +1,366 @@ +// Auto-generated unit tests for transaction AccountSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsAccountSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAccountSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const emailHashValue = canonical_UINT128(); + auto const walletLocatorValue = canonical_UINT256(); + auto const walletSizeValue = canonical_UINT32(); + auto const messageKeyValue = canonical_VL(); + auto const domainValue = canonical_VL(); + auto const transferRateValue = canonical_UINT32(); + auto const setFlagValue = canonical_UINT32(); + auto const clearFlagValue = canonical_UINT32(); + auto const tickSizeValue = canonical_UINT8(); + auto const nFTokenMinterValue = canonical_ACCOUNT(); + + AccountSetBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setEmailHash(emailHashValue); + builder.setWalletLocator(walletLocatorValue); + builder.setWalletSize(walletSizeValue); + builder.setMessageKey(messageKeyValue); + builder.setDomain(domainValue); + builder.setTransferRate(transferRateValue); + builder.setSetFlag(setFlagValue); + builder.setClearFlag(clearFlagValue); + builder.setTickSize(tickSizeValue); + builder.setNFTokenMinter(nFTokenMinterValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = emailHashValue; + auto const actualOpt = tx.getEmailHash(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfEmailHash should be present"; + expectEqualField(expected, *actualOpt, "sfEmailHash"); + EXPECT_TRUE(tx.hasEmailHash()); + } + + { + auto const& expected = walletLocatorValue; + auto const actualOpt = tx.getWalletLocator(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWalletLocator should be present"; + expectEqualField(expected, *actualOpt, "sfWalletLocator"); + EXPECT_TRUE(tx.hasWalletLocator()); + } + + { + auto const& expected = walletSizeValue; + auto const actualOpt = tx.getWalletSize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWalletSize should be present"; + expectEqualField(expected, *actualOpt, "sfWalletSize"); + EXPECT_TRUE(tx.hasWalletSize()); + } + + { + auto const& expected = messageKeyValue; + auto const actualOpt = tx.getMessageKey(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMessageKey should be present"; + expectEqualField(expected, *actualOpt, "sfMessageKey"); + EXPECT_TRUE(tx.hasMessageKey()); + } + + { + auto const& expected = domainValue; + auto const actualOpt = tx.getDomain(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomain should be present"; + expectEqualField(expected, *actualOpt, "sfDomain"); + EXPECT_TRUE(tx.hasDomain()); + } + + { + auto const& expected = transferRateValue; + auto const actualOpt = tx.getTransferRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferRate should be present"; + expectEqualField(expected, *actualOpt, "sfTransferRate"); + EXPECT_TRUE(tx.hasTransferRate()); + } + + { + auto const& expected = setFlagValue; + auto const actualOpt = tx.getSetFlag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSetFlag should be present"; + expectEqualField(expected, *actualOpt, "sfSetFlag"); + EXPECT_TRUE(tx.hasSetFlag()); + } + + { + auto const& expected = clearFlagValue; + auto const actualOpt = tx.getClearFlag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfClearFlag should be present"; + expectEqualField(expected, *actualOpt, "sfClearFlag"); + EXPECT_TRUE(tx.hasClearFlag()); + } + + { + auto const& expected = tickSizeValue; + auto const actualOpt = tx.getTickSize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTickSize should be present"; + expectEqualField(expected, *actualOpt, "sfTickSize"); + EXPECT_TRUE(tx.hasTickSize()); + } + + { + auto const& expected = nFTokenMinterValue; + auto const actualOpt = tx.getNFTokenMinter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenMinter should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenMinter"); + EXPECT_TRUE(tx.hasNFTokenMinter()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsAccountSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAccountSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const emailHashValue = canonical_UINT128(); + auto const walletLocatorValue = canonical_UINT256(); + auto const walletSizeValue = canonical_UINT32(); + auto const messageKeyValue = canonical_VL(); + auto const domainValue = canonical_VL(); + auto const transferRateValue = canonical_UINT32(); + auto const setFlagValue = canonical_UINT32(); + auto const clearFlagValue = canonical_UINT32(); + auto const tickSizeValue = canonical_UINT8(); + auto const nFTokenMinterValue = canonical_ACCOUNT(); + + // Build an initial transaction + AccountSetBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setEmailHash(emailHashValue); + initialBuilder.setWalletLocator(walletLocatorValue); + initialBuilder.setWalletSize(walletSizeValue); + initialBuilder.setMessageKey(messageKeyValue); + initialBuilder.setDomain(domainValue); + initialBuilder.setTransferRate(transferRateValue); + initialBuilder.setSetFlag(setFlagValue); + initialBuilder.setClearFlag(clearFlagValue); + initialBuilder.setTickSize(tickSizeValue); + initialBuilder.setNFTokenMinter(nFTokenMinterValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + AccountSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = emailHashValue; + auto const actualOpt = rebuiltTx.getEmailHash(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfEmailHash should be present"; + expectEqualField(expected, *actualOpt, "sfEmailHash"); + } + + { + auto const& expected = walletLocatorValue; + auto const actualOpt = rebuiltTx.getWalletLocator(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWalletLocator should be present"; + expectEqualField(expected, *actualOpt, "sfWalletLocator"); + } + + { + auto const& expected = walletSizeValue; + auto const actualOpt = rebuiltTx.getWalletSize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWalletSize should be present"; + expectEqualField(expected, *actualOpt, "sfWalletSize"); + } + + { + auto const& expected = messageKeyValue; + auto const actualOpt = rebuiltTx.getMessageKey(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMessageKey should be present"; + expectEqualField(expected, *actualOpt, "sfMessageKey"); + } + + { + auto const& expected = domainValue; + auto const actualOpt = rebuiltTx.getDomain(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomain should be present"; + expectEqualField(expected, *actualOpt, "sfDomain"); + } + + { + auto const& expected = transferRateValue; + auto const actualOpt = rebuiltTx.getTransferRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferRate should be present"; + expectEqualField(expected, *actualOpt, "sfTransferRate"); + } + + { + auto const& expected = setFlagValue; + auto const actualOpt = rebuiltTx.getSetFlag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSetFlag should be present"; + expectEqualField(expected, *actualOpt, "sfSetFlag"); + } + + { + auto const& expected = clearFlagValue; + auto const actualOpt = rebuiltTx.getClearFlag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfClearFlag should be present"; + expectEqualField(expected, *actualOpt, "sfClearFlag"); + } + + { + auto const& expected = tickSizeValue; + auto const actualOpt = rebuiltTx.getTickSize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTickSize should be present"; + expectEqualField(expected, *actualOpt, "sfTickSize"); + } + + { + auto const& expected = nFTokenMinterValue; + auto const actualOpt = rebuiltTx.getNFTokenMinter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenMinter should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenMinter"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsAccountSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + OfferCancelBuilder wrongBuilder{account, canonical_UINT32(), 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AccountSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsAccountSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + OfferCancelBuilder wrongBuilder{account, canonical_UINT32(), 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(AccountSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsAccountSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testAccountSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + AccountSetBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasEmailHash()); + EXPECT_FALSE(tx.getEmailHash().has_value()); + EXPECT_FALSE(tx.hasWalletLocator()); + EXPECT_FALSE(tx.getWalletLocator().has_value()); + EXPECT_FALSE(tx.hasWalletSize()); + EXPECT_FALSE(tx.getWalletSize().has_value()); + EXPECT_FALSE(tx.hasMessageKey()); + EXPECT_FALSE(tx.getMessageKey().has_value()); + EXPECT_FALSE(tx.hasDomain()); + EXPECT_FALSE(tx.getDomain().has_value()); + EXPECT_FALSE(tx.hasTransferRate()); + EXPECT_FALSE(tx.getTransferRate().has_value()); + EXPECT_FALSE(tx.hasSetFlag()); + EXPECT_FALSE(tx.getSetFlag().has_value()); + EXPECT_FALSE(tx.hasClearFlag()); + EXPECT_FALSE(tx.getClearFlag().has_value()); + EXPECT_FALSE(tx.hasTickSize()); + EXPECT_FALSE(tx.getTickSize().has_value()); + EXPECT_FALSE(tx.hasNFTokenMinter()); + EXPECT_FALSE(tx.getNFTokenMinter().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/BatchTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/BatchTests.cpp new file mode 100644 index 0000000000..c6818a26d7 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/BatchTests.cpp @@ -0,0 +1,195 @@ +// Auto-generated unit tests for transaction Batch + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsBatchTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testBatch")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const rawTransactionsValue = canonical_ARRAY(); + auto const batchSignersValue = canonical_ARRAY(); + + BatchBuilder builder{ + accountValue, + rawTransactionsValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setBatchSigners(batchSignersValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = rawTransactionsValue; + auto const actual = tx.getRawTransactions(); + expectEqualField(expected, actual, "sfRawTransactions"); + } + + // Verify optional fields + { + auto const& expected = batchSignersValue; + auto const actualOpt = tx.getBatchSigners(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBatchSigners should be present"; + expectEqualField(expected, *actualOpt, "sfBatchSigners"); + EXPECT_TRUE(tx.hasBatchSigners()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsBatchTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testBatchFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const rawTransactionsValue = canonical_ARRAY(); + auto const batchSignersValue = canonical_ARRAY(); + + // Build an initial transaction + BatchBuilder initialBuilder{ + accountValue, + rawTransactionsValue, + sequenceValue, + feeValue + }; + + initialBuilder.setBatchSigners(batchSignersValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + BatchBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = rawTransactionsValue; + auto const actual = rebuiltTx.getRawTransactions(); + expectEqualField(expected, actual, "sfRawTransactions"); + } + + // Verify optional fields + { + auto const& expected = batchSignersValue; + auto const actualOpt = rebuiltTx.getBatchSigners(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBatchSigners should be present"; + expectEqualField(expected, *actualOpt, "sfBatchSigners"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsBatchTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(Batch{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsBatchTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(BatchBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsBatchTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testBatchNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const rawTransactionsValue = canonical_ARRAY(); + + BatchBuilder builder{ + accountValue, + rawTransactionsValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasBatchSigners()); + EXPECT_FALSE(tx.getBatchSigners().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/CheckCancelTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/CheckCancelTests.cpp new file mode 100644 index 0000000000..afdc2d6d66 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/CheckCancelTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction CheckCancel + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsCheckCancelTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCancel")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const checkIDValue = canonical_UINT256(); + + CheckCancelBuilder builder{ + accountValue, + checkIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = checkIDValue; + auto const actual = tx.getCheckID(); + expectEqualField(expected, actual, "sfCheckID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsCheckCancelTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCancelFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const checkIDValue = canonical_UINT256(); + + // Build an initial transaction + CheckCancelBuilder initialBuilder{ + accountValue, + checkIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + CheckCancelBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = checkIDValue; + auto const actual = rebuiltTx.getCheckID(); + expectEqualField(expected, actual, "sfCheckID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsCheckCancelTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CheckCancel{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsCheckCancelTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CheckCancelBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/CheckCashTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/CheckCashTests.cpp new file mode 100644 index 0000000000..b8c4dccd55 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/CheckCashTests.cpp @@ -0,0 +1,216 @@ +// Auto-generated unit tests for transaction CheckCash + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsCheckCashTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCash")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const checkIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const deliverMinValue = canonical_AMOUNT(); + + CheckCashBuilder builder{ + accountValue, + checkIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAmount(amountValue); + builder.setDeliverMin(deliverMinValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = checkIDValue; + auto const actual = tx.getCheckID(); + expectEqualField(expected, actual, "sfCheckID"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + + { + auto const& expected = deliverMinValue; + auto const actualOpt = tx.getDeliverMin(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDeliverMin should be present"; + expectEqualField(expected, *actualOpt, "sfDeliverMin"); + EXPECT_TRUE(tx.hasDeliverMin()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsCheckCashTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCashFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const checkIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const deliverMinValue = canonical_AMOUNT(); + + // Build an initial transaction + CheckCashBuilder initialBuilder{ + accountValue, + checkIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setAmount(amountValue); + initialBuilder.setDeliverMin(deliverMinValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + CheckCashBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = checkIDValue; + auto const actual = rebuiltTx.getCheckID(); + expectEqualField(expected, actual, "sfCheckID"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + + { + auto const& expected = deliverMinValue; + auto const actualOpt = rebuiltTx.getDeliverMin(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDeliverMin should be present"; + expectEqualField(expected, *actualOpt, "sfDeliverMin"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsCheckCashTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CheckCash{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsCheckCashTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CheckCashBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsCheckCashTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCashNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const checkIDValue = canonical_UINT256(); + + CheckCashBuilder builder{ + accountValue, + checkIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); + EXPECT_FALSE(tx.hasDeliverMin()); + EXPECT_FALSE(tx.getDeliverMin().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/CheckCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/CheckCreateTests.cpp new file mode 100644 index 0000000000..9b8a831913 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/CheckCreateTests.cpp @@ -0,0 +1,255 @@ +// Auto-generated unit tests for transaction CheckCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsCheckCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + auto const expirationValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const invoiceIDValue = canonical_UINT256(); + + CheckCreateBuilder builder{ + accountValue, + destinationValue, + sendMaxValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setExpiration(expirationValue); + builder.setDestinationTag(destinationTagValue); + builder.setInvoiceID(invoiceIDValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = sendMaxValue; + auto const actual = tx.getSendMax(); + expectEqualField(expected, actual, "sfSendMax"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = tx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(tx.hasExpiration()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + + { + auto const& expected = invoiceIDValue; + auto const actualOpt = tx.getInvoiceID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfInvoiceID should be present"; + expectEqualField(expected, *actualOpt, "sfInvoiceID"); + EXPECT_TRUE(tx.hasInvoiceID()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsCheckCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + auto const expirationValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + auto const invoiceIDValue = canonical_UINT256(); + + // Build an initial transaction + CheckCreateBuilder initialBuilder{ + accountValue, + destinationValue, + sendMaxValue, + sequenceValue, + feeValue + }; + + initialBuilder.setExpiration(expirationValue); + initialBuilder.setDestinationTag(destinationTagValue); + initialBuilder.setInvoiceID(invoiceIDValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + CheckCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = sendMaxValue; + auto const actual = rebuiltTx.getSendMax(); + expectEqualField(expected, actual, "sfSendMax"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = rebuiltTx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + + { + auto const& expected = invoiceIDValue; + auto const actualOpt = rebuiltTx.getInvoiceID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfInvoiceID should be present"; + expectEqualField(expected, *actualOpt, "sfInvoiceID"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsCheckCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CheckCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsCheckCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CheckCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsCheckCreateTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCheckCreateNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const destinationValue = canonical_ACCOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + + CheckCreateBuilder builder{ + accountValue, + destinationValue, + sendMaxValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasExpiration()); + EXPECT_FALSE(tx.getExpiration().has_value()); + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); + EXPECT_FALSE(tx.hasInvoiceID()); + EXPECT_FALSE(tx.getInvoiceID().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/ClawbackTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/ClawbackTests.cpp new file mode 100644 index 0000000000..2f9b7f1e3a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/ClawbackTests.cpp @@ -0,0 +1,195 @@ +// Auto-generated unit tests for transaction Clawback + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsClawbackTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testClawback")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const amountValue = canonical_AMOUNT(); + auto const holderValue = canonical_ACCOUNT(); + + ClawbackBuilder builder{ + accountValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setHolder(holderValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = holderValue; + auto const actualOpt = tx.getHolder(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present"; + expectEqualField(expected, *actualOpt, "sfHolder"); + EXPECT_TRUE(tx.hasHolder()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsClawbackTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testClawbackFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const amountValue = canonical_AMOUNT(); + auto const holderValue = canonical_ACCOUNT(); + + // Build an initial transaction + ClawbackBuilder initialBuilder{ + accountValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setHolder(holderValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + ClawbackBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = holderValue; + auto const actualOpt = rebuiltTx.getHolder(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present"; + expectEqualField(expected, *actualOpt, "sfHolder"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsClawbackTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(Clawback{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsClawbackTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(ClawbackBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsClawbackTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testClawbackNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const amountValue = canonical_AMOUNT(); + + ClawbackBuilder builder{ + accountValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasHolder()); + EXPECT_FALSE(tx.getHolder().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/CredentialAcceptTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/CredentialAcceptTests.cpp new file mode 100644 index 0000000000..5ae9c8a181 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/CredentialAcceptTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction CredentialAccept + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsCredentialAcceptTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialAccept")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const issuerValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + + CredentialAcceptBuilder builder{ + accountValue, + issuerValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = issuerValue; + auto const actual = tx.getIssuer(); + expectEqualField(expected, actual, "sfIssuer"); + } + + { + auto const& expected = credentialTypeValue; + auto const actual = tx.getCredentialType(); + expectEqualField(expected, actual, "sfCredentialType"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsCredentialAcceptTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialAcceptFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const issuerValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + + // Build an initial transaction + CredentialAcceptBuilder initialBuilder{ + accountValue, + issuerValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + CredentialAcceptBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = issuerValue; + auto const actual = rebuiltTx.getIssuer(); + expectEqualField(expected, actual, "sfIssuer"); + } + + { + auto const& expected = credentialTypeValue; + auto const actual = rebuiltTx.getCredentialType(); + expectEqualField(expected, actual, "sfCredentialType"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsCredentialAcceptTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CredentialAccept{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsCredentialAcceptTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CredentialAcceptBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/CredentialCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/CredentialCreateTests.cpp new file mode 100644 index 0000000000..0bfa9def33 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/CredentialCreateTests.cpp @@ -0,0 +1,234 @@ +// Auto-generated unit tests for transaction CredentialCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsCredentialCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const subjectValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + auto const expirationValue = canonical_UINT32(); + auto const uRIValue = canonical_VL(); + + CredentialCreateBuilder builder{ + accountValue, + subjectValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setExpiration(expirationValue); + builder.setURI(uRIValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = subjectValue; + auto const actual = tx.getSubject(); + expectEqualField(expected, actual, "sfSubject"); + } + + { + auto const& expected = credentialTypeValue; + auto const actual = tx.getCredentialType(); + expectEqualField(expected, actual, "sfCredentialType"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = tx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(tx.hasExpiration()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = tx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(tx.hasURI()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsCredentialCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const subjectValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + auto const expirationValue = canonical_UINT32(); + auto const uRIValue = canonical_VL(); + + // Build an initial transaction + CredentialCreateBuilder initialBuilder{ + accountValue, + subjectValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + initialBuilder.setExpiration(expirationValue); + initialBuilder.setURI(uRIValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + CredentialCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = subjectValue; + auto const actual = rebuiltTx.getSubject(); + expectEqualField(expected, actual, "sfSubject"); + } + + { + auto const& expected = credentialTypeValue; + auto const actual = rebuiltTx.getCredentialType(); + expectEqualField(expected, actual, "sfCredentialType"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = rebuiltTx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = rebuiltTx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsCredentialCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CredentialCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsCredentialCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CredentialCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsCredentialCreateTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialCreateNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const subjectValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + + CredentialCreateBuilder builder{ + accountValue, + subjectValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasExpiration()); + EXPECT_FALSE(tx.getExpiration().has_value()); + EXPECT_FALSE(tx.hasURI()); + EXPECT_FALSE(tx.getURI().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/CredentialDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/CredentialDeleteTests.cpp new file mode 100644 index 0000000000..26bba2ba1a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/CredentialDeleteTests.cpp @@ -0,0 +1,216 @@ +// Auto-generated unit tests for transaction CredentialDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsCredentialDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const subjectValue = canonical_ACCOUNT(); + auto const issuerValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + + CredentialDeleteBuilder builder{ + accountValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setSubject(subjectValue); + builder.setIssuer(issuerValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = credentialTypeValue; + auto const actual = tx.getCredentialType(); + expectEqualField(expected, actual, "sfCredentialType"); + } + + // Verify optional fields + { + auto const& expected = subjectValue; + auto const actualOpt = tx.getSubject(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSubject should be present"; + expectEqualField(expected, *actualOpt, "sfSubject"); + EXPECT_TRUE(tx.hasSubject()); + } + + { + auto const& expected = issuerValue; + auto const actualOpt = tx.getIssuer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfIssuer should be present"; + expectEqualField(expected, *actualOpt, "sfIssuer"); + EXPECT_TRUE(tx.hasIssuer()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsCredentialDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const subjectValue = canonical_ACCOUNT(); + auto const issuerValue = canonical_ACCOUNT(); + auto const credentialTypeValue = canonical_VL(); + + // Build an initial transaction + CredentialDeleteBuilder initialBuilder{ + accountValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + initialBuilder.setSubject(subjectValue); + initialBuilder.setIssuer(issuerValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + CredentialDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = credentialTypeValue; + auto const actual = rebuiltTx.getCredentialType(); + expectEqualField(expected, actual, "sfCredentialType"); + } + + // Verify optional fields + { + auto const& expected = subjectValue; + auto const actualOpt = rebuiltTx.getSubject(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSubject should be present"; + expectEqualField(expected, *actualOpt, "sfSubject"); + } + + { + auto const& expected = issuerValue; + auto const actualOpt = rebuiltTx.getIssuer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfIssuer should be present"; + expectEqualField(expected, *actualOpt, "sfIssuer"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsCredentialDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CredentialDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsCredentialDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(CredentialDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsCredentialDeleteTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testCredentialDeleteNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const credentialTypeValue = canonical_VL(); + + CredentialDeleteBuilder builder{ + accountValue, + credentialTypeValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasSubject()); + EXPECT_FALSE(tx.getSubject().has_value()); + EXPECT_FALSE(tx.hasIssuer()); + EXPECT_FALSE(tx.getIssuer().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/DIDDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/DIDDeleteTests.cpp new file mode 100644 index 0000000000..e60ef99fb1 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/DIDDeleteTests.cpp @@ -0,0 +1,130 @@ +// Auto-generated unit tests for transaction DIDDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsDIDDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDIDDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + + DIDDeleteBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsDIDDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDIDDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + + // Build an initial transaction + DIDDeleteBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + DIDDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsDIDDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DIDDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsDIDDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DIDDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/DIDSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/DIDSetTests.cpp new file mode 100644 index 0000000000..07215e6966 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/DIDSetTests.cpp @@ -0,0 +1,219 @@ +// Auto-generated unit tests for transaction DIDSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsDIDSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDIDSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const dIDDocumentValue = canonical_VL(); + auto const uRIValue = canonical_VL(); + auto const dataValue = canonical_VL(); + + DIDSetBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDIDDocument(dIDDocumentValue); + builder.setURI(uRIValue); + builder.setData(dataValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = dIDDocumentValue; + auto const actualOpt = tx.getDIDDocument(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDIDDocument should be present"; + expectEqualField(expected, *actualOpt, "sfDIDDocument"); + EXPECT_TRUE(tx.hasDIDDocument()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = tx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(tx.hasURI()); + } + + { + auto const& expected = dataValue; + auto const actualOpt = tx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(tx.hasData()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsDIDSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDIDSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const dIDDocumentValue = canonical_VL(); + auto const uRIValue = canonical_VL(); + auto const dataValue = canonical_VL(); + + // Build an initial transaction + DIDSetBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDIDDocument(dIDDocumentValue); + initialBuilder.setURI(uRIValue); + initialBuilder.setData(dataValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + DIDSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = dIDDocumentValue; + auto const actualOpt = rebuiltTx.getDIDDocument(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDIDDocument should be present"; + expectEqualField(expected, *actualOpt, "sfDIDDocument"); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = rebuiltTx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + } + + { + auto const& expected = dataValue; + auto const actualOpt = rebuiltTx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsDIDSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DIDSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsDIDSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DIDSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsDIDSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDIDSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + DIDSetBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDIDDocument()); + EXPECT_FALSE(tx.getDIDDocument().has_value()); + EXPECT_FALSE(tx.hasURI()); + EXPECT_FALSE(tx.getURI().has_value()); + EXPECT_FALSE(tx.hasData()); + EXPECT_FALSE(tx.getData().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/DelegateSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/DelegateSetTests.cpp new file mode 100644 index 0000000000..8e7fed9419 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/DelegateSetTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction DelegateSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsDelegateSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDelegateSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const authorizeValue = canonical_ACCOUNT(); + auto const permissionsValue = canonical_ARRAY(); + + DelegateSetBuilder builder{ + accountValue, + authorizeValue, + permissionsValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = authorizeValue; + auto const actual = tx.getAuthorize(); + expectEqualField(expected, actual, "sfAuthorize"); + } + + { + auto const& expected = permissionsValue; + auto const actual = tx.getPermissions(); + expectEqualField(expected, actual, "sfPermissions"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsDelegateSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDelegateSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const authorizeValue = canonical_ACCOUNT(); + auto const permissionsValue = canonical_ARRAY(); + + // Build an initial transaction + DelegateSetBuilder initialBuilder{ + accountValue, + authorizeValue, + permissionsValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + DelegateSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = authorizeValue; + auto const actual = rebuiltTx.getAuthorize(); + expectEqualField(expected, actual, "sfAuthorize"); + } + + { + auto const& expected = permissionsValue; + auto const actual = rebuiltTx.getPermissions(); + expectEqualField(expected, actual, "sfPermissions"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsDelegateSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DelegateSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsDelegateSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DelegateSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/DepositPreauthTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/DepositPreauthTests.cpp new file mode 100644 index 0000000000..36232eb220 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/DepositPreauthTests.cpp @@ -0,0 +1,240 @@ +// Auto-generated unit tests for transaction DepositPreauth + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsDepositPreauthTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDepositPreauth")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const authorizeValue = canonical_ACCOUNT(); + auto const unauthorizeValue = canonical_ACCOUNT(); + auto const authorizeCredentialsValue = canonical_ARRAY(); + auto const unauthorizeCredentialsValue = canonical_ARRAY(); + + DepositPreauthBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAuthorize(authorizeValue); + builder.setUnauthorize(unauthorizeValue); + builder.setAuthorizeCredentials(authorizeCredentialsValue); + builder.setUnauthorizeCredentials(unauthorizeCredentialsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = authorizeValue; + auto const actualOpt = tx.getAuthorize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuthorize should be present"; + expectEqualField(expected, *actualOpt, "sfAuthorize"); + EXPECT_TRUE(tx.hasAuthorize()); + } + + { + auto const& expected = unauthorizeValue; + auto const actualOpt = tx.getUnauthorize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfUnauthorize should be present"; + expectEqualField(expected, *actualOpt, "sfUnauthorize"); + EXPECT_TRUE(tx.hasUnauthorize()); + } + + { + auto const& expected = authorizeCredentialsValue; + auto const actualOpt = tx.getAuthorizeCredentials(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuthorizeCredentials should be present"; + expectEqualField(expected, *actualOpt, "sfAuthorizeCredentials"); + EXPECT_TRUE(tx.hasAuthorizeCredentials()); + } + + { + auto const& expected = unauthorizeCredentialsValue; + auto const actualOpt = tx.getUnauthorizeCredentials(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfUnauthorizeCredentials should be present"; + expectEqualField(expected, *actualOpt, "sfUnauthorizeCredentials"); + EXPECT_TRUE(tx.hasUnauthorizeCredentials()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsDepositPreauthTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDepositPreauthFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const authorizeValue = canonical_ACCOUNT(); + auto const unauthorizeValue = canonical_ACCOUNT(); + auto const authorizeCredentialsValue = canonical_ARRAY(); + auto const unauthorizeCredentialsValue = canonical_ARRAY(); + + // Build an initial transaction + DepositPreauthBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setAuthorize(authorizeValue); + initialBuilder.setUnauthorize(unauthorizeValue); + initialBuilder.setAuthorizeCredentials(authorizeCredentialsValue); + initialBuilder.setUnauthorizeCredentials(unauthorizeCredentialsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + DepositPreauthBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = authorizeValue; + auto const actualOpt = rebuiltTx.getAuthorize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuthorize should be present"; + expectEqualField(expected, *actualOpt, "sfAuthorize"); + } + + { + auto const& expected = unauthorizeValue; + auto const actualOpt = rebuiltTx.getUnauthorize(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfUnauthorize should be present"; + expectEqualField(expected, *actualOpt, "sfUnauthorize"); + } + + { + auto const& expected = authorizeCredentialsValue; + auto const actualOpt = rebuiltTx.getAuthorizeCredentials(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuthorizeCredentials should be present"; + expectEqualField(expected, *actualOpt, "sfAuthorizeCredentials"); + } + + { + auto const& expected = unauthorizeCredentialsValue; + auto const actualOpt = rebuiltTx.getUnauthorizeCredentials(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfUnauthorizeCredentials should be present"; + expectEqualField(expected, *actualOpt, "sfUnauthorizeCredentials"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsDepositPreauthTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DepositPreauth{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsDepositPreauthTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(DepositPreauthBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsDepositPreauthTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testDepositPreauthNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + DepositPreauthBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAuthorize()); + EXPECT_FALSE(tx.getAuthorize().has_value()); + EXPECT_FALSE(tx.hasUnauthorize()); + EXPECT_FALSE(tx.getUnauthorize().has_value()); + EXPECT_FALSE(tx.hasAuthorizeCredentials()); + EXPECT_FALSE(tx.getAuthorizeCredentials().has_value()); + EXPECT_FALSE(tx.hasUnauthorizeCredentials()); + EXPECT_FALSE(tx.getUnauthorizeCredentials().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/EnableAmendmentTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/EnableAmendmentTests.cpp new file mode 100644 index 0000000000..e9dfe892e4 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/EnableAmendmentTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction EnableAmendment + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsEnableAmendmentTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEnableAmendment")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ledgerSequenceValue = canonical_UINT32(); + auto const amendmentValue = canonical_UINT256(); + + EnableAmendmentBuilder builder{ + accountValue, + ledgerSequenceValue, + amendmentValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ledgerSequenceValue; + auto const actual = tx.getLedgerSequence(); + expectEqualField(expected, actual, "sfLedgerSequence"); + } + + { + auto const& expected = amendmentValue; + auto const actual = tx.getAmendment(); + expectEqualField(expected, actual, "sfAmendment"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsEnableAmendmentTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEnableAmendmentFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ledgerSequenceValue = canonical_UINT32(); + auto const amendmentValue = canonical_UINT256(); + + // Build an initial transaction + EnableAmendmentBuilder initialBuilder{ + accountValue, + ledgerSequenceValue, + amendmentValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + EnableAmendmentBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ledgerSequenceValue; + auto const actual = rebuiltTx.getLedgerSequence(); + expectEqualField(expected, actual, "sfLedgerSequence"); + } + + { + auto const& expected = amendmentValue; + auto const actual = rebuiltTx.getAmendment(); + expectEqualField(expected, actual, "sfAmendment"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsEnableAmendmentTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EnableAmendment{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsEnableAmendmentTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EnableAmendmentBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/EscrowCancelTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/EscrowCancelTests.cpp new file mode 100644 index 0000000000..300a9b7615 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/EscrowCancelTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction EscrowCancel + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsEscrowCancelTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowCancel")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ownerValue = canonical_ACCOUNT(); + auto const offerSequenceValue = canonical_UINT32(); + + EscrowCancelBuilder builder{ + accountValue, + ownerValue, + offerSequenceValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ownerValue; + auto const actual = tx.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = offerSequenceValue; + auto const actual = tx.getOfferSequence(); + expectEqualField(expected, actual, "sfOfferSequence"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsEscrowCancelTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowCancelFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ownerValue = canonical_ACCOUNT(); + auto const offerSequenceValue = canonical_UINT32(); + + // Build an initial transaction + EscrowCancelBuilder initialBuilder{ + accountValue, + ownerValue, + offerSequenceValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + EscrowCancelBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ownerValue; + auto const actual = rebuiltTx.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = offerSequenceValue; + auto const actual = rebuiltTx.getOfferSequence(); + expectEqualField(expected, actual, "sfOfferSequence"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsEscrowCancelTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EscrowCancel{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsEscrowCancelTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EscrowCancelBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/EscrowCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/EscrowCreateTests.cpp new file mode 100644 index 0000000000..1f9b3d30a9 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/EscrowCreateTests.cpp @@ -0,0 +1,276 @@ +// Auto-generated unit tests for transaction EscrowCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsEscrowCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const conditionValue = canonical_VL(); + auto const cancelAfterValue = canonical_UINT32(); + auto const finishAfterValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + + EscrowCreateBuilder builder{ + accountValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setCondition(conditionValue); + builder.setCancelAfter(cancelAfterValue); + builder.setFinishAfter(finishAfterValue); + builder.setDestinationTag(destinationTagValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = conditionValue; + auto const actualOpt = tx.getCondition(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCondition should be present"; + expectEqualField(expected, *actualOpt, "sfCondition"); + EXPECT_TRUE(tx.hasCondition()); + } + + { + auto const& expected = cancelAfterValue; + auto const actualOpt = tx.getCancelAfter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCancelAfter should be present"; + expectEqualField(expected, *actualOpt, "sfCancelAfter"); + EXPECT_TRUE(tx.hasCancelAfter()); + } + + { + auto const& expected = finishAfterValue; + auto const actualOpt = tx.getFinishAfter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfFinishAfter should be present"; + expectEqualField(expected, *actualOpt, "sfFinishAfter"); + EXPECT_TRUE(tx.hasFinishAfter()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsEscrowCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const conditionValue = canonical_VL(); + auto const cancelAfterValue = canonical_UINT32(); + auto const finishAfterValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + + // Build an initial transaction + EscrowCreateBuilder initialBuilder{ + accountValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setCondition(conditionValue); + initialBuilder.setCancelAfter(cancelAfterValue); + initialBuilder.setFinishAfter(finishAfterValue); + initialBuilder.setDestinationTag(destinationTagValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + EscrowCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = conditionValue; + auto const actualOpt = rebuiltTx.getCondition(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCondition should be present"; + expectEqualField(expected, *actualOpt, "sfCondition"); + } + + { + auto const& expected = cancelAfterValue; + auto const actualOpt = rebuiltTx.getCancelAfter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCancelAfter should be present"; + expectEqualField(expected, *actualOpt, "sfCancelAfter"); + } + + { + auto const& expected = finishAfterValue; + auto const actualOpt = rebuiltTx.getFinishAfter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfFinishAfter should be present"; + expectEqualField(expected, *actualOpt, "sfFinishAfter"); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsEscrowCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EscrowCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsEscrowCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EscrowCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsEscrowCreateTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowCreateNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + + EscrowCreateBuilder builder{ + accountValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasCondition()); + EXPECT_FALSE(tx.getCondition().has_value()); + EXPECT_FALSE(tx.hasCancelAfter()); + EXPECT_FALSE(tx.getCancelAfter().has_value()); + EXPECT_FALSE(tx.hasFinishAfter()); + EXPECT_FALSE(tx.getFinishAfter().has_value()); + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/EscrowFinishTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/EscrowFinishTests.cpp new file mode 100644 index 0000000000..f729d0fda3 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/EscrowFinishTests.cpp @@ -0,0 +1,255 @@ +// Auto-generated unit tests for transaction EscrowFinish + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsEscrowFinishTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowFinish")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ownerValue = canonical_ACCOUNT(); + auto const offerSequenceValue = canonical_UINT32(); + auto const fulfillmentValue = canonical_VL(); + auto const conditionValue = canonical_VL(); + auto const credentialIDsValue = canonical_VECTOR256(); + + EscrowFinishBuilder builder{ + accountValue, + ownerValue, + offerSequenceValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setFulfillment(fulfillmentValue); + builder.setCondition(conditionValue); + builder.setCredentialIDs(credentialIDsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ownerValue; + auto const actual = tx.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = offerSequenceValue; + auto const actual = tx.getOfferSequence(); + expectEqualField(expected, actual, "sfOfferSequence"); + } + + // Verify optional fields + { + auto const& expected = fulfillmentValue; + auto const actualOpt = tx.getFulfillment(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfFulfillment should be present"; + expectEqualField(expected, *actualOpt, "sfFulfillment"); + EXPECT_TRUE(tx.hasFulfillment()); + } + + { + auto const& expected = conditionValue; + auto const actualOpt = tx.getCondition(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCondition should be present"; + expectEqualField(expected, *actualOpt, "sfCondition"); + EXPECT_TRUE(tx.hasCondition()); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = tx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + EXPECT_TRUE(tx.hasCredentialIDs()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsEscrowFinishTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowFinishFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ownerValue = canonical_ACCOUNT(); + auto const offerSequenceValue = canonical_UINT32(); + auto const fulfillmentValue = canonical_VL(); + auto const conditionValue = canonical_VL(); + auto const credentialIDsValue = canonical_VECTOR256(); + + // Build an initial transaction + EscrowFinishBuilder initialBuilder{ + accountValue, + ownerValue, + offerSequenceValue, + sequenceValue, + feeValue + }; + + initialBuilder.setFulfillment(fulfillmentValue); + initialBuilder.setCondition(conditionValue); + initialBuilder.setCredentialIDs(credentialIDsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + EscrowFinishBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ownerValue; + auto const actual = rebuiltTx.getOwner(); + expectEqualField(expected, actual, "sfOwner"); + } + + { + auto const& expected = offerSequenceValue; + auto const actual = rebuiltTx.getOfferSequence(); + expectEqualField(expected, actual, "sfOfferSequence"); + } + + // Verify optional fields + { + auto const& expected = fulfillmentValue; + auto const actualOpt = rebuiltTx.getFulfillment(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfFulfillment should be present"; + expectEqualField(expected, *actualOpt, "sfFulfillment"); + } + + { + auto const& expected = conditionValue; + auto const actualOpt = rebuiltTx.getCondition(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCondition should be present"; + expectEqualField(expected, *actualOpt, "sfCondition"); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = rebuiltTx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsEscrowFinishTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EscrowFinish{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsEscrowFinishTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(EscrowFinishBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsEscrowFinishTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testEscrowFinishNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const ownerValue = canonical_ACCOUNT(); + auto const offerSequenceValue = canonical_UINT32(); + + EscrowFinishBuilder builder{ + accountValue, + ownerValue, + offerSequenceValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasFulfillment()); + EXPECT_FALSE(tx.getFulfillment().has_value()); + EXPECT_FALSE(tx.hasCondition()); + EXPECT_FALSE(tx.getCondition().has_value()); + EXPECT_FALSE(tx.hasCredentialIDs()); + EXPECT_FALSE(tx.getCredentialIDs().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LedgerStateFixTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LedgerStateFixTests.cpp new file mode 100644 index 0000000000..b366605a4f --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LedgerStateFixTests.cpp @@ -0,0 +1,195 @@ +// Auto-generated unit tests for transaction LedgerStateFix + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLedgerStateFixTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLedgerStateFix")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ledgerFixTypeValue = canonical_UINT16(); + auto const ownerValue = canonical_ACCOUNT(); + + LedgerStateFixBuilder builder{ + accountValue, + ledgerFixTypeValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setOwner(ownerValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ledgerFixTypeValue; + auto const actual = tx.getLedgerFixType(); + expectEqualField(expected, actual, "sfLedgerFixType"); + } + + // Verify optional fields + { + auto const& expected = ownerValue; + auto const actualOpt = tx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + EXPECT_TRUE(tx.hasOwner()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLedgerStateFixTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLedgerStateFixFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ledgerFixTypeValue = canonical_UINT16(); + auto const ownerValue = canonical_ACCOUNT(); + + // Build an initial transaction + LedgerStateFixBuilder initialBuilder{ + accountValue, + ledgerFixTypeValue, + sequenceValue, + feeValue + }; + + initialBuilder.setOwner(ownerValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LedgerStateFixBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ledgerFixTypeValue; + auto const actual = rebuiltTx.getLedgerFixType(); + expectEqualField(expected, actual, "sfLedgerFixType"); + } + + // Verify optional fields + { + auto const& expected = ownerValue; + auto const actualOpt = rebuiltTx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLedgerStateFixTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LedgerStateFix{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLedgerStateFixTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LedgerStateFixBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsLedgerStateFixTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLedgerStateFixNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const ledgerFixTypeValue = canonical_UINT16(); + + LedgerStateFixBuilder builder{ + accountValue, + ledgerFixTypeValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasOwner()); + EXPECT_FALSE(tx.getOwner().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverClawbackTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverClawbackTests.cpp new file mode 100644 index 0000000000..1e6c72f458 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverClawbackTests.cpp @@ -0,0 +1,198 @@ +// Auto-generated unit tests for transaction LoanBrokerCoverClawback + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanBrokerCoverClawbackTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverClawback")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + LoanBrokerCoverClawbackBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setLoanBrokerID(loanBrokerIDValue); + builder.setAmount(amountValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = loanBrokerIDValue; + auto const actualOpt = tx.getLoanBrokerID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanBrokerID should be present"; + expectEqualField(expected, *actualOpt, "sfLoanBrokerID"); + EXPECT_TRUE(tx.hasLoanBrokerID()); + } + + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanBrokerCoverClawbackTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverClawbackFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + // Build an initial transaction + LoanBrokerCoverClawbackBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setLoanBrokerID(loanBrokerIDValue); + initialBuilder.setAmount(amountValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanBrokerCoverClawbackBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = loanBrokerIDValue; + auto const actualOpt = rebuiltTx.getLoanBrokerID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanBrokerID should be present"; + expectEqualField(expected, *actualOpt, "sfLoanBrokerID"); + } + + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerCoverClawbackTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerCoverClawback{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerCoverClawbackTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerCoverClawbackBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsLoanBrokerCoverClawbackTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverClawbackNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + LoanBrokerCoverClawbackBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasLoanBrokerID()); + EXPECT_FALSE(tx.getLoanBrokerID().has_value()); + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverDepositTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverDepositTests.cpp new file mode 100644 index 0000000000..d6addb2fef --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverDepositTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction LoanBrokerCoverDeposit + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanBrokerCoverDepositTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverDeposit")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + LoanBrokerCoverDepositBuilder builder{ + accountValue, + loanBrokerIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = tx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanBrokerCoverDepositTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverDepositFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + // Build an initial transaction + LoanBrokerCoverDepositBuilder initialBuilder{ + accountValue, + loanBrokerIDValue, + amountValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanBrokerCoverDepositBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = rebuiltTx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerCoverDepositTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerCoverDeposit{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerCoverDepositTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerCoverDepositBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverWithdrawTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverWithdrawTests.cpp new file mode 100644 index 0000000000..3e66944e39 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerCoverWithdrawTests.cpp @@ -0,0 +1,234 @@ +// Auto-generated unit tests for transaction LoanBrokerCoverWithdraw + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanBrokerCoverWithdrawTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverWithdraw")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + + LoanBrokerCoverWithdrawBuilder builder{ + accountValue, + loanBrokerIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDestination(destinationValue); + builder.setDestinationTag(destinationTagValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = tx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = tx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + EXPECT_TRUE(tx.hasDestination()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanBrokerCoverWithdrawTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverWithdrawFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + + // Build an initial transaction + LoanBrokerCoverWithdrawBuilder initialBuilder{ + accountValue, + loanBrokerIDValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDestination(destinationValue); + initialBuilder.setDestinationTag(destinationTagValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanBrokerCoverWithdrawBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = rebuiltTx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = rebuiltTx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerCoverWithdrawTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerCoverWithdraw{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerCoverWithdrawTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerCoverWithdrawBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsLoanBrokerCoverWithdrawTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerCoverWithdrawNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + LoanBrokerCoverWithdrawBuilder builder{ + accountValue, + loanBrokerIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDestination()); + EXPECT_FALSE(tx.getDestination().has_value()); + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerDeleteTests.cpp new file mode 100644 index 0000000000..b557ab4397 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerDeleteTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction LoanBrokerDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanBrokerDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + + LoanBrokerDeleteBuilder builder{ + accountValue, + loanBrokerIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = tx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanBrokerDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + + // Build an initial transaction + LoanBrokerDeleteBuilder initialBuilder{ + accountValue, + loanBrokerIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanBrokerDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = rebuiltTx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerSetTests.cpp new file mode 100644 index 0000000000..e270332f42 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanBrokerSetTests.cpp @@ -0,0 +1,300 @@ +// Auto-generated unit tests for transaction LoanBrokerSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanBrokerSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const loanBrokerIDValue = canonical_UINT256(); + auto const dataValue = canonical_VL(); + auto const managementFeeRateValue = canonical_UINT16(); + auto const debtMaximumValue = canonical_NUMBER(); + auto const coverRateMinimumValue = canonical_UINT32(); + auto const coverRateLiquidationValue = canonical_UINT32(); + + LoanBrokerSetBuilder builder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setLoanBrokerID(loanBrokerIDValue); + builder.setData(dataValue); + builder.setManagementFeeRate(managementFeeRateValue); + builder.setDebtMaximum(debtMaximumValue); + builder.setCoverRateMinimum(coverRateMinimumValue); + builder.setCoverRateLiquidation(coverRateLiquidationValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = tx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + // Verify optional fields + { + auto const& expected = loanBrokerIDValue; + auto const actualOpt = tx.getLoanBrokerID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanBrokerID should be present"; + expectEqualField(expected, *actualOpt, "sfLoanBrokerID"); + EXPECT_TRUE(tx.hasLoanBrokerID()); + } + + { + auto const& expected = dataValue; + auto const actualOpt = tx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(tx.hasData()); + } + + { + auto const& expected = managementFeeRateValue; + auto const actualOpt = tx.getManagementFeeRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfManagementFeeRate should be present"; + expectEqualField(expected, *actualOpt, "sfManagementFeeRate"); + EXPECT_TRUE(tx.hasManagementFeeRate()); + } + + { + auto const& expected = debtMaximumValue; + auto const actualOpt = tx.getDebtMaximum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDebtMaximum should be present"; + expectEqualField(expected, *actualOpt, "sfDebtMaximum"); + EXPECT_TRUE(tx.hasDebtMaximum()); + } + + { + auto const& expected = coverRateMinimumValue; + auto const actualOpt = tx.getCoverRateMinimum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCoverRateMinimum should be present"; + expectEqualField(expected, *actualOpt, "sfCoverRateMinimum"); + EXPECT_TRUE(tx.hasCoverRateMinimum()); + } + + { + auto const& expected = coverRateLiquidationValue; + auto const actualOpt = tx.getCoverRateLiquidation(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCoverRateLiquidation should be present"; + expectEqualField(expected, *actualOpt, "sfCoverRateLiquidation"); + EXPECT_TRUE(tx.hasCoverRateLiquidation()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanBrokerSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const loanBrokerIDValue = canonical_UINT256(); + auto const dataValue = canonical_VL(); + auto const managementFeeRateValue = canonical_UINT16(); + auto const debtMaximumValue = canonical_NUMBER(); + auto const coverRateMinimumValue = canonical_UINT32(); + auto const coverRateLiquidationValue = canonical_UINT32(); + + // Build an initial transaction + LoanBrokerSetBuilder initialBuilder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setLoanBrokerID(loanBrokerIDValue); + initialBuilder.setData(dataValue); + initialBuilder.setManagementFeeRate(managementFeeRateValue); + initialBuilder.setDebtMaximum(debtMaximumValue); + initialBuilder.setCoverRateMinimum(coverRateMinimumValue); + initialBuilder.setCoverRateLiquidation(coverRateLiquidationValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanBrokerSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = rebuiltTx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + // Verify optional fields + { + auto const& expected = loanBrokerIDValue; + auto const actualOpt = rebuiltTx.getLoanBrokerID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanBrokerID should be present"; + expectEqualField(expected, *actualOpt, "sfLoanBrokerID"); + } + + { + auto const& expected = dataValue; + auto const actualOpt = rebuiltTx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + } + + { + auto const& expected = managementFeeRateValue; + auto const actualOpt = rebuiltTx.getManagementFeeRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfManagementFeeRate should be present"; + expectEqualField(expected, *actualOpt, "sfManagementFeeRate"); + } + + { + auto const& expected = debtMaximumValue; + auto const actualOpt = rebuiltTx.getDebtMaximum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDebtMaximum should be present"; + expectEqualField(expected, *actualOpt, "sfDebtMaximum"); + } + + { + auto const& expected = coverRateMinimumValue; + auto const actualOpt = rebuiltTx.getCoverRateMinimum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCoverRateMinimum should be present"; + expectEqualField(expected, *actualOpt, "sfCoverRateMinimum"); + } + + { + auto const& expected = coverRateLiquidationValue; + auto const actualOpt = rebuiltTx.getCoverRateLiquidation(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCoverRateLiquidation should be present"; + expectEqualField(expected, *actualOpt, "sfCoverRateLiquidation"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanBrokerSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanBrokerSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsLoanBrokerSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanBrokerSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const vaultIDValue = canonical_UINT256(); + + LoanBrokerSetBuilder builder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasLoanBrokerID()); + EXPECT_FALSE(tx.getLoanBrokerID().has_value()); + EXPECT_FALSE(tx.hasData()); + EXPECT_FALSE(tx.getData().has_value()); + EXPECT_FALSE(tx.hasManagementFeeRate()); + EXPECT_FALSE(tx.getManagementFeeRate().has_value()); + EXPECT_FALSE(tx.hasDebtMaximum()); + EXPECT_FALSE(tx.getDebtMaximum().has_value()); + EXPECT_FALSE(tx.hasCoverRateMinimum()); + EXPECT_FALSE(tx.getCoverRateMinimum().has_value()); + EXPECT_FALSE(tx.hasCoverRateLiquidation()); + EXPECT_FALSE(tx.getCoverRateLiquidation().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanDeleteTests.cpp new file mode 100644 index 0000000000..0edcdf4d06 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanDeleteTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction LoanDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanIDValue = canonical_UINT256(); + + LoanDeleteBuilder builder{ + accountValue, + loanIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanIDValue; + auto const actual = tx.getLoanID(); + expectEqualField(expected, actual, "sfLoanID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanIDValue = canonical_UINT256(); + + // Build an initial transaction + LoanDeleteBuilder initialBuilder{ + accountValue, + loanIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanIDValue; + auto const actual = rebuiltTx.getLoanID(); + expectEqualField(expected, actual, "sfLoanID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanManageTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanManageTests.cpp new file mode 100644 index 0000000000..bb842330d6 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanManageTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction LoanManage + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanManageTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanManage")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanIDValue = canonical_UINT256(); + + LoanManageBuilder builder{ + accountValue, + loanIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanIDValue; + auto const actual = tx.getLoanID(); + expectEqualField(expected, actual, "sfLoanID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanManageTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanManageFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanIDValue = canonical_UINT256(); + + // Build an initial transaction + LoanManageBuilder initialBuilder{ + accountValue, + loanIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanManageBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanIDValue; + auto const actual = rebuiltTx.getLoanID(); + expectEqualField(expected, actual, "sfLoanID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanManageTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanManage{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanManageTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanManageBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanPayTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanPayTests.cpp new file mode 100644 index 0000000000..2b0f16f25c --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanPayTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction LoanPay + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanPayTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanPay")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + LoanPayBuilder builder{ + accountValue, + loanIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanIDValue; + auto const actual = tx.getLoanID(); + expectEqualField(expected, actual, "sfLoanID"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanPayTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanPayFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + // Build an initial transaction + LoanPayBuilder initialBuilder{ + accountValue, + loanIDValue, + amountValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanPayBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanIDValue; + auto const actual = rebuiltTx.getLoanID(); + expectEqualField(expected, actual, "sfLoanID"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanPayTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanPay{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanPayTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanPayBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/LoanSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/LoanSetTests.cpp new file mode 100644 index 0000000000..4141a958a0 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/LoanSetTests.cpp @@ -0,0 +1,507 @@ +// Auto-generated unit tests for transaction LoanSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsLoanSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const dataValue = canonical_VL(); + auto const counterpartyValue = canonical_ACCOUNT(); + auto const counterpartySignatureValue = canonical_OBJECT(); + auto const loanOriginationFeeValue = canonical_NUMBER(); + auto const loanServiceFeeValue = canonical_NUMBER(); + auto const latePaymentFeeValue = canonical_NUMBER(); + auto const closePaymentFeeValue = canonical_NUMBER(); + auto const overpaymentFeeValue = canonical_UINT32(); + auto const interestRateValue = canonical_UINT32(); + auto const lateInterestRateValue = canonical_UINT32(); + auto const closeInterestRateValue = canonical_UINT32(); + auto const overpaymentInterestRateValue = canonical_UINT32(); + auto const principalRequestedValue = canonical_NUMBER(); + auto const paymentTotalValue = canonical_UINT32(); + auto const paymentIntervalValue = canonical_UINT32(); + auto const gracePeriodValue = canonical_UINT32(); + + LoanSetBuilder builder{ + accountValue, + loanBrokerIDValue, + principalRequestedValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setData(dataValue); + builder.setCounterparty(counterpartyValue); + builder.setCounterpartySignature(counterpartySignatureValue); + builder.setLoanOriginationFee(loanOriginationFeeValue); + builder.setLoanServiceFee(loanServiceFeeValue); + builder.setLatePaymentFee(latePaymentFeeValue); + builder.setClosePaymentFee(closePaymentFeeValue); + builder.setOverpaymentFee(overpaymentFeeValue); + builder.setInterestRate(interestRateValue); + builder.setLateInterestRate(lateInterestRateValue); + builder.setCloseInterestRate(closeInterestRateValue); + builder.setOverpaymentInterestRate(overpaymentInterestRateValue); + builder.setPaymentTotal(paymentTotalValue); + builder.setPaymentInterval(paymentIntervalValue); + builder.setGracePeriod(gracePeriodValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = tx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + { + auto const& expected = principalRequestedValue; + auto const actual = tx.getPrincipalRequested(); + expectEqualField(expected, actual, "sfPrincipalRequested"); + } + + // Verify optional fields + { + auto const& expected = dataValue; + auto const actualOpt = tx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(tx.hasData()); + } + + { + auto const& expected = counterpartyValue; + auto const actualOpt = tx.getCounterparty(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCounterparty should be present"; + expectEqualField(expected, *actualOpt, "sfCounterparty"); + EXPECT_TRUE(tx.hasCounterparty()); + } + + { + auto const& expected = counterpartySignatureValue; + auto const actualOpt = tx.getCounterpartySignature(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCounterpartySignature should be present"; + expectEqualField(expected, *actualOpt, "sfCounterpartySignature"); + EXPECT_TRUE(tx.hasCounterpartySignature()); + } + + { + auto const& expected = loanOriginationFeeValue; + auto const actualOpt = tx.getLoanOriginationFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanOriginationFee should be present"; + expectEqualField(expected, *actualOpt, "sfLoanOriginationFee"); + EXPECT_TRUE(tx.hasLoanOriginationFee()); + } + + { + auto const& expected = loanServiceFeeValue; + auto const actualOpt = tx.getLoanServiceFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanServiceFee should be present"; + expectEqualField(expected, *actualOpt, "sfLoanServiceFee"); + EXPECT_TRUE(tx.hasLoanServiceFee()); + } + + { + auto const& expected = latePaymentFeeValue; + auto const actualOpt = tx.getLatePaymentFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLatePaymentFee should be present"; + expectEqualField(expected, *actualOpt, "sfLatePaymentFee"); + EXPECT_TRUE(tx.hasLatePaymentFee()); + } + + { + auto const& expected = closePaymentFeeValue; + auto const actualOpt = tx.getClosePaymentFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfClosePaymentFee should be present"; + expectEqualField(expected, *actualOpt, "sfClosePaymentFee"); + EXPECT_TRUE(tx.hasClosePaymentFee()); + } + + { + auto const& expected = overpaymentFeeValue; + auto const actualOpt = tx.getOverpaymentFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOverpaymentFee should be present"; + expectEqualField(expected, *actualOpt, "sfOverpaymentFee"); + EXPECT_TRUE(tx.hasOverpaymentFee()); + } + + { + auto const& expected = interestRateValue; + auto const actualOpt = tx.getInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfInterestRate"); + EXPECT_TRUE(tx.hasInterestRate()); + } + + { + auto const& expected = lateInterestRateValue; + auto const actualOpt = tx.getLateInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLateInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfLateInterestRate"); + EXPECT_TRUE(tx.hasLateInterestRate()); + } + + { + auto const& expected = closeInterestRateValue; + auto const actualOpt = tx.getCloseInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCloseInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfCloseInterestRate"); + EXPECT_TRUE(tx.hasCloseInterestRate()); + } + + { + auto const& expected = overpaymentInterestRateValue; + auto const actualOpt = tx.getOverpaymentInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOverpaymentInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfOverpaymentInterestRate"); + EXPECT_TRUE(tx.hasOverpaymentInterestRate()); + } + + { + auto const& expected = paymentTotalValue; + auto const actualOpt = tx.getPaymentTotal(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPaymentTotal should be present"; + expectEqualField(expected, *actualOpt, "sfPaymentTotal"); + EXPECT_TRUE(tx.hasPaymentTotal()); + } + + { + auto const& expected = paymentIntervalValue; + auto const actualOpt = tx.getPaymentInterval(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPaymentInterval should be present"; + expectEqualField(expected, *actualOpt, "sfPaymentInterval"); + EXPECT_TRUE(tx.hasPaymentInterval()); + } + + { + auto const& expected = gracePeriodValue; + auto const actualOpt = tx.getGracePeriod(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGracePeriod should be present"; + expectEqualField(expected, *actualOpt, "sfGracePeriod"); + EXPECT_TRUE(tx.hasGracePeriod()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsLoanSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const dataValue = canonical_VL(); + auto const counterpartyValue = canonical_ACCOUNT(); + auto const counterpartySignatureValue = canonical_OBJECT(); + auto const loanOriginationFeeValue = canonical_NUMBER(); + auto const loanServiceFeeValue = canonical_NUMBER(); + auto const latePaymentFeeValue = canonical_NUMBER(); + auto const closePaymentFeeValue = canonical_NUMBER(); + auto const overpaymentFeeValue = canonical_UINT32(); + auto const interestRateValue = canonical_UINT32(); + auto const lateInterestRateValue = canonical_UINT32(); + auto const closeInterestRateValue = canonical_UINT32(); + auto const overpaymentInterestRateValue = canonical_UINT32(); + auto const principalRequestedValue = canonical_NUMBER(); + auto const paymentTotalValue = canonical_UINT32(); + auto const paymentIntervalValue = canonical_UINT32(); + auto const gracePeriodValue = canonical_UINT32(); + + // Build an initial transaction + LoanSetBuilder initialBuilder{ + accountValue, + loanBrokerIDValue, + principalRequestedValue, + sequenceValue, + feeValue + }; + + initialBuilder.setData(dataValue); + initialBuilder.setCounterparty(counterpartyValue); + initialBuilder.setCounterpartySignature(counterpartySignatureValue); + initialBuilder.setLoanOriginationFee(loanOriginationFeeValue); + initialBuilder.setLoanServiceFee(loanServiceFeeValue); + initialBuilder.setLatePaymentFee(latePaymentFeeValue); + initialBuilder.setClosePaymentFee(closePaymentFeeValue); + initialBuilder.setOverpaymentFee(overpaymentFeeValue); + initialBuilder.setInterestRate(interestRateValue); + initialBuilder.setLateInterestRate(lateInterestRateValue); + initialBuilder.setCloseInterestRate(closeInterestRateValue); + initialBuilder.setOverpaymentInterestRate(overpaymentInterestRateValue); + initialBuilder.setPaymentTotal(paymentTotalValue); + initialBuilder.setPaymentInterval(paymentIntervalValue); + initialBuilder.setGracePeriod(gracePeriodValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + LoanSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = loanBrokerIDValue; + auto const actual = rebuiltTx.getLoanBrokerID(); + expectEqualField(expected, actual, "sfLoanBrokerID"); + } + + { + auto const& expected = principalRequestedValue; + auto const actual = rebuiltTx.getPrincipalRequested(); + expectEqualField(expected, actual, "sfPrincipalRequested"); + } + + // Verify optional fields + { + auto const& expected = dataValue; + auto const actualOpt = rebuiltTx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + } + + { + auto const& expected = counterpartyValue; + auto const actualOpt = rebuiltTx.getCounterparty(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCounterparty should be present"; + expectEqualField(expected, *actualOpt, "sfCounterparty"); + } + + { + auto const& expected = counterpartySignatureValue; + auto const actualOpt = rebuiltTx.getCounterpartySignature(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCounterpartySignature should be present"; + expectEqualField(expected, *actualOpt, "sfCounterpartySignature"); + } + + { + auto const& expected = loanOriginationFeeValue; + auto const actualOpt = rebuiltTx.getLoanOriginationFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanOriginationFee should be present"; + expectEqualField(expected, *actualOpt, "sfLoanOriginationFee"); + } + + { + auto const& expected = loanServiceFeeValue; + auto const actualOpt = rebuiltTx.getLoanServiceFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLoanServiceFee should be present"; + expectEqualField(expected, *actualOpt, "sfLoanServiceFee"); + } + + { + auto const& expected = latePaymentFeeValue; + auto const actualOpt = rebuiltTx.getLatePaymentFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLatePaymentFee should be present"; + expectEqualField(expected, *actualOpt, "sfLatePaymentFee"); + } + + { + auto const& expected = closePaymentFeeValue; + auto const actualOpt = rebuiltTx.getClosePaymentFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfClosePaymentFee should be present"; + expectEqualField(expected, *actualOpt, "sfClosePaymentFee"); + } + + { + auto const& expected = overpaymentFeeValue; + auto const actualOpt = rebuiltTx.getOverpaymentFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOverpaymentFee should be present"; + expectEqualField(expected, *actualOpt, "sfOverpaymentFee"); + } + + { + auto const& expected = interestRateValue; + auto const actualOpt = rebuiltTx.getInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfInterestRate"); + } + + { + auto const& expected = lateInterestRateValue; + auto const actualOpt = rebuiltTx.getLateInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLateInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfLateInterestRate"); + } + + { + auto const& expected = closeInterestRateValue; + auto const actualOpt = rebuiltTx.getCloseInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCloseInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfCloseInterestRate"); + } + + { + auto const& expected = overpaymentInterestRateValue; + auto const actualOpt = rebuiltTx.getOverpaymentInterestRate(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOverpaymentInterestRate should be present"; + expectEqualField(expected, *actualOpt, "sfOverpaymentInterestRate"); + } + + { + auto const& expected = paymentTotalValue; + auto const actualOpt = rebuiltTx.getPaymentTotal(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPaymentTotal should be present"; + expectEqualField(expected, *actualOpt, "sfPaymentTotal"); + } + + { + auto const& expected = paymentIntervalValue; + auto const actualOpt = rebuiltTx.getPaymentInterval(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPaymentInterval should be present"; + expectEqualField(expected, *actualOpt, "sfPaymentInterval"); + } + + { + auto const& expected = gracePeriodValue; + auto const actualOpt = rebuiltTx.getGracePeriod(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfGracePeriod should be present"; + expectEqualField(expected, *actualOpt, "sfGracePeriod"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsLoanSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsLoanSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(LoanSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsLoanSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testLoanSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const loanBrokerIDValue = canonical_UINT256(); + auto const principalRequestedValue = canonical_NUMBER(); + + LoanSetBuilder builder{ + accountValue, + loanBrokerIDValue, + principalRequestedValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasData()); + EXPECT_FALSE(tx.getData().has_value()); + EXPECT_FALSE(tx.hasCounterparty()); + EXPECT_FALSE(tx.getCounterparty().has_value()); + EXPECT_FALSE(tx.hasCounterpartySignature()); + EXPECT_FALSE(tx.getCounterpartySignature().has_value()); + EXPECT_FALSE(tx.hasLoanOriginationFee()); + EXPECT_FALSE(tx.getLoanOriginationFee().has_value()); + EXPECT_FALSE(tx.hasLoanServiceFee()); + EXPECT_FALSE(tx.getLoanServiceFee().has_value()); + EXPECT_FALSE(tx.hasLatePaymentFee()); + EXPECT_FALSE(tx.getLatePaymentFee().has_value()); + EXPECT_FALSE(tx.hasClosePaymentFee()); + EXPECT_FALSE(tx.getClosePaymentFee().has_value()); + EXPECT_FALSE(tx.hasOverpaymentFee()); + EXPECT_FALSE(tx.getOverpaymentFee().has_value()); + EXPECT_FALSE(tx.hasInterestRate()); + EXPECT_FALSE(tx.getInterestRate().has_value()); + EXPECT_FALSE(tx.hasLateInterestRate()); + EXPECT_FALSE(tx.getLateInterestRate().has_value()); + EXPECT_FALSE(tx.hasCloseInterestRate()); + EXPECT_FALSE(tx.getCloseInterestRate().has_value()); + EXPECT_FALSE(tx.hasOverpaymentInterestRate()); + EXPECT_FALSE(tx.getOverpaymentInterestRate().has_value()); + EXPECT_FALSE(tx.hasPaymentTotal()); + EXPECT_FALSE(tx.getPaymentTotal().has_value()); + EXPECT_FALSE(tx.hasPaymentInterval()); + EXPECT_FALSE(tx.getPaymentInterval().has_value()); + EXPECT_FALSE(tx.hasGracePeriod()); + EXPECT_FALSE(tx.getGracePeriod().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/MPTokenAuthorizeTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenAuthorizeTests.cpp new file mode 100644 index 0000000000..bde6df05ff --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenAuthorizeTests.cpp @@ -0,0 +1,195 @@ +// Auto-generated unit tests for transaction MPTokenAuthorize + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsMPTokenAuthorizeTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenAuthorize")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + auto const holderValue = canonical_ACCOUNT(); + + MPTokenAuthorizeBuilder builder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setHolder(holderValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = mPTokenIssuanceIDValue; + auto const actual = tx.getMPTokenIssuanceID(); + expectEqualField(expected, actual, "sfMPTokenIssuanceID"); + } + + // Verify optional fields + { + auto const& expected = holderValue; + auto const actualOpt = tx.getHolder(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present"; + expectEqualField(expected, *actualOpt, "sfHolder"); + EXPECT_TRUE(tx.hasHolder()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsMPTokenAuthorizeTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenAuthorizeFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + auto const holderValue = canonical_ACCOUNT(); + + // Build an initial transaction + MPTokenAuthorizeBuilder initialBuilder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setHolder(holderValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + MPTokenAuthorizeBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = mPTokenIssuanceIDValue; + auto const actual = rebuiltTx.getMPTokenIssuanceID(); + expectEqualField(expected, actual, "sfMPTokenIssuanceID"); + } + + // Verify optional fields + { + auto const& expected = holderValue; + auto const actualOpt = rebuiltTx.getHolder(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present"; + expectEqualField(expected, *actualOpt, "sfHolder"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenAuthorizeTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenAuthorize{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenAuthorizeTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenAuthorizeBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsMPTokenAuthorizeTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenAuthorizeNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + + MPTokenAuthorizeBuilder builder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasHolder()); + EXPECT_FALSE(tx.getHolder().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceCreateTests.cpp new file mode 100644 index 0000000000..dd4874e268 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceCreateTests.cpp @@ -0,0 +1,282 @@ +// Auto-generated unit tests for transaction MPTokenIssuanceCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsMPTokenIssuanceCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetScaleValue = canonical_UINT8(); + auto const transferFeeValue = canonical_UINT16(); + auto const maximumAmountValue = canonical_UINT64(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const domainIDValue = canonical_UINT256(); + auto const mutableFlagsValue = canonical_UINT32(); + + MPTokenIssuanceCreateBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAssetScale(assetScaleValue); + builder.setTransferFee(transferFeeValue); + builder.setMaximumAmount(maximumAmountValue); + builder.setMPTokenMetadata(mPTokenMetadataValue); + builder.setDomainID(domainIDValue); + builder.setMutableFlags(mutableFlagsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = assetScaleValue; + auto const actualOpt = tx.getAssetScale(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetScale should be present"; + expectEqualField(expected, *actualOpt, "sfAssetScale"); + EXPECT_TRUE(tx.hasAssetScale()); + } + + { + auto const& expected = transferFeeValue; + auto const actualOpt = tx.getTransferFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present"; + expectEqualField(expected, *actualOpt, "sfTransferFee"); + EXPECT_TRUE(tx.hasTransferFee()); + } + + { + auto const& expected = maximumAmountValue; + auto const actualOpt = tx.getMaximumAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMaximumAmount should be present"; + expectEqualField(expected, *actualOpt, "sfMaximumAmount"); + EXPECT_TRUE(tx.hasMaximumAmount()); + } + + { + auto const& expected = mPTokenMetadataValue; + auto const actualOpt = tx.getMPTokenMetadata(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present"; + expectEqualField(expected, *actualOpt, "sfMPTokenMetadata"); + EXPECT_TRUE(tx.hasMPTokenMetadata()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = tx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(tx.hasDomainID()); + } + + { + auto const& expected = mutableFlagsValue; + auto const actualOpt = tx.getMutableFlags(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present"; + expectEqualField(expected, *actualOpt, "sfMutableFlags"); + EXPECT_TRUE(tx.hasMutableFlags()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsMPTokenIssuanceCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetScaleValue = canonical_UINT8(); + auto const transferFeeValue = canonical_UINT16(); + auto const maximumAmountValue = canonical_UINT64(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const domainIDValue = canonical_UINT256(); + auto const mutableFlagsValue = canonical_UINT32(); + + // Build an initial transaction + MPTokenIssuanceCreateBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setAssetScale(assetScaleValue); + initialBuilder.setTransferFee(transferFeeValue); + initialBuilder.setMaximumAmount(maximumAmountValue); + initialBuilder.setMPTokenMetadata(mPTokenMetadataValue); + initialBuilder.setDomainID(domainIDValue); + initialBuilder.setMutableFlags(mutableFlagsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + MPTokenIssuanceCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = assetScaleValue; + auto const actualOpt = rebuiltTx.getAssetScale(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetScale should be present"; + expectEqualField(expected, *actualOpt, "sfAssetScale"); + } + + { + auto const& expected = transferFeeValue; + auto const actualOpt = rebuiltTx.getTransferFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present"; + expectEqualField(expected, *actualOpt, "sfTransferFee"); + } + + { + auto const& expected = maximumAmountValue; + auto const actualOpt = rebuiltTx.getMaximumAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMaximumAmount should be present"; + expectEqualField(expected, *actualOpt, "sfMaximumAmount"); + } + + { + auto const& expected = mPTokenMetadataValue; + auto const actualOpt = rebuiltTx.getMPTokenMetadata(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present"; + expectEqualField(expected, *actualOpt, "sfMPTokenMetadata"); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = rebuiltTx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + } + + { + auto const& expected = mutableFlagsValue; + auto const actualOpt = rebuiltTx.getMutableFlags(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present"; + expectEqualField(expected, *actualOpt, "sfMutableFlags"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenIssuanceCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenIssuanceCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenIssuanceCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenIssuanceCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsMPTokenIssuanceCreateTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceCreateNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + MPTokenIssuanceCreateBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAssetScale()); + EXPECT_FALSE(tx.getAssetScale().has_value()); + EXPECT_FALSE(tx.hasTransferFee()); + EXPECT_FALSE(tx.getTransferFee().has_value()); + EXPECT_FALSE(tx.hasMaximumAmount()); + EXPECT_FALSE(tx.getMaximumAmount().has_value()); + EXPECT_FALSE(tx.hasMPTokenMetadata()); + EXPECT_FALSE(tx.getMPTokenMetadata().has_value()); + EXPECT_FALSE(tx.hasDomainID()); + EXPECT_FALSE(tx.getDomainID().has_value()); + EXPECT_FALSE(tx.hasMutableFlags()); + EXPECT_FALSE(tx.getMutableFlags().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceDestroyTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceDestroyTests.cpp new file mode 100644 index 0000000000..8a69c1f63a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceDestroyTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction MPTokenIssuanceDestroy + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsMPTokenIssuanceDestroyTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceDestroy")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + + MPTokenIssuanceDestroyBuilder builder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = mPTokenIssuanceIDValue; + auto const actual = tx.getMPTokenIssuanceID(); + expectEqualField(expected, actual, "sfMPTokenIssuanceID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsMPTokenIssuanceDestroyTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceDestroyFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + + // Build an initial transaction + MPTokenIssuanceDestroyBuilder initialBuilder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + MPTokenIssuanceDestroyBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = mPTokenIssuanceIDValue; + auto const actual = rebuiltTx.getMPTokenIssuanceID(); + expectEqualField(expected, actual, "sfMPTokenIssuanceID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenIssuanceDestroyTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenIssuanceDestroy{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenIssuanceDestroyTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenIssuanceDestroyBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceSetTests.cpp new file mode 100644 index 0000000000..2ed9e42184 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/MPTokenIssuanceSetTests.cpp @@ -0,0 +1,279 @@ +// Auto-generated unit tests for transaction MPTokenIssuanceSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsMPTokenIssuanceSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + auto const holderValue = canonical_ACCOUNT(); + auto const domainIDValue = canonical_UINT256(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const transferFeeValue = canonical_UINT16(); + auto const mutableFlagsValue = canonical_UINT32(); + + MPTokenIssuanceSetBuilder builder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setHolder(holderValue); + builder.setDomainID(domainIDValue); + builder.setMPTokenMetadata(mPTokenMetadataValue); + builder.setTransferFee(transferFeeValue); + builder.setMutableFlags(mutableFlagsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = mPTokenIssuanceIDValue; + auto const actual = tx.getMPTokenIssuanceID(); + expectEqualField(expected, actual, "sfMPTokenIssuanceID"); + } + + // Verify optional fields + { + auto const& expected = holderValue; + auto const actualOpt = tx.getHolder(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present"; + expectEqualField(expected, *actualOpt, "sfHolder"); + EXPECT_TRUE(tx.hasHolder()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = tx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(tx.hasDomainID()); + } + + { + auto const& expected = mPTokenMetadataValue; + auto const actualOpt = tx.getMPTokenMetadata(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present"; + expectEqualField(expected, *actualOpt, "sfMPTokenMetadata"); + EXPECT_TRUE(tx.hasMPTokenMetadata()); + } + + { + auto const& expected = transferFeeValue; + auto const actualOpt = tx.getTransferFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present"; + expectEqualField(expected, *actualOpt, "sfTransferFee"); + EXPECT_TRUE(tx.hasTransferFee()); + } + + { + auto const& expected = mutableFlagsValue; + auto const actualOpt = tx.getMutableFlags(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present"; + expectEqualField(expected, *actualOpt, "sfMutableFlags"); + EXPECT_TRUE(tx.hasMutableFlags()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsMPTokenIssuanceSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + auto const holderValue = canonical_ACCOUNT(); + auto const domainIDValue = canonical_UINT256(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const transferFeeValue = canonical_UINT16(); + auto const mutableFlagsValue = canonical_UINT32(); + + // Build an initial transaction + MPTokenIssuanceSetBuilder initialBuilder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setHolder(holderValue); + initialBuilder.setDomainID(domainIDValue); + initialBuilder.setMPTokenMetadata(mPTokenMetadataValue); + initialBuilder.setTransferFee(transferFeeValue); + initialBuilder.setMutableFlags(mutableFlagsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + MPTokenIssuanceSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = mPTokenIssuanceIDValue; + auto const actual = rebuiltTx.getMPTokenIssuanceID(); + expectEqualField(expected, actual, "sfMPTokenIssuanceID"); + } + + // Verify optional fields + { + auto const& expected = holderValue; + auto const actualOpt = rebuiltTx.getHolder(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolder should be present"; + expectEqualField(expected, *actualOpt, "sfHolder"); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = rebuiltTx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + } + + { + auto const& expected = mPTokenMetadataValue; + auto const actualOpt = rebuiltTx.getMPTokenMetadata(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present"; + expectEqualField(expected, *actualOpt, "sfMPTokenMetadata"); + } + + { + auto const& expected = transferFeeValue; + auto const actualOpt = rebuiltTx.getTransferFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present"; + expectEqualField(expected, *actualOpt, "sfTransferFee"); + } + + { + auto const& expected = mutableFlagsValue; + auto const actualOpt = rebuiltTx.getMutableFlags(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMutableFlags should be present"; + expectEqualField(expected, *actualOpt, "sfMutableFlags"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenIssuanceSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenIssuanceSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsMPTokenIssuanceSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(MPTokenIssuanceSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsMPTokenIssuanceSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testMPTokenIssuanceSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const mPTokenIssuanceIDValue = canonical_UINT192(); + + MPTokenIssuanceSetBuilder builder{ + accountValue, + mPTokenIssuanceIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasHolder()); + EXPECT_FALSE(tx.getHolder().has_value()); + EXPECT_FALSE(tx.hasDomainID()); + EXPECT_FALSE(tx.getDomainID().has_value()); + EXPECT_FALSE(tx.hasMPTokenMetadata()); + EXPECT_FALSE(tx.getMPTokenMetadata().has_value()); + EXPECT_FALSE(tx.hasTransferFee()); + EXPECT_FALSE(tx.getTransferFee().has_value()); + EXPECT_FALSE(tx.hasMutableFlags()); + EXPECT_FALSE(tx.getMutableFlags().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/NFTokenAcceptOfferTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenAcceptOfferTests.cpp new file mode 100644 index 0000000000..e2fb8d29ec --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenAcceptOfferTests.cpp @@ -0,0 +1,219 @@ +// Auto-generated unit tests for transaction NFTokenAcceptOffer + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsNFTokenAcceptOfferTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenAcceptOffer")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenBuyOfferValue = canonical_UINT256(); + auto const nFTokenSellOfferValue = canonical_UINT256(); + auto const nFTokenBrokerFeeValue = canonical_AMOUNT(); + + NFTokenAcceptOfferBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setNFTokenBuyOffer(nFTokenBuyOfferValue); + builder.setNFTokenSellOffer(nFTokenSellOfferValue); + builder.setNFTokenBrokerFee(nFTokenBrokerFeeValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = nFTokenBuyOfferValue; + auto const actualOpt = tx.getNFTokenBuyOffer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenBuyOffer should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenBuyOffer"); + EXPECT_TRUE(tx.hasNFTokenBuyOffer()); + } + + { + auto const& expected = nFTokenSellOfferValue; + auto const actualOpt = tx.getNFTokenSellOffer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenSellOffer should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenSellOffer"); + EXPECT_TRUE(tx.hasNFTokenSellOffer()); + } + + { + auto const& expected = nFTokenBrokerFeeValue; + auto const actualOpt = tx.getNFTokenBrokerFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenBrokerFee should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenBrokerFee"); + EXPECT_TRUE(tx.hasNFTokenBrokerFee()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsNFTokenAcceptOfferTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenAcceptOfferFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenBuyOfferValue = canonical_UINT256(); + auto const nFTokenSellOfferValue = canonical_UINT256(); + auto const nFTokenBrokerFeeValue = canonical_AMOUNT(); + + // Build an initial transaction + NFTokenAcceptOfferBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setNFTokenBuyOffer(nFTokenBuyOfferValue); + initialBuilder.setNFTokenSellOffer(nFTokenSellOfferValue); + initialBuilder.setNFTokenBrokerFee(nFTokenBrokerFeeValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + NFTokenAcceptOfferBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = nFTokenBuyOfferValue; + auto const actualOpt = rebuiltTx.getNFTokenBuyOffer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenBuyOffer should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenBuyOffer"); + } + + { + auto const& expected = nFTokenSellOfferValue; + auto const actualOpt = rebuiltTx.getNFTokenSellOffer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenSellOffer should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenSellOffer"); + } + + { + auto const& expected = nFTokenBrokerFeeValue; + auto const actualOpt = rebuiltTx.getNFTokenBrokerFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfNFTokenBrokerFee should be present"; + expectEqualField(expected, *actualOpt, "sfNFTokenBrokerFee"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenAcceptOfferTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenAcceptOffer{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenAcceptOfferTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenAcceptOfferBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsNFTokenAcceptOfferTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenAcceptOfferNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + NFTokenAcceptOfferBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasNFTokenBuyOffer()); + EXPECT_FALSE(tx.getNFTokenBuyOffer().has_value()); + EXPECT_FALSE(tx.hasNFTokenSellOffer()); + EXPECT_FALSE(tx.getNFTokenSellOffer().has_value()); + EXPECT_FALSE(tx.hasNFTokenBrokerFee()); + EXPECT_FALSE(tx.getNFTokenBrokerFee().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/NFTokenBurnTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenBurnTests.cpp new file mode 100644 index 0000000000..128ff51794 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenBurnTests.cpp @@ -0,0 +1,195 @@ +// Auto-generated unit tests for transaction NFTokenBurn + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsNFTokenBurnTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenBurn")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenIDValue = canonical_UINT256(); + auto const ownerValue = canonical_ACCOUNT(); + + NFTokenBurnBuilder builder{ + accountValue, + nFTokenIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setOwner(ownerValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenIDValue; + auto const actual = tx.getNFTokenID(); + expectEqualField(expected, actual, "sfNFTokenID"); + } + + // Verify optional fields + { + auto const& expected = ownerValue; + auto const actualOpt = tx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + EXPECT_TRUE(tx.hasOwner()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsNFTokenBurnTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenBurnFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenIDValue = canonical_UINT256(); + auto const ownerValue = canonical_ACCOUNT(); + + // Build an initial transaction + NFTokenBurnBuilder initialBuilder{ + accountValue, + nFTokenIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setOwner(ownerValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + NFTokenBurnBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenIDValue; + auto const actual = rebuiltTx.getNFTokenID(); + expectEqualField(expected, actual, "sfNFTokenID"); + } + + // Verify optional fields + { + auto const& expected = ownerValue; + auto const actualOpt = rebuiltTx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenBurnTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenBurn{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenBurnTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenBurnBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsNFTokenBurnTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenBurnNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const nFTokenIDValue = canonical_UINT256(); + + NFTokenBurnBuilder builder{ + accountValue, + nFTokenIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasOwner()); + EXPECT_FALSE(tx.getOwner().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/NFTokenCancelOfferTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenCancelOfferTests.cpp new file mode 100644 index 0000000000..f8ab0f7da1 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenCancelOfferTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction NFTokenCancelOffer + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsNFTokenCancelOfferTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenCancelOffer")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenOffersValue = canonical_VECTOR256(); + + NFTokenCancelOfferBuilder builder{ + accountValue, + nFTokenOffersValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenOffersValue; + auto const actual = tx.getNFTokenOffers(); + expectEqualField(expected, actual, "sfNFTokenOffers"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsNFTokenCancelOfferTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenCancelOfferFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenOffersValue = canonical_VECTOR256(); + + // Build an initial transaction + NFTokenCancelOfferBuilder initialBuilder{ + accountValue, + nFTokenOffersValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + NFTokenCancelOfferBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenOffersValue; + auto const actual = rebuiltTx.getNFTokenOffers(); + expectEqualField(expected, actual, "sfNFTokenOffers"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenCancelOfferTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenCancelOffer{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenCancelOfferTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenCancelOfferBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/NFTokenCreateOfferTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenCreateOfferTests.cpp new file mode 100644 index 0000000000..c57ede25c4 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenCreateOfferTests.cpp @@ -0,0 +1,255 @@ +// Auto-generated unit tests for transaction NFTokenCreateOffer + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsNFTokenCreateOfferTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenCreateOffer")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const ownerValue = canonical_ACCOUNT(); + auto const expirationValue = canonical_UINT32(); + + NFTokenCreateOfferBuilder builder{ + accountValue, + nFTokenIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDestination(destinationValue); + builder.setOwner(ownerValue); + builder.setExpiration(expirationValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenIDValue; + auto const actual = tx.getNFTokenID(); + expectEqualField(expected, actual, "sfNFTokenID"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = tx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + EXPECT_TRUE(tx.hasDestination()); + } + + { + auto const& expected = ownerValue; + auto const actualOpt = tx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + EXPECT_TRUE(tx.hasOwner()); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = tx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(tx.hasExpiration()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsNFTokenCreateOfferTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenCreateOfferFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const ownerValue = canonical_ACCOUNT(); + auto const expirationValue = canonical_UINT32(); + + // Build an initial transaction + NFTokenCreateOfferBuilder initialBuilder{ + accountValue, + nFTokenIDValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDestination(destinationValue); + initialBuilder.setOwner(ownerValue); + initialBuilder.setExpiration(expirationValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + NFTokenCreateOfferBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenIDValue; + auto const actual = rebuiltTx.getNFTokenID(); + expectEqualField(expected, actual, "sfNFTokenID"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = rebuiltTx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + } + + { + auto const& expected = ownerValue; + auto const actualOpt = rebuiltTx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = rebuiltTx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenCreateOfferTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenCreateOffer{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenCreateOfferTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenCreateOfferBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsNFTokenCreateOfferTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenCreateOfferNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const nFTokenIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + NFTokenCreateOfferBuilder builder{ + accountValue, + nFTokenIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDestination()); + EXPECT_FALSE(tx.getDestination().has_value()); + EXPECT_FALSE(tx.hasOwner()); + EXPECT_FALSE(tx.getOwner().has_value()); + EXPECT_FALSE(tx.hasExpiration()); + EXPECT_FALSE(tx.getExpiration().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/NFTokenMintTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenMintTests.cpp new file mode 100644 index 0000000000..e85dbd238c --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenMintTests.cpp @@ -0,0 +1,300 @@ +// Auto-generated unit tests for transaction NFTokenMint + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsNFTokenMintTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenMint")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenTaxonValue = canonical_UINT32(); + auto const transferFeeValue = canonical_UINT16(); + auto const issuerValue = canonical_ACCOUNT(); + auto const uRIValue = canonical_VL(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const expirationValue = canonical_UINT32(); + + NFTokenMintBuilder builder{ + accountValue, + nFTokenTaxonValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setTransferFee(transferFeeValue); + builder.setIssuer(issuerValue); + builder.setURI(uRIValue); + builder.setAmount(amountValue); + builder.setDestination(destinationValue); + builder.setExpiration(expirationValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenTaxonValue; + auto const actual = tx.getNFTokenTaxon(); + expectEqualField(expected, actual, "sfNFTokenTaxon"); + } + + // Verify optional fields + { + auto const& expected = transferFeeValue; + auto const actualOpt = tx.getTransferFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present"; + expectEqualField(expected, *actualOpt, "sfTransferFee"); + EXPECT_TRUE(tx.hasTransferFee()); + } + + { + auto const& expected = issuerValue; + auto const actualOpt = tx.getIssuer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfIssuer should be present"; + expectEqualField(expected, *actualOpt, "sfIssuer"); + EXPECT_TRUE(tx.hasIssuer()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = tx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(tx.hasURI()); + } + + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + + { + auto const& expected = destinationValue; + auto const actualOpt = tx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + EXPECT_TRUE(tx.hasDestination()); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = tx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(tx.hasExpiration()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsNFTokenMintTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenMintFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenTaxonValue = canonical_UINT32(); + auto const transferFeeValue = canonical_UINT16(); + auto const issuerValue = canonical_ACCOUNT(); + auto const uRIValue = canonical_VL(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const expirationValue = canonical_UINT32(); + + // Build an initial transaction + NFTokenMintBuilder initialBuilder{ + accountValue, + nFTokenTaxonValue, + sequenceValue, + feeValue + }; + + initialBuilder.setTransferFee(transferFeeValue); + initialBuilder.setIssuer(issuerValue); + initialBuilder.setURI(uRIValue); + initialBuilder.setAmount(amountValue); + initialBuilder.setDestination(destinationValue); + initialBuilder.setExpiration(expirationValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + NFTokenMintBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenTaxonValue; + auto const actual = rebuiltTx.getNFTokenTaxon(); + expectEqualField(expected, actual, "sfNFTokenTaxon"); + } + + // Verify optional fields + { + auto const& expected = transferFeeValue; + auto const actualOpt = rebuiltTx.getTransferFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfTransferFee should be present"; + expectEqualField(expected, *actualOpt, "sfTransferFee"); + } + + { + auto const& expected = issuerValue; + auto const actualOpt = rebuiltTx.getIssuer(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfIssuer should be present"; + expectEqualField(expected, *actualOpt, "sfIssuer"); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = rebuiltTx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + } + + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + + { + auto const& expected = destinationValue; + auto const actualOpt = rebuiltTx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + } + + { + auto const& expected = expirationValue; + auto const actualOpt = rebuiltTx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenMintTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenMint{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenMintTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenMintBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsNFTokenMintTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenMintNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const nFTokenTaxonValue = canonical_UINT32(); + + NFTokenMintBuilder builder{ + accountValue, + nFTokenTaxonValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasTransferFee()); + EXPECT_FALSE(tx.getTransferFee().has_value()); + EXPECT_FALSE(tx.hasIssuer()); + EXPECT_FALSE(tx.getIssuer().has_value()); + EXPECT_FALSE(tx.hasURI()); + EXPECT_FALSE(tx.getURI().has_value()); + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); + EXPECT_FALSE(tx.hasDestination()); + EXPECT_FALSE(tx.getDestination().has_value()); + EXPECT_FALSE(tx.hasExpiration()); + EXPECT_FALSE(tx.getExpiration().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/NFTokenModifyTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenModifyTests.cpp new file mode 100644 index 0000000000..9f5eeb052d --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/NFTokenModifyTests.cpp @@ -0,0 +1,216 @@ +// Auto-generated unit tests for transaction NFTokenModify + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsNFTokenModifyTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenModify")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenIDValue = canonical_UINT256(); + auto const ownerValue = canonical_ACCOUNT(); + auto const uRIValue = canonical_VL(); + + NFTokenModifyBuilder builder{ + accountValue, + nFTokenIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setOwner(ownerValue); + builder.setURI(uRIValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenIDValue; + auto const actual = tx.getNFTokenID(); + expectEqualField(expected, actual, "sfNFTokenID"); + } + + // Verify optional fields + { + auto const& expected = ownerValue; + auto const actualOpt = tx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + EXPECT_TRUE(tx.hasOwner()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = tx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(tx.hasURI()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsNFTokenModifyTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenModifyFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const nFTokenIDValue = canonical_UINT256(); + auto const ownerValue = canonical_ACCOUNT(); + auto const uRIValue = canonical_VL(); + + // Build an initial transaction + NFTokenModifyBuilder initialBuilder{ + accountValue, + nFTokenIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setOwner(ownerValue); + initialBuilder.setURI(uRIValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + NFTokenModifyBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = nFTokenIDValue; + auto const actual = rebuiltTx.getNFTokenID(); + expectEqualField(expected, actual, "sfNFTokenID"); + } + + // Verify optional fields + { + auto const& expected = ownerValue; + auto const actualOpt = rebuiltTx.getOwner(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOwner should be present"; + expectEqualField(expected, *actualOpt, "sfOwner"); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = rebuiltTx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenModifyTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenModify{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsNFTokenModifyTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(NFTokenModifyBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsNFTokenModifyTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testNFTokenModifyNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const nFTokenIDValue = canonical_UINT256(); + + NFTokenModifyBuilder builder{ + accountValue, + nFTokenIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasOwner()); + EXPECT_FALSE(tx.getOwner().has_value()); + EXPECT_FALSE(tx.hasURI()); + EXPECT_FALSE(tx.getURI().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/OfferCancelTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/OfferCancelTests.cpp new file mode 100644 index 0000000000..0e3c8a4224 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/OfferCancelTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction OfferCancel + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsOfferCancelTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOfferCancel")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const offerSequenceValue = canonical_UINT32(); + + OfferCancelBuilder builder{ + accountValue, + offerSequenceValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = offerSequenceValue; + auto const actual = tx.getOfferSequence(); + expectEqualField(expected, actual, "sfOfferSequence"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsOfferCancelTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOfferCancelFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const offerSequenceValue = canonical_UINT32(); + + // Build an initial transaction + OfferCancelBuilder initialBuilder{ + accountValue, + offerSequenceValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + OfferCancelBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = offerSequenceValue; + auto const actual = rebuiltTx.getOfferSequence(); + expectEqualField(expected, actual, "sfOfferSequence"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsOfferCancelTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OfferCancel{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsOfferCancelTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OfferCancelBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/OfferCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/OfferCreateTests.cpp new file mode 100644 index 0000000000..3dde69574e --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/OfferCreateTests.cpp @@ -0,0 +1,255 @@ +// Auto-generated unit tests for transaction OfferCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsOfferCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOfferCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const takerPaysValue = canonical_AMOUNT(); + auto const takerGetsValue = canonical_AMOUNT(); + auto const expirationValue = canonical_UINT32(); + auto const offerSequenceValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + + OfferCreateBuilder builder{ + accountValue, + takerPaysValue, + takerGetsValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setExpiration(expirationValue); + builder.setOfferSequence(offerSequenceValue); + builder.setDomainID(domainIDValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = takerPaysValue; + auto const actual = tx.getTakerPays(); + expectEqualField(expected, actual, "sfTakerPays"); + } + + { + auto const& expected = takerGetsValue; + auto const actual = tx.getTakerGets(); + expectEqualField(expected, actual, "sfTakerGets"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = tx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(tx.hasExpiration()); + } + + { + auto const& expected = offerSequenceValue; + auto const actualOpt = tx.getOfferSequence(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOfferSequence should be present"; + expectEqualField(expected, *actualOpt, "sfOfferSequence"); + EXPECT_TRUE(tx.hasOfferSequence()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = tx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(tx.hasDomainID()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsOfferCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOfferCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const takerPaysValue = canonical_AMOUNT(); + auto const takerGetsValue = canonical_AMOUNT(); + auto const expirationValue = canonical_UINT32(); + auto const offerSequenceValue = canonical_UINT32(); + auto const domainIDValue = canonical_UINT256(); + + // Build an initial transaction + OfferCreateBuilder initialBuilder{ + accountValue, + takerPaysValue, + takerGetsValue, + sequenceValue, + feeValue + }; + + initialBuilder.setExpiration(expirationValue); + initialBuilder.setOfferSequence(offerSequenceValue); + initialBuilder.setDomainID(domainIDValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + OfferCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = takerPaysValue; + auto const actual = rebuiltTx.getTakerPays(); + expectEqualField(expected, actual, "sfTakerPays"); + } + + { + auto const& expected = takerGetsValue; + auto const actual = rebuiltTx.getTakerGets(); + expectEqualField(expected, actual, "sfTakerGets"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = rebuiltTx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + } + + { + auto const& expected = offerSequenceValue; + auto const actualOpt = rebuiltTx.getOfferSequence(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOfferSequence should be present"; + expectEqualField(expected, *actualOpt, "sfOfferSequence"); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = rebuiltTx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsOfferCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OfferCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsOfferCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OfferCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsOfferCreateTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOfferCreateNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const takerPaysValue = canonical_AMOUNT(); + auto const takerGetsValue = canonical_AMOUNT(); + + OfferCreateBuilder builder{ + accountValue, + takerPaysValue, + takerGetsValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasExpiration()); + EXPECT_FALSE(tx.getExpiration().has_value()); + EXPECT_FALSE(tx.hasOfferSequence()); + EXPECT_FALSE(tx.getOfferSequence().has_value()); + EXPECT_FALSE(tx.hasDomainID()); + EXPECT_FALSE(tx.getDomainID().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/OracleDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/OracleDeleteTests.cpp new file mode 100644 index 0000000000..631ad0861a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/OracleDeleteTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction OracleDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsOracleDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOracleDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const oracleDocumentIDValue = canonical_UINT32(); + + OracleDeleteBuilder builder{ + accountValue, + oracleDocumentIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = oracleDocumentIDValue; + auto const actual = tx.getOracleDocumentID(); + expectEqualField(expected, actual, "sfOracleDocumentID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsOracleDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOracleDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const oracleDocumentIDValue = canonical_UINT32(); + + // Build an initial transaction + OracleDeleteBuilder initialBuilder{ + accountValue, + oracleDocumentIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + OracleDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = oracleDocumentIDValue; + auto const actual = rebuiltTx.getOracleDocumentID(); + expectEqualField(expected, actual, "sfOracleDocumentID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsOracleDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OracleDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsOracleDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OracleDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/OracleSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/OracleSetTests.cpp new file mode 100644 index 0000000000..e13e8a8374 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/OracleSetTests.cpp @@ -0,0 +1,273 @@ +// Auto-generated unit tests for transaction OracleSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsOracleSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOracleSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const oracleDocumentIDValue = canonical_UINT32(); + auto const providerValue = canonical_VL(); + auto const uRIValue = canonical_VL(); + auto const assetClassValue = canonical_VL(); + auto const lastUpdateTimeValue = canonical_UINT32(); + auto const priceDataSeriesValue = canonical_ARRAY(); + + OracleSetBuilder builder{ + accountValue, + oracleDocumentIDValue, + lastUpdateTimeValue, + priceDataSeriesValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setProvider(providerValue); + builder.setURI(uRIValue); + builder.setAssetClass(assetClassValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = oracleDocumentIDValue; + auto const actual = tx.getOracleDocumentID(); + expectEqualField(expected, actual, "sfOracleDocumentID"); + } + + { + auto const& expected = lastUpdateTimeValue; + auto const actual = tx.getLastUpdateTime(); + expectEqualField(expected, actual, "sfLastUpdateTime"); + } + + { + auto const& expected = priceDataSeriesValue; + auto const actual = tx.getPriceDataSeries(); + expectEqualField(expected, actual, "sfPriceDataSeries"); + } + + // Verify optional fields + { + auto const& expected = providerValue; + auto const actualOpt = tx.getProvider(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfProvider should be present"; + expectEqualField(expected, *actualOpt, "sfProvider"); + EXPECT_TRUE(tx.hasProvider()); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = tx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + EXPECT_TRUE(tx.hasURI()); + } + + { + auto const& expected = assetClassValue; + auto const actualOpt = tx.getAssetClass(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetClass should be present"; + expectEqualField(expected, *actualOpt, "sfAssetClass"); + EXPECT_TRUE(tx.hasAssetClass()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsOracleSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOracleSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const oracleDocumentIDValue = canonical_UINT32(); + auto const providerValue = canonical_VL(); + auto const uRIValue = canonical_VL(); + auto const assetClassValue = canonical_VL(); + auto const lastUpdateTimeValue = canonical_UINT32(); + auto const priceDataSeriesValue = canonical_ARRAY(); + + // Build an initial transaction + OracleSetBuilder initialBuilder{ + accountValue, + oracleDocumentIDValue, + lastUpdateTimeValue, + priceDataSeriesValue, + sequenceValue, + feeValue + }; + + initialBuilder.setProvider(providerValue); + initialBuilder.setURI(uRIValue); + initialBuilder.setAssetClass(assetClassValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + OracleSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = oracleDocumentIDValue; + auto const actual = rebuiltTx.getOracleDocumentID(); + expectEqualField(expected, actual, "sfOracleDocumentID"); + } + + { + auto const& expected = lastUpdateTimeValue; + auto const actual = rebuiltTx.getLastUpdateTime(); + expectEqualField(expected, actual, "sfLastUpdateTime"); + } + + { + auto const& expected = priceDataSeriesValue; + auto const actual = rebuiltTx.getPriceDataSeries(); + expectEqualField(expected, actual, "sfPriceDataSeries"); + } + + // Verify optional fields + { + auto const& expected = providerValue; + auto const actualOpt = rebuiltTx.getProvider(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfProvider should be present"; + expectEqualField(expected, *actualOpt, "sfProvider"); + } + + { + auto const& expected = uRIValue; + auto const actualOpt = rebuiltTx.getURI(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfURI should be present"; + expectEqualField(expected, *actualOpt, "sfURI"); + } + + { + auto const& expected = assetClassValue; + auto const actualOpt = rebuiltTx.getAssetClass(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetClass should be present"; + expectEqualField(expected, *actualOpt, "sfAssetClass"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsOracleSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OracleSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsOracleSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(OracleSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsOracleSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testOracleSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const oracleDocumentIDValue = canonical_UINT32(); + auto const lastUpdateTimeValue = canonical_UINT32(); + auto const priceDataSeriesValue = canonical_ARRAY(); + + OracleSetBuilder builder{ + accountValue, + oracleDocumentIDValue, + lastUpdateTimeValue, + priceDataSeriesValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasProvider()); + EXPECT_FALSE(tx.getProvider().has_value()); + EXPECT_FALSE(tx.hasURI()); + EXPECT_FALSE(tx.getURI().has_value()); + EXPECT_FALSE(tx.hasAssetClass()); + EXPECT_FALSE(tx.getAssetClass().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelClaimTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelClaimTests.cpp new file mode 100644 index 0000000000..1b742196a5 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelClaimTests.cpp @@ -0,0 +1,279 @@ +// Auto-generated unit tests for transaction PaymentChannelClaim + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsPaymentChannelClaimTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelClaim")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const channelValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const balanceValue = canonical_AMOUNT(); + auto const signatureValue = canonical_VL(); + auto const publicKeyValue = canonical_VL(); + auto const credentialIDsValue = canonical_VECTOR256(); + + PaymentChannelClaimBuilder builder{ + accountValue, + channelValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAmount(amountValue); + builder.setBalance(balanceValue); + builder.setSignature(signatureValue); + builder.setPublicKey(publicKeyValue); + builder.setCredentialIDs(credentialIDsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = channelValue; + auto const actual = tx.getChannel(); + expectEqualField(expected, actual, "sfChannel"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + + { + auto const& expected = balanceValue; + auto const actualOpt = tx.getBalance(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBalance should be present"; + expectEqualField(expected, *actualOpt, "sfBalance"); + EXPECT_TRUE(tx.hasBalance()); + } + + { + auto const& expected = signatureValue; + auto const actualOpt = tx.getSignature(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSignature should be present"; + expectEqualField(expected, *actualOpt, "sfSignature"); + EXPECT_TRUE(tx.hasSignature()); + } + + { + auto const& expected = publicKeyValue; + auto const actualOpt = tx.getPublicKey(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPublicKey should be present"; + expectEqualField(expected, *actualOpt, "sfPublicKey"); + EXPECT_TRUE(tx.hasPublicKey()); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = tx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + EXPECT_TRUE(tx.hasCredentialIDs()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsPaymentChannelClaimTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelClaimFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const channelValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const balanceValue = canonical_AMOUNT(); + auto const signatureValue = canonical_VL(); + auto const publicKeyValue = canonical_VL(); + auto const credentialIDsValue = canonical_VECTOR256(); + + // Build an initial transaction + PaymentChannelClaimBuilder initialBuilder{ + accountValue, + channelValue, + sequenceValue, + feeValue + }; + + initialBuilder.setAmount(amountValue); + initialBuilder.setBalance(balanceValue); + initialBuilder.setSignature(signatureValue); + initialBuilder.setPublicKey(publicKeyValue); + initialBuilder.setCredentialIDs(credentialIDsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + PaymentChannelClaimBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = channelValue; + auto const actual = rebuiltTx.getChannel(); + expectEqualField(expected, actual, "sfChannel"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + + { + auto const& expected = balanceValue; + auto const actualOpt = rebuiltTx.getBalance(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBalance should be present"; + expectEqualField(expected, *actualOpt, "sfBalance"); + } + + { + auto const& expected = signatureValue; + auto const actualOpt = rebuiltTx.getSignature(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSignature should be present"; + expectEqualField(expected, *actualOpt, "sfSignature"); + } + + { + auto const& expected = publicKeyValue; + auto const actualOpt = rebuiltTx.getPublicKey(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPublicKey should be present"; + expectEqualField(expected, *actualOpt, "sfPublicKey"); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = rebuiltTx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsPaymentChannelClaimTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PaymentChannelClaim{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsPaymentChannelClaimTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PaymentChannelClaimBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsPaymentChannelClaimTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelClaimNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const channelValue = canonical_UINT256(); + + PaymentChannelClaimBuilder builder{ + accountValue, + channelValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); + EXPECT_FALSE(tx.hasBalance()); + EXPECT_FALSE(tx.getBalance().has_value()); + EXPECT_FALSE(tx.hasSignature()); + EXPECT_FALSE(tx.getSignature().has_value()); + EXPECT_FALSE(tx.hasPublicKey()); + EXPECT_FALSE(tx.getPublicKey().has_value()); + EXPECT_FALSE(tx.hasCredentialIDs()); + EXPECT_FALSE(tx.getCredentialIDs().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelCreateTests.cpp new file mode 100644 index 0000000000..e3ba999d0b --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelCreateTests.cpp @@ -0,0 +1,270 @@ +// Auto-generated unit tests for transaction PaymentChannelCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsPaymentChannelCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const settleDelayValue = canonical_UINT32(); + auto const publicKeyValue = canonical_VL(); + auto const cancelAfterValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + + PaymentChannelCreateBuilder builder{ + accountValue, + destinationValue, + amountValue, + settleDelayValue, + publicKeyValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setCancelAfter(cancelAfterValue); + builder.setDestinationTag(destinationTagValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = settleDelayValue; + auto const actual = tx.getSettleDelay(); + expectEqualField(expected, actual, "sfSettleDelay"); + } + + { + auto const& expected = publicKeyValue; + auto const actual = tx.getPublicKey(); + expectEqualField(expected, actual, "sfPublicKey"); + } + + // Verify optional fields + { + auto const& expected = cancelAfterValue; + auto const actualOpt = tx.getCancelAfter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCancelAfter should be present"; + expectEqualField(expected, *actualOpt, "sfCancelAfter"); + EXPECT_TRUE(tx.hasCancelAfter()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsPaymentChannelCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const settleDelayValue = canonical_UINT32(); + auto const publicKeyValue = canonical_VL(); + auto const cancelAfterValue = canonical_UINT32(); + auto const destinationTagValue = canonical_UINT32(); + + // Build an initial transaction + PaymentChannelCreateBuilder initialBuilder{ + accountValue, + destinationValue, + amountValue, + settleDelayValue, + publicKeyValue, + sequenceValue, + feeValue + }; + + initialBuilder.setCancelAfter(cancelAfterValue); + initialBuilder.setDestinationTag(destinationTagValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + PaymentChannelCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = settleDelayValue; + auto const actual = rebuiltTx.getSettleDelay(); + expectEqualField(expected, actual, "sfSettleDelay"); + } + + { + auto const& expected = publicKeyValue; + auto const actual = rebuiltTx.getPublicKey(); + expectEqualField(expected, actual, "sfPublicKey"); + } + + // Verify optional fields + { + auto const& expected = cancelAfterValue; + auto const actualOpt = rebuiltTx.getCancelAfter(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCancelAfter should be present"; + expectEqualField(expected, *actualOpt, "sfCancelAfter"); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsPaymentChannelCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PaymentChannelCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsPaymentChannelCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PaymentChannelCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsPaymentChannelCreateTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelCreateNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const settleDelayValue = canonical_UINT32(); + auto const publicKeyValue = canonical_VL(); + + PaymentChannelCreateBuilder builder{ + accountValue, + destinationValue, + amountValue, + settleDelayValue, + publicKeyValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasCancelAfter()); + EXPECT_FALSE(tx.getCancelAfter().has_value()); + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelFundTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelFundTests.cpp new file mode 100644 index 0000000000..ce070c0761 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/PaymentChannelFundTests.cpp @@ -0,0 +1,213 @@ +// Auto-generated unit tests for transaction PaymentChannelFund + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsPaymentChannelFundTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelFund")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const channelValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const expirationValue = canonical_UINT32(); + + PaymentChannelFundBuilder builder{ + accountValue, + channelValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setExpiration(expirationValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = channelValue; + auto const actual = tx.getChannel(); + expectEqualField(expected, actual, "sfChannel"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = tx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + EXPECT_TRUE(tx.hasExpiration()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsPaymentChannelFundTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelFundFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const channelValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const expirationValue = canonical_UINT32(); + + // Build an initial transaction + PaymentChannelFundBuilder initialBuilder{ + accountValue, + channelValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setExpiration(expirationValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + PaymentChannelFundBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = channelValue; + auto const actual = rebuiltTx.getChannel(); + expectEqualField(expected, actual, "sfChannel"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = expirationValue; + auto const actualOpt = rebuiltTx.getExpiration(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfExpiration should be present"; + expectEqualField(expected, *actualOpt, "sfExpiration"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsPaymentChannelFundTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PaymentChannelFund{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsPaymentChannelFundTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PaymentChannelFundBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsPaymentChannelFundTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentChannelFundNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const channelValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + PaymentChannelFundBuilder builder{ + accountValue, + channelValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasExpiration()); + EXPECT_FALSE(tx.getExpiration().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/PaymentTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/PaymentTests.cpp new file mode 100644 index 0000000000..7e5c046fca --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/PaymentTests.cpp @@ -0,0 +1,339 @@ +// Auto-generated unit tests for transaction Payment + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsPaymentTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPayment")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + auto const pathsValue = canonical_PATHSET(); + auto const invoiceIDValue = canonical_UINT256(); + auto const destinationTagValue = canonical_UINT32(); + auto const deliverMinValue = canonical_AMOUNT(); + auto const credentialIDsValue = canonical_VECTOR256(); + auto const domainIDValue = canonical_UINT256(); + + PaymentBuilder builder{ + accountValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setSendMax(sendMaxValue); + builder.setPaths(pathsValue); + builder.setInvoiceID(invoiceIDValue); + builder.setDestinationTag(destinationTagValue); + builder.setDeliverMin(deliverMinValue); + builder.setCredentialIDs(credentialIDsValue); + builder.setDomainID(domainIDValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = sendMaxValue; + auto const actualOpt = tx.getSendMax(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSendMax should be present"; + expectEqualField(expected, *actualOpt, "sfSendMax"); + EXPECT_TRUE(tx.hasSendMax()); + } + + { + auto const& expected = pathsValue; + auto const actualOpt = tx.getPaths(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPaths should be present"; + expectEqualField(expected, *actualOpt, "sfPaths"); + EXPECT_TRUE(tx.hasPaths()); + } + + { + auto const& expected = invoiceIDValue; + auto const actualOpt = tx.getInvoiceID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfInvoiceID should be present"; + expectEqualField(expected, *actualOpt, "sfInvoiceID"); + EXPECT_TRUE(tx.hasInvoiceID()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + + { + auto const& expected = deliverMinValue; + auto const actualOpt = tx.getDeliverMin(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDeliverMin should be present"; + expectEqualField(expected, *actualOpt, "sfDeliverMin"); + EXPECT_TRUE(tx.hasDeliverMin()); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = tx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + EXPECT_TRUE(tx.hasCredentialIDs()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = tx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(tx.hasDomainID()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsPaymentTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const sendMaxValue = canonical_AMOUNT(); + auto const pathsValue = canonical_PATHSET(); + auto const invoiceIDValue = canonical_UINT256(); + auto const destinationTagValue = canonical_UINT32(); + auto const deliverMinValue = canonical_AMOUNT(); + auto const credentialIDsValue = canonical_VECTOR256(); + auto const domainIDValue = canonical_UINT256(); + + // Build an initial transaction + PaymentBuilder initialBuilder{ + accountValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setSendMax(sendMaxValue); + initialBuilder.setPaths(pathsValue); + initialBuilder.setInvoiceID(invoiceIDValue); + initialBuilder.setDestinationTag(destinationTagValue); + initialBuilder.setDeliverMin(deliverMinValue); + initialBuilder.setCredentialIDs(credentialIDsValue); + initialBuilder.setDomainID(domainIDValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + PaymentBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = sendMaxValue; + auto const actualOpt = rebuiltTx.getSendMax(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSendMax should be present"; + expectEqualField(expected, *actualOpt, "sfSendMax"); + } + + { + auto const& expected = pathsValue; + auto const actualOpt = rebuiltTx.getPaths(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfPaths should be present"; + expectEqualField(expected, *actualOpt, "sfPaths"); + } + + { + auto const& expected = invoiceIDValue; + auto const actualOpt = rebuiltTx.getInvoiceID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfInvoiceID should be present"; + expectEqualField(expected, *actualOpt, "sfInvoiceID"); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + + { + auto const& expected = deliverMinValue; + auto const actualOpt = rebuiltTx.getDeliverMin(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDeliverMin should be present"; + expectEqualField(expected, *actualOpt, "sfDeliverMin"); + } + + { + auto const& expected = credentialIDsValue; + auto const actualOpt = rebuiltTx.getCredentialIDs(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present"; + expectEqualField(expected, *actualOpt, "sfCredentialIDs"); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = rebuiltTx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsPaymentTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(Payment{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsPaymentTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PaymentBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsPaymentTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPaymentNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + + PaymentBuilder builder{ + accountValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasSendMax()); + EXPECT_FALSE(tx.getSendMax().has_value()); + EXPECT_FALSE(tx.hasPaths()); + EXPECT_FALSE(tx.getPaths().has_value()); + EXPECT_FALSE(tx.hasInvoiceID()); + EXPECT_FALSE(tx.getInvoiceID().has_value()); + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); + EXPECT_FALSE(tx.hasDeliverMin()); + EXPECT_FALSE(tx.getDeliverMin().has_value()); + EXPECT_FALSE(tx.hasCredentialIDs()); + EXPECT_FALSE(tx.getCredentialIDs().has_value()); + EXPECT_FALSE(tx.hasDomainID()); + EXPECT_FALSE(tx.getDomainID().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainDeleteTests.cpp new file mode 100644 index 0000000000..e9f92fb5b3 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainDeleteTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction PermissionedDomainDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsPermissionedDomainDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPermissionedDomainDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const domainIDValue = canonical_UINT256(); + + PermissionedDomainDeleteBuilder builder{ + accountValue, + domainIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = domainIDValue; + auto const actual = tx.getDomainID(); + expectEqualField(expected, actual, "sfDomainID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsPermissionedDomainDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPermissionedDomainDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const domainIDValue = canonical_UINT256(); + + // Build an initial transaction + PermissionedDomainDeleteBuilder initialBuilder{ + accountValue, + domainIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + PermissionedDomainDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = domainIDValue; + auto const actual = rebuiltTx.getDomainID(); + expectEqualField(expected, actual, "sfDomainID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsPermissionedDomainDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PermissionedDomainDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsPermissionedDomainDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PermissionedDomainDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainSetTests.cpp new file mode 100644 index 0000000000..eeec170f4c --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/PermissionedDomainSetTests.cpp @@ -0,0 +1,195 @@ +// Auto-generated unit tests for transaction PermissionedDomainSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsPermissionedDomainSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPermissionedDomainSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const domainIDValue = canonical_UINT256(); + auto const acceptedCredentialsValue = canonical_ARRAY(); + + PermissionedDomainSetBuilder builder{ + accountValue, + acceptedCredentialsValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDomainID(domainIDValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = acceptedCredentialsValue; + auto const actual = tx.getAcceptedCredentials(); + expectEqualField(expected, actual, "sfAcceptedCredentials"); + } + + // Verify optional fields + { + auto const& expected = domainIDValue; + auto const actualOpt = tx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(tx.hasDomainID()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsPermissionedDomainSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPermissionedDomainSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const domainIDValue = canonical_UINT256(); + auto const acceptedCredentialsValue = canonical_ARRAY(); + + // Build an initial transaction + PermissionedDomainSetBuilder initialBuilder{ + accountValue, + acceptedCredentialsValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDomainID(domainIDValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + PermissionedDomainSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = acceptedCredentialsValue; + auto const actual = rebuiltTx.getAcceptedCredentials(); + expectEqualField(expected, actual, "sfAcceptedCredentials"); + } + + // Verify optional fields + { + auto const& expected = domainIDValue; + auto const actualOpt = rebuiltTx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsPermissionedDomainSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PermissionedDomainSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsPermissionedDomainSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(PermissionedDomainSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsPermissionedDomainSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testPermissionedDomainSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const acceptedCredentialsValue = canonical_ARRAY(); + + PermissionedDomainSetBuilder builder{ + accountValue, + acceptedCredentialsValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDomainID()); + EXPECT_FALSE(tx.getDomainID().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/SetFeeTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/SetFeeTests.cpp new file mode 100644 index 0000000000..981bf72ea7 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/SetFeeTests.cpp @@ -0,0 +1,324 @@ +// Auto-generated unit tests for transaction SetFee + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsSetFeeTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSetFee")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ledgerSequenceValue = canonical_UINT32(); + auto const baseFeeValue = canonical_UINT64(); + auto const referenceFeeUnitsValue = canonical_UINT32(); + auto const reserveBaseValue = canonical_UINT32(); + auto const reserveIncrementValue = canonical_UINT32(); + auto const baseFeeDropsValue = canonical_AMOUNT(); + auto const reserveBaseDropsValue = canonical_AMOUNT(); + auto const reserveIncrementDropsValue = canonical_AMOUNT(); + + SetFeeBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setLedgerSequence(ledgerSequenceValue); + builder.setBaseFee(baseFeeValue); + builder.setReferenceFeeUnits(referenceFeeUnitsValue); + builder.setReserveBase(reserveBaseValue); + builder.setReserveIncrement(reserveIncrementValue); + builder.setBaseFeeDrops(baseFeeDropsValue); + builder.setReserveBaseDrops(reserveBaseDropsValue); + builder.setReserveIncrementDrops(reserveIncrementDropsValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = ledgerSequenceValue; + auto const actualOpt = tx.getLedgerSequence(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLedgerSequence should be present"; + expectEqualField(expected, *actualOpt, "sfLedgerSequence"); + EXPECT_TRUE(tx.hasLedgerSequence()); + } + + { + auto const& expected = baseFeeValue; + auto const actualOpt = tx.getBaseFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBaseFee should be present"; + expectEqualField(expected, *actualOpt, "sfBaseFee"); + EXPECT_TRUE(tx.hasBaseFee()); + } + + { + auto const& expected = referenceFeeUnitsValue; + auto const actualOpt = tx.getReferenceFeeUnits(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReferenceFeeUnits should be present"; + expectEqualField(expected, *actualOpt, "sfReferenceFeeUnits"); + EXPECT_TRUE(tx.hasReferenceFeeUnits()); + } + + { + auto const& expected = reserveBaseValue; + auto const actualOpt = tx.getReserveBase(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveBase should be present"; + expectEqualField(expected, *actualOpt, "sfReserveBase"); + EXPECT_TRUE(tx.hasReserveBase()); + } + + { + auto const& expected = reserveIncrementValue; + auto const actualOpt = tx.getReserveIncrement(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveIncrement should be present"; + expectEqualField(expected, *actualOpt, "sfReserveIncrement"); + EXPECT_TRUE(tx.hasReserveIncrement()); + } + + { + auto const& expected = baseFeeDropsValue; + auto const actualOpt = tx.getBaseFeeDrops(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBaseFeeDrops should be present"; + expectEqualField(expected, *actualOpt, "sfBaseFeeDrops"); + EXPECT_TRUE(tx.hasBaseFeeDrops()); + } + + { + auto const& expected = reserveBaseDropsValue; + auto const actualOpt = tx.getReserveBaseDrops(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveBaseDrops should be present"; + expectEqualField(expected, *actualOpt, "sfReserveBaseDrops"); + EXPECT_TRUE(tx.hasReserveBaseDrops()); + } + + { + auto const& expected = reserveIncrementDropsValue; + auto const actualOpt = tx.getReserveIncrementDrops(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveIncrementDrops should be present"; + expectEqualField(expected, *actualOpt, "sfReserveIncrementDrops"); + EXPECT_TRUE(tx.hasReserveIncrementDrops()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsSetFeeTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSetFeeFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ledgerSequenceValue = canonical_UINT32(); + auto const baseFeeValue = canonical_UINT64(); + auto const referenceFeeUnitsValue = canonical_UINT32(); + auto const reserveBaseValue = canonical_UINT32(); + auto const reserveIncrementValue = canonical_UINT32(); + auto const baseFeeDropsValue = canonical_AMOUNT(); + auto const reserveBaseDropsValue = canonical_AMOUNT(); + auto const reserveIncrementDropsValue = canonical_AMOUNT(); + + // Build an initial transaction + SetFeeBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setLedgerSequence(ledgerSequenceValue); + initialBuilder.setBaseFee(baseFeeValue); + initialBuilder.setReferenceFeeUnits(referenceFeeUnitsValue); + initialBuilder.setReserveBase(reserveBaseValue); + initialBuilder.setReserveIncrement(reserveIncrementValue); + initialBuilder.setBaseFeeDrops(baseFeeDropsValue); + initialBuilder.setReserveBaseDrops(reserveBaseDropsValue); + initialBuilder.setReserveIncrementDrops(reserveIncrementDropsValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + SetFeeBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = ledgerSequenceValue; + auto const actualOpt = rebuiltTx.getLedgerSequence(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLedgerSequence should be present"; + expectEqualField(expected, *actualOpt, "sfLedgerSequence"); + } + + { + auto const& expected = baseFeeValue; + auto const actualOpt = rebuiltTx.getBaseFee(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBaseFee should be present"; + expectEqualField(expected, *actualOpt, "sfBaseFee"); + } + + { + auto const& expected = referenceFeeUnitsValue; + auto const actualOpt = rebuiltTx.getReferenceFeeUnits(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReferenceFeeUnits should be present"; + expectEqualField(expected, *actualOpt, "sfReferenceFeeUnits"); + } + + { + auto const& expected = reserveBaseValue; + auto const actualOpt = rebuiltTx.getReserveBase(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveBase should be present"; + expectEqualField(expected, *actualOpt, "sfReserveBase"); + } + + { + auto const& expected = reserveIncrementValue; + auto const actualOpt = rebuiltTx.getReserveIncrement(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveIncrement should be present"; + expectEqualField(expected, *actualOpt, "sfReserveIncrement"); + } + + { + auto const& expected = baseFeeDropsValue; + auto const actualOpt = rebuiltTx.getBaseFeeDrops(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfBaseFeeDrops should be present"; + expectEqualField(expected, *actualOpt, "sfBaseFeeDrops"); + } + + { + auto const& expected = reserveBaseDropsValue; + auto const actualOpt = rebuiltTx.getReserveBaseDrops(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveBaseDrops should be present"; + expectEqualField(expected, *actualOpt, "sfReserveBaseDrops"); + } + + { + auto const& expected = reserveIncrementDropsValue; + auto const actualOpt = rebuiltTx.getReserveIncrementDrops(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfReserveIncrementDrops should be present"; + expectEqualField(expected, *actualOpt, "sfReserveIncrementDrops"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsSetFeeTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(SetFee{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsSetFeeTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(SetFeeBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsSetFeeTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSetFeeNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + SetFeeBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasLedgerSequence()); + EXPECT_FALSE(tx.getLedgerSequence().has_value()); + EXPECT_FALSE(tx.hasBaseFee()); + EXPECT_FALSE(tx.getBaseFee().has_value()); + EXPECT_FALSE(tx.hasReferenceFeeUnits()); + EXPECT_FALSE(tx.getReferenceFeeUnits().has_value()); + EXPECT_FALSE(tx.hasReserveBase()); + EXPECT_FALSE(tx.getReserveBase().has_value()); + EXPECT_FALSE(tx.hasReserveIncrement()); + EXPECT_FALSE(tx.getReserveIncrement().has_value()); + EXPECT_FALSE(tx.hasBaseFeeDrops()); + EXPECT_FALSE(tx.getBaseFeeDrops().has_value()); + EXPECT_FALSE(tx.hasReserveBaseDrops()); + EXPECT_FALSE(tx.getReserveBaseDrops().has_value()); + EXPECT_FALSE(tx.hasReserveIncrementDrops()); + EXPECT_FALSE(tx.getReserveIncrementDrops().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/SetRegularKeyTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/SetRegularKeyTests.cpp new file mode 100644 index 0000000000..ce4f8ce2ef --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/SetRegularKeyTests.cpp @@ -0,0 +1,177 @@ +// Auto-generated unit tests for transaction SetRegularKey + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsSetRegularKeyTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSetRegularKey")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const regularKeyValue = canonical_ACCOUNT(); + + SetRegularKeyBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setRegularKey(regularKeyValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = regularKeyValue; + auto const actualOpt = tx.getRegularKey(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfRegularKey should be present"; + expectEqualField(expected, *actualOpt, "sfRegularKey"); + EXPECT_TRUE(tx.hasRegularKey()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsSetRegularKeyTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSetRegularKeyFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const regularKeyValue = canonical_ACCOUNT(); + + // Build an initial transaction + SetRegularKeyBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setRegularKey(regularKeyValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + SetRegularKeyBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = regularKeyValue; + auto const actualOpt = rebuiltTx.getRegularKey(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfRegularKey should be present"; + expectEqualField(expected, *actualOpt, "sfRegularKey"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsSetRegularKeyTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(SetRegularKey{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsSetRegularKeyTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(SetRegularKeyBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsSetRegularKeyTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSetRegularKeyNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + SetRegularKeyBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasRegularKey()); + EXPECT_FALSE(tx.getRegularKey().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/SignerListSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/SignerListSetTests.cpp new file mode 100644 index 0000000000..8d027823d0 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/SignerListSetTests.cpp @@ -0,0 +1,195 @@ +// Auto-generated unit tests for transaction SignerListSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsSignerListSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSignerListSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const signerQuorumValue = canonical_UINT32(); + auto const signerEntriesValue = canonical_ARRAY(); + + SignerListSetBuilder builder{ + accountValue, + signerQuorumValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setSignerEntries(signerEntriesValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = signerQuorumValue; + auto const actual = tx.getSignerQuorum(); + expectEqualField(expected, actual, "sfSignerQuorum"); + } + + // Verify optional fields + { + auto const& expected = signerEntriesValue; + auto const actualOpt = tx.getSignerEntries(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSignerEntries should be present"; + expectEqualField(expected, *actualOpt, "sfSignerEntries"); + EXPECT_TRUE(tx.hasSignerEntries()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsSignerListSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSignerListSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const signerQuorumValue = canonical_UINT32(); + auto const signerEntriesValue = canonical_ARRAY(); + + // Build an initial transaction + SignerListSetBuilder initialBuilder{ + accountValue, + signerQuorumValue, + sequenceValue, + feeValue + }; + + initialBuilder.setSignerEntries(signerEntriesValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + SignerListSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = signerQuorumValue; + auto const actual = rebuiltTx.getSignerQuorum(); + expectEqualField(expected, actual, "sfSignerQuorum"); + } + + // Verify optional fields + { + auto const& expected = signerEntriesValue; + auto const actualOpt = rebuiltTx.getSignerEntries(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSignerEntries should be present"; + expectEqualField(expected, *actualOpt, "sfSignerEntries"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsSignerListSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(SignerListSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsSignerListSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(SignerListSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsSignerListSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testSignerListSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const signerQuorumValue = canonical_UINT32(); + + SignerListSetBuilder builder{ + accountValue, + signerQuorumValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasSignerEntries()); + EXPECT_FALSE(tx.getSignerEntries().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/TicketCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/TicketCreateTests.cpp new file mode 100644 index 0000000000..bb07cdef84 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/TicketCreateTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction TicketCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsTicketCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testTicketCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ticketCountValue = canonical_UINT32(); + + TicketCreateBuilder builder{ + accountValue, + ticketCountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ticketCountValue; + auto const actual = tx.getTicketCount(); + expectEqualField(expected, actual, "sfTicketCount"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsTicketCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testTicketCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const ticketCountValue = canonical_UINT32(); + + // Build an initial transaction + TicketCreateBuilder initialBuilder{ + accountValue, + ticketCountValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + TicketCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = ticketCountValue; + auto const actual = rebuiltTx.getTicketCount(); + expectEqualField(expected, actual, "sfTicketCount"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsTicketCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(TicketCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsTicketCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(TicketCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/TrustSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/TrustSetTests.cpp new file mode 100644 index 0000000000..12b243ca5c --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/TrustSetTests.cpp @@ -0,0 +1,219 @@ +// Auto-generated unit tests for transaction TrustSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsTrustSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testTrustSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const limitAmountValue = canonical_AMOUNT(); + auto const qualityInValue = canonical_UINT32(); + auto const qualityOutValue = canonical_UINT32(); + + TrustSetBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setLimitAmount(limitAmountValue); + builder.setQualityIn(qualityInValue); + builder.setQualityOut(qualityOutValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = limitAmountValue; + auto const actualOpt = tx.getLimitAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLimitAmount should be present"; + expectEqualField(expected, *actualOpt, "sfLimitAmount"); + EXPECT_TRUE(tx.hasLimitAmount()); + } + + { + auto const& expected = qualityInValue; + auto const actualOpt = tx.getQualityIn(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfQualityIn should be present"; + expectEqualField(expected, *actualOpt, "sfQualityIn"); + EXPECT_TRUE(tx.hasQualityIn()); + } + + { + auto const& expected = qualityOutValue; + auto const actualOpt = tx.getQualityOut(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfQualityOut should be present"; + expectEqualField(expected, *actualOpt, "sfQualityOut"); + EXPECT_TRUE(tx.hasQualityOut()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsTrustSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testTrustSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const limitAmountValue = canonical_AMOUNT(); + auto const qualityInValue = canonical_UINT32(); + auto const qualityOutValue = canonical_UINT32(); + + // Build an initial transaction + TrustSetBuilder initialBuilder{ + accountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setLimitAmount(limitAmountValue); + initialBuilder.setQualityIn(qualityInValue); + initialBuilder.setQualityOut(qualityOutValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + TrustSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + // Verify optional fields + { + auto const& expected = limitAmountValue; + auto const actualOpt = rebuiltTx.getLimitAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfLimitAmount should be present"; + expectEqualField(expected, *actualOpt, "sfLimitAmount"); + } + + { + auto const& expected = qualityInValue; + auto const actualOpt = rebuiltTx.getQualityIn(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfQualityIn should be present"; + expectEqualField(expected, *actualOpt, "sfQualityIn"); + } + + { + auto const& expected = qualityOutValue; + auto const actualOpt = rebuiltTx.getQualityOut(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfQualityOut should be present"; + expectEqualField(expected, *actualOpt, "sfQualityOut"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsTrustSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(TrustSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsTrustSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(TrustSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsTrustSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testTrustSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + + TrustSetBuilder builder{ + accountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasLimitAmount()); + EXPECT_FALSE(tx.getLimitAmount().has_value()); + EXPECT_FALSE(tx.hasQualityIn()); + EXPECT_FALSE(tx.getQualityIn().has_value()); + EXPECT_FALSE(tx.hasQualityOut()); + EXPECT_FALSE(tx.getQualityOut().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/UNLModifyTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/UNLModifyTests.cpp new file mode 100644 index 0000000000..3481460641 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/UNLModifyTests.cpp @@ -0,0 +1,178 @@ +// Auto-generated unit tests for transaction UNLModify + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsUNLModifyTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testUNLModify")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const uNLModifyDisablingValue = canonical_UINT8(); + auto const ledgerSequenceValue = canonical_UINT32(); + auto const uNLModifyValidatorValue = canonical_VL(); + + UNLModifyBuilder builder{ + accountValue, + uNLModifyDisablingValue, + ledgerSequenceValue, + uNLModifyValidatorValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = uNLModifyDisablingValue; + auto const actual = tx.getUNLModifyDisabling(); + expectEqualField(expected, actual, "sfUNLModifyDisabling"); + } + + { + auto const& expected = ledgerSequenceValue; + auto const actual = tx.getLedgerSequence(); + expectEqualField(expected, actual, "sfLedgerSequence"); + } + + { + auto const& expected = uNLModifyValidatorValue; + auto const actual = tx.getUNLModifyValidator(); + expectEqualField(expected, actual, "sfUNLModifyValidator"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsUNLModifyTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testUNLModifyFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const uNLModifyDisablingValue = canonical_UINT8(); + auto const ledgerSequenceValue = canonical_UINT32(); + auto const uNLModifyValidatorValue = canonical_VL(); + + // Build an initial transaction + UNLModifyBuilder initialBuilder{ + accountValue, + uNLModifyDisablingValue, + ledgerSequenceValue, + uNLModifyValidatorValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + UNLModifyBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = uNLModifyDisablingValue; + auto const actual = rebuiltTx.getUNLModifyDisabling(); + expectEqualField(expected, actual, "sfUNLModifyDisabling"); + } + + { + auto const& expected = ledgerSequenceValue; + auto const actual = rebuiltTx.getLedgerSequence(); + expectEqualField(expected, actual, "sfLedgerSequence"); + } + + { + auto const& expected = uNLModifyValidatorValue; + auto const actual = rebuiltTx.getUNLModifyValidator(); + expectEqualField(expected, actual, "sfUNLModifyValidator"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsUNLModifyTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(UNLModify{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsUNLModifyTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(UNLModifyBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/VaultClawbackTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/VaultClawbackTests.cpp new file mode 100644 index 0000000000..d089e3d097 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/VaultClawbackTests.cpp @@ -0,0 +1,213 @@ +// Auto-generated unit tests for transaction VaultClawback + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsVaultClawbackTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultClawback")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const holderValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + + VaultClawbackBuilder builder{ + accountValue, + vaultIDValue, + holderValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAmount(amountValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = tx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + { + auto const& expected = holderValue; + auto const actual = tx.getHolder(); + expectEqualField(expected, actual, "sfHolder"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = tx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + EXPECT_TRUE(tx.hasAmount()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsVaultClawbackTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultClawbackFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const holderValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + + // Build an initial transaction + VaultClawbackBuilder initialBuilder{ + accountValue, + vaultIDValue, + holderValue, + sequenceValue, + feeValue + }; + + initialBuilder.setAmount(amountValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + VaultClawbackBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = rebuiltTx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + { + auto const& expected = holderValue; + auto const actual = rebuiltTx.getHolder(); + expectEqualField(expected, actual, "sfHolder"); + } + + // Verify optional fields + { + auto const& expected = amountValue; + auto const actualOpt = rebuiltTx.getAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAmount should be present"; + expectEqualField(expected, *actualOpt, "sfAmount"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsVaultClawbackTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultClawback{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsVaultClawbackTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultClawbackBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsVaultClawbackTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultClawbackNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const vaultIDValue = canonical_UINT256(); + auto const holderValue = canonical_ACCOUNT(); + + VaultClawbackBuilder builder{ + accountValue, + vaultIDValue, + holderValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAmount()); + EXPECT_FALSE(tx.getAmount().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/VaultCreateTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/VaultCreateTests.cpp new file mode 100644 index 0000000000..da141ce812 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/VaultCreateTests.cpp @@ -0,0 +1,300 @@ +// Auto-generated unit tests for transaction VaultCreate + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsVaultCreateTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultCreate")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const assetsMaximumValue = canonical_NUMBER(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const domainIDValue = canonical_UINT256(); + auto const withdrawalPolicyValue = canonical_UINT8(); + auto const dataValue = canonical_VL(); + auto const scaleValue = canonical_UINT8(); + + VaultCreateBuilder builder{ + accountValue, + assetValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAssetsMaximum(assetsMaximumValue); + builder.setMPTokenMetadata(mPTokenMetadataValue); + builder.setDomainID(domainIDValue); + builder.setWithdrawalPolicy(withdrawalPolicyValue); + builder.setData(dataValue); + builder.setScale(scaleValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = tx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + // Verify optional fields + { + auto const& expected = assetsMaximumValue; + auto const actualOpt = tx.getAssetsMaximum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetsMaximum should be present"; + expectEqualField(expected, *actualOpt, "sfAssetsMaximum"); + EXPECT_TRUE(tx.hasAssetsMaximum()); + } + + { + auto const& expected = mPTokenMetadataValue; + auto const actualOpt = tx.getMPTokenMetadata(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present"; + expectEqualField(expected, *actualOpt, "sfMPTokenMetadata"); + EXPECT_TRUE(tx.hasMPTokenMetadata()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = tx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(tx.hasDomainID()); + } + + { + auto const& expected = withdrawalPolicyValue; + auto const actualOpt = tx.getWithdrawalPolicy(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWithdrawalPolicy should be present"; + expectEqualField(expected, *actualOpt, "sfWithdrawalPolicy"); + EXPECT_TRUE(tx.hasWithdrawalPolicy()); + } + + { + auto const& expected = dataValue; + auto const actualOpt = tx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(tx.hasData()); + } + + { + auto const& expected = scaleValue; + auto const actualOpt = tx.getScale(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfScale should be present"; + expectEqualField(expected, *actualOpt, "sfScale"); + EXPECT_TRUE(tx.hasScale()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsVaultCreateTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultCreateFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const assetValue = canonical_ISSUE(); + auto const assetsMaximumValue = canonical_NUMBER(); + auto const mPTokenMetadataValue = canonical_VL(); + auto const domainIDValue = canonical_UINT256(); + auto const withdrawalPolicyValue = canonical_UINT8(); + auto const dataValue = canonical_VL(); + auto const scaleValue = canonical_UINT8(); + + // Build an initial transaction + VaultCreateBuilder initialBuilder{ + accountValue, + assetValue, + sequenceValue, + feeValue + }; + + initialBuilder.setAssetsMaximum(assetsMaximumValue); + initialBuilder.setMPTokenMetadata(mPTokenMetadataValue); + initialBuilder.setDomainID(domainIDValue); + initialBuilder.setWithdrawalPolicy(withdrawalPolicyValue); + initialBuilder.setData(dataValue); + initialBuilder.setScale(scaleValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + VaultCreateBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = assetValue; + auto const actual = rebuiltTx.getAsset(); + expectEqualField(expected, actual, "sfAsset"); + } + + // Verify optional fields + { + auto const& expected = assetsMaximumValue; + auto const actualOpt = rebuiltTx.getAssetsMaximum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetsMaximum should be present"; + expectEqualField(expected, *actualOpt, "sfAssetsMaximum"); + } + + { + auto const& expected = mPTokenMetadataValue; + auto const actualOpt = rebuiltTx.getMPTokenMetadata(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present"; + expectEqualField(expected, *actualOpt, "sfMPTokenMetadata"); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = rebuiltTx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + } + + { + auto const& expected = withdrawalPolicyValue; + auto const actualOpt = rebuiltTx.getWithdrawalPolicy(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWithdrawalPolicy should be present"; + expectEqualField(expected, *actualOpt, "sfWithdrawalPolicy"); + } + + { + auto const& expected = dataValue; + auto const actualOpt = rebuiltTx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + } + + { + auto const& expected = scaleValue; + auto const actualOpt = rebuiltTx.getScale(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfScale should be present"; + expectEqualField(expected, *actualOpt, "sfScale"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsVaultCreateTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultCreate{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsVaultCreateTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultCreateBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsVaultCreateTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultCreateNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const assetValue = canonical_ISSUE(); + + VaultCreateBuilder builder{ + accountValue, + assetValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAssetsMaximum()); + EXPECT_FALSE(tx.getAssetsMaximum().has_value()); + EXPECT_FALSE(tx.hasMPTokenMetadata()); + EXPECT_FALSE(tx.getMPTokenMetadata().has_value()); + EXPECT_FALSE(tx.hasDomainID()); + EXPECT_FALSE(tx.getDomainID().has_value()); + EXPECT_FALSE(tx.hasWithdrawalPolicy()); + EXPECT_FALSE(tx.getWithdrawalPolicy().has_value()); + EXPECT_FALSE(tx.hasData()); + EXPECT_FALSE(tx.getData().has_value()); + EXPECT_FALSE(tx.hasScale()); + EXPECT_FALSE(tx.getScale().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/VaultDeleteTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/VaultDeleteTests.cpp new file mode 100644 index 0000000000..24c89d249a --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/VaultDeleteTests.cpp @@ -0,0 +1,146 @@ +// Auto-generated unit tests for transaction VaultDelete + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsVaultDeleteTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultDelete")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + + VaultDeleteBuilder builder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = tx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsVaultDeleteTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultDeleteFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + + // Build an initial transaction + VaultDeleteBuilder initialBuilder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + VaultDeleteBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = rebuiltTx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsVaultDeleteTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultDelete{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsVaultDeleteTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultDeleteBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/VaultDepositTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/VaultDepositTests.cpp new file mode 100644 index 0000000000..c18ee8bd62 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/VaultDepositTests.cpp @@ -0,0 +1,162 @@ +// Auto-generated unit tests for transaction VaultDeposit + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsVaultDepositTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultDeposit")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + VaultDepositBuilder builder{ + accountValue, + vaultIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = tx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsVaultDepositTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultDepositFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + // Build an initial transaction + VaultDepositBuilder initialBuilder{ + accountValue, + vaultIDValue, + amountValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + VaultDepositBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = rebuiltTx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsVaultDepositTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultDeposit{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsVaultDepositTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultDepositBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/VaultSetTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/VaultSetTests.cpp new file mode 100644 index 0000000000..995c1019f3 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/VaultSetTests.cpp @@ -0,0 +1,237 @@ +// Auto-generated unit tests for transaction VaultSet + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsVaultSetTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultSet")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const assetsMaximumValue = canonical_NUMBER(); + auto const domainIDValue = canonical_UINT256(); + auto const dataValue = canonical_VL(); + + VaultSetBuilder builder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setAssetsMaximum(assetsMaximumValue); + builder.setDomainID(domainIDValue); + builder.setData(dataValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = tx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + // Verify optional fields + { + auto const& expected = assetsMaximumValue; + auto const actualOpt = tx.getAssetsMaximum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetsMaximum should be present"; + expectEqualField(expected, *actualOpt, "sfAssetsMaximum"); + EXPECT_TRUE(tx.hasAssetsMaximum()); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = tx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + EXPECT_TRUE(tx.hasDomainID()); + } + + { + auto const& expected = dataValue; + auto const actualOpt = tx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + EXPECT_TRUE(tx.hasData()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsVaultSetTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultSetFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const assetsMaximumValue = canonical_NUMBER(); + auto const domainIDValue = canonical_UINT256(); + auto const dataValue = canonical_VL(); + + // Build an initial transaction + VaultSetBuilder initialBuilder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setAssetsMaximum(assetsMaximumValue); + initialBuilder.setDomainID(domainIDValue); + initialBuilder.setData(dataValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + VaultSetBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = rebuiltTx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + // Verify optional fields + { + auto const& expected = assetsMaximumValue; + auto const actualOpt = rebuiltTx.getAssetsMaximum(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetsMaximum should be present"; + expectEqualField(expected, *actualOpt, "sfAssetsMaximum"); + } + + { + auto const& expected = domainIDValue; + auto const actualOpt = rebuiltTx.getDomainID(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present"; + expectEqualField(expected, *actualOpt, "sfDomainID"); + } + + { + auto const& expected = dataValue; + auto const actualOpt = rebuiltTx.getData(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present"; + expectEqualField(expected, *actualOpt, "sfData"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsVaultSetTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultSet{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsVaultSetTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultSetBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsVaultSetTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultSetNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const vaultIDValue = canonical_UINT256(); + + VaultSetBuilder builder{ + accountValue, + vaultIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasAssetsMaximum()); + EXPECT_FALSE(tx.getAssetsMaximum().has_value()); + EXPECT_FALSE(tx.hasDomainID()); + EXPECT_FALSE(tx.getDomainID().has_value()); + EXPECT_FALSE(tx.hasData()); + EXPECT_FALSE(tx.getData().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/VaultWithdrawTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/VaultWithdrawTests.cpp new file mode 100644 index 0000000000..9d8a7fecb9 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/VaultWithdrawTests.cpp @@ -0,0 +1,234 @@ +// Auto-generated unit tests for transaction VaultWithdraw + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsVaultWithdrawTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultWithdraw")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + + VaultWithdrawBuilder builder{ + accountValue, + vaultIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDestination(destinationValue); + builder.setDestinationTag(destinationTagValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = tx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = tx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + EXPECT_TRUE(tx.hasDestination()); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsVaultWithdrawTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultWithdrawFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const vaultIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + + // Build an initial transaction + VaultWithdrawBuilder initialBuilder{ + accountValue, + vaultIDValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDestination(destinationValue); + initialBuilder.setDestinationTag(destinationTagValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + VaultWithdrawBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = vaultIDValue; + auto const actual = rebuiltTx.getVaultID(); + expectEqualField(expected, actual, "sfVaultID"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = rebuiltTx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + } + + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsVaultWithdrawTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultWithdraw{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsVaultWithdrawTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(VaultWithdrawBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsVaultWithdrawTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testVaultWithdrawNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const vaultIDValue = canonical_UINT256(); + auto const amountValue = canonical_AMOUNT(); + + VaultWithdrawBuilder builder{ + accountValue, + vaultIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDestination()); + EXPECT_FALSE(tx.getDestination().has_value()); + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainAccountCreateCommitTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainAccountCreateCommitTests.cpp new file mode 100644 index 0000000000..c3f2f11a00 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainAccountCreateCommitTests.cpp @@ -0,0 +1,194 @@ +// Auto-generated unit tests for transaction XChainAccountCreateCommit + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainAccountCreateCommitTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainAccountCreateCommit")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const signatureRewardValue = canonical_AMOUNT(); + + XChainAccountCreateCommitBuilder builder{ + accountValue, + xChainBridgeValue, + destinationValue, + amountValue, + signatureRewardValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = tx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainAccountCreateCommitTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainAccountCreateCommitFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const signatureRewardValue = canonical_AMOUNT(); + + // Build an initial transaction + XChainAccountCreateCommitBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + destinationValue, + amountValue, + signatureRewardValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainAccountCreateCommitBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = rebuiltTx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainAccountCreateCommitTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainAccountCreateCommit{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainAccountCreateCommitTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainAccountCreateCommitBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestationTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestationTests.cpp new file mode 100644 index 0000000000..82f9c6afc1 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainAddAccountCreateAttestationTests.cpp @@ -0,0 +1,306 @@ +// Auto-generated unit tests for transaction XChainAddAccountCreateAttestation + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainAddAccountCreateAttestationTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainAddAccountCreateAttestation")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const attestationSignerAccountValue = canonical_ACCOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const signatureValue = canonical_VL(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const attestationRewardAccountValue = canonical_ACCOUNT(); + auto const wasLockingChainSendValue = canonical_UINT8(); + auto const xChainAccountCreateCountValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + auto const signatureRewardValue = canonical_AMOUNT(); + + XChainAddAccountCreateAttestationBuilder builder{ + accountValue, + xChainBridgeValue, + attestationSignerAccountValue, + publicKeyValue, + signatureValue, + otherChainSourceValue, + amountValue, + attestationRewardAccountValue, + wasLockingChainSendValue, + xChainAccountCreateCountValue, + destinationValue, + signatureRewardValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = attestationSignerAccountValue; + auto const actual = tx.getAttestationSignerAccount(); + expectEqualField(expected, actual, "sfAttestationSignerAccount"); + } + + { + auto const& expected = publicKeyValue; + auto const actual = tx.getPublicKey(); + expectEqualField(expected, actual, "sfPublicKey"); + } + + { + auto const& expected = signatureValue; + auto const actual = tx.getSignature(); + expectEqualField(expected, actual, "sfSignature"); + } + + { + auto const& expected = otherChainSourceValue; + auto const actual = tx.getOtherChainSource(); + expectEqualField(expected, actual, "sfOtherChainSource"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = attestationRewardAccountValue; + auto const actual = tx.getAttestationRewardAccount(); + expectEqualField(expected, actual, "sfAttestationRewardAccount"); + } + + { + auto const& expected = wasLockingChainSendValue; + auto const actual = tx.getWasLockingChainSend(); + expectEqualField(expected, actual, "sfWasLockingChainSend"); + } + + { + auto const& expected = xChainAccountCreateCountValue; + auto const actual = tx.getXChainAccountCreateCount(); + expectEqualField(expected, actual, "sfXChainAccountCreateCount"); + } + + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = tx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainAddAccountCreateAttestationTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainAddAccountCreateAttestationFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const attestationSignerAccountValue = canonical_ACCOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const signatureValue = canonical_VL(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const attestationRewardAccountValue = canonical_ACCOUNT(); + auto const wasLockingChainSendValue = canonical_UINT8(); + auto const xChainAccountCreateCountValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + auto const signatureRewardValue = canonical_AMOUNT(); + + // Build an initial transaction + XChainAddAccountCreateAttestationBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + attestationSignerAccountValue, + publicKeyValue, + signatureValue, + otherChainSourceValue, + amountValue, + attestationRewardAccountValue, + wasLockingChainSendValue, + xChainAccountCreateCountValue, + destinationValue, + signatureRewardValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainAddAccountCreateAttestationBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = attestationSignerAccountValue; + auto const actual = rebuiltTx.getAttestationSignerAccount(); + expectEqualField(expected, actual, "sfAttestationSignerAccount"); + } + + { + auto const& expected = publicKeyValue; + auto const actual = rebuiltTx.getPublicKey(); + expectEqualField(expected, actual, "sfPublicKey"); + } + + { + auto const& expected = signatureValue; + auto const actual = rebuiltTx.getSignature(); + expectEqualField(expected, actual, "sfSignature"); + } + + { + auto const& expected = otherChainSourceValue; + auto const actual = rebuiltTx.getOtherChainSource(); + expectEqualField(expected, actual, "sfOtherChainSource"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = attestationRewardAccountValue; + auto const actual = rebuiltTx.getAttestationRewardAccount(); + expectEqualField(expected, actual, "sfAttestationRewardAccount"); + } + + { + auto const& expected = wasLockingChainSendValue; + auto const actual = rebuiltTx.getWasLockingChainSend(); + expectEqualField(expected, actual, "sfWasLockingChainSend"); + } + + { + auto const& expected = xChainAccountCreateCountValue; + auto const actual = rebuiltTx.getXChainAccountCreateCount(); + expectEqualField(expected, actual, "sfXChainAccountCreateCount"); + } + + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = rebuiltTx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainAddAccountCreateAttestationTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainAddAccountCreateAttestation{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainAddAccountCreateAttestationTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainAddAccountCreateAttestationBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainAddClaimAttestationTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainAddClaimAttestationTests.cpp new file mode 100644 index 0000000000..6b9144fa68 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainAddClaimAttestationTests.cpp @@ -0,0 +1,339 @@ +// Auto-generated unit tests for transaction XChainAddClaimAttestation + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainAddClaimAttestationTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainAddClaimAttestation")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const attestationSignerAccountValue = canonical_ACCOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const signatureValue = canonical_VL(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const attestationRewardAccountValue = canonical_ACCOUNT(); + auto const wasLockingChainSendValue = canonical_UINT8(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + + XChainAddClaimAttestationBuilder builder{ + accountValue, + xChainBridgeValue, + attestationSignerAccountValue, + publicKeyValue, + signatureValue, + otherChainSourceValue, + amountValue, + attestationRewardAccountValue, + wasLockingChainSendValue, + xChainClaimIDValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDestination(destinationValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = attestationSignerAccountValue; + auto const actual = tx.getAttestationSignerAccount(); + expectEqualField(expected, actual, "sfAttestationSignerAccount"); + } + + { + auto const& expected = publicKeyValue; + auto const actual = tx.getPublicKey(); + expectEqualField(expected, actual, "sfPublicKey"); + } + + { + auto const& expected = signatureValue; + auto const actual = tx.getSignature(); + expectEqualField(expected, actual, "sfSignature"); + } + + { + auto const& expected = otherChainSourceValue; + auto const actual = tx.getOtherChainSource(); + expectEqualField(expected, actual, "sfOtherChainSource"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = attestationRewardAccountValue; + auto const actual = tx.getAttestationRewardAccount(); + expectEqualField(expected, actual, "sfAttestationRewardAccount"); + } + + { + auto const& expected = wasLockingChainSendValue; + auto const actual = tx.getWasLockingChainSend(); + expectEqualField(expected, actual, "sfWasLockingChainSend"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = tx.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = tx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + EXPECT_TRUE(tx.hasDestination()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainAddClaimAttestationTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainAddClaimAttestationFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const attestationSignerAccountValue = canonical_ACCOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const signatureValue = canonical_VL(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const attestationRewardAccountValue = canonical_ACCOUNT(); + auto const wasLockingChainSendValue = canonical_UINT8(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + + // Build an initial transaction + XChainAddClaimAttestationBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + attestationSignerAccountValue, + publicKeyValue, + signatureValue, + otherChainSourceValue, + amountValue, + attestationRewardAccountValue, + wasLockingChainSendValue, + xChainClaimIDValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDestination(destinationValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainAddClaimAttestationBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = attestationSignerAccountValue; + auto const actual = rebuiltTx.getAttestationSignerAccount(); + expectEqualField(expected, actual, "sfAttestationSignerAccount"); + } + + { + auto const& expected = publicKeyValue; + auto const actual = rebuiltTx.getPublicKey(); + expectEqualField(expected, actual, "sfPublicKey"); + } + + { + auto const& expected = signatureValue; + auto const actual = rebuiltTx.getSignature(); + expectEqualField(expected, actual, "sfSignature"); + } + + { + auto const& expected = otherChainSourceValue; + auto const actual = rebuiltTx.getOtherChainSource(); + expectEqualField(expected, actual, "sfOtherChainSource"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + { + auto const& expected = attestationRewardAccountValue; + auto const actual = rebuiltTx.getAttestationRewardAccount(); + expectEqualField(expected, actual, "sfAttestationRewardAccount"); + } + + { + auto const& expected = wasLockingChainSendValue; + auto const actual = rebuiltTx.getWasLockingChainSend(); + expectEqualField(expected, actual, "sfWasLockingChainSend"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = rebuiltTx.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + // Verify optional fields + { + auto const& expected = destinationValue; + auto const actualOpt = rebuiltTx.getDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestination should be present"; + expectEqualField(expected, *actualOpt, "sfDestination"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainAddClaimAttestationTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainAddClaimAttestation{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainAddClaimAttestationTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainAddClaimAttestationBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsXChainAddClaimAttestationTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainAddClaimAttestationNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const attestationSignerAccountValue = canonical_ACCOUNT(); + auto const publicKeyValue = canonical_VL(); + auto const signatureValue = canonical_VL(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + auto const attestationRewardAccountValue = canonical_ACCOUNT(); + auto const wasLockingChainSendValue = canonical_UINT8(); + auto const xChainClaimIDValue = canonical_UINT64(); + + XChainAddClaimAttestationBuilder builder{ + accountValue, + xChainBridgeValue, + attestationSignerAccountValue, + publicKeyValue, + signatureValue, + otherChainSourceValue, + amountValue, + attestationRewardAccountValue, + wasLockingChainSendValue, + xChainClaimIDValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDestination()); + EXPECT_FALSE(tx.getDestination().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainClaimTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainClaimTests.cpp new file mode 100644 index 0000000000..69101c843d --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainClaimTests.cpp @@ -0,0 +1,249 @@ +// Auto-generated unit tests for transaction XChainClaim + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainClaimTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainClaim")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + auto const amountValue = canonical_AMOUNT(); + + XChainClaimBuilder builder{ + accountValue, + xChainBridgeValue, + xChainClaimIDValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setDestinationTag(destinationTagValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = tx.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + { + auto const& expected = destinationValue; + auto const actual = tx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationTagValue; + auto const actualOpt = tx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + EXPECT_TRUE(tx.hasDestinationTag()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainClaimTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainClaimFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + auto const destinationTagValue = canonical_UINT32(); + auto const amountValue = canonical_AMOUNT(); + + // Build an initial transaction + XChainClaimBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + xChainClaimIDValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setDestinationTag(destinationTagValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainClaimBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = rebuiltTx.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + { + auto const& expected = destinationValue; + auto const actual = rebuiltTx.getDestination(); + expectEqualField(expected, actual, "sfDestination"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = destinationTagValue; + auto const actualOpt = rebuiltTx.getDestinationTag(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present"; + expectEqualField(expected, *actualOpt, "sfDestinationTag"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainClaimTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainClaim{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainClaimTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainClaimBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsXChainClaimTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainClaimNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const destinationValue = canonical_ACCOUNT(); + auto const amountValue = canonical_AMOUNT(); + + XChainClaimBuilder builder{ + accountValue, + xChainBridgeValue, + xChainClaimIDValue, + destinationValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasDestinationTag()); + EXPECT_FALSE(tx.getDestinationTag().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainCommitTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainCommitTests.cpp new file mode 100644 index 0000000000..e6c72ec908 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainCommitTests.cpp @@ -0,0 +1,231 @@ +// Auto-generated unit tests for transaction XChainCommit + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainCommitTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCommit")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const amountValue = canonical_AMOUNT(); + auto const otherChainDestinationValue = canonical_ACCOUNT(); + + XChainCommitBuilder builder{ + accountValue, + xChainBridgeValue, + xChainClaimIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setOtherChainDestination(otherChainDestinationValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = tx.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + { + auto const& expected = amountValue; + auto const actual = tx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = otherChainDestinationValue; + auto const actualOpt = tx.getOtherChainDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOtherChainDestination should be present"; + expectEqualField(expected, *actualOpt, "sfOtherChainDestination"); + EXPECT_TRUE(tx.hasOtherChainDestination()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainCommitTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCommitFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const amountValue = canonical_AMOUNT(); + auto const otherChainDestinationValue = canonical_ACCOUNT(); + + // Build an initial transaction + XChainCommitBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + xChainClaimIDValue, + amountValue, + sequenceValue, + feeValue + }; + + initialBuilder.setOtherChainDestination(otherChainDestinationValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainCommitBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = xChainClaimIDValue; + auto const actual = rebuiltTx.getXChainClaimID(); + expectEqualField(expected, actual, "sfXChainClaimID"); + } + + { + auto const& expected = amountValue; + auto const actual = rebuiltTx.getAmount(); + expectEqualField(expected, actual, "sfAmount"); + } + + // Verify optional fields + { + auto const& expected = otherChainDestinationValue; + auto const actualOpt = rebuiltTx.getOtherChainDestination(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfOtherChainDestination should be present"; + expectEqualField(expected, *actualOpt, "sfOtherChainDestination"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainCommitTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainCommit{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainCommitTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainCommitBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsXChainCommitTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCommitNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const xChainClaimIDValue = canonical_UINT64(); + auto const amountValue = canonical_AMOUNT(); + + XChainCommitBuilder builder{ + accountValue, + xChainBridgeValue, + xChainClaimIDValue, + amountValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasOtherChainDestination()); + EXPECT_FALSE(tx.getOtherChainDestination().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainCreateBridgeTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainCreateBridgeTests.cpp new file mode 100644 index 0000000000..5f529440f3 --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainCreateBridgeTests.cpp @@ -0,0 +1,213 @@ +// Auto-generated unit tests for transaction XChainCreateBridge + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainCreateBridgeTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCreateBridge")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const minAccountCreateAmountValue = canonical_AMOUNT(); + + XChainCreateBridgeBuilder builder{ + accountValue, + xChainBridgeValue, + signatureRewardValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setMinAccountCreateAmount(minAccountCreateAmountValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = tx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + // Verify optional fields + { + auto const& expected = minAccountCreateAmountValue; + auto const actualOpt = tx.getMinAccountCreateAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMinAccountCreateAmount should be present"; + expectEqualField(expected, *actualOpt, "sfMinAccountCreateAmount"); + EXPECT_TRUE(tx.hasMinAccountCreateAmount()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainCreateBridgeTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCreateBridgeFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const minAccountCreateAmountValue = canonical_AMOUNT(); + + // Build an initial transaction + XChainCreateBridgeBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + signatureRewardValue, + sequenceValue, + feeValue + }; + + initialBuilder.setMinAccountCreateAmount(minAccountCreateAmountValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainCreateBridgeBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = rebuiltTx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + // Verify optional fields + { + auto const& expected = minAccountCreateAmountValue; + auto const actualOpt = rebuiltTx.getMinAccountCreateAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMinAccountCreateAmount should be present"; + expectEqualField(expected, *actualOpt, "sfMinAccountCreateAmount"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainCreateBridgeTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainCreateBridge{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainCreateBridgeTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainCreateBridgeBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsXChainCreateBridgeTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCreateBridgeNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const signatureRewardValue = canonical_AMOUNT(); + + XChainCreateBridgeBuilder builder{ + accountValue, + xChainBridgeValue, + signatureRewardValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasMinAccountCreateAmount()); + EXPECT_FALSE(tx.getMinAccountCreateAmount().has_value()); +} + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainCreateClaimIDTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainCreateClaimIDTests.cpp new file mode 100644 index 0000000000..41c71b9d8d --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainCreateClaimIDTests.cpp @@ -0,0 +1,178 @@ +// Auto-generated unit tests for transaction XChainCreateClaimID + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainCreateClaimIDTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCreateClaimID")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + + XChainCreateClaimIDBuilder builder{ + accountValue, + xChainBridgeValue, + signatureRewardValue, + otherChainSourceValue, + sequenceValue, + feeValue + }; + + // Set optional fields + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = tx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + { + auto const& expected = otherChainSourceValue; + auto const actual = tx.getOtherChainSource(); + expectEqualField(expected, actual, "sfOtherChainSource"); + } + + // Verify optional fields +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainCreateClaimIDTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainCreateClaimIDFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const otherChainSourceValue = canonical_ACCOUNT(); + + // Build an initial transaction + XChainCreateClaimIDBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + signatureRewardValue, + otherChainSourceValue, + sequenceValue, + feeValue + }; + + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainCreateClaimIDBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + { + auto const& expected = signatureRewardValue; + auto const actual = rebuiltTx.getSignatureReward(); + expectEqualField(expected, actual, "sfSignatureReward"); + } + + { + auto const& expected = otherChainSourceValue; + auto const actual = rebuiltTx.getOtherChainSource(); + expectEqualField(expected, actual, "sfOtherChainSource"); + } + + // Verify optional fields +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainCreateClaimIDTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainCreateClaimID{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainCreateClaimIDTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainCreateClaimIDBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + + +} diff --git a/src/tests/libxrpl/protocol_autogen/transactions/XChainModifyBridgeTests.cpp b/src/tests/libxrpl/protocol_autogen/transactions/XChainModifyBridgeTests.cpp new file mode 100644 index 0000000000..7b3c4be5ce --- /dev/null +++ b/src/tests/libxrpl/protocol_autogen/transactions/XChainModifyBridgeTests.cpp @@ -0,0 +1,216 @@ +// Auto-generated unit tests for transaction XChainModifyBridge + + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +namespace xrpl::transactions { + +// 1 & 4) Set fields via builder setters, build, then read them back via +// wrapper getters. After build(), validate() should succeed. +TEST(TransactionsXChainModifyBridgeTests, BuilderSettersRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainModifyBridge")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 1; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const minAccountCreateAmountValue = canonical_AMOUNT(); + + XChainModifyBridgeBuilder builder{ + accountValue, + xChainBridgeValue, + sequenceValue, + feeValue + }; + + // Set optional fields + builder.setSignatureReward(signatureRewardValue); + builder.setMinAccountCreateAmount(minAccountCreateAmountValue); + + auto tx = builder.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(tx.validate(reason)) << reason; + + // Verify signing was applied + EXPECT_FALSE(tx.getSigningPubKey().empty()); + EXPECT_TRUE(tx.hasTxnSignature()); + + // Verify common fields + EXPECT_EQ(tx.getAccount(), accountValue); + EXPECT_EQ(tx.getSequence(), sequenceValue); + EXPECT_EQ(tx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = tx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + // Verify optional fields + { + auto const& expected = signatureRewardValue; + auto const actualOpt = tx.getSignatureReward(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSignatureReward should be present"; + expectEqualField(expected, *actualOpt, "sfSignatureReward"); + EXPECT_TRUE(tx.hasSignatureReward()); + } + + { + auto const& expected = minAccountCreateAmountValue; + auto const actualOpt = tx.getMinAccountCreateAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMinAccountCreateAmount should be present"; + expectEqualField(expected, *actualOpt, "sfMinAccountCreateAmount"); + EXPECT_TRUE(tx.hasMinAccountCreateAmount()); + } + +} + +// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper, +// and verify all fields match. +TEST(TransactionsXChainModifyBridgeTests, BuilderFromStTxRoundTrip) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainModifyBridgeFromTx")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 2; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + auto const signatureRewardValue = canonical_AMOUNT(); + auto const minAccountCreateAmountValue = canonical_AMOUNT(); + + // Build an initial transaction + XChainModifyBridgeBuilder initialBuilder{ + accountValue, + xChainBridgeValue, + sequenceValue, + feeValue + }; + + initialBuilder.setSignatureReward(signatureRewardValue); + initialBuilder.setMinAccountCreateAmount(minAccountCreateAmountValue); + + auto initialTx = initialBuilder.build(publicKey, secretKey); + + // Create builder from existing STTx + XChainModifyBridgeBuilder builderFromTx{initialTx.getSTTx()}; + + auto rebuiltTx = builderFromTx.build(publicKey, secretKey); + + std::string reason; + EXPECT_TRUE(rebuiltTx.validate(reason)) << reason; + + // Verify common fields + EXPECT_EQ(rebuiltTx.getAccount(), accountValue); + EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue); + EXPECT_EQ(rebuiltTx.getFee(), feeValue); + + // Verify required fields + { + auto const& expected = xChainBridgeValue; + auto const actual = rebuiltTx.getXChainBridge(); + expectEqualField(expected, actual, "sfXChainBridge"); + } + + // Verify optional fields + { + auto const& expected = signatureRewardValue; + auto const actualOpt = rebuiltTx.getSignatureReward(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSignatureReward should be present"; + expectEqualField(expected, *actualOpt, "sfSignatureReward"); + } + + { + auto const& expected = minAccountCreateAmountValue; + auto const actualOpt = rebuiltTx.getMinAccountCreateAmount(); + ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMinAccountCreateAmount should be present"; + expectEqualField(expected, *actualOpt, "sfMinAccountCreateAmount"); + } + +} + +// 3) Verify wrapper throws when constructed from wrong transaction type. +TEST(TransactionsXChainModifyBridgeTests, WrapperThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainModifyBridge{wrongTx.getSTTx()}, std::runtime_error); +} + +// 4) Verify builder throws when constructed from wrong transaction type. +TEST(TransactionsXChainModifyBridgeTests, BuilderThrowsOnWrongTxType) +{ + // Build a valid transaction of a different type + auto const [pk, sk] = + generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder")); + auto const account = calcAccountID(pk); + + AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()}; + auto wrongTx = wrongBuilder.build(pk, sk); + + EXPECT_THROW(XChainModifyBridgeBuilder{wrongTx.getSTTx()}, std::runtime_error); +} + +// 5) Build with only required fields and verify optional fields return nullopt. +TEST(TransactionsXChainModifyBridgeTests, OptionalFieldsReturnNullopt) +{ + // Generate a deterministic keypair for signing + auto const [publicKey, secretKey] = + generateKeyPair(KeyType::secp256k1, generateSeed("testXChainModifyBridgeNullopt")); + + // Common transaction fields + auto const accountValue = calcAccountID(publicKey); + std::uint32_t const sequenceValue = 3; + auto const feeValue = canonical_AMOUNT(); + + // Transaction-specific required field values + auto const xChainBridgeValue = canonical_XCHAIN_BRIDGE(); + + XChainModifyBridgeBuilder builder{ + accountValue, + xChainBridgeValue, + sequenceValue, + feeValue + }; + + // Do NOT set optional fields + + auto tx = builder.build(publicKey, secretKey); + + // Verify optional fields are not present + EXPECT_FALSE(tx.hasSignatureReward()); + EXPECT_FALSE(tx.getSignatureReward().has_value()); + EXPECT_FALSE(tx.hasMinAccountCreateAmount()); + EXPECT_FALSE(tx.getMinAccountCreateAmount().has_value()); +} + +} From 12954d5392294338081ba941012e9b5055a5cbaa Mon Sep 17 00:00:00 2001 From: Alex Kremer Date: Wed, 18 Mar 2026 22:41:09 +0000 Subject: [PATCH 05/10] fix: Address remaining issue after clang-tidy merge (#6582) --- src/tests/libxrpl/basics/MallocTrim.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/libxrpl/basics/MallocTrim.cpp b/src/tests/libxrpl/basics/MallocTrim.cpp index f01bd91bbf..483cf37fe2 100644 --- a/src/tests/libxrpl/basics/MallocTrim.cpp +++ b/src/tests/libxrpl/basics/MallocTrim.cpp @@ -89,7 +89,7 @@ TEST(parseStatmRSSkB, standard_format) // Test empty string { - std::string statm = ""; + std::string statm; long result = parseStatmRSSkB(statm); EXPECT_EQ(result, -1); } From 6efd31229aad51ee208ebcf39fcbd4b84e689d09 Mon Sep 17 00:00:00 2001 From: Michael Legleux Date: Thu, 19 Mar 2026 03:23:51 -0700 Subject: [PATCH 06/10] fix: Use correct format and event for workflows for release tags (#6554) --- .github/actions/generate-version/action.yml | 4 ++-- .github/workflows/on-tag.yml | 2 +- .github/workflows/reusable-upload-recipe.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/generate-version/action.yml b/.github/actions/generate-version/action.yml index 6b84aac2f3..8edb7920c6 100644 --- a/.github/actions/generate-version/action.yml +++ b/.github/actions/generate-version/action.yml @@ -11,7 +11,7 @@ runs: steps: # When a tag is pushed, the version is used as-is. - name: Generate version for tag event - if: ${{ github.event_name == 'tag' }} + if: ${{ startsWith(github.ref, 'refs/tags/') }} shell: bash env: VERSION: ${{ github.ref_name }} @@ -22,7 +22,7 @@ runs: # We use a plus sign instead of a hyphen because Conan recipe versions do # not support two hyphens. - name: Generate version for non-tag event - if: ${{ github.event_name != 'tag' }} + if: ${{ !startsWith(github.ref, 'refs/tags/') }} shell: bash run: | echo 'Extracting version from BuildInfo.cpp.' diff --git a/.github/workflows/on-tag.yml b/.github/workflows/on-tag.yml index af3ea4309e..e570a0e119 100644 --- a/.github/workflows/on-tag.yml +++ b/.github/workflows/on-tag.yml @@ -5,7 +5,7 @@ name: Tag on: push: tags: - - "v*" + - "[0-9]+.[0-9]+.[0-9]*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/reusable-upload-recipe.yml b/.github/workflows/reusable-upload-recipe.yml index 178dd65b8e..d3fe0f356b 100644 --- a/.github/workflows/reusable-upload-recipe.yml +++ b/.github/workflows/reusable-upload-recipe.yml @@ -89,10 +89,10 @@ jobs: conan export . --version=rc conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/rc - # When this workflow is triggered by a tag event, it will always be when tagging a final + # When this workflow is triggered by a push event, it will always be when tagging a final # release, see on-tag.yml. - name: Upload Conan recipe (release) - if: ${{ github.event_name == 'tag' }} + if: ${{ startsWith(github.ref, 'refs/tags/') }} env: REMOTE_NAME: ${{ inputs.remote_name }} run: | From 9316da784a6290447a9164209e4440743210ab0f Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 19 Mar 2026 17:29:22 +0000 Subject: [PATCH 07/10] ci: Update XRPLF/actions (#6594) --- .github/workflows/pre-commit.yml | 2 +- .github/workflows/publish-docs.yml | 2 +- .github/workflows/reusable-build-test-config.yml | 2 +- .github/workflows/reusable-clang-tidy-files.yml | 2 +- .github/workflows/upload-conan-deps.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 8600429a6b..5cc99d1804 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -14,7 +14,7 @@ on: jobs: # Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks. run-hooks: - uses: XRPLF/actions/.github/workflows/pre-commit.yml@44856eb0d6ecb7d376370244324ab3dc8b863bad + uses: XRPLF/actions/.github/workflows/pre-commit.yml@e7896f15cc60d0da1a272c77ee5c4026b424f9c7 with: runs_on: ubuntu-latest container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }' diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index d4abd74363..4b840405bb 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -48,7 +48,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Prepare runner - uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d + uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e with: enable_ccache: false diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index 6e7a093b96..02a47e169d 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -107,7 +107,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Prepare runner - uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d + uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e with: enable_ccache: ${{ inputs.ccache_enabled }} diff --git a/.github/workflows/reusable-clang-tidy-files.yml b/.github/workflows/reusable-clang-tidy-files.yml index 129726ec8f..5d3230f7d1 100644 --- a/.github/workflows/reusable-clang-tidy-files.yml +++ b/.github/workflows/reusable-clang-tidy-files.yml @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Prepare runner - uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d + uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e with: enable_ccache: false diff --git a/.github/workflows/upload-conan-deps.yml b/.github/workflows/upload-conan-deps.yml index d0fea4b8ae..832e455453 100644 --- a/.github/workflows/upload-conan-deps.yml +++ b/.github/workflows/upload-conan-deps.yml @@ -70,7 +70,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Prepare runner - uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d + uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e with: enable_ccache: false From fd28656ded6d7d23d650c1b50f7b7918bcd4434a Mon Sep 17 00:00:00 2001 From: Bart Date: Thu, 19 Mar 2026 13:38:09 -0400 Subject: [PATCH 08/10] ci: Check for signed commits in PR (#6559) Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com> --- .github/workflows/check-pr-commits.yml | 13 +++++++++++++ .github/workflows/check-pr-title.yml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/check-pr-commits.yml diff --git a/.github/workflows/check-pr-commits.yml b/.github/workflows/check-pr-commits.yml new file mode 100644 index 0000000000..07c62c9ff5 --- /dev/null +++ b/.github/workflows/check-pr-commits.yml @@ -0,0 +1,13 @@ +name: Check PR commits + +on: + pull_request: + +# The action needs to have write permissions to post comments on the PR. +permissions: + contents: read + pull-requests: write + +jobs: + check_commits: + uses: XRPLF/actions/.github/workflows/check-pr-commits.yml@481048b78b94ac3343d1292b4ef125a813879f2b diff --git a/.github/workflows/check-pr-title.yml b/.github/workflows/check-pr-title.yml index 1181ca586f..fc03cdf8e1 100644 --- a/.github/workflows/check-pr-title.yml +++ b/.github/workflows/check-pr-title.yml @@ -11,4 +11,4 @@ on: jobs: check_title: if: ${{ github.event.pull_request.draft != true }} - uses: XRPLF/actions/.github/workflows/check-pr-title.yml@f9c2b57a7ac30d70555b5de6e627005f62e933f3 + uses: XRPLF/actions/.github/workflows/check-pr-title.yml@e2c7f400d1e85ae65dad552fd425169fbacca4a3 From 762922a07f0a14cc834ab78b085854c019586fad Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 19 Mar 2026 21:20:56 +0000 Subject: [PATCH 09/10] chore: Don't allow files more than 400kb to be added to the repo (#6597) --- .pre-commit-config.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0fcd8ca75d..59d42ccebc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,12 +13,11 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 hooks: + - id: check-added-large-files + args: [--maxkb=400, --enforce-all] - id: trailing-whitespace - exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/ - id: end-of-file-fixer - exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/ - id: mixed-line-ending - exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/ - id: check-merge-conflict args: [--assume-in-merge] From cf2eb149eed4ce1f449a4607f7b9106b3b780ac2 Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Thu, 19 Mar 2026 22:48:20 +0000 Subject: [PATCH 10/10] fix: Update `.git-blame-ignore-revs` (#6577) --- .git-blame-ignore-revs | 87 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index cf50d48f95..0cf704b051 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,16 +1,79 @@ # This feature requires Git >= 2.24 # To use it by default in git blame: # git config blame.ignoreRevsFile .git-blame-ignore-revs -50760c693510894ca368e90369b0cc2dabfd07f3 -e2384885f5f630c8f0ffe4bf21a169b433a16858 -241b9ddde9e11beb7480600fd5ed90e1ef109b21 -760f16f56835663d9286bd29294d074de26a7ba6 -0eebe6a5f4246fced516d52b83ec4e7f47373edd -2189cc950c0cebb89e4e2fa3b2d8817205bf7cef -b9d007813378ad0ff45660dc07285b823c7e9855 -fe9a5365b8a52d4acc42eb27369247e6f238a4f9 -9a93577314e6a8d4b4a8368cc9d2b15a5d8303e8 -552377c76f55b403a1c876df873a23d780fcc81c -97f0747e103f13e26e45b731731059b32f7679ac -b13370ac0d207217354f1fc1c29aef87769fb8a1 + +# This file is sorted in reverse chronological order, with the most recent commits at the top. +# The commits listed here are ignored by git blame, which is useful for formatting-only commits that would otherwise obscure the history of changes to a file. + +# refactor: Enable remaining clang-tidy `cppcoreguidelines` checks (#6538) +72f4cb097f626b08b02fc3efcb4aa11cb2e7adb8 +# refactor: Rename system name from 'ripple' to 'xrpld' (#6347) +ffea3977f0b771fe8e43a8f74e4d393d63a7afd8 +# refactor: Update transaction folder structure (#6483) +5865bd017f777491b4a956f9210be0c4161f5442 +# chore: Use gersemi instead of ancient cmake-format (#6486) +0c74270b055133a57a497b5c9fc5a75f7647b1f4 +# chore: Apply clang-format width 100 (#6387) +2c1fad102353e11293e3edde1c043224e7d3e983 +# chore: Set clang-format width to 100 in config file (#6387) +25cca465538a56cce501477f9e5e2c1c7ea2d84c +# chore: Set cmake-format width to 100 (#6386) +469ce9f291a4480c38d4ee3baca5136b2f053cd0 +# refactor: Modularize app/tx (#6228) +0976b2b68b64972af8e6e7c497900b5bce9fe22f +# chore: Update clang-format to 21.1.8 (#6352) +958d8f375453d80bb1aa4c293b5102c045a3e4b4 +# refactor: Replace include guards by '#pragma once' (#6322) +34ef577604782ca8d6e1c17df8bd7470990a52ff +# chore: Format all cmake files without comments (#6294) +fe9c8d568fcf6ac21483024e01f58962dd5c8260 +# chore: Add cmake-format pre-commit hook (#6279) +a0e09187b9370805d027c611a7e9ff5a0125282a +# chore: Set ColumnLimit to 120 in clang-format (#6288) +5f638f55536def0d88b970d1018a465a238e55f4 +# refactor: Fix typos in comments, configure cspell (#6164) +3c9f5b62525cb1d6ca1153eeb10433db7d7379fd +# refactor: Rename `rippled.cfg` to `xrpld.cfg` (#6098) +3d1b3a49b3601a0a7037fa0b19d5df7b5e0e2fc1 +# refactor: Rename `ripple` namespace to `xrpl` (#5982) +1eb0fdac6543706b4b9ddca57fd4102928a1f871 +# refactor: Rename `rippled` binary to `xrpld` (#5983) +9eb84a561ef8bb066d89f098bd9b4ac71baed67c +# refactor: Replaces secp256k1 source by Conan package (#6089) +813bc4d9491b078bb950f8255f93b02f71320478 +# refactor: Remove unnecessary copyright notices already covered by LICENSE.md (#5929) +1d42c4f6de6bf01d1286fc7459b17a37a5189e88 +# refactor: Rename `RIPPLE_` and `RIPPLED_` definitions to `XRPL_` (#5821) +ada83564d894829424b0f4d922b0e737e07abbf7 +# refactor: Modularize shamap and nodestore (#5668) +8eb233c2ea8ad5a159be73b77f0f5e1496d547ac +# refactor: Modularise ledger (#5493) +dc8b37a52448b005153c13a7f046ad494128cf94 +# chore: Update clang-format and prettier with pre-commit (#5709) +c14ce956adeabe476ad73c18d73103f347c9c613 +# chore: Fix file formatting (#5718) 896b8c3b54a22b0497cb0d1ce95e1095f9a227ce +# chore: Reverts formatting changes to external files, adds formatting changes to proto files (#5711) +b13370ac0d207217354f1fc1c29aef87769fb8a1 +# chore: Run prettier on all files (#5657) +97f0747e103f13e26e45b731731059b32f7679ac +# Reformat code with clang-format-18 +552377c76f55b403a1c876df873a23d780fcc81c +# Recompute loops (#4997) +d028005aa6319338b0adae1aebf8abe113162960 +# Rewrite includes (#4997) +1d23148e6dd53957fcb6205c07a5c6cd7b64d50c +# Rearrange sources (#4997) +e416ee72ca26fa0c09d2aee1b68bdfb2b7046eed +# Move CMake directory (#4997) +2e902dee53aab2a8f27f32971047bb81e022f94f +# Rewrite includes +0eebe6a5f4246fced516d52b83ec4e7f47373edd +# Format formerly .hpp files +760f16f56835663d9286bd29294d074de26a7ba6 +# Rename .hpp to .h +241b9ddde9e11beb7480600fd5ed90e1ef109b21 +# Consolidate external libraries +e2384885f5f630c8f0ffe4bf21a169b433a16858 +# Format first-party source according to .clang-format +50760c693510894ca368e90369b0cc2dabfd07f3