rippled
Transaction_ordering_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5  Permission to use, copy, modify, and/or distribute this software for any
6  purpose with or without fee is hereby granted, provided that the above
7  copyright notice and this permission notice appear in all copies.
8  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16 //==============================================================================
17 
18 #include <ripple/app/misc/NetworkOPs.h>
19 #include <ripple/core/JobQueue.h>
20 #include <ripple/protocol/ErrorCodes.h>
21 #include <test/jtx.h>
22 
23 namespace ripple {
24 namespace test {
25 
26 struct Transaction_ordering_test : public beast::unit_test::suite
27 {
28  void
30  {
31  using namespace jtx;
32  testcase("Correct Order");
33 
34  Env env(*this);
35  auto const alice = Account("alice");
36  env.fund(XRP(1000), noripple(alice));
37 
38  auto const aliceSequence = env.seq(alice);
39 
40  auto const tx1 = env.jt(noop(alice), seq(aliceSequence));
41  auto const tx2 = env.jt(
42  noop(alice),
43  seq(aliceSequence + 1),
44  json(R"({"LastLedgerSequence":7})"));
45 
46  env(tx1);
47  env.close();
48  BEAST_EXPECT(env.seq(alice) == aliceSequence + 1);
49  env(tx2);
50  env.close();
51  BEAST_EXPECT(env.seq(alice) == aliceSequence + 2);
52 
53  env.close();
54 
55  {
56  auto const result =
57  env.rpc("tx", to_string(tx1.stx->getTransactionID()));
58  BEAST_EXPECT(
59  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
60  }
61  {
62  auto const result =
63  env.rpc("tx", to_string(tx2.stx->getTransactionID()));
64  BEAST_EXPECT(
65  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
66  }
67  }
68 
69  void
71  {
72  using namespace jtx;
73 
74  testcase("Incorrect order");
75 
76  Env env(*this, envconfig([](std::unique_ptr<Config> cfg) {
77  cfg->FORCE_MULTI_THREAD = false;
78  return cfg;
79  }));
80 
81  auto const alice = Account("alice");
82  env.fund(XRP(1000), noripple(alice));
83 
84  auto const aliceSequence = env.seq(alice);
85 
86  auto const tx1 = env.jt(noop(alice), seq(aliceSequence));
87  auto const tx2 = env.jt(
88  noop(alice),
89  seq(aliceSequence + 1),
90  json(R"({"LastLedgerSequence":7})"));
91 
92  env(tx2, ter(terPRE_SEQ));
93  BEAST_EXPECT(env.seq(alice) == aliceSequence);
94  env(tx1);
95  BEAST_EXPECT(env.app().getOPs().transactionBatch(false));
96  env.app().getJobQueue().rendezvous();
97  BEAST_EXPECT(env.seq(alice) == aliceSequence + 2);
98 
99  env.close();
100 
101  {
102  auto const result =
103  env.rpc("tx", to_string(tx1.stx->getTransactionID()));
104  BEAST_EXPECT(
105  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
106  }
107  {
108  auto const result =
109  env.rpc("tx", to_string(tx2.stx->getTransactionID()));
110  BEAST_EXPECT(
111  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
112  }
113  }
114 
115  void
117  {
118  using namespace jtx;
119 
120  testcase("Incorrect order multiple intermediaries");
121 
122  Env env(*this, envconfig([](std::unique_ptr<Config> cfg) {
123  cfg->FORCE_MULTI_THREAD = true;
124  return cfg;
125  }));
126 
127  auto const alice = Account("alice");
128  env.fund(XRP(1000), noripple(alice));
129 
130  auto const aliceSequence = env.seq(alice);
131 
132  std::vector<JTx> tx;
133  for (auto i = 0; i < 5; ++i)
134  {
135  tx.emplace_back(env.jt(
136  noop(alice),
137  seq(aliceSequence + i),
138  json(R"({"LastLedgerSequence":7})")));
139  }
140 
141  for (auto i = 1; i < 5; ++i)
142  {
143  env(tx[i], ter(terPRE_SEQ));
144  BEAST_EXPECT(env.seq(alice) == aliceSequence);
145  }
146 
147  env(tx[0]);
148  // Apply until no more deferred/held transactions.
149  BEAST_EXPECT(env.app().getOPs().transactionBatch(true));
150  env.app().getJobQueue().rendezvous();
151  BEAST_EXPECT(env.seq(alice) == aliceSequence + 5);
152 
153  env.close();
154 
155  for (auto i = 0; i < 5; ++i)
156  {
157  auto const result =
158  env.rpc("tx", to_string(tx[i].stx->getTransactionID()));
159  BEAST_EXPECT(
160  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
161  }
162  }
163 
164  void
165  run() override
166  {
170  }
171 };
172 
173 BEAST_DEFINE_TESTSUITE(Transaction_ordering, app, ripple);
174 
175 } // namespace test
176 } // namespace ripple
ripple::test::jtx::json
Inject raw JSON.
Definition: jtx_json.h:31
ripple::test::jtx::noop
Json::Value noop(Account const &account)
The null transaction.
Definition: noop.h:31
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::test::jtx::ter
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: ter.h:33
std::vector
STL class.
ripple::test::jtx::Env::jt
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition: Env.h:440
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:242
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
ripple::Application::getOPs
virtual NetworkOPs & getOPs()=0
ripple::test::Transaction_ordering_test::testIncorrectOrder
void testIncorrectOrder()
Definition: Transaction_ordering_test.cpp:70
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::test::Transaction_ordering_test::testIncorrectOrderMultipleIntermediaries
void testIncorrectOrderMultipleIntermediaries()
Definition: Transaction_ordering_test.cpp:116
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:121
ripple::test::jtx::Env::seq
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition: Env.cpp:207
ripple::NetworkOPs::transactionBatch
virtual bool transactionBatch(bool drain)=0
Apply transactions in batches.
ripple::JobQueue::rendezvous
void rendezvous()
Block until no jobs running.
Definition: JobQueue.cpp:254
ripple::test::Transaction_ordering_test::testCorrectOrder
void testCorrectOrder()
Definition: Transaction_ordering_test.cpp:29
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:33
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::jtx::noripple
std::array< Account, 1+sizeof...(Args)> noripple(Account const &account, Args const &... args)
Designate accounts as no-ripple in Env::fund.
Definition: Env.h:65
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:228
ripple::test::Transaction_ordering_test::run
void run() override
Definition: Transaction_ordering_test.cpp:165
ripple::test::Transaction_ordering_test
Definition: Transaction_ordering_test.cpp:26
ripple::terPRE_SEQ
@ terPRE_SEQ
Definition: TER.h:214
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
std::unique_ptr
STL class.
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:117
ripple::test::jtx::Env::rpc
Json::Value rpc(std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:700
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)