diff --git a/src/database/Database.cpp b/src/database/Database.cpp index 64779a0c67..433df01bff 100644 --- a/src/database/Database.cpp +++ b/src/database/Database.cpp @@ -250,6 +250,7 @@ Database::upgradeToCurrentSchema() // Tx meta column no longer supported dropTxMetaIfExists(); + maybeUpgradeToBucketListDB(); CLOG_INFO(Database, "DB schema is in current version"); releaseAssert(vers == SCHEMA_VERSION); @@ -289,6 +290,50 @@ Database::dropTxMetaIfExists() } } +void +Database::maybeUpgradeToBucketListDB() +{ + if (mApp.getPersistentState().getState(PersistentState::kDBBackend) != + BucketIndex::DB_BACKEND_STATE) + { + CLOG_INFO(Database, "Upgrading to BucketListDB"); + + // Drop all LedgerEntry tables except for offers + CLOG_INFO(Database, "Dropping table accounts"); + getSession() << "DROP TABLE IF EXISTS accounts;"; + + CLOG_INFO(Database, "Dropping table signers"); + getSession() << "DROP TABLE IF EXISTS signers;"; + + CLOG_INFO(Database, "Dropping table claimablebalance"); + getSession() << "DROP TABLE IF EXISTS claimablebalance;"; + + CLOG_INFO(Database, "Dropping table configsettings"); + getSession() << "DROP TABLE IF EXISTS configsettings;"; + + CLOG_INFO(Database, "Dropping table contractcode"); + getSession() << "DROP TABLE IF EXISTS contractcode;"; + + CLOG_INFO(Database, "Dropping table contractdata"); + getSession() << "DROP TABLE IF EXISTS contractdata;"; + + CLOG_INFO(Database, "Dropping table accountdata"); + getSession() << "DROP TABLE IF EXISTS accountdata;"; + + CLOG_INFO(Database, "Dropping table liquiditypool"); + getSession() << "DROP TABLE IF EXISTS liquiditypool;"; + + CLOG_INFO(Database, "Dropping table trustlines"); + getSession() << "DROP TABLE IF EXISTS trustlines;"; + + CLOG_INFO(Database, "Dropping table ttl"); + getSession() << "DROP TABLE IF EXISTS ttl;"; + + mApp.getPersistentState().setState(PersistentState::kDBBackend, + BucketIndex::DB_BACKEND_STATE); + } +} + void Database::putSchemaVersion(unsigned long vers) { diff --git a/src/database/Database.h b/src/database/Database.h index e3ad43b214..73540c2884 100644 --- a/src/database/Database.h +++ b/src/database/Database.h @@ -174,6 +174,7 @@ class Database : NonMovableOrCopyable void upgradeToCurrentSchema(); void dropTxMetaIfExists(); + void maybeUpgradeToBucketListDB(); // Access the underlying SOCI session object soci::session& getSession(); diff --git a/src/invariant/BucketListIsConsistentWithDatabase.cpp b/src/invariant/BucketListIsConsistentWithDatabase.cpp index 231180e40f..dfd00554c3 100644 --- a/src/invariant/BucketListIsConsistentWithDatabase.cpp +++ b/src/invariant/BucketListIsConsistentWithDatabase.cpp @@ -164,7 +164,7 @@ BucketListIsConsistentWithDatabase::checkEntireBucketlist() { throw std::runtime_error( "Corrupt DB: BucketListDB flag " - "not set in PersistentState. Please run new-db"); + "not set in PersistentState. Please run new-db or upgrade-db"); } } diff --git a/src/main/test/ApplicationUtilsTests.cpp b/src/main/test/ApplicationUtilsTests.cpp index bdb7b9ecff..31ee9dbba9 100644 --- a/src/main/test/ApplicationUtilsTests.cpp +++ b/src/main/test/ApplicationUtilsTests.cpp @@ -2,11 +2,13 @@ // under the Apache License, Version 2.0. See the COPYING file at the root // of this distribution or at http://www.apache.org/licenses/LICENSE-2.0 +#include "bucket/test/BucketTestUtils.h" #include "crypto/Random.h" #include "history/HistoryArchiveManager.h" #include "history/test/HistoryTestsUtils.h" #include "invariant/BucketListIsConsistentWithDatabase.h" #include "ledger/LedgerTxn.h" +#include "ledger/test/LedgerTestUtils.h" #include "lib/catch.hpp" #include "main/Application.h" #include "main/ApplicationUtils.h" @@ -51,45 +53,6 @@ class TemporaryFileDamager } }; -class TemporarySQLiteDBDamager : public TemporaryFileDamager -{ - Config mConfig; - static std::filesystem::path - getSQLiteDBPath(Config const& cfg) - { - auto str = cfg.DATABASE.value; - std::string prefix = "sqlite3://"; - REQUIRE(str.find(prefix) == 0); - str = str.substr(prefix.size()); - REQUIRE(!str.empty()); - std::filesystem::path path(str); - REQUIRE(std::filesystem::exists(path)); - return path; - } - - public: - TemporarySQLiteDBDamager(Config const& cfg) - : TemporaryFileDamager(getSQLiteDBPath(cfg)), mConfig(cfg) - { - } - void - damageVictim() override - { - // Damage a database by bumping the root account's last-modified. - VirtualClock clock; - auto app = createTestApplication(clock, mConfig, /*newDB=*/false); - LedgerTxn ltx(app->getLedgerTxnRoot(), - /*shouldUpdateLastModified=*/false); - { - auto rootKey = accountKey( - stellar::txtest::getRoot(app->getNetworkID()).getPublicKey()); - auto rootLe = ltx.load(rootKey); - rootLe.current().lastModifiedLedgerSeq += 1; - } - ltx.commit(); - } -}; - // Logic to check the state of the bucket list with the state of the DB static bool checkState(Application& app) @@ -415,12 +378,6 @@ TEST_CASE("offline self-check works", "[applicationutils][selfcheck]") damage.damageVictim(); REQUIRE(selfCheck(chkConfig) == 1); } - { - // Damage the SQL ledger. - TemporarySQLiteDBDamager damage(chkConfig); - damage.damageVictim(); - REQUIRE(selfCheck(chkConfig) == 1); - } } TEST_CASE("application setup", "[applicationutils]")