diff --git a/include/xrpl/protocol/detail/features.macro b/include/xrpl/protocol/detail/features.macro index 855a714f69..75b8db515d 100644 --- a/include/xrpl/protocol/detail/features.macro +++ b/include/xrpl/protocol/detail/features.macro @@ -66,7 +66,6 @@ XRPL_FEATURE(XRPFees, Supported::yes, VoteBehavior::DefaultNo XRPL_FEATURE(DisallowIncoming, Supported::yes, VoteBehavior::DefaultNo) XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::yes, VoteBehavior::DefaultYes) XRPL_FEATURE(FlowSortStrands, Supported::yes, VoteBehavior::DefaultYes) -XRPL_FEATURE(TicketBatch, Supported::yes, VoteBehavior::DefaultYes) XRPL_FEATURE(NegativeUNL, Supported::yes, VoteBehavior::DefaultYes) XRPL_FEATURE(RequireFullyCanonicalSig, Supported::yes, VoteBehavior::DefaultYes) XRPL_FEATURE(DeletableAccounts, Supported::yes, VoteBehavior::DefaultYes) @@ -134,5 +133,6 @@ XRPL_RETIRE_FEATURE(MultiSignReserve) XRPL_RETIRE_FEATURE(NonFungibleTokensV1_1) XRPL_RETIRE_FEATURE(PayChan) XRPL_RETIRE_FEATURE(SortedDirectories) +XRPL_RETIRE_FEATURE(TicketBatch) XRPL_RETIRE_FEATURE(TickSize) XRPL_RETIRE_FEATURE(TrustSetAuth) diff --git a/include/xrpl/protocol/detail/transactions.macro b/include/xrpl/protocol/detail/transactions.macro index fd651fb94e..23049d2543 100644 --- a/include/xrpl/protocol/detail/transactions.macro +++ b/include/xrpl/protocol/detail/transactions.macro @@ -155,7 +155,7 @@ TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, #endif TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, Delegation::delegatable, - featureTicketBatch, + uint256{}, noPriv, ({ {sfTicketCount, soeREQUIRED}, diff --git a/src/test/app/Delegate_test.cpp b/src/test/app/Delegate_test.cpp index c0fd4b1f3b..9e1c777a91 100644 --- a/src/test/app/Delegate_test.cpp +++ b/src/test/app/Delegate_test.cpp @@ -1703,7 +1703,6 @@ class Delegate_test : public beast::unit_test::suite // NFTokenMint, NFTokenBurn, NFTokenCreateOffer, NFTokenCancelOffer, // NFTokenAcceptOffer are not included, they are tested separately. std::unordered_map txRequiredFeatures{ - {"TicketCreate", featureTicketBatch}, {"CheckCreate", featureChecks}, {"CheckCash", featureChecks}, {"CheckCancel", featureChecks}, diff --git a/src/test/app/Ticket_test.cpp b/src/test/app/Ticket_test.cpp index 10e159553f..4c3208af02 100644 --- a/src/test/app/Ticket_test.cpp +++ b/src/test/app/Ticket_test.cpp @@ -360,52 +360,6 @@ class Ticket_test : public beast::unit_test::suite BEAST_EXPECT(ticketSeq < acctRootSeq); } - void - testTicketNotEnabled() - { - testcase("Feature Not Enabled"); - - using namespace test::jtx; - Env env{*this, testable_amendments() - featureTicketBatch}; - - env(ticket::create(env.master, 1), ter(temDISABLED)); - env.close(); - env.require(owners(env.master, 0), tickets(env.master, 0)); - - env(noop(env.master), ticket::use(1), ter(temMALFORMED)); - env(noop(env.master), - ticket::use(1), - seq(env.seq(env.master)), - ter(temMALFORMED)); - - // Close enough ledgers that the previous transactions are no - // longer retried. - for (int i = 0; i < 8; ++i) - env.close(); - - env.enableFeature(featureTicketBatch); - env.close(); - env.require(owners(env.master, 0), tickets(env.master, 0)); - - std::uint32_t ticketSeq{env.seq(env.master) + 1}; - env(ticket::create(env.master, 2)); - checkTicketCreateMeta(env); - env.close(); - env.require(owners(env.master, 2), tickets(env.master, 2)); - - env(noop(env.master), ticket::use(ticketSeq++)); - checkTicketConsumeMeta(env); - env.close(); - env.require(owners(env.master, 1), tickets(env.master, 1)); - - env(fset(env.master, asfDisableMaster), - ticket::use(ticketSeq++), - ter(tecNO_ALTERNATIVE_KEY)); - checkTicketConsumeMeta(env); - env.close(); - env.require(owners(env.master, 0), tickets(env.master, 0)); - } - void testTicketCreatePreflightFail() { @@ -907,70 +861,43 @@ class Ticket_test : public beast::unit_test::suite void testFixBothSeqAndTicket() { + using namespace test::jtx; + // It is an error if a transaction contains a non-zero Sequence field // and a TicketSequence field. Verify that the error is detected. testcase("Fix both Seq and Ticket"); - // Try the test without featureTicketBatch enabled. - using namespace test::jtx; - { - Env env{*this, testable_amendments() - featureTicketBatch}; - Account alice{"alice"}; + Env env{*this, testable_amendments()}; + Account alice{"alice"}; - env.fund(XRP(10000), alice); - env.close(); + env.fund(XRP(10000), alice); + env.close(); - // Fail to create a ticket. - std::uint32_t const ticketSeq = env.seq(alice) + 1; - env(ticket::create(alice, 1), ter(temDISABLED)); - env.close(); - env.require(owners(alice, 0), tickets(alice, 0)); - BEAST_EXPECT(ticketSeq == env.seq(alice) + 1); + // Create a ticket. + std::uint32_t const ticketSeq = env.seq(alice) + 1; + env(ticket::create(alice, 1)); + env.close(); + env.require(owners(alice, 1), tickets(alice, 1)); + BEAST_EXPECT(ticketSeq + 1 == env.seq(alice)); - // Create a transaction that includes both a ticket and a non-zero - // sequence number. Since a ticket is used and tickets are not yet - // enabled the transaction should be malformed. - env(noop(alice), - ticket::use(ticketSeq), - seq(env.seq(alice)), - ter(temMALFORMED)); - env.close(); - } - // Try the test with featureTicketBatch enabled. - { - Env env{*this, testable_amendments()}; - Account alice{"alice"}; + // Create a transaction that includes both a ticket and a non-zero + // sequence number. The transaction fails with temSEQ_AND_TICKET. + env(noop(alice), + ticket::use(ticketSeq), + seq(env.seq(alice)), + ter(temSEQ_AND_TICKET)); + env.close(); - env.fund(XRP(10000), alice); - env.close(); - - // Create a ticket. - std::uint32_t const ticketSeq = env.seq(alice) + 1; - env(ticket::create(alice, 1)); - env.close(); - env.require(owners(alice, 1), tickets(alice, 1)); - BEAST_EXPECT(ticketSeq + 1 == env.seq(alice)); - - // Create a transaction that includes both a ticket and a non-zero - // sequence number. The transaction fails with temSEQ_AND_TICKET. - env(noop(alice), - ticket::use(ticketSeq), - seq(env.seq(alice)), - ter(temSEQ_AND_TICKET)); - env.close(); - - // Verify that the transaction failed by looking at alice's - // sequence number and tickets. - env.require(owners(alice, 1), tickets(alice, 1)); - BEAST_EXPECT(ticketSeq + 1 == env.seq(alice)); - } + // Verify that the transaction failed by looking at alice's + // sequence number and tickets. + env.require(owners(alice, 1), tickets(alice, 1)); + BEAST_EXPECT(ticketSeq + 1 == env.seq(alice)); } public: void run() override { - testTicketNotEnabled(); testTicketCreatePreflightFail(); testTicketCreatePreclaimFail(); testTicketInsufficientReserve(); diff --git a/src/xrpld/app/tx/detail/Transactor.cpp b/src/xrpld/app/tx/detail/Transactor.cpp index 288ae4c85d..9d84abe12e 100644 --- a/src/xrpld/app/tx/detail/Transactor.cpp +++ b/src/xrpld/app/tx/detail/Transactor.cpp @@ -143,14 +143,6 @@ preflightCheckSimulateKeys( NotTEC Transactor::preflight1(PreflightContext const& ctx, std::uint32_t flagMask) { - // This is inappropriate in preflight0, because only Change transactions - // skip this function, and those do not allow an sfTicketSequence field. - if (ctx.tx.isFieldPresent(sfTicketSequence) && - !ctx.rules.enabled(featureTicketBatch)) - { - return temMALFORMED; - } - if (ctx.tx.isFieldPresent(sfDelegate)) { if (!ctx.rules.enabled(featurePermissionDelegationV1_1)) @@ -442,8 +434,7 @@ Transactor::checkSeqProxy( if (t_seqProx.isSeq()) { - if (tx.isFieldPresent(sfTicketSequence) && - view.rules().enabled(featureTicketBatch)) + if (tx.isFieldPresent(sfTicketSequence)) { JLOG(j.trace()) << "applyTransaction: has both a TicketSequence " "and a non-zero Sequence number";