20 #include <ripple/app/ledger/LedgerMaster.h>
21 #include <ripple/app/ledger/LedgerToJson.h>
22 #include <ripple/beast/hash/hash_append.h>
23 #include <ripple/beast/utility/temp_dir.h>
24 #include <ripple/core/ConfigSections.h>
25 #include <ripple/nodestore/DatabaseShard.h>
26 #include <ripple/nodestore/DummyScheduler.h>
27 #include <ripple/nodestore/Manager.h>
28 #include <ripple/nodestore/impl/DecodedBlob.h>
29 #include <ripple/nodestore/impl/EncodedBlob.h>
30 #include <ripple/nodestore/impl/Shard.h>
31 #include <ripple/protocol/digest.h>
32 #include <boost/algorithm/hex.hpp>
36 #include <openssl/ripemd.h>
38 #include <test/nodestore/TestBase.h>
53 template <
class IntType =
int>
77 :
A(params.
A),
B(params.
B)
81 template <
class Generator>
88 template <
class Generator>
92 return rnd(g, params.
A, params.
B);
120 template <
class Generator>
129 Generator::min() == 0,
"If non-zero we have handle the offset");
131 assert(Generator::max() >=
range);
136 while (n <= rejectLim);
141 template <
class Engine,
class Integral>
143 randInt(Engine& engine, Integral min, Integral max)
153 template <
class Engine,
class Integral>
157 return randInt(engine, Integral(0), max);
220 for (
int j = 0; j < p; ++j)
227 }
while (from == to);
237 for (
int j = 0; j < 8; ++j)
258 using namespace test::jtx;
281 if (ledger->info().seq != i)
307 using namespace test::jtx;
312 for (
auto const& sles : ledger->sles)
318 const auto id = sles->getAccountID(
sfAccount);
320 for (
int i = 0; i < data.accounts_.size(); ++i)
322 if (
id == data.accounts_[i].id())
325 for (
int j = 0; j <= seq; ++j)
326 if (data.nAccounts_[j] > i + 1 ||
327 (data.nAccounts_[j] == i + 1 &&
328 !data.isNewAccounts(j)))
330 for (
int k = 0; k < data.payAccounts_[j].size();
332 if (data.payAccounts_[j][k].first == i)
343 reqsq = data.nAccounts_[seq] + 1;
346 BEAST_EXPECT(sq == reqsq);
351 BEAST_EXPECT(rootCount == 1);
352 BEAST_EXPECT(accCount == data.nAccounts_[seq]);
353 BEAST_EXPECT(sothCount == 3);
359 for (
auto const& tx : ledger->txs)
364 tx.first->getFieldAmount(
sfAmount).xrp().decimalXRP();
370 BEAST_EXPECT(xrpAmount == data.xrpAmount_[seq]);
378 int newacc = data.isNewAccounts(seq) ? 1 : 0;
379 BEAST_EXPECT(iniCount == newacc);
380 BEAST_EXPECT(setCount == newacc);
381 BEAST_EXPECT(payCount == data.payAccounts_[seq].size());
382 BEAST_EXPECT(tothCount == !seq);
398 std::move(s.modData()),
408 node.getType() == SHAMapAbstractNode::TNType::tnINNER
412 node.getNodeHash().as_uint256(),
421 if (next && next->info().parentHash == ledger.
info().
hash)
423 auto have = next->stateMap().snapShot(
false);
432 auto visitTx = [&](SHAMapAbstractNode& node) {
436 node.getType() == SHAMapAbstractNode::TNType::tnINNER
439 std::move(s.modData()),
440 node.getNodeHash().as_uint256(),
459 if (!BEAST_EXPECT(fetched))
482 node.getType() == SHAMapAbstractNode::TNType::tnINNER
486 node.getNodeHash().as_uint256())};
487 if (!BEAST_EXPECT(nSrc))
491 db.
fetch(node.getNodeHash().as_uint256(), ledger.
info().
seq);
492 if (!BEAST_EXPECT(nDst))
495 BEAST_EXPECT(
isSame(nSrc, nDst));
506 node.getType() == SHAMapAbstractNode::TNType::tnINNER
510 node.getNodeHash().as_uint256())};
511 if (!BEAST_EXPECT(nSrc))
515 db.
fetch(node.getNodeHash().as_uint256(), ledger.
info().
seq);
516 if (!BEAST_EXPECT(nDst))
519 BEAST_EXPECT(
isSame(nSrc, nDst));
537 if (bitmask & (1ll << i))
558 using namespace test::jtx;
563 "DatabaseShard " + testName +
" with backend " + backendType;
608 auto end = start + timeout;
610 !boost::icl::contains(rs, shardNumber))
623 int shardNumber = -1;
628 if (!BEAST_EXPECT(ind != boost::none))
634 BEAST_EXPECT(
saveLedger(db, *data.ledgers_[arrInd]));
642 s.
addRaw(data.ledgers_[arrInd]->info().hash.data(), 256 / 8);
654 using namespace test::jtx;
657 Env env{*
this,
testConfig(
"standalone", backendType, shardDir.
path())};
665 BEAST_EXPECT(db->ledgersPerShard() == db->ledgersPerShardDefault);
666 BEAST_EXPECT(db->init());
675 BEAST_EXPECT(db->getRootDir().string() == shardDir.
path());
683 using namespace test::jtx;
686 Env env{*
this,
testConfig(
"createShard", backendType, shardDir.
path())};
691 if (!BEAST_EXPECT(data.makeLedgers(env)))
706 using namespace test::jtx;
717 if (!BEAST_EXPECT(data.makeLedgers(env)))
730 if (!BEAST_EXPECT(data.makeLedgers(env)))
746 using namespace test::jtx;
756 if (!BEAST_EXPECT(data.makeLedgers(env)))
766 if (!BEAST_EXPECT(n && *n >= 1 && *n <=
nTestShards))
768 bitMask |= 1ll << *n;
778 using namespace test::jtx;
787 if (!BEAST_EXPECT(data.makeLedgers(env)))
796 if (bitMask & (1ll << n))
799 bitMask &= ~(1ll << n);
826 if (!BEAST_EXPECT(n && *n >= 1 && *n <=
nTestShards))
828 bitMask2 |= 1ll << *n;
831 BEAST_EXPECT((bitMask & bitMask2) == 0);
832 if ((bitMask | bitMask2) == ((1ll <<
nTestShards) - 1) << 1)
847 using namespace test::jtx;
859 if (!BEAST_EXPECT(data.makeLedgers(env)))
868 data.ledgers_.clear();
871 boost::filesystem::path importPath(importDir.
path());
880 if (!BEAST_EXPECT(data.makeLedgers(env)))
890 if (!BEAST_EXPECT(n && *n == 1))
903 using namespace test::jtx;
912 "corruptedDatabase", backendType, shardDir.
path())};
916 if (!BEAST_EXPECT(data.makeLedgers(env)))
924 boost::filesystem::path path = shardDir.
path();
926 path /= backendType +
".dat";
928 FILE* f = fopen(path.string().c_str(),
"r+b");
929 if (!BEAST_EXPECT(f))
933 BEAST_EXPECT(fwrite(buf, 1, 256, f) == 256);
942 if (!BEAST_EXPECT(data.makeLedgers(env)))
960 using namespace test::jtx;
962 for (
int i = 0; i < 5; ++i)
969 (i == 0 ?
"illegalFinalKey" :
""),
976 if (!BEAST_EXPECT(data.makeLedgers(env)))
979 int shardNumber = -1;
983 if (!BEAST_EXPECT(ind != boost::none))
988 BEAST_EXPECT(
saveLedger(*db, *data.ledgers_[arrInd]));
997 data.ledgers_[arrInd - (i == 4)]
1014 boost::filesystem::path path(shardDir.
path());
1016 boost::system::error_code ec;
1020 boost::filesystem::exists(path, ec))
1037 if (!BEAST_EXPECT(data.makeLedgers(env)))
1059 using namespace test::jtx;
1067 "import", backendType, shardDir.
path(), nodeDir.
path())};
1069 Database& ndb = env.app().getNodeStore();
1073 if (!BEAST_EXPECT(data.makeLedgers(env)))
1077 BEAST_EXPECT(
saveLedger(ndb, *data.ledgers_[i]));
1091 if (!BEAST_EXPECT(data.makeLedgers(env)))
1108 std::ifstream input(filename, std::ios::in | std::ios::binary);
1112 while (input.
read(buf, 4096), input.
gcount() > 0)
1116 const auto charDigest = binResult.
data();
1118 boost::algorithm::hex(
1120 charDigest +
sizeof(binResult),
1131 using namespace test::jtx;
1133 std::string ripemd160Key(
"4CFA8985836B549EC99D2E9705707F488DC91E4E"),
1134 ripemd160Dat(
"8CC61F503C36339803F8C2FC652C1102DDB889F1");
1136 for (
int i = 0; i < 2; i++)
1143 (i ?
"" :
"deterministicShard"),
1150 if (!BEAST_EXPECT(data.makeLedgers(env)))
1162 if (!BEAST_EXPECT(data.makeLedgers(env)))
1171 boost::filesystem::path path(shardDir.
path());
1173 boost::filesystem::path keypath = path / (backendType +
".key");
1175 boost::filesystem::path datpath = path / (backendType +
".dat");
1178 std::cerr <<
"Iteration " << i <<
": RIPEMD160[" << backendType
1180 std::cerr <<
"Iteration " << i <<
": RIPEMD160[" << backendType
1183 BEAST_EXPECT(key == ripemd160Key);
1184 BEAST_EXPECT(dat == ripemd160Dat);
1214 #if RIPPLE_ROCKSDB_AVAILABLE
1218 #if RIPPLE_ENABLE_SQLITE_BACKEND_TESTS