20 #include <ripple/app/ledger/LedgerMaster.h>
21 #include <ripple/app/ledger/LedgerToJson.h>
22 #include <ripple/beast/utility/temp_dir.h>
23 #include <ripple/core/ConfigSections.h>
24 #include <ripple/nodestore/DatabaseShard.h>
25 #include <ripple/nodestore/DummyScheduler.h>
26 #include <ripple/nodestore/impl/DecodedBlob.h>
27 #include <ripple/nodestore/impl/Shard.h>
31 #include <test/nodestore/TestBase.h>
97 for (
int j = 0; j < p; ++j)
104 }
while (from == to);
114 for (
int j = 0; j < 8; ++j)
135 using namespace test::jtx;
160 if (ledger->info().seq != i)
189 using namespace test::jtx;
194 for (
auto const& sles : ledger->sles)
200 const auto id = sles->getAccountID(
sfAccount);
202 for (
int i = 0; i < data.accounts_.size(); ++i)
204 if (
id == data.accounts_[i].id())
207 for (
int j = 0; j <= seq; ++j)
208 if (data.nAccounts_[j] > i + 1 ||
209 (data.nAccounts_[j] == i + 1 &&
210 !data.isNewAccounts(j)))
212 for (
int k = 0; k < data.payAccounts_[j].size();
214 if (data.payAccounts_[j][k].first == i)
225 reqsq = data.nAccounts_[seq] + 1;
228 BEAST_EXPECT(sq == reqsq);
233 BEAST_EXPECT(rootCount == 1);
234 BEAST_EXPECT(accCount == data.nAccounts_[seq]);
235 BEAST_EXPECT(sothCount == 3);
241 for (
auto const& tx : ledger->txs)
246 tx.first->getFieldAmount(
sfAmount).xrp().decimalXRP();
252 BEAST_EXPECT(xrpAmount == data.xrpAmount_[seq]);
260 int newacc = data.isNewAccounts(seq) ? 1 : 0;
261 BEAST_EXPECT(iniCount == newacc);
262 BEAST_EXPECT(setCount == newacc);
263 BEAST_EXPECT(payCount == data.payAccounts_[seq].size());
264 BEAST_EXPECT(tothCount == !seq);
280 std::move(s.modData()),
290 node.getType() == SHAMapAbstractNode::TNType::tnINNER
294 node.getNodeHash().as_uint256(),
303 if (next && next->info().parentHash == ledger.
info().
hash)
305 auto have = next->stateMap().snapShot(
false);
314 auto visitTx = [&](SHAMapAbstractNode& node) {
318 node.getType() == SHAMapAbstractNode::TNType::tnINNER
321 std::move(s.modData()),
322 node.getNodeHash().as_uint256(),
341 if (!BEAST_EXPECT(fetched))
364 node.getType() == SHAMapAbstractNode::TNType::tnINNER
368 node.getNodeHash().as_uint256())};
369 if (!BEAST_EXPECT(nSrc))
373 db.
fetch(node.getNodeHash().as_uint256(), ledger.
info().
seq);
374 if (!BEAST_EXPECT(nDst))
377 BEAST_EXPECT(
isSame(nSrc, nDst));
388 node.getType() == SHAMapAbstractNode::TNType::tnINNER
392 node.getNodeHash().as_uint256())};
393 if (!BEAST_EXPECT(nSrc))
397 db.
fetch(node.getNodeHash().as_uint256(), ledger.
info().
seq);
398 if (!BEAST_EXPECT(nDst))
401 BEAST_EXPECT(
isSame(nSrc, nDst));
419 if (bitmask & (1ll << i))
440 using namespace test::jtx;
445 "DatabaseShard " + testName +
" with backend " + backendType;
454 "max_historical_shards",
490 auto end = start + timeout;
492 !boost::icl::contains(rs, shardNumber))
506 int maxShardNumber = 1,
507 int ledgerOffset = 0)
509 int shardNumber = -1;
514 if (!BEAST_EXPECT(ind != boost::none))
521 BEAST_EXPECT(
saveLedger(db, *data.ledgers_[arrInd]));
529 s.
addRaw(data.ledgers_[arrInd]->info().hash.data(), 256 / 8);
541 using namespace test::jtx;
544 Env env{*
this,
testConfig(
"standalone", backendType, shardDir.
path())};
552 BEAST_EXPECT(db->ledgersPerShard() == db->ledgersPerShardDefault);
553 BEAST_EXPECT(db->init());
562 BEAST_EXPECT(db->getRootDir().string() == shardDir.
path());
570 using namespace test::jtx;
573 Env env{*
this,
testConfig(
"createShard", backendType, shardDir.
path())};
578 if (!BEAST_EXPECT(data.makeLedgers(env)))
593 using namespace test::jtx;
604 if (!BEAST_EXPECT(data.makeLedgers(env)))
617 if (!BEAST_EXPECT(data.makeLedgers(env)))
633 using namespace test::jtx;
643 if (!BEAST_EXPECT(data.makeLedgers(env)))
653 if (!BEAST_EXPECT(n && *n >= 1 && *n <=
nTestShards))
655 bitMask |= 1ll << *n;
665 using namespace test::jtx;
674 if (!BEAST_EXPECT(data.makeLedgers(env)))
683 if (bitMask & (1ll << n))
686 bitMask &= ~(1ll << n);
713 if (!BEAST_EXPECT(n && *n >= 1 && *n <=
nTestShards))
715 bitMask2 |= 1ll << *n;
718 BEAST_EXPECT((bitMask & bitMask2) == 0);
719 if ((bitMask | bitMask2) == ((1ll <<
nTestShards) - 1) << 1)
734 using namespace test::jtx;
746 if (!BEAST_EXPECT(data.makeLedgers(env)))
755 data.ledgers_.clear();
758 boost::filesystem::path importPath(importDir.
path());
767 if (!BEAST_EXPECT(data.makeLedgers(env)))
777 if (!BEAST_EXPECT(n && *n == 1))
790 using namespace test::jtx;
799 "corruptedDatabase", backendType, shardDir.
path())};
803 if (!BEAST_EXPECT(data.makeLedgers(env)))
811 boost::filesystem::path path = shardDir.
path();
813 path /= backendType +
".dat";
815 FILE* f = fopen(path.string().c_str(),
"r+b");
816 if (!BEAST_EXPECT(f))
820 BEAST_EXPECT(fwrite(buf, 1, 256, f) == 256);
829 if (!BEAST_EXPECT(data.makeLedgers(env)))
847 using namespace test::jtx;
849 for (
int i = 0; i < 5; ++i)
856 (i == 0 ?
"illegalFinalKey" :
""),
863 if (!BEAST_EXPECT(data.makeLedgers(env)))
866 int shardNumber = -1;
870 if (!BEAST_EXPECT(ind != boost::none))
875 BEAST_EXPECT(
saveLedger(*db, *data.ledgers_[arrInd]));
884 data.ledgers_[arrInd - (i == 4)]
901 boost::filesystem::path path(shardDir.
path());
903 boost::system::error_code ec;
907 boost::filesystem::exists(path, ec))
924 if (!BEAST_EXPECT(data.makeLedgers(env)))
946 using namespace test::jtx;
954 "import", backendType, shardDir.
path(), nodeDir.
path())};
956 Database& ndb = env.app().getNodeStore();
960 if (!BEAST_EXPECT(data.makeLedgers(env)))
964 BEAST_EXPECT(
saveLedger(ndb, *data.ledgers_[i]));
978 if (!BEAST_EXPECT(data.makeLedgers(env)))
996 using namespace test::jtx;
1006 historicalDirs.
begin(),
1007 historicalDirs.
end(),
1008 historicalPaths.
begin(),
1013 "importWithHistoricalPaths",
1018 auto& historyPaths = c->section(SECTION_HISTORICAL_SHARD_PATHS);
1019 historyPaths.append(
1020 {historicalPaths[0].string(),
1021 historicalPaths[1].
string(),
1022 historicalPaths[2].
string(),
1023 historicalPaths[3].
string()});
1025 Env env{*
this, std::move(c)};
1027 Database& ndb = env.app().getNodeStore();
1030 auto const ledgerCount = 4;
1032 TestData data(seedValue, 4, ledgerCount);
1033 if (!BEAST_EXPECT(data.makeLedgers(env)))
1037 BEAST_EXPECT(
saveLedger(ndb, *data.ledgers_[i]));
1048 boost::filesystem::directory_iterator(shardDir.
path()),
1049 boost::filesystem::directory_iterator());
1053 BEAST_EXPECT(mainPathCount == 2);
1056 historicalPaths.
begin(),
1057 historicalPaths.
end(),
1059 [](
int const sum, boost::filesystem::path
const& path) {
1062 boost::filesystem::directory_iterator(path),
1063 boost::filesystem::directory_iterator());
1068 BEAST_EXPECT(historicalPathCount == ledgerCount - 2);
1079 "importWithSingleHistoricalPath",
1084 auto& historyPaths = c->section(SECTION_HISTORICAL_SHARD_PATHS);
1085 historyPaths.append({historicalDir.
path()});
1087 Env env{*
this, std::move(c)};
1089 Database& ndb = env.app().getNodeStore();
1092 auto const ledgerCount = 4;
1094 TestData data(seedValue * 2, 4, ledgerCount);
1095 if (!BEAST_EXPECT(data.makeLedgers(env)))
1099 BEAST_EXPECT(
saveLedger(ndb, *data.ledgers_[i]));
1110 boost::filesystem::directory_iterator(shardDir.
path()),
1111 boost::filesystem::directory_iterator());
1115 BEAST_EXPECT(mainPathCount == 2);
1118 boost::filesystem::directory_iterator(historicalDir.
path()),
1119 boost::filesystem::directory_iterator());
1123 BEAST_EXPECT(historicalPathCount == ledgerCount - 2);
1132 using namespace test::jtx;
1142 historicalDirs.
begin(),
1143 historicalDirs.
end(),
1144 historicalPaths.
begin(),
1149 "prepareWithHistoricalPaths", backendType, shardDir.
path());
1151 auto& historyPaths = c->section(SECTION_HISTORICAL_SHARD_PATHS);
1152 historyPaths.append(
1153 {historicalPaths[0].string(),
1154 historicalPaths[1].
string(),
1155 historicalPaths[2].
string(),
1156 historicalPaths[3].
string()});
1158 Env env{*
this, std::move(c)};
1162 auto const ledgerCount = 4;
1164 TestData data(seedValue, 4, ledgerCount);
1165 if (!BEAST_EXPECT(data.makeLedgers(env)))
1175 if (!BEAST_EXPECT(n && *n >= 1 && *n <= ledgerCount))
1177 bitMask |= 1ll << *n;
1183 boost::filesystem::directory_iterator(shardDir.
path()),
1184 boost::filesystem::directory_iterator());
1188 BEAST_EXPECT(mainPathCount == 2);
1192 shardDir.
path() / boost::filesystem::path(
"3"),
1193 shardDir.
path() / boost::filesystem::path(
"4")};
1195 boost::filesystem::directory_iterator(shardDir.
path()),
1196 boost::filesystem::directory_iterator());
1198 BEAST_EXPECT(mainPathShards == actual);
1200 const auto generateHistoricalStems = [&historicalPaths, &actual] {
1201 for (
auto const& path : historicalPaths)
1203 for (
auto const& shard :
1204 boost::filesystem::directory_iterator(path))
1206 actual.
insert(boost::filesystem::path(shard).stem());
1215 historicalPathShards, historicalPathShards.
begin()),
1217 [n = 1]()
mutable { return std::to_string(n++); });
1219 generateHistoricalStems();
1221 BEAST_EXPECT(historicalPathShards == actual);
1224 historicalPaths.
begin(),
1225 historicalPaths.
end(),
1227 [](
int const sum, boost::filesystem::path
const& path) {
1230 boost::filesystem::directory_iterator(path),
1231 boost::filesystem::directory_iterator());
1236 BEAST_EXPECT(historicalPathCount == ledgerCount - 2);
1238 data =
TestData(seedValue * 2, 4, ledgerCount);
1239 if (!BEAST_EXPECT(data.makeLedgers(env, ledgerCount)))
1246 auto n =
createShard(data, *db, ledgerCount * 2, ledgerCount);
1248 n && *n >= 1 + ledgerCount && *n <= ledgerCount * 2))
1250 bitMask |= 1ll << *n;
1256 boost::filesystem::directory_iterator(shardDir.
path()),
1257 boost::filesystem::directory_iterator());
1261 BEAST_EXPECT(mainPathCount == 2);
1265 shardDir.
path() / boost::filesystem::path(
"7"),
1266 shardDir.
path() / boost::filesystem::path(
"8")};
1268 boost::filesystem::directory_iterator(shardDir.
path()),
1269 boost::filesystem::directory_iterator()};
1271 BEAST_EXPECT(mainPathShards == actual);
1274 historicalPathShards.
clear();
1277 historicalPathShards, historicalPathShards.
begin()),
1279 [n = 1]()
mutable { return std::to_string(n++); });
1281 generateHistoricalStems();
1283 BEAST_EXPECT(historicalPathShards == actual);
1286 historicalPaths.
begin(),
1287 historicalPaths.
end(),
1289 [](
int const sum, boost::filesystem::path
const& path) {
1292 boost::filesystem::directory_iterator(path),
1293 boost::filesystem::directory_iterator());
1298 BEAST_EXPECT(historicalPathCount == (ledgerCount * 2) - 2);
1329 #if RIPPLE_ROCKSDB_AVAILABLE
1333 #if RIPPLE_ENABLE_SQLITE_BACKEND_TESTS