mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Test cancelling offers that are still in the TxQ
This commit is contained in:
committed by
manojsdoshi
parent
d89c158a77
commit
a3f2196d4e
@@ -164,8 +164,7 @@ transResults()
|
||||
MAKE_ERROR(terPRE_SEQ, "Missing/inapplicable prior transaction."),
|
||||
MAKE_ERROR(terOWNERS, "Non-zero owner count."),
|
||||
MAKE_ERROR(terQUEUED, "Held until escalated fee drops."),
|
||||
{terPRE_TICKET, {"terPRE_TICKET", "Ticket is not yet in ledger."}},
|
||||
|
||||
MAKE_ERROR(terPRE_TICKET, "Ticket is not yet in ledger."),
|
||||
MAKE_ERROR(tesSUCCESS, "The transaction was applied. Only final in a validated ledger."),
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace ripple {
|
||||
|
||||
namespace test {
|
||||
|
||||
class TxQ_test : public beast::unit_test::suite
|
||||
class TxQ1_test : public beast::unit_test::suite
|
||||
{
|
||||
void
|
||||
checkMetrics(
|
||||
@@ -2320,7 +2320,7 @@ public:
|
||||
cancelOffer[jss::Account] = alice.human();
|
||||
cancelOffer[jss::OfferSequence] = 3;
|
||||
cancelOffer[jss::TransactionType] = jss::OfferCancel;
|
||||
auto const jtx = env.jt(cancelOffer, seq(1), fee(10));
|
||||
auto const jtx = env.jt(cancelOffer, seq(5), fee(10));
|
||||
auto const pf = preflight(
|
||||
env.app(),
|
||||
env.current()->rules(),
|
||||
@@ -4530,6 +4530,120 @@ public:
|
||||
ter(telCAN_NOT_QUEUE_FEE));
|
||||
}
|
||||
|
||||
void
|
||||
testCancelQueuedOffers()
|
||||
{
|
||||
testcase("Cancel queued offers");
|
||||
using namespace jtx;
|
||||
|
||||
Account const alice("alice");
|
||||
auto gw = Account("gw");
|
||||
auto USD = gw["USD"];
|
||||
|
||||
auto cfg = makeConfig(
|
||||
{{"minimum_txn_in_ledger_standalone", "5"},
|
||||
{"ledgers_in_queue", "5"},
|
||||
{"maximum_txn_per_account", "30"},
|
||||
{"minimum_queue_size", "50"}});
|
||||
|
||||
Env env(
|
||||
*this, std::move(cfg), supported_amendments() | featureTicketBatch);
|
||||
|
||||
// The noripple is to reduce the number of transactions required to
|
||||
// fund the accounts. There is no rippling in this test.
|
||||
env.fund(XRP(100000), noripple(alice));
|
||||
env.close();
|
||||
|
||||
{
|
||||
// ------- Sequence-based transactions -------
|
||||
fillQueue(env, alice);
|
||||
|
||||
// Alice creates a couple offers
|
||||
auto const aliceSeq = env.seq(alice);
|
||||
env(offer(alice, USD(1000), XRP(1000)), ter(terQUEUED));
|
||||
|
||||
env(offer(alice, USD(1000), XRP(1001)),
|
||||
seq(aliceSeq + 1),
|
||||
ter(terQUEUED));
|
||||
|
||||
// Alice creates transactions that cancel the first set of
|
||||
// offers, one through another offer, and one cancel
|
||||
env(offer(alice, USD(1000), XRP(1002)),
|
||||
seq(aliceSeq + 2),
|
||||
json(jss::OfferSequence, aliceSeq),
|
||||
ter(terQUEUED));
|
||||
|
||||
env(offer_cancel(alice, aliceSeq + 1),
|
||||
seq(aliceSeq + 3),
|
||||
ter(terQUEUED));
|
||||
|
||||
env.close();
|
||||
|
||||
checkMetrics(env, 0, 50, 4, 6, 256);
|
||||
}
|
||||
|
||||
{
|
||||
// ------- Ticket-based transactions -------
|
||||
|
||||
// Alice creates some tickets
|
||||
auto const aliceTkt = env.seq(alice);
|
||||
env(ticket::create(alice, 6));
|
||||
env.close();
|
||||
|
||||
fillQueue(env, alice);
|
||||
|
||||
// Alice creates a couple offers using tickets, consuming the
|
||||
// tickets in reverse order
|
||||
auto const aliceSeq = env.seq(alice);
|
||||
env(offer(alice, USD(1000), XRP(1000)),
|
||||
ticket::use(aliceTkt + 4),
|
||||
ter(terQUEUED));
|
||||
|
||||
env(offer(alice, USD(1000), XRP(1001)),
|
||||
ticket::use(aliceTkt + 3),
|
||||
ter(terQUEUED));
|
||||
|
||||
// Alice creates a couple more transactions that cancel the first
|
||||
// set of offers, also in reverse order. This allows Alice to submit
|
||||
// a tx with a lower ticket value than the offer it's cancelling.
|
||||
// These transactions succeed because Ticket ordering is arbitrary
|
||||
// and it's up to the user to ensure they don't step on their own
|
||||
// feet.
|
||||
env(offer(alice, USD(1000), XRP(1002)),
|
||||
ticket::use(aliceTkt + 2),
|
||||
json(jss::OfferSequence, aliceTkt + 4),
|
||||
ter(terQUEUED));
|
||||
|
||||
env(offer_cancel(alice, aliceTkt + 3),
|
||||
ticket::use(aliceTkt + 1),
|
||||
ter(terQUEUED));
|
||||
|
||||
// Create a couple more offers using sequences
|
||||
env(offer(alice, USD(1000), XRP(1000)), ter(terQUEUED));
|
||||
|
||||
env(offer(alice, USD(1000), XRP(1001)),
|
||||
seq(aliceSeq + 1),
|
||||
ter(terQUEUED));
|
||||
|
||||
// And try to cancel those using tickets
|
||||
env(offer(alice, USD(1000), XRP(1002)),
|
||||
ticket::use(aliceTkt + 5),
|
||||
json(jss::OfferSequence, aliceSeq),
|
||||
ter(terQUEUED));
|
||||
|
||||
env(offer_cancel(alice, aliceSeq + 1),
|
||||
ticket::use(aliceTkt + 6),
|
||||
ter(terQUEUED));
|
||||
|
||||
env.close();
|
||||
|
||||
// The ticket transactions that didn't succeed or get queued succeed
|
||||
// this time because the tickets got consumed when the offers came
|
||||
// out of the queue
|
||||
checkMetrics(env, 0, 50, 8, 7, 256);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
@@ -4550,6 +4664,11 @@ public:
|
||||
testBlockersTicket();
|
||||
testInFlightBalance();
|
||||
testConsequences();
|
||||
}
|
||||
|
||||
void
|
||||
run2()
|
||||
{
|
||||
testAcctInQueueButEmpty();
|
||||
testRPC();
|
||||
testExpirationReplacement();
|
||||
@@ -4564,10 +4683,21 @@ public:
|
||||
testInLedgerTicket();
|
||||
testReexecutePreflight();
|
||||
testQueueFullDropPenalty();
|
||||
testCancelQueuedOffers();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(TxQ, app, ripple, 1);
|
||||
class TxQ2_test : public TxQ1_test
|
||||
{
|
||||
void
|
||||
run() override
|
||||
{
|
||||
run2();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(TxQ1, app, ripple, 1);
|
||||
BEAST_DEFINE_TESTSUITE_PRIO(TxQ2, app, ripple, 1);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
|
||||
Reference in New Issue
Block a user