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/core/JobQueue.h>
19 #include <ripple/protocol/ErrorCodes.h>
20 #include <test/jtx.h>
21 
22 namespace ripple {
23 namespace test {
24 
25 struct Transaction_ordering_test : public beast::unit_test::suite
26 {
27  void
29  {
30  using namespace jtx;
31 
32  Env env(*this);
33  auto const alice = Account("alice");
34  env.fund(XRP(1000), noripple(alice));
35 
36  auto const aliceSequence = env.seq(alice);
37 
38  auto const tx1 = env.jt(noop(alice), seq(aliceSequence));
39  auto const tx2 = env.jt(
40  noop(alice),
41  seq(aliceSequence + 1),
42  json(R"({"LastLedgerSequence":7})"));
43 
44  env(tx1);
45  env.close();
46  BEAST_EXPECT(env.seq(alice) == aliceSequence + 1);
47  env(tx2);
48  env.close();
49  BEAST_EXPECT(env.seq(alice) == aliceSequence + 2);
50 
51  env.close();
52 
53  {
54  auto const result =
55  env.rpc("tx", to_string(tx1.stx->getTransactionID()));
56  BEAST_EXPECT(
57  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
58  }
59  {
60  auto const result =
61  env.rpc("tx", to_string(tx2.stx->getTransactionID()));
62  BEAST_EXPECT(
63  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
64  }
65  }
66 
67  void
69  {
70  using namespace jtx;
71 
72  Env env(*this);
73  env.app().getJobQueue().setThreadCount(0, false);
74  auto const alice = Account("alice");
75  env.fund(XRP(1000), noripple(alice));
76 
77  auto const aliceSequence = env.seq(alice);
78 
79  auto const tx1 = env.jt(noop(alice), seq(aliceSequence));
80  auto const tx2 = env.jt(
81  noop(alice),
82  seq(aliceSequence + 1),
83  json(R"({"LastLedgerSequence":7})"));
84 
85  env(tx2, ter(terPRE_SEQ));
86  BEAST_EXPECT(env.seq(alice) == aliceSequence);
87  env(tx1);
88  env.app().getJobQueue().rendezvous();
89  BEAST_EXPECT(env.seq(alice) == aliceSequence + 2);
90 
91  env.close();
92 
93  {
94  auto const result =
95  env.rpc("tx", to_string(tx1.stx->getTransactionID()));
96  BEAST_EXPECT(
97  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
98  }
99  {
100  auto const result =
101  env.rpc("tx", to_string(tx2.stx->getTransactionID()));
102  BEAST_EXPECT(
103  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
104  }
105  }
106 
107  void
109  {
110  using namespace jtx;
111 
112  Env env(*this);
113  env.app().getJobQueue().setThreadCount(0, false);
114  auto const alice = Account("alice");
115  env.fund(XRP(1000), noripple(alice));
116 
117  auto const aliceSequence = env.seq(alice);
118 
119  std::vector<JTx> tx;
120  for (auto i = 0; i < 5; ++i)
121  {
122  tx.emplace_back(env.jt(
123  noop(alice),
124  seq(aliceSequence + i),
125  json(R"({"LastLedgerSequence":7})")));
126  }
127 
128  for (auto i = 1; i < 5; ++i)
129  {
130  env(tx[i], ter(terPRE_SEQ));
131  BEAST_EXPECT(env.seq(alice) == aliceSequence);
132  }
133 
134  env(tx[0]);
135  env.app().getJobQueue().rendezvous();
136  BEAST_EXPECT(env.seq(alice) == aliceSequence + 5);
137 
138  env.close();
139 
140  for (auto i = 0; i < 5; ++i)
141  {
142  auto const result =
143  env.rpc("tx", to_string(tx[i].stx->getTransactionID()));
144  BEAST_EXPECT(
145  result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
146  }
147  }
148 
149  void
150  run() override
151  {
155  }
156 };
157 
158 BEAST_DEFINE_TESTSUITE(Transaction_ordering, app, ripple);
159 
160 } // namespace test
161 } // 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::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
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:437
ripple::test::jtx::Env::app
Application & app()
Definition: Env.h:238
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::test::Transaction_ordering_test::testIncorrectOrder
void testIncorrectOrder()
Definition: Transaction_ordering_test.cpp:68
ripple::Application::getJobQueue
virtual JobQueue & getJobQueue()=0
ripple::test::Transaction_ordering_test::testIncorrectOrderMultipleIntermediaries
void testIncorrectOrderMultipleIntermediaries()
Definition: Transaction_ordering_test.cpp:108
ripple::test::jtx::Env::seq
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition: Env.cpp:188
ripple::JobQueue::rendezvous
void rendezvous()
Block until no tasks running.
Definition: JobQueue.cpp:276
ripple::test::Transaction_ordering_test::testCorrectOrder
void testCorrectOrder()
Definition: Transaction_ordering_test.cpp:28
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:32
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:63
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, boost::optional< std::chrono::milliseconds > consensusDelay=boost::none)
Close and advance the ledger.
Definition: Env.cpp:111
ripple::JobQueue::setThreadCount
void setThreadCount(int c, bool const standaloneMode)
Set the number of thread serving the job queue to precisely this number.
Definition: JobQueue.cpp:158
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:209
ripple::test::Transaction_ordering_test::run
void run() override
Definition: Transaction_ordering_test.cpp:150
ripple::test::Transaction_ordering_test
Definition: Transaction_ordering_test.cpp:25
ripple::terPRE_SEQ
@ terPRE_SEQ
Definition: TER.h:194
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:114
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:682