Compare commits

..

13 Commits

Author SHA1 Message Date
Mayukha Vadari
aa1f84e226 fix clang-tidy issues 2026-04-25 12:36:43 -04:00
copilot-swe-agent[bot]
ae7076c054 Address second round of review feedback: non-throwing exists(), direct path streams, errno propagation
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ebfae1ee-800f-4a23-b484-a709c2321693

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 21:16:42 +00:00
copilot-swe-agent[bot]
9a221d1291 Address code review feedback: retry loop, comment cleanup, error code improvements
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/629eace2-9c23-40d9-89f5-9ef3099cdf14

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 18:42:23 +00:00
copilot-swe-agent[bot]
5e6d8a4692 Merge remote-tracking branch 'origin/develop' into copilot/refactor-replace-boost-filesystem
# Conflicts:
#	src/xrpld/core/Config.h

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 17:59:58 +00:00
Mayukha Vadari
11c7d912f6 fix build 2026-04-24 12:54:09 -04:00
Mayukha Vadari
b7d6cdf713 fix clang-tidy issues 2026-04-24 12:49:36 -04:00
copilot-swe-agent[bot]
193ddcbfac Fix pre-commit and clang-tidy issues using tools
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/e5845adb-dc3f-46cf-8461-0ea7855be1cf

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 15:38:40 +00:00
copilot-swe-agent[bot]
3a70d9dfba Fix build error and pre-commit include ordering issues
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/e53fe2d3-e57e-4ad9-9d43-5dc1519645fc

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 14:13:56 +00:00
Mayukha Vadari
03e8a68670 Merge branch 'develop' into copilot/refactor-replace-boost-filesystem 2026-04-24 09:54:16 -04:00
copilot-swe-agent[bot]
28143d74af Increase entropy in SHAMapStoreImp.cpp unique path generation
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ec2fa57d-2d9c-4388-b4e1-90a40f55b5e8

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 13:52:06 +00:00
copilot-swe-agent[bot]
ff4c538a9f Address code review: improve random path generation and fix includes
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ec2fa57d-2d9c-4388-b4e1-90a40f55b5e8

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 13:50:38 +00:00
copilot-swe-agent[bot]
9fe94c47c3 Replace boost::filesystem with std::filesystem across codebase
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ec2fa57d-2d9c-4388-b4e1-90a40f55b5e8

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 13:47:08 +00:00
copilot-swe-agent[bot]
3f307f8128 Initial plan 2026-04-24 13:24:30 +00:00
43 changed files with 311 additions and 645 deletions

View File

@@ -1033,11 +1033,10 @@
# The online delete process checks periodically
# that xrpld is still in sync with the network,
# and that the validated ledger is less than
# 'age_threshold_seconds' old, and that all
# recent ledgers are available. If not, then continue
# 'age_threshold_seconds' old. If not, then continue
# sleeping for this number of seconds and
# checking until healthy.
# Default is 1.
# Default is 5.
#
# Notes:
# The 'node_db' entry configures the primary, persistent storage.

View File

@@ -1,6 +1,6 @@
#pragma once
#include <boost/filesystem.hpp>
#include <filesystem>
namespace xrpl {
@@ -12,6 +12,6 @@ namespace xrpl {
@throws runtime_error
*/
void
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst);
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst);
} // namespace xrpl

View File

@@ -1,22 +1,22 @@
#pragma once
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <filesystem>
#include <optional>
#include <string>
#include <system_error>
namespace xrpl {
std::string
getFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& sourcePath,
std::error_code& ec,
std::filesystem::path const& sourcePath,
std::optional<std::size_t> maxSize = std::nullopt);
void
writeFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& destPath,
std::error_code& ec,
std::filesystem::path const& destPath,
std::string const& contents);
} // namespace xrpl

View File

@@ -4,8 +4,8 @@
#include <xrpl/beast/utility/Journal.h>
#include <boost/beast/core/string.hpp>
#include <boost/filesystem.hpp>
#include <filesystem>
#include <fstream>
#include <map>
#include <memory>
@@ -88,7 +88,7 @@ private:
@return `true` if the file was opened.
*/
bool
open(boost::filesystem::path const& path);
open(std::filesystem::path const& path);
/** Close and re-open the system file associated with the log
This assists in interoperating with external log management tools.
@@ -130,7 +130,7 @@ private:
private:
std::unique_ptr<std::ofstream> m_stream;
boost::filesystem::path m_path;
std::filesystem::path m_path;
};
std::mutex mutable mutex_;
@@ -149,7 +149,7 @@ public:
virtual ~Logs() = default;
bool
open(boost::filesystem::path const& pathToLogFile);
open(std::filesystem::path const& pathToLogFile);
beast::Journal::Sink&
get(std::string const& name);

View File

@@ -6,10 +6,10 @@
#include <xrpl/beast/unit_test/runner.h>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/throw_exception.hpp>
#include <filesystem>
#include <ostream>
#include <sstream>
#include <string>
@@ -25,7 +25,7 @@ make_reason(String const& reason, char const* file, int line)
std::string s(reason);
if (!s.empty())
s.append(": ");
namespace fs = boost::filesystem;
namespace fs = std::filesystem;
s.append(fs::path{file}.filename().string());
s.append("(");
s.append(boost::lexical_cast<std::string>(line));

View File

@@ -1,8 +1,11 @@
#pragma once
#include <boost/filesystem.hpp>
#include <filesystem>
#include <iomanip>
#include <random>
#include <sstream>
#include <string>
#include <system_error>
namespace beast {
@@ -13,7 +16,7 @@ namespace beast {
*/
class temp_dir
{
boost::filesystem::path path_;
std::filesystem::path path_;
public:
#if !GENERATING_DOCS
@@ -25,20 +28,30 @@ public:
/// Construct a temporary directory.
temp_dir()
{
auto const dir = boost::filesystem::temp_directory_path();
do
auto const dir = std::filesystem::temp_directory_path();
std::random_device rd;
constexpr std::size_t maxAttempts = 100;
for (std::size_t attempt = 0; attempt < maxAttempts; ++attempt)
{
path_ = dir / boost::filesystem::unique_path();
} while (boost::filesystem::exists(path_));
boost::filesystem::create_directory(path_);
std::error_code ec;
std::ostringstream oss;
oss << std::hex << std::setfill('0') << std::setw(8) << rd() << std::setw(8) << rd();
path_ = dir / oss.str();
if (!std::filesystem::exists(path_, ec) && !ec)
break;
path_.clear();
}
if (path_.empty())
throw std::runtime_error("Unable to generate a unique temporary directory path");
std::filesystem::create_directory(path_);
}
/// Destroy a temporary directory.
~temp_dir()
{
// use non-throwing calls in the destructor
boost::system::error_code ec;
boost::filesystem::remove_all(path_, ec);
std::error_code ec;
std::filesystem::remove_all(path_, ec);
// TODO: warn/notify if ec set ?
}

View File

@@ -4,10 +4,9 @@
#include <xrpl/core/JobTypes.h>
#include <xrpl/json/json_value.h>
#include <boost/filesystem.hpp>
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <memory>
#include <string>
@@ -43,7 +42,7 @@ public:
*/
struct Setup
{
boost::filesystem::path perfLog;
std::filesystem::path perfLog;
// log_interval is in milliseconds to support faster testing.
milliseconds logInterval{seconds(1)};
};
@@ -148,7 +147,7 @@ public:
};
PerfLog::Setup
setup_PerfLog(Section const& section, boost::filesystem::path const& configDir);
setup_PerfLog(Section const& section, std::filesystem::path const& configDir);
std::unique_ptr<PerfLog>
make_PerfLog(

View File

@@ -6,8 +6,7 @@
#include <xrpl/rdb/DBInit.h>
#include <xrpl/rdb/SociDB.h>
#include <boost/filesystem/path.hpp>
#include <filesystem>
#include <mutex>
#include <optional>
#include <string>
@@ -72,7 +71,7 @@ public:
StartUpType startUp = StartUpType::Normal;
bool standAlone = false;
boost::filesystem::path dataDir;
std::filesystem::path dataDir;
// Indicates whether or not to return the `globalPragma`
// from commonPragma()
bool useGlobalPragma = false;
@@ -135,7 +134,7 @@ public:
template <std::size_t N, std::size_t M>
DatabaseCon(
boost::filesystem::path const& dataDir,
std::filesystem::path const& dataDir,
std::string const& dbName,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
@@ -147,7 +146,7 @@ public:
// Use this constructor to setup checkpointing
template <std::size_t N, std::size_t M>
DatabaseCon(
boost::filesystem::path const& dataDir,
std::filesystem::path const& dataDir,
std::string const& dbName,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
@@ -182,7 +181,7 @@ private:
template <std::size_t N, std::size_t M>
DatabaseCon(
boost::filesystem::path const& pPath,
std::filesystem::path const& pPath,
std::vector<std::string> const* commonPragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,

View File

@@ -10,7 +10,6 @@
#include <xrpl/protocol/TxSearched.h>
#include <xrpl/rdb/DatabaseCon.h>
#include <boost/filesystem.hpp>
#include <boost/variant.hpp>
namespace xrpl {

View File

@@ -4,8 +4,6 @@
#include <xrpl/rdb/DatabaseCon.h>
#include <xrpl/server/Manifest.h>
#include <boost/filesystem.hpp>
namespace xrpl {
struct SavedState

View File

@@ -2,20 +2,18 @@
#include <xrpl/basics/contract.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <archive.h>
#include <archive_entry.h>
#include <cstddef>
#include <filesystem>
#include <memory>
#include <stdexcept>
namespace xrpl {
void
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst)
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst)
{
if (!is_regular_file(src))
Throw<std::runtime_error>("Invalid source file");

View File

@@ -1,29 +1,24 @@
#include <xrpl/basics/FileUtilities.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/errc.hpp>
#include <cerrno>
#include <cstddef>
#include <filesystem>
#include <fstream>
#include <ios>
#include <iterator>
#include <optional>
#include <string>
#include <system_error>
namespace xrpl {
std::string
getFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& sourcePath,
std::error_code& ec,
std::filesystem::path const& sourcePath,
std::optional<std::size_t> maxSize)
{
using namespace boost::filesystem;
using namespace boost::system::errc;
using namespace std::filesystem;
path const fullPath{canonical(sourcePath, ec)};
if (ec)
@@ -32,15 +27,15 @@ getFileContents(
if (maxSize && (file_size(fullPath, ec) > *maxSize || ec))
{
if (!ec)
ec = make_error_code(file_too_large);
ec = make_error_code(std::errc::file_too_large);
return {};
}
std::ifstream fileStream(fullPath.string(), std::ios::in);
std::ifstream fileStream(fullPath, std::ios::in);
if (!fileStream)
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return {};
}
@@ -49,7 +44,7 @@ getFileContents(
if (fileStream.bad())
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return {};
}
@@ -58,18 +53,15 @@ getFileContents(
void
writeFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& destPath,
std::error_code& ec,
std::filesystem::path const& destPath,
std::string const& contents)
{
using namespace boost::filesystem;
using namespace boost::system::errc;
std::ofstream fileStream(destPath.string(), std::ios::out | std::ios::trunc);
std::ofstream fileStream(destPath, std::ios::out | std::ios::trunc);
if (!fileStream)
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return;
}
@@ -77,7 +69,7 @@ writeFileContents(
if (fileStream.bad())
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return;
}
}

View File

@@ -5,10 +5,10 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/path.hpp>
#include <chrono>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
@@ -53,7 +53,7 @@ Logs::File::isOpen() const noexcept
}
bool
Logs::File::open(boost::filesystem::path const& path)
Logs::File::open(std::filesystem::path const& path)
{
close();
@@ -112,7 +112,7 @@ Logs::Logs(beast::severities::Severity thresh) : thresh_(thresh) // default sev
}
bool
Logs::open(boost::filesystem::path const& pathToLogFile)
Logs::open(std::filesystem::path const& pathToLogFile)
{
return file_.open(pathToLogFile);
}

View File

@@ -15,8 +15,6 @@
#include <xrpl/nodestore/detail/EncodedBlob.h>
#include <xrpl/nodestore/detail/codec.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/errc.hpp>
#include <nudb/context.hpp>
@@ -35,12 +33,14 @@
#include <cstdint>
#include <cstdio>
#include <exception>
#include <filesystem>
#include <functional>
#include <memory>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
@@ -131,7 +131,7 @@ public:
void
open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt) override
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (db_.is_open())
{
// LCOV_EXCL_START
@@ -194,11 +194,12 @@ public:
if (deletePath_)
{
boost::filesystem::remove_all(name_, ec);
if (ec)
std::error_code fsec;
std::filesystem::remove_all(name_, fsec);
if (fsec)
{
JLOG(j_.fatal())
<< "Filesystem remove_all of " << name_ << " failed with: " << ec.message();
JLOG(j_.fatal()) << "Filesystem remove_all of " << name_
<< " failed with: " << fsec.message();
}
}
}
@@ -374,7 +375,7 @@ private:
static std::size_t
parseBlockSize(std::string const& name, Section const& keyValues, beast::Journal journal)
{
using namespace boost::filesystem;
using namespace std::filesystem;
auto const folder = path(name);
auto const kp = (folder / "nudb.key").string();

View File

@@ -8,9 +8,6 @@
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <rocksdb/advanced_options.h>
#include <rocksdb/cache.h>
#include <rocksdb/compression_type.h>
@@ -26,6 +23,7 @@
#include <bit>
#include <cstddef>
#include <filesystem>
#include <functional>
#include <stdexcept>
#include <string>
@@ -265,8 +263,8 @@ public:
m_db.reset();
if (m_deletePath)
{
boost::filesystem::path const dir = m_name;
boost::filesystem::remove_all(dir);
std::filesystem::path const dir = m_name;
std::filesystem::remove_all(dir);
}
}
}

View File

@@ -4,13 +4,11 @@
#include <xrpl/core/JobQueue.h>
#include <xrpl/core/ServiceRegistry.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <soci/blob.h>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <mutex>
#include <stdexcept>
#include <string>
@@ -44,7 +42,7 @@ getSociSqliteInit(std::string const& name, std::string const& dir, std::string c
Throw<std::runtime_error>(
"Sqlite databases must specify a dir and a name. Name: " + name + " Dir: " + dir);
}
boost::filesystem::path file(dir);
std::filesystem::path file(dir);
if (is_directory(file))
file /= name + ext;
return file.string();

View File

@@ -5,13 +5,12 @@
#include <xrpl/rdb/DBInit.h>
#include <xrpl/rdb/DatabaseCon.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format.hpp> // IWYU pragma: keep
#include <soci/into.h>
#include <cstdint>
#include <filesystem>
#include <iostream>
#include <memory>
@@ -20,7 +19,7 @@ namespace xrpl {
bool
doVacuumDB(DatabaseCon::Setup const& setup, beast::Journal j)
{
boost::filesystem::path const dbPath = setup.dataDir / TxDBName;
std::filesystem::path const dbPath = setup.dataDir / TxDBName;
uintmax_t const dbSize = file_size(dbPath);
XRPL_ASSERT(dbSize != static_cast<uintmax_t>(-1), "xrpl::doVacuumDB : file_size succeeded");

View File

@@ -7,8 +7,6 @@
#include <xrpl/proto/org/xrpl/rpc/v1/get_ledger.pb.h>
#include <xrpl/proto/org/xrpl/rpc/v1/xrp_ledger.grpc.pb.h>
#include <boost/filesystem/operations.hpp>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/grpcpp.h>
@@ -16,9 +14,14 @@
#include <grpcpp/support/status.h>
#include <chrono>
#include <cstddef>
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <ios>
#include <memory>
#include <random>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
@@ -256,9 +259,23 @@ public:
TemporaryTLSCertificates()
{
auto tmpDir = std::filesystem::temp_directory_path();
auto uniqueDirName =
boost::filesystem::unique_path(std::string(kCERTS_DIR_PREFIX) + "%%%%%%%%");
tempDir_ = tmpDir / uniqueDirName.string();
std::random_device rd;
constexpr std::size_t maxAttempts = 100;
for (std::size_t attempt = 0; attempt < maxAttempts; ++attempt)
{
std::error_code ec;
std::ostringstream oss;
oss << kCERTS_DIR_PREFIX << std::hex << std::setfill('0') << std::setw(8) << rd();
tempDir_ = tmpDir / oss.str();
if (!std::filesystem::exists(tempDir_, ec) && !ec)
break;
tempDir_.clear();
}
if (tempDir_.empty())
{
throw std::runtime_error(
"Unable to generate a unique temporary TLS certificate directory");
}
std::filesystem::create_directories(tempDir_);
writeFile(tempDir_ / kCA_CERT_FILENAME, kCA_CERT_CONTENT);

View File

@@ -18,16 +18,16 @@
#include <xrpl/protocol/jss.h>
#include <boost/algorithm/string/erase.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/system/detail/error_code.hpp>
#include <cassert>
#include <filesystem>
#include <fstream>
#include <ios>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <system_error>
namespace xrpl {
@@ -139,7 +139,7 @@ class LedgerLoad_test : public beast::unit_test::suite
{
testcase("Load ledger: Bad Files");
using namespace test::jtx;
using namespace boost::filesystem;
using namespace std::filesystem;
// empty path
except([&] {
@@ -161,8 +161,8 @@ class LedgerLoad_test : public beast::unit_test::suite
});
// make a corrupted version of the ledger file (last 10 bytes removed).
boost::system::error_code ec;
auto ledgerFileCorrupt = boost::filesystem::path{sd.dbPath} / "ledgerdata_bad.json";
std::error_code ec;
auto ledgerFileCorrupt = std::filesystem::path{sd.dbPath} / "ledgerdata_bad.json";
copy_file(sd.ledgerFile, ledgerFileCorrupt, copy_options::overwrite_existing, ec);
if (!BEAST_EXPECTS(!ec, ec.message()))
return;

View File

@@ -5,21 +5,17 @@
#include <test/jtx/noop.h>
#include <xrpld/app/ledger/LedgerMaster.h>
#include <xrpld/app/misc/SHAMapStore.h>
#include <xrpld/core/Config.h>
#include <xrpl/basics/ToString.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/STTx.h>
#include <cstdint>
#include <memory>
#include <sstream>
#include <vector>
namespace xrpl::test {
@@ -115,74 +111,6 @@ class LedgerMaster_test : public beast::unit_test::suite
}
}
void
testCompleteLedgerRange(FeatureBitset features)
{
// Note that this test is intentionally very similar to
// SHAMapStore_test::testLedgerGaps, but has a different
// focus.
testcase("Complete Ledger operations");
using namespace test::jtx;
auto const deleteInterval = 8;
Env env{*this, envconfig([](auto cfg) {
return online_delete(std::move(cfg), deleteInterval);
})};
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
env.close();
auto& lm = env.app().getLedgerMaster();
LedgerIndex minSeq = 2;
LedgerIndex maxSeq = env.closed()->header().seq;
auto& store = env.app().getSHAMapStore();
store.rendezvous();
LedgerIndex lastRotated = store.getLastRotated();
BEAST_EXPECTS(maxSeq == 3, to_string(maxSeq));
BEAST_EXPECTS(lm.getCompleteLedgers() == "2-3", lm.getCompleteLedgers());
BEAST_EXPECTS(lastRotated == 3, to_string(lastRotated));
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq, maxSeq) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 1, maxSeq - 1) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 1, maxSeq + 1) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 2, maxSeq - 2) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 2, maxSeq + 2) == 2);
// Close enough ledgers to rotate a few times
for (int i = 0; i < 24; ++i)
{
for (int t = 0; t < 3; ++t)
{
env(noop(alice));
}
env.close();
store.rendezvous();
++maxSeq;
if (maxSeq == lastRotated + deleteInterval)
{
minSeq = lastRotated;
lastRotated = store.getLastRotated();
BEAST_EXPECT(lastRotated = maxSeq + 2);
}
BEAST_EXPECTS(
env.closed()->header().seq == maxSeq, to_string(env.closed()->header().seq));
BEAST_EXPECTS(store.getLastRotated() == lastRotated, to_string(store.getLastRotated()));
std::stringstream expectedRange;
expectedRange << minSeq << "-" << maxSeq;
BEAST_EXPECTS(lm.getCompleteLedgers() == expectedRange.str(), lm.getCompleteLedgers());
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq, maxSeq) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 1, maxSeq - 1) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 1, maxSeq + 1) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 2, maxSeq - 2) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 2, maxSeq + 2) == 2);
}
}
public:
void
run() override
@@ -196,7 +124,6 @@ public:
testWithFeats(FeatureBitset features)
{
testTxnIdFromIndex(features);
testCompleteLedgerRange(features);
}
};

View File

@@ -21,14 +21,12 @@
#include <xrpl/server/Manifest.h>
#include <xrpl/server/Wallet.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <exception>
#include <filesystem>
#include <limits>
#include <memory>
#include <optional>
@@ -55,18 +53,18 @@ private:
}
static void
cleanupDatabaseDir(boost::filesystem::path const& dbPath)
cleanupDatabaseDir(std::filesystem::path const& dbPath)
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (!exists(dbPath) || !is_directory(dbPath) || !is_empty(dbPath))
return;
remove(dbPath);
}
static void
setupDatabaseDir(boost::filesystem::path const& dbPath)
setupDatabaseDir(std::filesystem::path const& dbPath)
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (!exists(dbPath))
{
create_directory(dbPath);
@@ -79,10 +77,10 @@ private:
Throw<std::runtime_error>("Cannot create directory: " + dbPath.string());
}
}
static boost::filesystem::path
static std::filesystem::path
getDatabasePath()
{
return boost::filesystem::current_path() / "manifest_test_databases";
return std::filesystem::current_path() / "manifest_test_databases";
}
public:
@@ -351,7 +349,7 @@ public:
BEAST_EXPECT(loaded.revoked(pk));
}
}
boost::filesystem::remove(getDatabasePath() / boost::filesystem::path(dbName));
std::filesystem::remove(getDatabasePath() / std::filesystem::path(dbName));
}
void

View File

@@ -1,9 +1,7 @@
#include <test/jtx/Env.h>
#include <test/jtx/amount.h>
#include <test/jtx/envconfig.h>
#include <test/jtx/noop.h>
#include <xrpld/app/ledger/LedgerMaster.h>
#include <xrpld/app/main/Application.h>
#include <xrpld/app/main/NodeStoreScheduler.h>
#include <xrpld/app/misc/SHAMapStore.h>
@@ -23,17 +21,14 @@
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/jss.h>
#include <boost/filesystem/path.hpp>
#include <atomic>
#include <cstdint>
#include <filesystem>
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <sstream>
#include <string>
#include <thread>
#include <utility>
namespace xrpl::test {
@@ -45,8 +40,10 @@ class SHAMapStore_test : public beast::unit_test::suite
static auto
onlineDelete(std::unique_ptr<Config> cfg)
{
using namespace jtx;
return online_delete(std::move(cfg), deleteInterval);
cfg->LEDGER_HISTORY = deleteInterval;
auto& section = cfg->section(ConfigSection::nodeDatabase());
section.set("online_delete", std::to_string(deleteInterval));
return cfg;
}
static auto
@@ -230,10 +227,9 @@ public:
store.rendezvous();
BEAST_EXPECT(env.closed()->info().seq == deleteInterval + 3);
BEAST_EXPECT(store.getLastRotated() == deleteInterval + 3);
lastRotated = store.getLastRotated();
BEAST_EXPECT(lastRotated == deleteInterval + 5);
BEAST_EXPECT(lastRotated == 13);
BEAST_EXPECT(lastRotated == 11);
// That took care of the fake hashes
ledgerCheck(env, deleteInterval + 1, 3);
@@ -241,10 +237,8 @@ public:
accountTransactionCheck(env, 2 * deleteInterval);
// The last iteration of this loop should trigger a rotate
for (auto i = lastRotated - 3; i < lastRotated + deleteInterval - 1; ++i)
for (auto i = lastRotated - 1; i < lastRotated + deleteInterval - 1; ++i)
{
BEAST_EXPECT(store.getLastRotated() == lastRotated);
env.close();
ledgerTmp = env.rpc("ledger", "current");
@@ -260,7 +254,7 @@ public:
store.rendezvous();
BEAST_EXPECT(store.getLastRotated() == deleteInterval + lastRotated + 2);
BEAST_EXPECT(store.getLastRotated() == deleteInterval + lastRotated);
ledgerCheck(env, deleteInterval + 1, lastRotated);
transactionCheck(env, 0);
@@ -393,8 +387,8 @@ public:
ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
lastRotated = store.getLastRotated();
BEAST_EXPECT(lastRotated == ledgerSeq + 1);
BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
lastRotated = ledgerSeq - 1;
for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
{
@@ -419,10 +413,10 @@ public:
store.rendezvous();
ledgerCheck(env, ledgerSeq - firstBatch - 2, firstBatch + 2);
ledgerCheck(env, ledgerSeq - firstBatch, firstBatch);
lastRotated = store.getLastRotated();
BEAST_EXPECT(lastRotated == ledgerSeq + 1);
BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
lastRotated = ledgerSeq - 1;
// This does not kick off a cleanup
canDelete = env.rpc("can_delete", "always");
@@ -455,13 +449,13 @@ public:
ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
lastRotated = store.getLastRotated();
BEAST_EXPECT(lastRotated == ledgerSeq + 1);
BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
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] == lastRotated);
BEAST_EXPECT(canDelete[jss::result][jss::can_delete] == ledgerSeq - 1);
for (; ledgerSeq < lastRotated + deleteInterval; ++ledgerSeq)
{
@@ -488,15 +482,15 @@ public:
ledgerCheck(env, ledgerSeq - lastRotated, lastRotated);
lastRotated = store.getLastRotated();
BEAST_EXPECT(lastRotated == ledgerSeq + 1);
BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
lastRotated = ledgerSeq - 1;
}
std::unique_ptr<NodeStore::Backend>
makeBackendRotating(jtx::Env& env, NodeStoreScheduler& scheduler, std::string path)
{
Section section{env.app().config().section(ConfigSection::nodeDatabase())};
boost::filesystem::path newPath;
std::filesystem::path newPath;
if (!BEAST_EXPECT(path.size()))
return {};
@@ -589,187 +583,6 @@ public:
BEAST_EXPECT(dbr->getName() == "3");
}
void
testLedgerGaps()
{
// Note that this test is intentionally very similar to
// LedgerMaster_test::testCompleteLedgerRange, but has a different
// focus.
testcase("Wait for ledger gaps to fill in");
using namespace test::jtx;
Env env{*this, envconfig(onlineDelete)};
auto& ns = env.app().getNodeStore();
std::map<LedgerIndex, uint256> hashes;
auto storeHash = [&]() {
hashes.emplace(env.current()->info().seq, env.current()->info().hash);
auto const& root = ns.fetchNodeObject(hashes[env.current()->info().seq]);
BEAST_EXPECT(root);
};
auto failureMessage = [&](char const* label, auto expected, auto actual) {
std::stringstream ss;
ss << label << ": Expected: " << expected << ", Got: " << actual;
return ss.str();
};
auto const alice = Account("alice");
env.fund(XRP(1000), alice);
env.close();
storeHash();
auto& lm = env.app().getLedgerMaster();
LedgerIndex minSeq = 2;
LedgerIndex maxSeq = env.closed()->header().seq;
auto& store = env.app().getSHAMapStore();
store.rendezvous();
LedgerIndex lastRotated = store.getLastRotated();
BEAST_EXPECTS(maxSeq == 3, std::to_string(maxSeq));
BEAST_EXPECTS(lm.getCompleteLedgers() == "2-3", lm.getCompleteLedgers());
BEAST_EXPECTS(lastRotated == 3, to_string(lastRotated));
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq, maxSeq) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 1, maxSeq - 1) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 1, maxSeq + 1) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 2, maxSeq - 2) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 2, maxSeq + 2) == 2);
// Close enough ledgers to rotate a few times
while (maxSeq < 28)
{
for (int t = 0; t < 3; ++t)
{
env(noop(alice));
}
env.close();
storeHash();
store.rendezvous();
++maxSeq;
if (maxSeq + 1 == lastRotated + deleteInterval)
{
using namespace std::chrono_literals;
// The next ledger will trigger a rotation. Delete the
// current ledger from LedgerMaster.
std::this_thread::sleep_for(100ms);
LedgerIndex const deleteSeq = maxSeq;
while (!lm.haveLedger(deleteSeq))
{
std::this_thread::sleep_for(100ms);
}
lm.clearLedger(deleteSeq);
auto expectedRange = [](auto minSeq, auto deleteSeq, auto maxSeq) {
std::stringstream expectedRange;
expectedRange << minSeq << "-" << (deleteSeq - 1);
if (deleteSeq + 1 == maxSeq)
{
expectedRange << "," << maxSeq;
}
else if (deleteSeq < maxSeq)
{
expectedRange << "," << (deleteSeq + 1) << "-" << maxSeq;
}
return expectedRange.str();
};
BEAST_EXPECTS(
lm.getCompleteLedgers() == expectedRange(minSeq, deleteSeq, maxSeq),
failureMessage(
"Complete ledgers",
expectedRange(minSeq, deleteSeq, maxSeq),
lm.getCompleteLedgers()));
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq, maxSeq) == 1);
// Close another ledger, which will trigger a rotation, but the
// rotation will be stuck until the missing ledger is filled in.
env.close();
storeHash();
// DO NOT CALL rendezvous()! You'll end up with a deadlock.
++maxSeq;
// Nothing has changed
BEAST_EXPECTS(
store.getLastRotated() == lastRotated,
failureMessage("lastRotated", lastRotated, store.getLastRotated()));
BEAST_EXPECTS(
lm.getCompleteLedgers() == expectedRange(minSeq, deleteSeq, maxSeq),
failureMessage(
"Complete ledgers",
expectedRange(minSeq, deleteSeq, maxSeq),
lm.getCompleteLedgers()));
// Close 5 more ledgers, waiting one second in between to
// simulate the ledger making progress while online delete waits
// for the missing ledger to be filled in.
// This ensures the healthWait check has time to run and
// detect the gap.
for (int l = 0; l < 5; ++l)
{
env.close();
storeHash();
// DO NOT CALL rendezvous()! You'll end up with a deadlock.
++maxSeq;
// Nothing has changed
BEAST_EXPECTS(
store.getLastRotated() == lastRotated,
failureMessage("lastRotated", lastRotated, store.getLastRotated()));
BEAST_EXPECTS(
lm.getCompleteLedgers() == expectedRange(minSeq, deleteSeq, maxSeq),
failureMessage(
"Complete Ledgers",
expectedRange(minSeq, deleteSeq, maxSeq),
lm.getCompleteLedgers()));
std::this_thread::sleep_for(1s);
}
// Put the missing ledger back in LedgerMaster
lm.setLedgerRangePresent(deleteSeq, deleteSeq);
// Wait for the rotation to finish
store.rendezvous();
minSeq = lastRotated;
lastRotated = maxSeq + 2;
// Bypass caching and try to load the ledger roots from the node
// store
for (auto const& [seq, hash] : hashes)
{
auto const nodeObject = ns.fetchNodeObject(hash);
std::stringstream ss;
ss << "minSeq: " << minSeq << ", maxSeq: " << maxSeq << ", search: " << seq
<< ". Should " << (seq < minSeq ? "NOT " : "") << "be found";
if (seq < minSeq)
BEAST_EXPECTS(!nodeObject, ss.str());
else
BEAST_EXPECTS(nodeObject, ss.str());
}
}
BEAST_EXPECT(maxSeq != lastRotated + deleteInterval);
BEAST_EXPECTS(
env.closed()->header().seq == maxSeq,
failureMessage("maxSeq", maxSeq, env.closed()->header().seq));
BEAST_EXPECTS(
store.getLastRotated() == lastRotated,
failureMessage("lastRotated", lastRotated, store.getLastRotated()));
std::stringstream expectedRange;
expectedRange << minSeq << "-" << maxSeq;
BEAST_EXPECTS(
lm.getCompleteLedgers() == expectedRange.str(),
failureMessage("CompleteLedgers", expectedRange.str(), lm.getCompleteLedgers()));
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq, maxSeq) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 1, maxSeq - 1) == 0);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 1, maxSeq + 1) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 2, maxSeq - 2) == 2);
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 2, maxSeq + 2) == 2);
}
}
void
run() override
{
@@ -777,7 +590,6 @@ public:
testAutomatic();
testCanDelete();
testRotate();
testLedgerGaps();
}
};

View File

@@ -15,13 +15,12 @@
#include <xrpl/protocol/jss.h>
#include <boost/algorithm/string/join.hpp>
#include <boost/filesystem/directory.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <date/date.h>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <memory>
#include <ostream>
@@ -601,7 +600,7 @@ public:
detail::default_effective_overlap,
60 * 24}}); // max of 24 hours
}
using namespace boost::filesystem;
using namespace std::filesystem;
for (auto const& file : directory_iterator(good.subdir()))
{
remove_all(file);

View File

@@ -4,8 +4,7 @@
#include <xrpl/basics/FileUtilities.h>
#include <xrpl/beast/unit_test/suite.h>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/error_code.hpp>
#include <system_error>
namespace xrpl {
@@ -16,14 +15,13 @@ public:
testGetFileContents()
{
using namespace xrpl::detail;
using namespace boost::system;
constexpr char const* expectedContents = "This file is very short. That's all we need.";
FileDirGuard const file(
*this, "test_file", "test.txt", "This is temporary text that should get overwritten");
error_code ec;
std::error_code ec;
auto const path = file.file();
writeFileContents(ec, path, expectedContents);
@@ -46,7 +44,7 @@ public:
{
// Test with small max
auto const bad = getFileContents(ec, path, 16);
BEAST_EXPECT(ec && ec.value() == boost::system::errc::file_too_large);
BEAST_EXPECT(ec && ec == std::errc::file_too_large);
BEAST_EXPECT(bad.empty());
}
}

View File

@@ -15,14 +15,10 @@
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/jss.h>
#include <boost/filesystem/file_status.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/error_code.hpp>
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <ios>
#include <iterator>
@@ -31,6 +27,7 @@
#include <ostream>
#include <random>
#include <string>
#include <system_error>
#include <thread>
#include <utility>
#include <vector>
@@ -43,7 +40,7 @@ class PerfLog_test : public beast::unit_test::suite
{
enum class WithFile : bool { no = false, yes = true };
using path = boost::filesystem::path;
using path = std::filesystem::path;
// We're only using Env for its Journal. That Journal gives better
// coverage in unit tests.
@@ -66,14 +63,14 @@ class PerfLog_test : public beast::unit_test::suite
// The error code is intentionally ignored: if the path doesn't
// exist (the common case on a clean runner) remove_all returns
// an error, and that's fine — there's nothing to clean up.
using namespace boost::filesystem;
boost::system::error_code ec;
using namespace std::filesystem;
std::error_code ec;
remove_all(logDir(), ec);
}
~Fixture()
{
using namespace boost::filesystem;
using namespace std::filesystem;
auto const dir{logDir()};
auto const file{logFile()};
@@ -96,7 +93,7 @@ class PerfLog_test : public beast::unit_test::suite
static path
logDir()
{
using namespace boost::filesystem;
using namespace std::filesystem;
return temp_directory_path() / "perf_log_test_dir";
}
@@ -129,7 +126,7 @@ class PerfLog_test : public beast::unit_test::suite
static void
wait()
{
using namespace boost::filesystem;
using namespace std::filesystem;
auto const path = logFile();
if (!exists(path))
@@ -201,7 +198,7 @@ public:
void
testFileCreation()
{
using namespace boost::filesystem;
using namespace std::filesystem;
{
// Verify a PerfLog creates its file when constructed.
@@ -256,22 +253,23 @@ public:
// Construct and write protect a file to prevent PerfLog
// from creating its file.
boost::system::error_code ec;
boost::filesystem::create_directories(fixture.logDir(), ec);
std::error_code ec;
std::filesystem::create_directories(fixture.logDir(), ec);
if (!BEAST_EXPECT(!ec))
return;
auto fileWriteable = [](boost::filesystem::path const& p) -> bool {
auto fileWriteable = [](std::filesystem::path const& p) -> bool {
return std::ofstream{p.c_str(), std::ios::out | std::ios::app}.is_open();
};
if (!BEAST_EXPECT(fileWriteable(fixture.logFile())))
return;
boost::filesystem::permissions(
std::filesystem::permissions(
fixture.logFile(),
perms::remove_perms | perms::owner_write | perms::others_write |
perms::group_write);
std::filesystem::perms::owner_write | std::filesystem::perms::others_write |
std::filesystem::perms::group_write,
std::filesystem::perm_options::remove);
// If the test is running as root, then the write protect may have
// no effect. Make sure write protect worked before proceeding.
@@ -295,9 +293,11 @@ public:
perfLog->stop();
// Fix file permissions so the file can be cleaned up.
boost::filesystem::permissions(
std::filesystem::permissions(
fixture.logFile(),
perms::add_perms | perms::owner_write | perms::others_write | perms::group_write);
std::filesystem::perms::owner_write | std::filesystem::perms::others_write |
std::filesystem::perms::group_write,
std::filesystem::perm_options::add);
}
}
@@ -962,7 +962,7 @@ public:
// We can't fully test rotate because unit tests must run on Windows,
// and Windows doesn't (may not?) support rotate. But at least call
// the interface and see that it doesn't crash.
using namespace boost::filesystem;
using namespace std::filesystem;
Fixture fixture{env_.app(), j_};
BEAST_EXPECT(!exists(fixture.logDir()));

View File

@@ -10,7 +10,6 @@
#include <xrpl/protocol/SystemParameters.h> // IWYU pragma: keep
#include <xrpl/server/Port.h>
#include <boost/filesystem/operations.hpp>
#include <boost/format.hpp> // IWYU pragma: keep
#include <boost/format/free_funcs.hpp>
#include <boost/lexical_cast/bad_lexical_cast.hpp>
@@ -20,6 +19,7 @@
#include <cstdint>
#include <cstdlib>
#include <exception>
#include <filesystem>
#include <fstream>
#include <optional>
#include <ostream>
@@ -179,7 +179,7 @@ public:
[[nodiscard]] bool
dataDirExists() const
{
return boost::filesystem::is_directory(dataDir_);
return std::filesystem::is_directory(dataDir_);
}
[[nodiscard]] bool
@@ -192,7 +192,7 @@ public:
{
try
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (rmDataDir_)
rmDir(dataDir_);
}
@@ -273,7 +273,7 @@ public:
class Config_test final : public TestSuite
{
private:
using path = boost::filesystem::path;
using path = std::filesystem::path;
public:
void
@@ -309,7 +309,7 @@ port_wss_admin
{
testcase("config_file");
using namespace boost::filesystem;
using namespace std::filesystem;
auto const cwd = current_path();
// Test both config file names.
@@ -425,7 +425,7 @@ port_wss_admin
{
testcase("database_path");
using namespace boost::filesystem;
using namespace std::filesystem;
{
boost::format cc("[database_path]\n%1%\n");
@@ -601,7 +601,7 @@ main
{
testcase("validators_file");
using namespace boost::filesystem;
using namespace std::filesystem;
{
// load should throw for missing specified validators file
boost::format cc("[validators_file]\n%1%\n");

View File

@@ -6,8 +6,6 @@
#include <xrpl/rdb/SociDB.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/optional/optional.hpp>
#include <soci/into.h>
@@ -18,6 +16,7 @@
#include <cstdint>
#include <cstring>
#include <exception>
#include <filesystem>
#include <iterator>
#include <limits>
#include <stdexcept>
@@ -30,7 +29,7 @@ class SociDB_test final : public TestSuite
{
private:
static void
setupSQLiteConfig(BasicConfig& config, boost::filesystem::path const& dbPath)
setupSQLiteConfig(BasicConfig& config, std::filesystem::path const& dbPath)
{
config.overwrite("sqdb", "backend", "sqlite");
auto value = dbPath.string();
@@ -39,18 +38,18 @@ private:
}
static void
cleanupDatabaseDir(boost::filesystem::path const& dbPath)
cleanupDatabaseDir(std::filesystem::path const& dbPath)
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (!exists(dbPath) || !is_directory(dbPath) || !is_empty(dbPath))
return;
remove(dbPath);
}
static void
setupDatabaseDir(boost::filesystem::path const& dbPath)
setupDatabaseDir(std::filesystem::path const& dbPath)
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (!exists(dbPath))
{
create_directory(dbPath);
@@ -63,10 +62,10 @@ private:
Throw<std::runtime_error>("Cannot create directory: " + dbPath.string());
}
}
static boost::filesystem::path
static std::filesystem::path
getDatabasePath()
{
return boost::filesystem::current_path() / "socidb_test_databases";
return std::filesystem::current_path() / "socidb_test_databases";
}
public:
@@ -156,7 +155,7 @@ public:
checkValues(s);
}
{
namespace bfs = boost::filesystem;
namespace bfs = std::filesystem;
// Remove the database
bfs::path const dbPath(sc.connectionString());
if (bfs::is_regular_file(dbPath))
@@ -286,7 +285,7 @@ public:
#endif
}
{
namespace bfs = boost::filesystem;
namespace bfs = std::filesystem;
// Remove the database
bfs::path const dbPath(sc.connectionString());
if (bfs::is_regular_file(dbPath))
@@ -338,7 +337,7 @@ public:
s << "SELECT LedgerSeq FROM Ledgers;", soci::into(ledgersLS);
BEAST_EXPECT(ledgersLS.size() == numRows);
}
namespace bfs = boost::filesystem;
namespace bfs = std::filesystem;
// Remove the database
bfs::path const dbPath(sc.connectionString());
if (bfs::is_regular_file(dbPath))

View File

@@ -56,17 +56,6 @@ envconfig(F&& modfunc, Args&&... args)
return modfunc(envconfig(), std::forward<Args>(args)...);
}
/// @brief adjust config to enable online_delete
///
/// @param cfg config instance to be modified
///
/// @param deleteInterval how many new ledgers should be available before
/// rotating. Defaults to 8, because the standalone minimum is 8.
///
/// @return unique_ptr to Config instance
std::unique_ptr<Config>
online_delete(std::unique_ptr<Config> cfg, std::uint32_t deleteInterval = 8);
/// @brief adjust config so no admin ports are enabled
///
/// this is intended for use with envconfig, as in

View File

@@ -6,10 +6,8 @@
#include <xrpld/core/ConfigSections.h>
#include <atomic>
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <vector>
namespace xrpl::test {
@@ -61,15 +59,6 @@ setupConfigForUnitTests(Config& cfg)
namespace jtx {
std::unique_ptr<Config>
online_delete(std::unique_ptr<Config> cfg, std::uint32_t deleteInterval)
{
cfg->LEDGER_HISTORY = deleteInterval;
auto& section = cfg->section(ConfigSection::nodeDatabase());
section.set("online_delete", std::to_string(deleteInterval));
return cfg;
}
std::unique_ptr<Config>
no_admin(std::unique_ptr<Config> cfg)
{

View File

@@ -4,8 +4,7 @@
#include <xrpl/basics/contract.h>
#include <boost/filesystem.hpp>
#include <filesystem>
#include <fstream>
namespace xrpl::detail {
@@ -16,7 +15,7 @@ namespace xrpl::detail {
class DirGuard
{
protected:
using path = boost::filesystem::path;
using path = std::filesystem::path;
private:
path subDir_;
@@ -43,7 +42,7 @@ public:
DirGuard(beast::unit_test::suite& test, path subDir, bool useCounter = true)
: subDir_(std::move(subDir)), test_(test)
{
using namespace boost::filesystem;
using namespace std::filesystem;
static auto subDirCounter = 0;
if (useCounter)
@@ -69,7 +68,7 @@ public:
{
try
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (rmSubDir_)
rmDir(subDir_);
@@ -126,7 +125,7 @@ public:
{
try
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (exists(file_))
{
remove(file_);
@@ -156,7 +155,7 @@ public:
[[nodiscard]] bool
fileExists() const
{
return boost::filesystem::exists(file_);
return std::filesystem::exists(file_);
}
};

View File

@@ -105,10 +105,7 @@ public:
failedSave(std::uint32_t seq, uint256 const& hash);
std::string
getCompleteLedgers() const;
std::size_t
missingFromCompleteLedgerRange(LedgerIndex first, LedgerIndex last) const;
getCompleteLedgers();
/** Apply held transactions to the open ledger
This is normally called as we close the ledger.
@@ -325,7 +322,7 @@ private:
// A set of transactions to replay during the next close
std::unique_ptr<LedgerReplay> replayData;
std::recursive_mutex mutable mCompleteLock;
std::recursive_mutex mCompleteLock;
RangeSet<std::uint32_t> mCompleteLedgers;
// Publish thread is running.

View File

@@ -1570,34 +1570,12 @@ LedgerMaster::getPublishedLedger()
}
std::string
LedgerMaster::getCompleteLedgers() const
LedgerMaster::getCompleteLedgers()
{
std::lock_guard const sl(mCompleteLock);
return to_string(mCompleteLedgers);
}
std::size_t
LedgerMaster::missingFromCompleteLedgerRange(LedgerIndex first, LedgerIndex last) const
{
// Make a copy of the range to avoid holding the lock
auto const range = [&] {
std::lock_guard const sl(mCompleteLock);
return mCompleteLedgers;
}();
std::size_t missing = 0;
for (LedgerIndex idx = first; idx <= last; ++idx)
{
if (!boost::icl::contains(range, idx))
{
++missing;
}
}
return missing;
}
std::optional<NetClock::time_point>
LedgerMaster::getCloseTimeBySeq(LedgerIndex ledgerIndex)
{

View File

@@ -78,9 +78,11 @@
#include <xrpl/protocol/ApiVersion.h>
#include <xrpl/protocol/BuildInfo.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/SystemParameters.h>
#include <xrpl/protocol/jss.h>
#include <xrpl/rdb/DatabaseCon.h>
#include <xrpl/resource/Charge.h>

View File

@@ -48,6 +48,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
@@ -613,7 +614,7 @@ GRPCServerImpl::createServerCredentials()
try
{
boost::system::error_code ec;
std::error_code ec;
grpc::SslServerCredentialsOptions sslOpts;
grpc::SslServerCredentialsOptions::PemKeyCertPair keyCertPair;

View File

@@ -8,6 +8,7 @@
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Fees.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/STValidation.h>

View File

@@ -24,19 +24,23 @@
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/directory.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <iomanip>
#include <ios>
#include <limits>
#include <memory>
#include <mutex>
#include <optional>
#include <random>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <thread>
#include <utility>
#include <vector>
@@ -292,17 +296,6 @@ SHAMapStoreImp::run()
bool const readyToRotate = validatedSeq >= lastRotated + deleteInterval_ &&
canDelete_ >= lastRotated - 1 && healthWait() == keepGoing;
JLOG(journal_.debug()) << "run: Setting lastGoodValidatedLedger_ to " << validatedSeq;
{
// Note that this is set after the healthWait() check, so that we
// don't start the rotation until the validated ledger is fully
// processed. It is not guaranteed to be done at this point. It also
// allows the testLedgerGaps unit test to work.
std::unique_lock<std::mutex> const lock(mutex_);
lastGoodValidatedLedger_ = validatedSeq;
}
// will delete up to (not including) lastRotated
if (readyToRotate)
{
@@ -310,8 +303,7 @@ SHAMapStoreImp::run()
<< lastRotated << " deleteInterval " << deleteInterval_
<< " canDelete_ " << canDelete_ << " state "
<< app_.getOPs().strOperatingMode(false) << " age "
<< ledgerMaster_->getValidatedLedgerAge().count()
<< "s. Complete ledgers: " << ledgerMaster_->getCompleteLedgers();
<< ledgerMaster_->getValidatedLedgerAge().count() << 's';
clearPrior(lastRotated);
if (healthWait() == stopping)
@@ -357,13 +349,7 @@ SHAMapStoreImp::run()
if (healthWait() == stopping)
return;
// 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;
lastRotated = validatedSeq;
dbRotating_->rotate(
std::move(newBackend),
@@ -377,9 +363,7 @@ SHAMapStoreImp::run()
clearCaches(validatedSeq);
});
JLOG(journal_.warn()) << "finished rotation. validatedSeq: " << validatedSeq
<< ", lastRotated: " << lastRotated
<< ". Complete ledgers: " << ledgerMaster_->getCompleteLedgers();
JLOG(journal_.warn()) << "finished rotation " << validatedSeq;
}
}
}
@@ -388,11 +372,11 @@ void
SHAMapStoreImp::dbPaths()
{
Section const section{app_.config().section(ConfigSection::nodeDatabase())};
boost::filesystem::path dbPath = get(section, "path");
std::filesystem::path dbPath = get(section, "path");
if (boost::filesystem::exists(dbPath))
if (std::filesystem::exists(dbPath))
{
if (!boost::filesystem::is_directory(dbPath))
if (!std::filesystem::is_directory(dbPath))
{
journal_.error() << "node db path must be a directory. " << dbPath.string();
Throw<std::runtime_error>("node db path must be a directory.");
@@ -400,7 +384,7 @@ SHAMapStoreImp::dbPaths()
}
else
{
boost::filesystem::create_directories(dbPath);
std::filesystem::create_directories(dbPath);
}
SavedState state = state_db_.getState();
@@ -411,8 +395,8 @@ SHAMapStoreImp::dbPaths()
return false;
// Check if configured "path" matches stored directory path
using namespace boost::filesystem;
auto const stored{path(sPath)};
using namespace std::filesystem;
auto const stored{std::filesystem::path(sPath)};
if (stored.parent_path() == dbPath)
return false;
@@ -430,9 +414,9 @@ SHAMapStoreImp::dbPaths()
bool writableDbExists = false;
bool archiveDbExists = false;
std::vector<boost::filesystem::path> pathsToDelete;
for (boost::filesystem::directory_iterator it(dbPath);
it != boost::filesystem::directory_iterator();
std::vector<std::filesystem::path> pathsToDelete;
for (std::filesystem::directory_iterator it(dbPath);
it != std::filesystem::directory_iterator();
++it)
{
if (state.writableDb.compare(it->path().string()) == 0)
@@ -453,7 +437,7 @@ SHAMapStoreImp::dbPaths()
(!archiveDbExists && !state.archiveDb.empty()) || (writableDbExists != archiveDbExists) ||
state.writableDb.empty() != state.archiveDb.empty())
{
boost::filesystem::path stateDbPathName = app_.config().legacy("database_path");
std::filesystem::path stateDbPathName = app_.config().legacy("database_path");
stateDbPathName /= dbName_;
stateDbPathName += "*";
@@ -475,15 +459,15 @@ SHAMapStoreImp::dbPaths()
}
// The necessary directories exist. Now, remove any others.
for (boost::filesystem::path const& p : pathsToDelete)
boost::filesystem::remove_all(p);
for (std::filesystem::path const& p : pathsToDelete)
std::filesystem::remove_all(p);
}
std::unique_ptr<NodeStore::Backend>
SHAMapStoreImp::makeBackendRotating(std::string path)
{
Section section{app_.config().section(ConfigSection::nodeDatabase())};
boost::filesystem::path newPath;
std::filesystem::path newPath;
if (!path.empty())
{
@@ -491,10 +475,24 @@ SHAMapStoreImp::makeBackendRotating(std::string path)
}
else
{
boost::filesystem::path p = get(section, "path");
p /= dbPrefix_;
p += ".%%%%";
newPath = boost::filesystem::unique_path(p);
std::filesystem::path const p = get(section, "path");
std::random_device rd;
constexpr std::size_t maxAttempts = 100;
for (std::size_t attempt = 0; attempt < maxAttempts; ++attempt)
{
std::ostringstream oss;
oss << std::hex << std::setfill('0') << std::setw(8) << rd() << std::setw(8) << rd();
auto const candidate =
std::filesystem::path((p / dbPrefix_).string() + "." + oss.str());
std::error_code existsEc;
if (!std::filesystem::exists(candidate, existsEc) && !existsEc)
{
newPath = candidate;
break;
}
}
if (newPath.empty())
Throw<std::runtime_error>("Unable to generate a unique rotating backend path");
}
section.set("path", newPath.string());
@@ -619,41 +617,22 @@ SHAMapStoreImp::clearPrior(LedgerIndex lastRotated)
SHAMapStoreImp::HealthResult
SHAMapStoreImp::healthWait()
{
auto index = ledgerMaster_->getValidLedgerIndex();
auto age = ledgerMaster_->getValidatedLedgerAge();
OperatingMode mode = netOPs_->getOperatingMode();
std::unique_lock lock(mutex_);
auto numMissing =
ledgerMaster_->missingFromCompleteLedgerRange(lastGoodValidatedLedger_, index);
while (!stop_ && (mode != OperatingMode::FULL || age > ageThreshold_ || numMissing > 0))
while (!stop_ && (mode != OperatingMode::FULL || age > ageThreshold_))
{
// this value shouldn't change, so grab it while we have the
// lock
auto const lowerBound = lastGoodValidatedLedger_;
lock.unlock();
auto const stream =
mode != OperatingMode::FULL || age > ageThreshold_ ? journal_.warn() : journal_.info();
JLOG(stream) << "Waiting " << recoveryWaitTime_.count()
<< "s for node to stabilize. state: "
<< app_.getOPs().strOperatingMode(mode, false) << ". age " << age.count()
<< "s. Missing ledgers: " << numMissing << ". Expect: " << lowerBound << "-"
<< index << ". Complete ledgers: " << ledgerMaster_->getCompleteLedgers();
JLOG(journal_.warn()) << "Waiting " << recoveryWaitTime_.count()
<< "s for node to stabilize. state: "
<< app_.getOPs().strOperatingMode(mode, false) << ". age "
<< age.count() << 's';
std::this_thread::sleep_for(recoveryWaitTime_);
index = ledgerMaster_->getValidLedgerIndex();
age = ledgerMaster_->getValidatedLedgerAge();
mode = netOPs_->getOperatingMode();
numMissing =
lowerBound == 0 ? 0 : ledgerMaster_->missingFromCompleteLedgerRange(lowerBound, index);
lock.lock();
}
JLOG(journal_.debug()) << "healthWait: Setting lastGoodValidatedLedger_ to " << index;
lastGoodValidatedLedger_ = index;
return stop_ ? stopping : keepGoing;
}

View File

@@ -70,11 +70,6 @@ private:
std::thread thread_;
bool stop_ = false;
bool healthy_ = true;
// Used to prevent ledger gaps from forming during online deletion. Keeps
// track of the last validated ledger that was processed without gaps. There
// are no guarantees about gaps while online delete is not running. For
// that, use advisory_delete and check for gaps externally.
LedgerIndex lastGoodValidatedLedger_ = 0;
mutable std::condition_variable cond_;
mutable std::condition_variable rendezvous_;
mutable std::mutex mutex_;
@@ -88,11 +83,11 @@ private:
std::uint32_t deleteBatch_ = 100;
std::chrono::milliseconds backOff_{100};
std::chrono::seconds ageThreshold_{60};
/// If the node is out of sync, or any recent ledgers are not
/// available during an online_delete healthWait() call, sleep
/// the thread for this time, and continue checking until recovery.
/// If the node is out of sync during an online_delete healthWait()
/// call, sleep the thread for this time, and continue checking until
/// recovery.
/// See also: "recovery_wait_seconds" in xrpld-example.cfg
std::chrono::seconds recoveryWaitTime_{1};
std::chrono::seconds recoveryWaitTime_{5};
// these do not exist upon SHAMapStore creation, but do exist
// as of run() or before
@@ -209,8 +204,6 @@ private:
enum HealthResult { stopping, keepGoing };
[[nodiscard]] HealthResult
healthWait();
bool
hasCompleteRange(LedgerIndex first, LedgerIndex last);
public:
void

View File

@@ -12,6 +12,7 @@
#include <boost/thread/shared_mutex.hpp>
#include <filesystem>
#include <mutex>
#include <shared_mutex>
@@ -204,7 +205,7 @@ class ValidatorList
ManifestCache& validatorManifests_;
ManifestCache& publisherManifests_;
TimeKeeper& timeKeeper_;
boost::filesystem::path const dataPath_;
std::filesystem::path const dataPath_;
beast::Journal const j_;
std::shared_mutex mutable mutex_;
using lock_guard = std::lock_guard<decltype(mutex_)>;
@@ -803,7 +804,7 @@ private:
/** Get the filename used for caching UNLs
*/
boost::filesystem::path
std::filesystem::path
getCacheFileName(lock_guard const&, PublicKey const& pubKey) const;
/** Build a Json representation of the collection, suitable for

View File

@@ -29,12 +29,8 @@
#include <xrpl/server/Manifest.h>
#include <xrpl/server/NetworkOPs.h>
#include <boost/filesystem/operations.hpp>
#include <boost/regex/v5/regex.hpp>
#include <boost/regex/v5/regex_match.hpp>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/errc.hpp>
#include <xrpl.pb.h>
@@ -43,6 +39,7 @@
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <iterator>
#include <limits>
@@ -54,6 +51,7 @@
#include <shared_mutex>
#include <string>
#include <string_view>
#include <system_error>
#include <utility>
#include <vector>
@@ -288,7 +286,7 @@ ValidatorList::load(
return true;
}
boost::filesystem::path
std::filesystem::path
ValidatorList::getCacheFileName(ValidatorList::lock_guard const&, PublicKey const& pubKey) const
{
return dataPath_ / (filePrefix_ + strHex(pubKey));
@@ -372,9 +370,9 @@ ValidatorList::cacheValidatorFile(ValidatorList::lock_guard const& lock, PublicK
if (dataPath_.empty())
return;
boost::filesystem::path const filename = getCacheFileName(lock, pubKey);
std::filesystem::path const filename = getCacheFileName(lock, pubKey);
boost::system::error_code ec;
std::error_code ec;
Json::Value value = buildFileData(strHex(pubKey), publisherLists_.at(pubKey), j_);
// xrpld should be the only process writing to this file, so
@@ -1283,8 +1281,7 @@ std::vector<std::string>
ValidatorList::loadLists()
{
using namespace std::string_literals;
using namespace boost::filesystem;
using namespace boost::system::errc;
using namespace std::filesystem;
std::lock_guard const lock{mutex_};
@@ -1292,12 +1289,12 @@ ValidatorList::loadLists()
sites.reserve(publisherLists_.size());
for (auto const& [pubKey, publisherCollection] : publisherLists_)
{
boost::system::error_code ec;
std::error_code ec;
if (publisherCollection.status == PublisherStatus::available)
continue;
boost::filesystem::path const filename = getCacheFileName(lock, pubKey);
std::filesystem::path const filename = getCacheFileName(lock, pubKey);
auto const fullPath{canonical(filename, ec)};
if (ec)
@@ -1308,7 +1305,7 @@ ValidatorList::loadLists()
{
// Treat an empty file as a missing file, because
// nobody else is going to write it.
ec = make_error_code(no_such_file_or_directory);
ec = make_error_code(std::errc::no_such_file_or_directory);
}
if (ec)
continue;

View File

@@ -37,10 +37,8 @@
#include <xrpl/rdb/RelationalDatabase.h>
#include <xrpl/rdb/SociDB.h>
#include <boost/filesystem/operations.hpp>
#include <boost/format/free_funcs.hpp>
#include <boost/optional/optional.hpp>
#include <boost/system/detail/error_code.hpp>
#include <soci/blob.h>
#include <soci/into.h>
@@ -53,6 +51,7 @@
#include <cstddef>
#include <cstdint>
#include <exception>
#include <filesystem>
#include <functional>
#include <limits>
#include <map>
@@ -61,6 +60,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
#include <variant>
#include <vector>
@@ -1290,8 +1290,8 @@ getTransaction(
bool
dbHasSpace(soci::session& session, Config const& config, beast::Journal j)
{
boost::filesystem::space_info const space =
boost::filesystem::space(config.legacy("database_path"));
std::filesystem::space_info const space =
std::filesystem::space(config.legacy("database_path"));
if (space.available < megabytes(512))
{
@@ -1302,9 +1302,9 @@ dbHasSpace(soci::session& session, Config const& config, beast::Journal j)
if (config.useTxTables())
{
DatabaseCon::Setup const dbSetup = setup_DatabaseCon(config);
boost::filesystem::path const dbPath = dbSetup.dataDir / TxDBName;
boost::system::error_code ec;
std::optional<std::uint64_t> dbSize = boost::filesystem::file_size(dbPath, ec);
std::filesystem::path const dbPath = dbSetup.dataDir / TxDBName;
std::error_code ec;
std::optional<std::uint64_t> dbSize = std::filesystem::file_size(dbPath, ec);
if (ec)
{
JLOG(j.error()) << "Error checking transaction db file size: " << ec.message();

View File

@@ -9,9 +9,8 @@
#include <xrpl/protocol/SystemParameters.h> // VFALCO Breaks levelization
#include <xrpl/rdb/DatabaseCon.h>
#include <boost/filesystem.hpp> // VFALCO FIX: This include should not be here
#include <cstdint>
#include <filesystem>
#include <optional>
#include <string>
#include <unordered_set>
@@ -82,17 +81,17 @@ public:
static char const* const validatorsFileName;
/** Returns the full path and filename of the debug log file. */
[[nodiscard]] boost::filesystem::path
[[nodiscard]] std::filesystem::path
getDebugLogFile() const;
private:
boost::filesystem::path CONFIG_FILE;
std::filesystem::path CONFIG_FILE;
public:
boost::filesystem::path CONFIG_DIR;
std::filesystem::path CONFIG_DIR;
private:
boost::filesystem::path DEBUG_LOGFILE;
std::filesystem::path DEBUG_LOGFILE;
void
load();

View File

@@ -22,21 +22,19 @@
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/format/free_funcs.hpp>
#include <boost/multiprecision/detail/endian.hpp>
#include <boost/predef.h>
#include <boost/regex.hpp> // IWYU pragma: keep
#include <boost/regex/v5/regex.hpp>
#include <boost/regex/v5/regex_match.hpp>
#include <boost/system/detail/error_code.hpp>
#include <algorithm>
#include <array>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <filesystem>
#include <iostream>
#include <iterator>
#include <limits>
@@ -46,6 +44,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <thread>
#include <type_traits>
#include <utility>
@@ -313,13 +312,13 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
// directory, use the current working directory as the
// config directory and that with "db" as the data
// directory.
boost::filesystem::path dataDir;
std::filesystem::path dataDir;
if (!strConf.empty())
{
// --conf=<path> : everything is relative that file.
CONFIG_FILE = strConf;
CONFIG_DIR = boost::filesystem::absolute(CONFIG_FILE);
CONFIG_DIR = std::filesystem::absolute(CONFIG_FILE);
CONFIG_DIR.remove_filename();
dataDir = CONFIG_DIR / databaseDirName;
}
@@ -330,13 +329,13 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
// Check if either of the config files exist in the current working
// directory, in which case the databases will be stored in a
// subdirectory.
CONFIG_DIR = boost::filesystem::current_path();
CONFIG_DIR = std::filesystem::current_path();
dataDir = CONFIG_DIR / databaseDirName;
CONFIG_FILE = CONFIG_DIR / configFileName;
if (boost::filesystem::exists(CONFIG_FILE))
if (std::filesystem::exists(CONFIG_FILE))
break;
CONFIG_FILE = CONFIG_DIR / configLegacyName;
if (boost::filesystem::exists(CONFIG_FILE))
if (std::filesystem::exists(CONFIG_FILE))
break;
// Check if the home directory is set, and optionally the XDG config
@@ -363,10 +362,10 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
dataDir = strXdgDataHome + "/" + systemName();
CONFIG_DIR = strXdgConfigHome + "/" + systemName();
CONFIG_FILE = CONFIG_DIR / configFileName;
if (boost::filesystem::exists(CONFIG_FILE))
if (std::filesystem::exists(CONFIG_FILE))
break;
CONFIG_FILE = CONFIG_DIR / configLegacyName;
if (boost::filesystem::exists(CONFIG_FILE))
if (std::filesystem::exists(CONFIG_FILE))
break;
}
@@ -374,7 +373,7 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
dataDir = "/var/opt/" + systemName();
CONFIG_DIR = "/etc/opt/" + systemName();
CONFIG_FILE = CONFIG_DIR / configFileName;
if (boost::filesystem::exists(CONFIG_FILE))
if (std::filesystem::exists(CONFIG_FILE))
break;
CONFIG_FILE = CONFIG_DIR / configLegacyName;
} while (false);
@@ -387,7 +386,7 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
std::string const dbPath(legacy("database_path"));
if (!dbPath.empty())
{
dataDir = boost::filesystem::path(dbPath);
dataDir = std::filesystem::path(dbPath);
}
else if (RUN_STANDALONE)
{
@@ -397,13 +396,13 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
if (!dataDir.empty())
{
boost::system::error_code ec;
boost::filesystem::create_directories(dataDir, ec);
std::error_code ec;
std::filesystem::create_directories(dataDir, ec);
if (ec)
Throw<std::runtime_error>(boost::str(boost::format("Can not create %s") % dataDir));
legacy("database_path", boost::filesystem::absolute(dataDir).string());
legacy("database_path", std::filesystem::absolute(dataDir).string());
}
HTTPClient::initializeSSLContext(
@@ -456,7 +455,7 @@ Config::load()
if (!QUIET)
std::cerr << "Loading: " << CONFIG_FILE << "\n";
boost::system::error_code ec;
std::error_code ec;
auto const fileContents = getFileContents(ec, CONFIG_FILE);
if (ec)
@@ -509,8 +508,8 @@ Config::loadFromString(std::string const& fileContents)
std::string dbPath;
if (getSingleSection(secConfig, "database_path", dbPath, j_))
{
boost::filesystem::path const p(dbPath);
legacy("database_path", boost::filesystem::absolute(p).string());
std::filesystem::path const p(dbPath);
legacy("database_path", std::filesystem::absolute(p).string());
}
}
@@ -953,7 +952,7 @@ Config::loadFromString(std::string const& fileContents)
// If no path was specified, then look for validators.txt
// in the same directory as the config file, but don't complain
// if we can't find it.
boost::filesystem::path validatorsFile;
std::filesystem::path validatorsFile;
if (getSingleSection(secConfig, SECTION_VALIDATORS_FILE, strTemp, j_))
{
@@ -968,7 +967,7 @@ Config::loadFromString(std::string const& fileContents)
if (!validatorsFile.is_absolute() && !CONFIG_DIR.empty())
validatorsFile = CONFIG_DIR / validatorsFile;
if (!boost::filesystem::exists(validatorsFile))
if (!std::filesystem::exists(validatorsFile))
{
Throw<std::runtime_error>(
"The file specified in [" SECTION_VALIDATORS_FILE
@@ -977,8 +976,8 @@ Config::loadFromString(std::string const& fileContents)
validatorsFile.string());
}
else if (
!boost::filesystem::is_regular_file(validatorsFile) &&
!boost::filesystem::is_symlink(validatorsFile))
!std::filesystem::is_regular_file(validatorsFile) &&
!std::filesystem::is_symlink(validatorsFile))
{
Throw<std::runtime_error>(
"Invalid file specified in [" SECTION_VALIDATORS_FILE "]: " +
@@ -991,24 +990,24 @@ Config::loadFromString(std::string const& fileContents)
if (!validatorsFile.empty())
{
if (!boost::filesystem::exists(validatorsFile))
if (!std::filesystem::exists(validatorsFile))
{
validatorsFile.clear();
}
else if (
!boost::filesystem::is_regular_file(validatorsFile) &&
!boost::filesystem::is_symlink(validatorsFile))
!std::filesystem::is_regular_file(validatorsFile) &&
!std::filesystem::is_symlink(validatorsFile))
{
validatorsFile.clear();
}
}
}
if (!validatorsFile.empty() && boost::filesystem::exists(validatorsFile) &&
(boost::filesystem::is_regular_file(validatorsFile) ||
boost::filesystem::is_symlink(validatorsFile)))
if (!validatorsFile.empty() && std::filesystem::exists(validatorsFile) &&
(std::filesystem::is_regular_file(validatorsFile) ||
std::filesystem::is_symlink(validatorsFile)))
{
boost::system::error_code ec;
std::error_code ec;
auto const data = getFileContents(ec, validatorsFile);
if (ec)
{
@@ -1134,7 +1133,7 @@ Config::loadFromString(std::string const& fileContents)
}
}
boost::filesystem::path
std::filesystem::path
Config::getDebugLogFile() const
{
auto log_file = DEBUG_LOGFILE;
@@ -1143,17 +1142,17 @@ Config::getDebugLogFile() const
{
// Unless an absolute path for the log file is specified, the
// path is relative to the config file directory.
log_file = boost::filesystem::absolute(log_file, CONFIG_DIR);
log_file = CONFIG_DIR / log_file;
}
if (!log_file.empty())
{
auto log_dir = log_file.parent_path();
if (!boost::filesystem::is_directory(log_dir))
if (!std::filesystem::is_directory(log_dir))
{
boost::system::error_code ec;
boost::filesystem::create_directories(log_dir, ec);
std::error_code ec;
std::filesystem::create_directories(log_dir, ec);
// If we fail, we warn but continue so that the calling code can
// decide how to handle this situation.

View File

@@ -13,11 +13,9 @@
#include <xrpl/json/json_writer.h>
#include <xrpl/protocol/jss.h>
#include <boost/filesystem/operations.hpp>
#include <boost/system/detail/error_code.hpp>
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <ios>
#include <memory>
@@ -25,6 +23,7 @@
#include <ostream>
#include <set>
#include <string>
#include <system_error>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -216,10 +215,10 @@ PerfLogImp::openLog()
logFile_.close();
auto logDir = setup_.perfLog.parent_path();
if (!boost::filesystem::is_directory(logDir))
if (!std::filesystem::is_directory(logDir))
{
boost::system::error_code ec;
boost::filesystem::create_directories(logDir, ec);
std::error_code ec;
std::filesystem::create_directories(logDir, ec);
if (ec)
{
JLOG(j_.fatal()) << "Unable to create performance log "
@@ -474,17 +473,17 @@ PerfLogImp::stop()
//-----------------------------------------------------------------------------
PerfLog::Setup
setup_PerfLog(Section const& section, boost::filesystem::path const& configDir)
setup_PerfLog(Section const& section, std::filesystem::path const& configDir)
{
PerfLog::Setup setup;
std::string perfLog;
set(perfLog, "perf_log", section);
if (!perfLog.empty())
{
setup.perfLog = boost::filesystem::path(perfLog);
setup.perfLog = std::filesystem::path(perfLog);
if (setup.perfLog.is_relative())
{
setup.perfLog = boost::filesystem::absolute(setup.perfLog, configDir);
setup.perfLog = configDir / setup.perfLog;
}
}