2#include <test/jtx/Env.h>
4#include <xrpl/beast/unit_test.h>
5#include <xrpl/beast/unit_test/suite.h>
6#include <xrpl/beast/utility/Journal.h>
7#include <xrpl/beast/utility/temp_dir.h>
8#include <xrpl/protocol/SField.h>
9#include <xrpl/protocol/jss.h>
11#include <boost/algorithm/string.hpp>
12#include <boost/filesystem.hpp>
27 cfg->START_LEDGER = ledger;
29 cfg->TRAP_TX_HASH = trapTxHash;
30 assert(!dbPath.
empty());
31 cfg->legacy(
"database_path", dbPath);
48 using namespace test::jtx;
56 for (
auto i = 0; i < 20; ++i)
59 env.fund(XRP(10000), acct);
61 if (i > 0 && BEAST_EXPECT(prev))
63 env.trust(acct[
"USD"](1000), *prev);
64 env(pay(acct, *prev, acct[
"USD"](5)));
66 env(offer(acct, XRP(100), acct[
"USD"](1)));
68 prev.emplace(std::move(acct));
71 retval.
ledger = env.rpc(
"ledger",
"current",
"full")[jss::result];
72 BEAST_EXPECT(retval.
ledger[jss::ledger][jss::accountState].
size() == 102);
75 for (
auto const& it : retval.
ledger[jss::ledger][jss::accountState])
77 if (it[sfLedgerEntryType.fieldName] == jss::LedgerHashes)
78 return it[sfHashes.fieldName];
85 auto const txs = env.rpc(
"ledger",
std::to_string(41),
"tx")[jss::result][jss::ledger][jss::transactions];
86 BEAST_EXPECT(txs.isArray() && txs.size() > 0);
88 BEAST_EXPECT(tmp.
parseHex(txs[0u][jss::hash].asString()));
103 using namespace test::jtx;
111 auto jrb = env.rpc(
"ledger",
"current",
"full")[jss::result];
112 BEAST_EXPECT(sd.
ledger[jss::ledger][jss::accountState].
size() == jrb[jss::ledger][jss::accountState].size());
119 using namespace test::jtx;
120 using namespace boost::filesystem;
141 boost::system::error_code ec;
142 auto ledgerFileCorrupt = boost::filesystem::path{sd.
dbPath} /
"ledgerdata_bad.json";
143 copy_file(sd.
ledgerFile, ledgerFileCorrupt, copy_options::overwrite_existing, ec);
144 if (!BEAST_EXPECTS(!ec, ec.message()))
146 auto filesize = file_size(ledgerFileCorrupt, ec);
147 if (!BEAST_EXPECTS(!ec, ec.message()))
149 resize_file(ledgerFileCorrupt, filesize - 10, ec);
150 if (!BEAST_EXPECTS(!ec, ec.message()))
166 using namespace test::jtx;
170 boost::erase_all(ledgerHash,
"\"");
176 auto jrb = env.rpc(
"ledger",
"current",
"full")[jss::result];
177 BEAST_EXPECT(jrb[jss::ledger][jss::accountState].size() == 98);
178 BEAST_EXPECT(jrb[jss::ledger][jss::accountState].size() <= sd.
ledger[jss::ledger][jss::accountState].
size());
184 testcase(
"Load and replay by hash");
185 using namespace test::jtx;
189 boost::erase_all(ledgerHash,
"\"");
195 auto const jrb = env.rpc(
"ledger",
"current",
"full")[jss::result];
196 BEAST_EXPECT(jrb[jss::ledger][jss::accountState].size() == 97);
200 auto const closed = env.rpc(
"ledger",
"current",
"full")[jss::result];
201 BEAST_EXPECT(closed[jss::ledger][jss::accountState].size() == 98);
202 BEAST_EXPECT(closed[jss::ledger][jss::accountState].size() <= sd.
ledger[jss::ledger][jss::accountState].
size());
208 testcase(
"Load and replay transaction by hash");
209 using namespace test::jtx;
213 boost::erase_all(ledgerHash,
"\"");
219 auto const jrb = env.rpc(
"ledger",
"current",
"full")[jss::result];
220 BEAST_EXPECT(jrb[jss::ledger][jss::accountState].size() == 97);
224 auto const closed = env.rpc(
"ledger",
"current",
"full")[jss::result];
225 BEAST_EXPECT(closed[jss::ledger][jss::accountState].size() == 98);
226 BEAST_EXPECT(closed[jss::ledger][jss::accountState].size() <= sd.
ledger[jss::ledger][jss::accountState].
size());
232 testcase(
"Load and replay transaction by hash failure");
233 using namespace test::jtx;
237 boost::erase_all(ledgerHash,
"\"");
263 using namespace test::jtx;
271 auto jrb = env.rpc(
"ledger",
"current",
"full")[jss::result];
272 BEAST_EXPECT(sd.
ledger[jss::ledger][jss::accountState].
size() == jrb[jss::ledger][jss::accountState].size());
279 using namespace test::jtx;
287 auto jrb = env.rpc(
"ledger",
"current",
"full")[jss::result];
288 BEAST_EXPECT(sd.
ledger[jss::ledger][jss::accountState].
size() == jrb[jss::ledger][jss::accountState].size());
310BEAST_DEFINE_TESTSUITE(LedgerLoad, app,
xrpl);
UInt size() const
Number of values in array or object.
RAII temporary directory.
std::string path() const
Get the native path for the temporary directory.
std::string file(std::string const &name) const
Get the native path for the a file.
testcase_t testcase
Memberspace for declaring test cases.
bool except(F &&f, String const &reason)
void testLoadLatest(SetupData const &sd)
void testReplay(SetupData const &sd)
void testReplayTxFail(SetupData const &sd)
void run() override
Runs the suite.
void testBadFiles(SetupData const &sd)
void testReplayTx(SetupData const &sd)
SetupData setupLedger(beast::temp_dir const &td)
void testLoadByHash(SetupData const &sd)
void testLoadIndex(SetupData const &sd)
static auto ledgerConfig(std::unique_ptr< Config > cfg, std::string const &dbPath, std::string const &ledger, Config::StartUpType type, std::optional< uint256 > trapTxHash)
void testLoad(SetupData const &sd)
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string to_string(base_uint< Bits, Tag > const &a)