Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Commit

Permalink
Make DatabasePaths class an immutable class
Browse files Browse the repository at this point in the history
  • Loading branch information
halfalicious committed Dec 4, 2019
1 parent 5d76fe6 commit 14e669d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 59 deletions.
66 changes: 31 additions & 35 deletions libethereum/BlockChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,21 +199,19 @@ bool BlockChain::open(fs::path const& _path, WithExisting _we)

if (db::isDiskDatabase())
{
if (!_path.empty())
m_dbPaths.setPaths(_path, m_genesisHash);
else if (!m_dbPaths.pathsSet())
BOOST_THROW_EXCEPTION(DatabasePathsNotSet());
if (!m_dbPaths || m_dbPaths->rootPath() != _path)
m_dbPaths = make_unique<DatabasePaths>(_path, m_genesisHash);

if (_we == WithExisting::Kill)
{
LOG(m_loggerInfo)
<< "Deleting chain databases. This will require a resync from genesis.";
fs::remove_all(m_dbPaths.blocksPath());
fs::remove_all(m_dbPaths.extrasPath());
fs::remove_all(m_dbPaths.extrasTemporaryPath());
fs::remove_all(m_dbPaths->blocksPath());
fs::remove_all(m_dbPaths->extrasPath());
fs::remove_all(m_dbPaths->extrasTemporaryPath());
}

bytes const minorVersionBytes = contents(m_dbPaths.extrasMinorVersionPath());
bytes const minorVersionBytes = contents(m_dbPaths->extrasMinorVersionPath());
if (!minorVersionBytes.empty())
{
DEV_IGNORE_EXCEPTIONS(lastMinor = (unsigned)RLP(minorVersionBytes));
Expand All @@ -222,44 +220,44 @@ bool BlockChain::open(fs::path const& _path, WithExisting _we)
rebuildNeeded = true;
LOG(m_loggerInfo) << "Database minor version change detected, the extras and state "
"databases will be rebuilt.";
LOG(m_loggerInfo) << "Version from " << m_dbPaths.extrasMinorVersionPath()
LOG(m_loggerInfo) << "Version from " << m_dbPaths->extrasMinorVersionPath()
<< " (" << lastMinor << ") != Aleth's version ("
<< c_databaseMinorVersion << ")";
}
}
else if (fs::exists(m_dbPaths.extrasPath()))
else if (fs::exists(m_dbPaths->extrasPath()))
{
LOG(m_loggerInfo) << "Database minor version file not found ("
<< m_dbPaths.extrasMinorVersionPath()
<< ") but extras database exists (" << m_dbPaths.extrasPath()
<< m_dbPaths->extrasMinorVersionPath()
<< ") but extras database exists (" << m_dbPaths->extrasPath()
<< "), assuming extras database needs to be upgraded.";
rebuildNeeded = true;
}
else
{
// First launch with new database
LOG(m_loggerDetail) << "Creating database minor version file: "
<< m_dbPaths.extrasMinorVersionPath()
<< m_dbPaths->extrasMinorVersionPath()
<< " (minor version: " << c_databaseMinorVersion << ")";
writeFile(m_dbPaths.extrasMinorVersionPath(), rlp(c_databaseMinorVersion));
writeFile(m_dbPaths->extrasMinorVersionPath(), rlp(c_databaseMinorVersion));
}
}

try
{
m_blocksDB = db::DBFactory::create(m_dbPaths.blocksPath());
m_extrasDB = db::DBFactory::create(m_dbPaths.extrasPath());
m_blocksDB = db::DBFactory::create(m_dbPaths->blocksPath());
m_extrasDB = db::DBFactory::create(m_dbPaths->extrasPath());
}
catch (db::DatabaseError const& ex)
{
// Determine which database open call failed
auto const dbPath =
!m_blocksDB.get() ? m_dbPaths.blocksPath() : m_dbPaths.extrasPath();
!m_blocksDB.get() ? m_dbPaths->blocksPath() : m_dbPaths->extrasPath();
if (db::isDiskDatabase())
{
LOG(m_loggerError) << "Error occurred when opening database: " << dbPath;
db::DatabaseStatus const dbStatus = *boost::get_error_info<db::errinfo_dbStatusCode>(ex);
if (fs::space(m_dbPaths.rootPath()).available < 1024)
if (fs::space(m_dbPaths->rootPath()).available < 1024)
{
LOG(m_loggerError)
<< "Not enough available space found on hard drive. Please free some up and "
Expand Down Expand Up @@ -315,14 +313,14 @@ bool BlockChain::open(fs::path const& _path, WithExisting _we)
void BlockChain::open(fs::path const& _path, WithExisting _we, ProgressCallback const& _pc)
{
if (open(_path, _we) || _we == WithExisting::Verify)
rebuild(fs::path{}, _pc);
rebuild(_path, _pc);
}

void BlockChain::reopen(ChainParams const& _p, WithExisting _we, ProgressCallback const& _pc)
{
close();
init(_p);
open(fs::path{}, _we, _pc);
open(m_dbPaths->rootPath(), _we, _pc);
}

void BlockChain::close()
Expand Down Expand Up @@ -358,10 +356,8 @@ void BlockChain::rebuild(
return;
}

if (!_path.empty())
m_dbPaths.setPaths(_path, m_genesisHash);
else if (!m_dbPaths.pathsSet())
BOOST_THROW_EXCEPTION(DatabasePathsNotSet());
if (!m_dbPaths || m_dbPaths->rootPath() != _path)
m_dbPaths = make_unique<DatabasePaths>(_path, m_genesisHash);

unsigned const originalNumber = m_lastBlockNumber;

Expand All @@ -372,25 +368,25 @@ void BlockChain::rebuild(

// Keep extras DB around, but under a temp name
m_extrasDB.reset();
LOG(m_loggerInfo) << "Renaming extras path " << m_dbPaths.extrasPath() << " to "
<< m_dbPaths.extrasTemporaryPath();
if (fs::exists(m_dbPaths.extrasTemporaryPath()))
LOG(m_loggerInfo) << "Renaming extras path " << m_dbPaths->extrasPath() << " to "
<< m_dbPaths->extrasTemporaryPath();
if (fs::exists(m_dbPaths->extrasTemporaryPath()))
{
LOG(m_loggerError)
<< "Temporary extras path " << m_dbPaths.extrasTemporaryPath()
<< "Temporary extras path " << m_dbPaths->extrasTemporaryPath()
<< " already exists (this usually happens because an in-progress rebuild was "
"prematurely terminated).";
LOG(m_loggerError) << "Please re-run Aleth the --kill option to delete all databases. This "
"will remove all chain data and require you to resync from genesis.";
BOOST_THROW_EXCEPTION(DatabaseExists());
}
fs::rename(m_dbPaths.extrasPath(), m_dbPaths.extrasTemporaryPath());
fs::rename(m_dbPaths->extrasPath(), m_dbPaths->extrasTemporaryPath());
std::unique_ptr<db::DatabaseFace> oldExtrasDB{
db::DBFactory::create(m_dbPaths.extrasTemporaryPath())};
m_extrasDB = db::DBFactory::create(m_dbPaths.extrasPath());
db::DBFactory::create(m_dbPaths->extrasTemporaryPath())};
m_extrasDB = db::DBFactory::create(m_dbPaths->extrasPath());

// Open a fresh state DB
Block s = genesisBlock(State::openDB(m_dbPaths.rootPath(), m_genesisHash, WithExisting::Kill));
Block s = genesisBlock(State::openDB(m_dbPaths->rootPath(), m_genesisHash, WithExisting::Kill));

// Clear all memos ready for replay.
m_details.clear();
Expand Down Expand Up @@ -459,13 +455,13 @@ void BlockChain::rebuild(
if (_progress)
_progress(d, originalNumber);
}
LOG(m_loggerInfo) << "Removing old extras database: " << m_dbPaths.extrasTemporaryPath();
LOG(m_loggerInfo) << "Removing old extras database: " << m_dbPaths->extrasTemporaryPath();
oldExtrasDB.reset();
fs::remove_all(m_dbPaths.extrasTemporaryPath());
fs::remove_all(m_dbPaths->extrasTemporaryPath());
if (!rebuildFailed)
{
LOG(m_loggerInfo) << "Rebuild complete! Reimported " << originalNumber << " blocks!";
writeFile(m_dbPaths.extrasMinorVersionPath(), rlp(c_databaseMinorVersion));
writeFile(m_dbPaths->extrasMinorVersionPath(), rlp(c_databaseMinorVersion));
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion libethereum/BlockChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ class BlockChain
mutable bytes m_genesisHeaderBytes; // mutable because they're effectively memos.
mutable h256 m_genesisHash; // mutable because they're effectively memos.

DatabasePaths m_dbPaths; // Paths for various databases (e.g. blocks, extras)
std::unique_ptr<DatabasePaths> m_dbPaths; // Paths for various databases (e.g. blocks, extras)

std::function<void(Exception&)> m_onBad; ///< Called if we have a block that doesn't verify.
std::function<void(BlockHeader const&)> m_onBlockImport; ///< Called if we have imported a new block into the db
Expand Down
21 changes: 8 additions & 13 deletions libethereum/DatabasePaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,12 @@ namespace eth
namespace fs = boost::filesystem;

DatabasePaths::DatabasePaths(fs::path const& _rootPath, h256 const& _genesisHash) noexcept
{
setPaths(_rootPath, _genesisHash);
}

void DatabasePaths::setPaths(fs::path const& _rootPath, h256 const& _genesisHash) noexcept
{
// Allow an empty root path and empty genesis hash since they are required by the tests
m_rootPath = _rootPath;
m_chainPath = m_rootPath / fs::path(toHex(_genesisHash.ref().cropped(0, 4)));
m_statePath = m_chainPath / fs::path("state");
m_blocksPath = m_statePath / fs::path("blocks");
m_blocksPath = m_chainPath / fs::path("blocks");

auto const extrasRootPath = m_chainPath / fs::path(toString(c_databaseVersion));
m_extrasPath = extrasRootPath / fs::path("extras");
Expand All @@ -36,37 +31,37 @@ bool DatabasePaths::pathsSet() const noexcept
return !m_rootPath.empty();
}

fs::path const& DatabasePaths::rootPath() noexcept
fs::path const& DatabasePaths::rootPath() const noexcept
{
return m_rootPath;
}

fs::path const& DatabasePaths::chainPath() noexcept
fs::path const& DatabasePaths::chainPath() const noexcept
{
return m_chainPath;
}

fs::path const& DatabasePaths::statePath() noexcept
fs::path const& DatabasePaths::statePath() const noexcept
{
return m_statePath;
}

fs::path const& DatabasePaths::blocksPath() noexcept
fs::path const& DatabasePaths::blocksPath() const noexcept
{
return m_blocksPath;
}

fs::path const& DatabasePaths::extrasPath() noexcept
fs::path const& DatabasePaths::extrasPath() const noexcept
{
return m_extrasPath;
}

fs::path const& DatabasePaths::extrasTemporaryPath() noexcept
fs::path const& DatabasePaths::extrasTemporaryPath() const noexcept
{
return m_extrasTemporaryPath;
}

fs::path const& DatabasePaths::extrasMinorVersionPath() noexcept
fs::path const& DatabasePaths::extrasMinorVersionPath() const noexcept
{
return m_extrasMinorVersionPath;
}
Expand Down
16 changes: 7 additions & 9 deletions libethereum/DatabasePaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@ class DatabasePaths
{
public:
DatabasePaths(boost::filesystem::path const& _rootPath, h256 const& _genesisHash) noexcept;
DatabasePaths() = default;
void setPaths(boost::filesystem::path const& _rootPath, h256 const& _genesisHash) noexcept;
bool pathsSet() const noexcept;
boost::filesystem::path const& rootPath() noexcept;
boost::filesystem::path const& chainPath() noexcept;
boost::filesystem::path const& blocksPath() noexcept;
boost::filesystem::path const& statePath() noexcept;
boost::filesystem::path const& extrasPath() noexcept;
boost::filesystem::path const& extrasTemporaryPath() noexcept;
boost::filesystem::path const& extrasMinorVersionPath() noexcept;
boost::filesystem::path const& rootPath() const noexcept;
boost::filesystem::path const& chainPath() const noexcept;
boost::filesystem::path const& blocksPath() const noexcept;
boost::filesystem::path const& statePath() const noexcept;
boost::filesystem::path const& extrasPath() const noexcept;
boost::filesystem::path const& extrasTemporaryPath() const noexcept;
boost::filesystem::path const& extrasMinorVersionPath() const noexcept;

private:
boost::filesystem::path m_rootPath;
Expand Down
2 changes: 1 addition & 1 deletion libethereum/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ State::State(State const& _s):

OverlayDB State::openDB(fs::path const& _basePath, h256 const& _genesisHash, WithExisting _we)
{
DatabasePaths dbPaths{_basePath, _genesisHash};
DatabasePaths const dbPaths{_basePath, _genesisHash};
if (db::isDiskDatabase())
{
if (_we == WithExisting::Kill)
Expand Down

0 comments on commit 14e669d

Please sign in to comment.