diff --git a/src/test/app/LedgerMaster_test.cpp b/src/test/app/LedgerMaster_test.cpp index 03409a3e80..3d652e564c 100644 --- a/src/test/app/LedgerMaster_test.cpp +++ b/src/test/app/LedgerMaster_test.cpp @@ -157,7 +157,8 @@ class LedgerMaster_test : public beast::unit_test::suite if (maxSeq == lastRotated + deleteInterval) { minSeq = lastRotated; - lastRotated = maxSeq; + lastRotated = store.getLastRotated(); + BEAST_EXPECT(lastRotated = maxSeq + 2); } BEAST_EXPECTS( env.closed()->info().seq == maxSeq, diff --git a/src/test/app/SHAMapStore_test.cpp b/src/test/app/SHAMapStore_test.cpp index 743397fae9..d2b91bf600 100644 --- a/src/test/app/SHAMapStore_test.cpp +++ b/src/test/app/SHAMapStore_test.cpp @@ -227,9 +227,10 @@ public: store.rendezvous(); - BEAST_EXPECT(store.getLastRotated() == deleteInterval + 3); + BEAST_EXPECT(env.closed()->info().seq == deleteInterval + 3); lastRotated = store.getLastRotated(); - BEAST_EXPECT(lastRotated == 11); + BEAST_EXPECT(lastRotated == deleteInterval + 5); + BEAST_EXPECT(lastRotated == 13); // That took care of the fake hashes ledgerCheck(env, deleteInterval + 1, 3); @@ -237,9 +238,11 @@ public: accountTransactionCheck(env, 2 * deleteInterval); // The last iteration of this loop should trigger a rotate - for (auto i = lastRotated - 1; i < lastRotated + deleteInterval - 1; + for (auto i = lastRotated - 3; i < lastRotated + deleteInterval - 1; ++i) { + BEAST_EXPECT(store.getLastRotated() == lastRotated); + env.close(); ledgerTmp = env.rpc("ledger", "current"); @@ -257,7 +260,8 @@ public: store.rendezvous(); - BEAST_EXPECT(store.getLastRotated() == deleteInterval + lastRotated); + BEAST_EXPECT( + store.getLastRotated() == deleteInterval + lastRotated + 2); ledgerCheck(env, deleteInterval + 1, lastRotated); transactionCheck(env, 0); @@ -398,8 +402,8 @@ public: ledgerCheck(env, ledgerSeq - lastRotated, lastRotated); - BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1); - lastRotated = ledgerSeq - 1; + lastRotated = store.getLastRotated(); + BEAST_EXPECT(lastRotated == ledgerSeq + 1); for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq) { @@ -426,10 +430,10 @@ public: store.rendezvous(); - ledgerCheck(env, ledgerSeq - firstBatch, firstBatch); + ledgerCheck(env, ledgerSeq - firstBatch - 2, firstBatch + 2); - BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1); - lastRotated = ledgerSeq - 1; + lastRotated = store.getLastRotated(); + BEAST_EXPECT(lastRotated == ledgerSeq + 1); // This does not kick off a cleanup canDelete = env.rpc("can_delete", "always"); @@ -465,13 +469,13 @@ public: ledgerCheck(env, ledgerSeq - lastRotated, lastRotated); - BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1); - lastRotated = ledgerSeq - 1; + lastRotated = store.getLastRotated(); + BEAST_EXPECT(lastRotated == ledgerSeq + 1); // This does not kick off a cleanup canDelete = env.rpc("can_delete", "now"); BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result])); - BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == ledgerSeq - 1); + BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == lastRotated); for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq) { @@ -500,8 +504,8 @@ public: ledgerCheck(env, ledgerSeq - lastRotated, lastRotated); - BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1); - lastRotated = ledgerSeq - 1; + lastRotated = store.getLastRotated(); + BEAST_EXPECT(lastRotated == ledgerSeq + 1); } std::unique_ptr @@ -670,8 +674,6 @@ public: auto& store = env.app().getSHAMapStore(); store.rendezvous(); LedgerIndex lastRotated = store.getLastRotated(); - LedgerIndex betterMinSeq = minSeq; - LedgerIndex betterLastRotated = lastRotated; BEAST_EXPECTS(maxSeq == 3, to_string(maxSeq)); BEAST_EXPECTS( lm.getCompleteLedgers() == "2-3", lm.getCompleteLedgers()); @@ -789,9 +791,7 @@ public: store.rendezvous(); minSeq = lastRotated; - lastRotated = deleteSeq + 1; - betterMinSeq = betterLastRotated; - betterLastRotated = maxSeq + 2; + lastRotated = maxSeq + 2; // Bypass caching and try to load the ledger roots from the node // store @@ -800,20 +800,10 @@ public: auto const nodeObject = ns.fetchNodeObject(hash); std::stringstream ss; ss << "minSeq: " << minSeq << ", maxSeq: " << maxSeq - << ", search: " << seq; - if (betterMinSeq != minSeq) - ss << ", betterMinSeq: " << betterMinSeq; - ss << ". Should " << (seq < minSeq ? "NOT " : "") - << "be found"; - BEAST_EXPECT(minSeq <= betterMinSeq); - if (betterMinSeq != minSeq && seq >= minSeq && - seq < betterMinSeq) - ss << ", but actually will NOT be found"; + << ", search: " << seq << ". Should " + << (seq < minSeq ? "NOT " : "") << "be found"; if (seq < minSeq) BEAST_EXPECTS(!nodeObject, ss.str()); - // Uncommenting this condition allows the test to succeed - // else if (seq < betterMinSeq) - // BEAST_EXPECTS(!nodeObject, ss.str()); else BEAST_EXPECTS(nodeObject, ss.str()); } diff --git a/src/xrpld/app/misc/SHAMapStoreImp.cpp b/src/xrpld/app/misc/SHAMapStoreImp.cpp index 69f6a7b81b..9f9c9928ca 100644 --- a/src/xrpld/app/misc/SHAMapStoreImp.cpp +++ b/src/xrpld/app/misc/SHAMapStoreImp.cpp @@ -359,7 +359,13 @@ SHAMapStoreImp::run() if (healthWait() == stopping) return; - lastRotated = validatedSeq; + // The rotation process takes time, and more ledgers - possibly many + // more - may have been written to the now-archive database before + // the writable database was created. Update the validatedSeq to the + // current validated ledger sequence plus a buffer to ensure that + // all modified nodes for that ledger forward are all written to the + // new writable database. + lastRotated = ledgerMaster_->getValidLedgerIndex() + 2; dbRotating_->rotate( std::move(newBackend),