diff --git a/.clang-format b/.clang-format index bd853278..5f7c0259 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,7 @@ --- Language: Cpp AccessModifierOffset: -4 -AlignAfterOpenBracket: AlwaysBreak +AlignAfterOpenBracket: BlockIndent AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlinesLeft: true @@ -18,20 +18,8 @@ AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: true BinPackArguments: false BinPackParameters: false -BraceWrapping: - AfterClass: true - AfterControlStatement: true - AfterEnum: false - AfterFunction: true - AfterNamespace: false - AfterObjCDeclaration: true - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true - IndentBraces: false BreakBeforeBinaryOperators: false -BreakBeforeBraces: Custom +BreakBeforeBraces: WebKit BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: true ColumnLimit: 120 @@ -43,6 +31,7 @@ Cpp11BracedListStyle: true DerivePointerAlignment: false DisableFormat: false ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true ForEachMacros: [ Q_FOREACH, BOOST_FOREACH ] IncludeCategories: - Regex: '^<(BeastConfig)' @@ -58,6 +47,8 @@ IndentCaseLabels: true IndentFunctionDeclarationAfterType: false IndentWidth: 4 IndentWrappedFunctionNames: false +IndentRequiresClause: true +RequiresClausePosition: OwnLine KeepEmptyLinesAtTheStartOfBlocks: false MaxEmptyLinesToKeep: 1 NamespaceIndentation: None @@ -70,6 +61,7 @@ PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Left +QualifierAlignment: Right ReflowComments: true SortIncludes: true SpaceAfterCStyleCast: false diff --git a/.githooks/pre-commit b/.githooks/pre-commit index e7e6df17..e541c4da 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -4,7 +4,21 @@ exec 1>&2 # paths to check and re-format sources="src unittests" -formatter="clang-format-11 -i" +formatter="clang-format -i" +version=$($formatter --version | awk -F'[[:space:]]' '{print $4}') + +if [[ "16.0.0" > "$version" ]]; then + cat <<\EOF + + ERROR +----------------------------------------------------------------------------- + A minimum of version 16 of `clang-format` is required. + Please fix paths and run again. +----------------------------------------------------------------------------- + +EOF + exit 2 +fi first=$(git diff $sources) find $sources -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.ipp' \) -print0 | xargs -0 $formatter diff --git a/.github/actions/clang_format/action.yml b/.github/actions/clang_format/action.yml index 031c846e..8f109049 100644 --- a/.github/actions/clang_format/action.yml +++ b/.github/actions/clang_format/action.yml @@ -1,11 +1,23 @@ name: Check format -description: Check format using clang-format-11 +description: Check format using clang-format-16 runs: using: composite steps: - # Github's ubuntu-20.04 image already has clang-format-11 installed - - run: | - find src unittests -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.ipp' \) -print0 | xargs -0 clang-format-11 -i + - name: Add llvm repo + run: | + echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main' | sudo tee -a /etc/apt/sources.list + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + shell: bash + + - name: Install packages + run: | + sudo apt update -qq + sudo apt install -y jq clang-format-16 + shell: bash + + - name: Run formatter + run: | + find src unittests -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.ipp' \) -print0 | xargs -0 clang-format-16 -i shell: bash - name: Check for differences diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a098f2c..ccaa0977 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,7 +91,7 @@ The button for that is near the bottom of the PR's page on GitHub. This is a non-exhaustive list of recommended style guidelines. These are not always strictly enforced and serve as a way to keep the codebase coherent. ## Formatting -Code must conform to `clang-format` version 10, unless the result would be unreasonably difficult to read or maintain. +Code must conform to `clang-format` version 16, unless the result would be unreasonably difficult to read or maintain. To change your code to conform use `clang-format -i `. ## Avoid diff --git a/src/data/BackendCounters.cpp b/src/data/BackendCounters.cpp index 12f37e4c..d38901ee 100644 --- a/src/data/BackendCounters.cpp +++ b/src/data/BackendCounters.cpp @@ -24,9 +24,7 @@ namespace data { BackendCounters::PtrType BackendCounters::make() { - struct EnableMakeShared : public BackendCounters - { - }; + struct EnableMakeShared : public BackendCounters {}; return std::make_shared(); } diff --git a/src/data/BackendCounters.h b/src/data/BackendCounters.h index 6243a98f..2a7cb688 100644 --- a/src/data/BackendCounters.h +++ b/src/data/BackendCounters.h @@ -52,8 +52,7 @@ concept SomeBackendCounters = requires(T a) { * @brief Holds statistics about the backend. * @note This class is thread-safe. */ -class BackendCounters -{ +class BackendCounters { public: using PtrType = std::shared_ptr; @@ -96,8 +95,7 @@ public: private: BackendCounters() = default; - class AsyncOperationCounters - { + class AsyncOperationCounters { public: AsyncOperationCounters(std::string name); diff --git a/src/data/BackendFactory.h b/src/data/BackendFactory.h index 00e4f63b..8adb5b1a 100644 --- a/src/data/BackendFactory.h +++ b/src/data/BackendFactory.h @@ -46,8 +46,7 @@ make_Backend(util::Config const& config) std::shared_ptr backend = nullptr; // TODO: retire `cassandra-new` by next release after 2.0 - if (boost::iequals(type, "cassandra") or boost::iequals(type, "cassandra-new")) - { + if (boost::iequals(type, "cassandra") or boost::iequals(type, "cassandra-new")) { auto cfg = config.section("database." + type); backend = std::make_shared(data::cassandra::SettingsProvider{cfg}, readOnly); } @@ -56,8 +55,7 @@ make_Backend(util::Config const& config) throw std::runtime_error("Invalid database type"); auto const rng = backend->hardFetchLedgerRangeNoThrow(); - if (rng) - { + if (rng) { backend->updateRange(rng->minSequence); backend->updateRange(rng->maxSequence); } diff --git a/src/data/BackendInterface.cpp b/src/data/BackendInterface.cpp index ac909cb9..0be08179 100644 --- a/src/data/BackendInterface.cpp +++ b/src/data/BackendInterface.cpp @@ -34,8 +34,7 @@ BackendInterface::finishWrites(std::uint32_t const ledgerSequence) { LOG(gLog.debug()) << "Want finish writes for " << ledgerSequence; auto commitRes = doFinishWrites(); - if (commitRes) - { + if (commitRes) { LOG(gLog.debug()) << "Successfully commited. Updating range now to " << ledgerSequence; updateRange(ledgerSequence); } @@ -59,23 +58,20 @@ std::optional BackendInterface::fetchLedgerObject( ripple::uint256 const& key, std::uint32_t const sequence, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { auto obj = cache_.get(key, sequence); - if (obj) - { + if (obj) { LOG(gLog.trace()) << "Cache hit - " << ripple::strHex(key); return *obj; } LOG(gLog.trace()) << "Cache miss - " << ripple::strHex(key); auto dbObj = doFetchLedgerObject(key, sequence, yield); - if (!dbObj) - { + if (!dbObj) { LOG(gLog.trace()) << "Missed cache and missed in db"; - } - else - { + } else { LOG(gLog.trace()) << "Missed cache but found in db"; } return dbObj; @@ -85,32 +81,26 @@ std::vector BackendInterface::fetchLedgerObjects( std::vector const& keys, std::uint32_t const sequence, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { std::vector results; results.resize(keys.size()); std::vector misses; - for (size_t i = 0; i < keys.size(); ++i) - { + for (size_t i = 0; i < keys.size(); ++i) { auto obj = cache_.get(keys[i], sequence); - if (obj) - { + if (obj) { results[i] = *obj; - } - else - { + } else { misses.push_back(keys[i]); } } LOG(gLog.trace()) << "Cache hits = " << keys.size() - misses.size() << " - cache misses = " << misses.size(); - if (!misses.empty()) - { + if (!misses.empty()) { auto objs = doFetchLedgerObjects(misses, sequence, yield); - for (size_t i = 0, j = 0; i < results.size(); ++i) - { - if (results[i].empty()) - { + for (size_t i = 0, j = 0; i < results.size(); ++i) { + if (results[i].empty()) { results[i] = objs[j]; ++j; } @@ -124,15 +114,13 @@ std::optional BackendInterface::fetchSuccessorKey( ripple::uint256 key, std::uint32_t const ledgerSequence, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { auto succ = cache_.getSuccessor(key, ledgerSequence); - if (succ) - { + if (succ) { LOG(gLog.trace()) << "Cache hit - " << ripple::strHex(key); - } - else - { + } else { LOG(gLog.trace()) << "Cache miss - " << ripple::strHex(key); } return succ ? succ->key : doFetchSuccessorKey(key, ledgerSequence, yield); @@ -142,11 +130,11 @@ std::optional BackendInterface::fetchSuccessorObject( ripple::uint256 key, std::uint32_t const ledgerSequence, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { auto succ = fetchSuccessorKey(key, ledgerSequence, yield); - if (succ) - { + if (succ) { auto obj = fetchLedgerObject(*succ, ledgerSequence, yield); if (!obj) return {{*succ, {}}}; @@ -161,7 +149,8 @@ BackendInterface::fetchBookOffers( ripple::uint256 const& book, std::uint32_t const ledgerSequence, std::uint32_t const limit, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { // TODO try to speed this up. This can take a few seconds. The goal is // to get it down to a few hundred milliseconds. @@ -175,29 +164,25 @@ BackendInterface::fetchBookOffers( std::uint32_t numPages = 0; long succMillis = 0; long pageMillis = 0; - while (keys.size() < limit) - { + while (keys.size() < limit) { auto mid1 = std::chrono::system_clock::now(); auto offerDir = fetchSuccessorObject(uTipIndex, ledgerSequence, yield); auto mid2 = std::chrono::system_clock::now(); numSucc++; succMillis += getMillis(mid2 - mid1); - if (!offerDir || offerDir->key >= bookEnd) - { + if (!offerDir || offerDir->key >= bookEnd) { LOG(gLog.trace()) << "offerDir.has_value() " << offerDir.has_value() << " breaking"; break; } uTipIndex = offerDir->key; - while (keys.size() < limit) - { + while (keys.size() < limit) { ++numPages; ripple::STLedgerEntry const sle{ ripple::SerialIter{offerDir->blob.data(), offerDir->blob.size()}, offerDir->key}; auto indexes = sle.getFieldV256(ripple::sfIndexes); keys.insert(keys.end(), indexes.begin(), indexes.end()); auto next = sle.getFieldU64(ripple::sfIndexNext); - if (next == 0u) - { + if (next == 0u) { LOG(gLog.trace()) << "Next is empty. breaking"; break; } @@ -212,8 +197,7 @@ BackendInterface::fetchBookOffers( } auto mid = std::chrono::system_clock::now(); auto objs = fetchLedgerObjects(keys, ledgerSequence, yield); - for (size_t i = 0; i < keys.size() && i < limit; ++i) - { + for (size_t i = 0; i < keys.size() && i < limit; ++i) { LOG(gLog.trace()) << "Key = " << ripple::strHex(keys[i]) << " blob = " << ripple::strHex(objs[i]) << " ledgerSequence = " << ledgerSequence; assert(objs[i].size()); @@ -251,12 +235,9 @@ BackendInterface::updateRange(uint32_t newMax) { std::scoped_lock const lck(rngMtx_); assert(!range || newMax >= range->maxSequence); - if (!range) - { + if (!range) { range = {newMax, newMax}; - } - else - { + } else { range->maxSequence = newMax; } } @@ -267,41 +248,33 @@ BackendInterface::fetchLedgerPage( std::uint32_t const ledgerSequence, std::uint32_t const limit, bool outOfOrder, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { LedgerPage page; std::vector keys; bool reachedEnd = false; - while (keys.size() < limit && !reachedEnd) - { + while (keys.size() < limit && !reachedEnd) { ripple::uint256 const& curCursor = !keys.empty() ? keys.back() : (cursor ? *cursor : firstKey); std::uint32_t const seq = outOfOrder ? range->maxSequence : ledgerSequence; auto succ = fetchSuccessorKey(curCursor, seq, yield); - if (!succ) - { + if (!succ) { reachedEnd = true; - } - else - { + } else { keys.push_back(*succ); } } auto objects = fetchLedgerObjects(keys, ledgerSequence, yield); - for (size_t i = 0; i < objects.size(); ++i) - { - if (!objects[i].empty()) - { + for (size_t i = 0; i < objects.size(); ++i) { + if (!objects[i].empty()) { page.objects.push_back({keys[i], std::move(objects[i])}); - } - else if (!outOfOrder) - { + } else if (!outOfOrder) { LOG(gLog.error()) << "Deleted or non-existent object in successor table. key = " << ripple::strHex(keys[i]) << " - seq = " << ledgerSequence; std::stringstream msg; - for (size_t j = 0; j < objects.size(); ++j) - { + for (size_t j = 0; j < objects.size(); ++j) { msg << " - " << ripple::strHex(keys[j]); } LOG(gLog.error()) << msg.str(); @@ -321,8 +294,7 @@ BackendInterface::fetchFees(std::uint32_t const seq, boost::asio::yield_context auto key = ripple::keylet::fees().key; auto bytes = fetchLedgerObject(key, seq, yield); - if (!bytes) - { + if (!bytes) { LOG(gLog.error()) << "Could not find fees"; return {}; } diff --git a/src/data/BackendInterface.h b/src/data/BackendInterface.h index b910ae8d..7432c27b 100644 --- a/src/data/BackendInterface.h +++ b/src/data/BackendInterface.h @@ -38,10 +38,9 @@ namespace data { /** * @brief Represents a database timeout error. */ -class DatabaseTimeout : public std::exception -{ +class DatabaseTimeout : public std::exception { public: - const char* + char const* what() const throw() override { return "Database read timed out. Please retry the request"; @@ -63,14 +62,10 @@ retryOnTimeout(FnType func, size_t waitMs = DEFAULT_WAIT_BETWEEN_RETRY) { static util::Logger const log{"Backend"}; - while (true) - { - try - { + while (true) { + try { return func(); - } - catch (DatabaseTimeout const&) - { + } catch (DatabaseTimeout const&) { LOG(log.error()) << "Database request timed out. Sleeping and retrying ... "; std::this_thread::sleep_for(std::chrono::milliseconds(waitMs)); } @@ -91,17 +86,15 @@ synchronous(FnType&& func) boost::asio::io_context ctx; using R = typename boost::result_of::type; - if constexpr (!std::is_same::value) - { + if constexpr (!std::is_same::value) { R res; - boost::asio::spawn( - ctx, [_ = boost::asio::make_work_guard(ctx), &func, &res](auto yield) { res = func(yield); }); + boost::asio::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func, &res](auto yield) { + res = func(yield); + }); ctx.run(); return res; - } - else - { + } else { boost::asio::spawn(ctx, [_ = boost::asio::make_work_guard(ctx), &func](auto yield) { func(yield); }); ctx.run(); } @@ -124,8 +117,7 @@ synchronousAndRetryOnTimeout(FnType&& func) /** * @brief The interface to the database used by Clio. */ -class BackendInterface -{ +class BackendInterface { protected: mutable std::shared_mutex rngMtx_; std::optional range; @@ -245,7 +237,8 @@ public: std::uint32_t limit, bool forward, std::optional const& cursor, - boost::asio::yield_context yield) const = 0; + boost::asio::yield_context yield + ) const = 0; /** * @brief Fetches all transactions from a specific ledger. @@ -294,7 +287,8 @@ public: std::uint32_t limit, bool forward, std::optional const& cursorIn, - boost::asio::yield_context yield) const = 0; + boost::asio::yield_context yield + ) const = 0; /** * @brief Fetches a specific ledger object. @@ -325,7 +319,8 @@ public: fetchLedgerObjects( std::vector const& keys, std::uint32_t sequence, - boost::asio::yield_context yield) const; + boost::asio::yield_context yield + ) const; /** * @brief The database-specific implementation for fetching a ledger object. @@ -350,7 +345,8 @@ public: doFetchLedgerObjects( std::vector const& keys, std::uint32_t sequence, - boost::asio::yield_context yield) const = 0; + boost::asio::yield_context yield + ) const = 0; /** * @brief Returns the difference between ledgers. @@ -378,7 +374,8 @@ public: std::uint32_t ledgerSequence, std::uint32_t limit, bool outOfOrder, - boost::asio::yield_context yield) const; + boost::asio::yield_context yield + ) const; /** * @brief Fetches the successor object. @@ -430,7 +427,8 @@ public: ripple::uint256 const& book, std::uint32_t ledgerSequence, std::uint32_t limit, - boost::asio::yield_context yield) const; + boost::asio::yield_context yield + ) const; /** * @brief Synchronously fetches the ledger range from DB. @@ -492,7 +490,8 @@ public: std::uint32_t seq, std::uint32_t date, std::string&& transaction, - std::string&& metadata) = 0; + std::string&& metadata + ) = 0; /** * @brief Writes NFTs to the database. diff --git a/src/data/CassandraBackend.h b/src/data/CassandraBackend.h index d01ac3bf..bdb72889 100644 --- a/src/data/CassandraBackend.h +++ b/src/data/CassandraBackend.h @@ -44,8 +44,7 @@ namespace data::cassandra { * @tparam ExecutionStrategyType The execution strategy type to use */ template -class BasicCassandraBackend : public BackendInterface -{ +class BasicCassandraBackend : public BackendInterface { util::Logger log_{"Backend"}; SettingsProviderType settingsProvider_; @@ -73,12 +72,10 @@ public: if (auto const res = handle_.connect(); not res) throw std::runtime_error("Could not connect to Cassandra: " + res.error()); - if (not readOnly) - { - if (auto const res = handle_.execute(schema_.createKeyspace); not res) - { - // on datastax, creation of keyspaces can be configured to only be done thru the admin interface. - // this does not mean that the keyspace does not already exist tho. + if (not readOnly) { + if (auto const res = handle_.execute(schema_.createKeyspace); not res) { + // on datastax, creation of keyspaces can be configured to only be done thru the admin + // interface. this does not mean that the keyspace does not already exist tho. if (res.error().code() != CASS_ERROR_SERVER_UNAUTHORIZED) throw std::runtime_error("Could not create keyspace: " + res.error()); } @@ -87,12 +84,9 @@ public: throw std::runtime_error("Could not create schema: " + res.error()); } - try - { + try { schema_.prepareStatements(handle_); - } - catch (std::runtime_error const& ex) - { + } catch (std::runtime_error const& ex) { LOG(log_.error()) << "Failed to prepare the statements: " << ex.what() << "; readOnly: " << readOnly; throw; } @@ -106,7 +100,8 @@ public: std::uint32_t const limit, bool forward, std::optional const& cursorIn, - boost::asio::yield_context yield) const override + boost::asio::yield_context yield + ) const override { auto rng = fetchLedgerRange(); if (!rng) @@ -120,14 +115,11 @@ public: }(); auto cursor = cursorIn; - if (cursor) - { + if (cursor) { statement.bindAt(1, cursor->asTuple()); LOG(log_.debug()) << "account = " << ripple::strHex(account) << " tuple = " << cursor->ledgerSequence << cursor->transactionIndex; - } - else - { + } else { auto const seq = forward ? rng->minSequence : rng->maxSequence; auto const placeHolder = forward ? 0u : std::numeric_limits::max(); @@ -142,8 +134,7 @@ public: statement.bindAt(2, Limit{limit}); auto const res = executor_.read(yield, statement); auto const& results = res.value(); - if (not results.hasRows()) - { + if (not results.hasRows()) { LOG(log_.debug()) << "No rows returned"; return {}; } @@ -152,11 +143,9 @@ public: auto numRows = results.numRows(); LOG(log_.info()) << "num_rows = " << numRows; - for (auto [hash, data] : extract>(results)) - { + for (auto [hash, data] : extract>(results)) { hashes.push_back(hash); - if (--numRows == 0) - { + if (--numRows == 0) { LOG(log_.debug()) << "Setting cursor"; cursor = data; @@ -170,8 +159,7 @@ public: auto const txns = fetchTransactions(hashes, yield); LOG(log_.debug()) << "Txns = " << txns.size(); - if (txns.size() == limit) - { + if (txns.size() == limit) { LOG(log_.debug()) << "Returning cursor"; return {txns, cursor}; } @@ -185,13 +173,11 @@ public: // wait for other threads to finish their writes executor_.sync(); - if (!range) - { + if (!range) { executor_.writeSync(schema_->updateLedgerRange, ledgerSequence_, false, ledgerSequence_); } - if (not executeSyncUpdate(schema_->updateLedgerRange.bind(ledgerSequence_, true, ledgerSequence_ - 1))) - { + if (not executeSyncUpdate(schema_->updateLedgerRange.bind(ledgerSequence_, true, ledgerSequence_ - 1))) { LOG(log_.warn()) << "Update failed for ledger " << ledgerSequence_; return false; } @@ -213,10 +199,8 @@ public: std::optional fetchLatestLedgerSequence(boost::asio::yield_context yield) const override { - if (auto const res = executor_.read(yield, schema_->selectLatestLedger); res) - { - if (auto const& result = res.value(); result) - { + if (auto const res = executor_.read(yield, schema_->selectLatestLedger); res) { + if (auto const& result = res.value(); result) { if (auto const maybeValue = result.template get(); maybeValue) return maybeValue; @@ -225,9 +209,7 @@ public: } LOG(log_.error()) << "Could not fetch latest ledger - no result"; - } - else - { + } else { LOG(log_.error()) << "Could not fetch latest ledger: " << res.error(); } @@ -238,12 +220,9 @@ public: fetchLedgerBySequence(std::uint32_t const sequence, boost::asio::yield_context yield) const override { auto const res = executor_.read(yield, schema_->selectLedgerBySeq, sequence); - if (res) - { - if (auto const& result = res.value(); result) - { - if (auto const maybeValue = result.template get>(); maybeValue) - { + if (res) { + if (auto const& result = res.value(); result) { + if (auto const maybeValue = result.template get>(); maybeValue) { return util::deserializeHeader(ripple::makeSlice(*maybeValue)); } @@ -252,9 +231,7 @@ public: } LOG(log_.error()) << "Could not fetch ledger by sequence - no result"; - } - else - { + } else { LOG(log_.error()) << "Could not fetch ledger by sequence: " << res.error(); } @@ -264,10 +241,8 @@ public: std::optional fetchLedgerByHash(ripple::uint256 const& hash, boost::asio::yield_context yield) const override { - if (auto const res = executor_.read(yield, schema_->selectLedgerByHash, hash); res) - { - if (auto const& result = res.value(); result) - { + if (auto const res = executor_.read(yield, schema_->selectLedgerByHash, hash); res) { + if (auto const& result = res.value(); result) { if (auto const maybeValue = result.template get(); maybeValue) return fetchLedgerBySequence(*maybeValue, yield); @@ -276,9 +251,7 @@ public: } LOG(log_.error()) << "Could not fetch ledger by hash - no result"; - } - else - { + } else { LOG(log_.error()) << "Could not fetch ledger by hash: " << res.error(); } @@ -289,11 +262,9 @@ public: hardFetchLedgerRange(boost::asio::yield_context yield) const override { auto const res = executor_.read(yield, schema_->selectLedgerRange); - if (res) - { + if (res) { auto const& results = res.value(); - if (not results.hasRows()) - { + if (not results.hasRows()) { LOG(log_.debug()) << "Could not fetch ledger range - no rows"; return std::nullopt; } @@ -303,14 +274,10 @@ public: // least use tuple? LedgerRange range; std::size_t idx = 0; - for (auto [seq] : extract(results)) - { - if (idx == 0) - { + for (auto [seq] : extract(results)) { + if (idx == 0) { range.maxSequence = range.minSequence = seq; - } - else if (idx == 1) - { + } else if (idx == 1) { range.maxSequence = seq; } @@ -343,15 +310,13 @@ public: auto start = std::chrono::system_clock::now(); auto const res = executor_.read(yield, schema_->selectAllTransactionHashesInLedger, ledgerSequence); - if (not res) - { + if (not res) { LOG(log_.error()) << "Could not fetch all transaction hashes: " << res.error(); return {}; } auto const& result = res.value(); - if (not result.hasRows()) - { + if (not result.hasRows()) { LOG(log_.error()) << "Could not fetch all transaction hashes - no rows; ledger = " << std::to_string(ledgerSequence); return {}; @@ -377,8 +342,7 @@ public: if (not res) return std::nullopt; - if (auto const maybeRow = res->template get(); maybeRow) - { + if (auto const maybeRow = res->template get(); maybeRow) { auto [seq, owner, isBurned] = *maybeRow; auto result = std::make_optional(tokenID, seq, owner, isBurned); @@ -394,8 +358,7 @@ public: // even though we are returning a blank URI, the NFT might have had // one. auto uriRes = executor_.read(yield, schema_->selectNFTURI, tokenID, ledgerSequence); - if (uriRes) - { + if (uriRes) { if (auto const maybeUri = uriRes->template get(); maybeUri) result->uri = *maybeUri; } @@ -413,7 +376,8 @@ public: std::uint32_t const limit, bool const forward, std::optional const& cursorIn, - boost::asio::yield_context yield) const override + boost::asio::yield_context yield + ) const override { auto rng = fetchLedgerRange(); if (!rng) @@ -427,14 +391,11 @@ public: }(); auto cursor = cursorIn; - if (cursor) - { + if (cursor) { statement.bindAt(1, cursor->asTuple()); LOG(log_.debug()) << "token_id = " << ripple::strHex(tokenID) << " tuple = " << cursor->ledgerSequence << cursor->transactionIndex; - } - else - { + } else { auto const seq = forward ? rng->minSequence : rng->maxSequence; auto const placeHolder = forward ? 0 : std::numeric_limits::max(); @@ -447,8 +408,7 @@ public: auto const res = executor_.read(yield, statement); auto const& results = res.value(); - if (not results.hasRows()) - { + if (not results.hasRows()) { LOG(log_.debug()) << "No rows returned"; return {}; } @@ -457,11 +417,9 @@ public: auto numRows = results.numRows(); LOG(log_.info()) << "num_rows = " << numRows; - for (auto [hash, data] : extract>(results)) - { + for (auto [hash, data] : extract>(results)) { hashes.push_back(hash); - if (--numRows == 0) - { + if (--numRows == 0) { LOG(log_.debug()) << "Setting cursor"; cursor = data; @@ -475,8 +433,7 @@ public: auto const txns = fetchTransactions(hashes, yield); LOG(log_.debug()) << "NFT Txns = " << txns.size(); - if (txns.size() == limit) - { + if (txns.size() == limit) { LOG(log_.debug()) << "Returning cursor"; return {txns, cursor}; } @@ -489,20 +446,14 @@ public: const override { LOG(log_.debug()) << "Fetching ledger object for seq " << sequence << ", key = " << ripple::to_string(key); - if (auto const res = executor_.read(yield, schema_->selectObject, key, sequence); res) - { - if (auto const result = res->template get(); result) - { + if (auto const res = executor_.read(yield, schema_->selectObject, key, sequence); res) { + if (auto const result = res->template get(); result) { if (result->size()) return *result; - } - else - { + } else { LOG(log_.debug()) << "Could not fetch ledger object - no rows"; } - } - else - { + } else { LOG(log_.error()) << "Could not fetch ledger object: " << res.error(); } @@ -512,18 +463,14 @@ public: std::optional fetchTransaction(ripple::uint256 const& hash, boost::asio::yield_context yield) const override { - if (auto const res = executor_.read(yield, schema_->selectTransaction, hash); res) - { - if (auto const maybeValue = res->template get(); maybeValue) - { + if (auto const res = executor_.read(yield, schema_->selectTransaction, hash); res) { + if (auto const maybeValue = res->template get(); maybeValue) { auto [transaction, meta, seq, date] = *maybeValue; return std::make_optional(transaction, meta, seq, date); } LOG(log_.debug()) << "Could not fetch transaction - no rows"; - } - else - { + } else { LOG(log_.error()) << "Could not fetch transaction: " << res.error(); } @@ -534,19 +481,15 @@ public: doFetchSuccessorKey(ripple::uint256 key, std::uint32_t const ledgerSequence, boost::asio::yield_context yield) const override { - if (auto const res = executor_.read(yield, schema_->selectSuccessor, key, ledgerSequence); res) - { - if (auto const result = res->template get(); result) - { + if (auto const res = executor_.read(yield, schema_->selectSuccessor, key, ledgerSequence); res) { + if (auto const result = res->template get(); result) { if (*result == lastKey) return std::nullopt; return *result; } LOG(log_.debug()) << "Could not fetch successor - no rows"; - } - else - { + } else { LOG(log_.error()) << "Could not fetch successor: " << res.error(); } @@ -569,9 +512,11 @@ public: auto const timeDiff = util::timed([this, yield, &results, &hashes, &statements]() { // TODO: seems like a job for "hash IN (list of hashes)" instead? std::transform( - std::cbegin(hashes), std::cend(hashes), std::back_inserter(statements), [this](auto const& hash) { - return schema_->selectTransaction.bind(hash); - }); + std::cbegin(hashes), + std::cend(hashes), + std::back_inserter(statements), + [this](auto const& hash) { return schema_->selectTransaction.bind(hash); } + ); auto const entries = executor_.readEach(yield, statements); std::transform( @@ -583,7 +528,8 @@ public: return *maybeRow; return {}; - }); + } + ); }); assert(numHashes == results.size()); @@ -596,7 +542,8 @@ public: doFetchLedgerObjects( std::vector const& keys, std::uint32_t const sequence, - boost::asio::yield_context yield) const override + boost::asio::yield_context yield + ) const override { if (keys.empty()) return {}; @@ -612,18 +559,24 @@ public: // TODO: seems like a job for "key IN (list of keys)" instead? std::transform( - std::cbegin(keys), std::cend(keys), std::back_inserter(statements), [this, &sequence](auto const& key) { - return schema_->selectObject.bind(key, sequence); - }); + std::cbegin(keys), + std::cend(keys), + std::back_inserter(statements), + [this, &sequence](auto const& key) { return schema_->selectObject.bind(key, sequence); } + ); auto const entries = executor_.readEach(yield, statements); std::transform( - std::cbegin(entries), std::cend(entries), std::back_inserter(results), [](auto const& res) -> Blob { + std::cbegin(entries), + std::cend(entries), + std::back_inserter(results), + [](auto const& res) -> Blob { if (auto const maybeValue = res.template get(); maybeValue) return *maybeValue; return {}; - }); + } + ); LOG(log_.trace()) << "Fetched " << numKeys << " objects"; return results; @@ -634,15 +587,13 @@ public: { auto const [keys, timeDiff] = util::timed([this, &ledgerSequence, yield]() -> std::vector { auto const res = executor_.read(yield, schema_->selectDiff, ledgerSequence); - if (not res) - { + if (not res) { LOG(log_.error()) << "Could not fetch ledger diff: " << res.error() << "; ledger = " << ledgerSequence; return {}; } auto const& results = res.value(); - if (not results) - { + if (not results) { LOG(log_.error()) << "Could not fetch ledger diff - no rows; ledger = " << ledgerSequence; return {}; } @@ -672,7 +623,8 @@ public: std::back_inserter(results), [](auto const& key, auto const& obj) { return LedgerObject{key, obj}; - }); + } + ); return results; } @@ -705,8 +657,7 @@ public: std::vector statements; statements.reserve(data.size() * 10); // assume 10 transactions avg - for (auto& record : data) - { + for (auto& record : data) { std::transform( std::begin(record.accounts), std::end(record.accounts), @@ -715,8 +666,10 @@ public: return schema_->insertAccountTx.bind( std::forward(account), std::make_tuple(record.ledgerSequence, record.transactionIndex), - record.txHash); - }); + record.txHash + ); + } + ); } executor_.write(std::move(statements)); @@ -730,7 +683,8 @@ public: std::transform(std::cbegin(data), std::cend(data), std::back_inserter(statements), [this](auto const& record) { return schema_->insertNFTTx.bind( - record.tokenID, std::make_tuple(record.ledgerSequence, record.transactionIndex), record.txHash); + record.tokenID, std::make_tuple(record.ledgerSequence, record.transactionIndex), record.txHash + ); }); executor_.write(std::move(statements)); @@ -742,13 +696,15 @@ public: std::uint32_t const seq, std::uint32_t const date, std::string&& transaction, - std::string&& metadata) override + std::string&& metadata + ) override { LOG(log_.trace()) << "Writing txn to cassandra"; executor_.write(schema_->insertLedgerTransaction, seq, hash); executor_.write( - schema_->insertTransaction, std::move(hash), seq, date, std::move(transaction), std::move(metadata)); + schema_->insertTransaction, std::move(hash), seq, date, std::move(transaction), std::move(metadata) + ); } void @@ -757,24 +713,25 @@ public: std::vector statements; statements.reserve(data.size() * 3); - for (NFTsData const& record : data) - { + for (NFTsData const& record : data) { statements.push_back( - schema_->insertNFT.bind(record.tokenID, record.ledgerSequence, record.owner, record.isBurned)); + schema_->insertNFT.bind(record.tokenID, record.ledgerSequence, record.owner, record.isBurned) + ); // If `uri` is set (and it can be set to an empty uri), we know this // is a net-new NFT. That is, this NFT has not been seen before by // us _OR_ it is in the extreme edge case of a re-minted NFT ID with // the same NFT ID as an already-burned token. In this case, we need // to record the URI and link to the issuer_nf_tokens table. - if (record.uri) - { + if (record.uri) { statements.push_back(schema_->insertIssuerNFT.bind( ripple::nft::getIssuer(record.tokenID), static_cast(ripple::nft::getTaxon(record.tokenID)), - record.tokenID)); + record.tokenID + )); statements.push_back( - schema_->insertNFTURI.bind(record.tokenID, record.ledgerSequence, record.uri.value())); + schema_->insertNFTURI.bind(record.tokenID, record.ledgerSequence, record.uri.value()) + ); } } @@ -806,14 +763,12 @@ private: { auto const res = executor_.writeSync(statement); auto maybeSuccess = res->template get(); - if (not maybeSuccess) - { + if (not maybeSuccess) { LOG(log_.error()) << "executeSyncUpdate - error getting result - no row"; return false; } - if (not maybeSuccess.value()) - { + if (not maybeSuccess.value()) { LOG(log_.warn()) << "Update failed. Checking if DB state is what we expect"; // error may indicate that another writer wrote something. diff --git a/src/data/DBHelpers.h b/src/data/DBHelpers.h index 9be7c991..9800c475 100644 --- a/src/data/DBHelpers.h +++ b/src/data/DBHelpers.h @@ -33,8 +33,7 @@ /** * @brief Struct used to keep track of what to write to account_transactions/account_tx tables. */ -struct AccountTransactionsData -{ +struct AccountTransactionsData { boost::container::flat_set accounts; std::uint32_t ledgerSequence{}; std::uint32_t transactionIndex{}; @@ -56,8 +55,7 @@ struct AccountTransactionsData * * Gets written to nf_token_transactions table and the like. */ -struct NFTTransactionsData -{ +struct NFTTransactionsData { ripple::uint256 tokenID; std::uint32_t ledgerSequence; std::uint32_t transactionIndex; @@ -74,8 +72,7 @@ struct NFTTransactionsData * * Gets written to nf_tokens table and the like. */ -struct NFTsData -{ +struct NFTsData { ripple::uint256 tokenID; std::uint32_t ledgerSequence; @@ -107,7 +104,8 @@ struct NFTsData ripple::uint256 const& tokenID, ripple::AccountID const& owner, ripple::Blob const& uri, - ripple::TxMeta const& meta) + ripple::TxMeta const& meta + ) : tokenID(tokenID), ledgerSequence(meta.getLgrSeq()), transactionIndex(meta.getIndex()), owner(owner), uri(uri) { } @@ -133,7 +131,8 @@ struct NFTsData ripple::uint256 const& tokenID, std::uint32_t const ledgerSequence, ripple::AccountID const& owner, - ripple::Blob const& uri) + ripple::Blob const& uri + ) : tokenID(tokenID), ledgerSequence(ledgerSequence), owner(owner), uri(uri) { } @@ -252,7 +251,7 @@ getBookBase(T const& key) inline std::string uint256ToString(ripple::uint256 const& input) { - return {reinterpret_cast(input.data()), ripple::uint256::size()}; + return {reinterpret_cast(input.data()), ripple::uint256::size()}; } /** @brief The ripple epoch start timestamp. Midnight on 1st January 2000. */ diff --git a/src/data/LedgerCache.cpp b/src/data/LedgerCache.cpp index f096c0d2..d184e6f7 100644 --- a/src/data/LedgerCache.cpp +++ b/src/data/LedgerCache.cpp @@ -36,26 +36,20 @@ LedgerCache::update(std::vector const& objs, uint32_t seq, bool is { std::scoped_lock const lck{mtx_}; - if (seq > latestSeq_) - { + if (seq > latestSeq_) { assert(seq == latestSeq_ + 1 || latestSeq_ == 0); latestSeq_ = seq; } - for (auto const& obj : objs) - { - if (!obj.blob.empty()) - { + for (auto const& obj : objs) { + if (!obj.blob.empty()) { if (isBackground && deletes_.contains(obj.key)) continue; auto& e = map_[obj.key]; - if (seq > e.seq) - { + if (seq > e.seq) { e = {seq, obj.blob}; } - } - else - { + } else { map_.erase(obj.key); if (!full_ && !isBackground) deletes_.insert(obj.key); diff --git a/src/data/LedgerCache.h b/src/data/LedgerCache.h index 7bc06039..9483d917 100644 --- a/src/data/LedgerCache.h +++ b/src/data/LedgerCache.h @@ -33,10 +33,8 @@ namespace data { /** * @brief Cache for an entire ledger. */ -class LedgerCache -{ - struct CacheEntry - { +class LedgerCache { + struct CacheEntry { uint32_t seq = 0; Blob blob; }; diff --git a/src/data/Types.h b/src/data/Types.h index b1ccd5cb..7ef18732 100644 --- a/src/data/Types.h +++ b/src/data/Types.h @@ -34,13 +34,12 @@ using Blob = std::vector; /** * @brief Represents an object in the ledger. */ -struct LedgerObject -{ +struct LedgerObject { ripple::uint256 key; Blob blob; bool - operator==(const LedgerObject& other) const + operator==(LedgerObject const& other) const { return key == other.key && blob == other.blob; } @@ -49,8 +48,7 @@ struct LedgerObject /** * @brief Represents a page of LedgerObjects. */ -struct LedgerPage -{ +struct LedgerPage { std::vector objects; std::optional cursor; }; @@ -58,8 +56,7 @@ struct LedgerPage /** * @brief Represents a page of book offer objects. */ -struct BookOffersPage -{ +struct BookOffersPage { std::vector offers; std::optional cursor; }; @@ -67,8 +64,7 @@ struct BookOffersPage /** * @brief Represents a transaction and its metadata bundled together. */ -struct TransactionAndMetadata -{ +struct TransactionAndMetadata { Blob transaction; Blob metadata; std::uint32_t ledgerSequence = 0; @@ -89,7 +85,7 @@ struct TransactionAndMetadata } bool - operator==(const TransactionAndMetadata& other) const + operator==(TransactionAndMetadata const& other) const { return transaction == other.transaction && metadata == other.metadata && ledgerSequence == other.ledgerSequence && date == other.date; @@ -99,8 +95,7 @@ struct TransactionAndMetadata /** * @brief Represents a cursor into the transactions table. */ -struct TransactionsCursor -{ +struct TransactionsCursor { std::uint32_t ledgerSequence = 0; std::uint32_t transactionIndex = 0; @@ -128,8 +123,7 @@ struct TransactionsCursor /** * @brief Represests a bundle of transactions with metadata and a cursor to the next page. */ -struct TransactionsAndCursor -{ +struct TransactionsAndCursor { std::vector txns; std::optional cursor; }; @@ -137,8 +131,7 @@ struct TransactionsAndCursor /** * @brief Represents a NFToken. */ -struct NFT -{ +struct NFT { ripple::uint256 tokenID; std::uint32_t ledgerSequence{}; ripple::AccountID owner; @@ -172,8 +165,7 @@ struct NFT /** * @brief Stores a range of sequences as a min and max pair. */ -struct LedgerRange -{ +struct LedgerRange { std::uint32_t minSequence = 0; std::uint32_t maxSequence = 0; }; diff --git a/src/data/cassandra/Concepts.h b/src/data/cassandra/Concepts.h index cd1e4c51..a1e50325 100644 --- a/src/data/cassandra/Concepts.h +++ b/src/data/cassandra/Concepts.h @@ -34,57 +34,93 @@ namespace data::cassandra { /** * @brief The requirements of a settings provider. */ -// clang-format off template concept SomeSettingsProvider = requires(T a) { - { a.getSettings() } -> std::same_as; - { a.getKeyspace() } -> std::same_as; - { a.getTablePrefix() } -> std::same_as>; - { a.getReplicationFactor() } -> std::same_as; - { a.getTtl() } -> std::same_as; + { + a.getSettings() + } -> std::same_as; + { + a.getKeyspace() + } -> std::same_as; + { + a.getTablePrefix() + } -> std::same_as>; + { + a.getReplicationFactor() + } -> std::same_as; + { + a.getTtl() + } -> std::same_as; }; -// clang-format on /** * @brief The requirements of an execution strategy. */ -// clang-format off template concept SomeExecutionStrategy = requires( - T a, - Settings settings, - Handle handle, - Statement statement, + T a, + Settings settings, + Handle handle, + Statement statement, std::vector statements, PreparedStatement prepared, boost::asio::yield_context token ) { - { T(settings, handle) }; - { a.sync() } -> std::same_as; - { a.isTooBusy() } -> std::same_as; - { a.writeSync(statement) } -> std::same_as; - { a.writeSync(prepared) } -> std::same_as; - { a.write(prepared) } -> std::same_as; - { a.write(std::move(statements)) } -> std::same_as; - { a.read(token, prepared) } -> std::same_as; - { a.read(token, statement) } -> std::same_as; - { a.read(token, statements) } -> std::same_as; - { a.readEach(token, statements) } -> std::same_as>; - { a.stats() } -> std::same_as; + { + T(settings, handle) + }; + { + a.sync() + } -> std::same_as; + { + a.isTooBusy() + } -> std::same_as; + { + a.writeSync(statement) + } -> std::same_as; + { + a.writeSync(prepared) + } -> std::same_as; + { + a.write(prepared) + } -> std::same_as; + { + a.write(std::move(statements)) + } -> std::same_as; + { + a.read(token, prepared) + } -> std::same_as; + { + a.read(token, statement) + } -> std::same_as; + { + a.read(token, statements) + } -> std::same_as; + { + a.readEach(token, statements) + } -> std::same_as>; + { + a.stats() + } -> std::same_as; }; -// clang-format on /** * @brief The requirements of a retry policy. */ -// clang-format off template concept SomeRetryPolicy = requires(T a, boost::asio::io_context ioc, CassandraError err, uint32_t attempt) { - { T(ioc) }; - { a.shouldRetry(err) } -> std::same_as; - { a.retry([](){}) } -> std::same_as; - { a.calculateDelay(attempt) } -> std::same_as; + { + T(ioc) + }; + { + a.shouldRetry(err) + } -> std::same_as; + { + a.retry([]() {}) + } -> std::same_as; + { + a.calculateDelay(attempt) + } -> std::same_as; }; -// clang-format on } // namespace data::cassandra diff --git a/src/data/cassandra/Error.h b/src/data/cassandra/Error.h index 165e095f..a16f560a 100644 --- a/src/data/cassandra/Error.h +++ b/src/data/cassandra/Error.h @@ -29,8 +29,7 @@ namespace data::cassandra { /** * @brief A simple container for both error message and error code. */ -class CassandraError -{ +class CassandraError { std::string message_; uint32_t code_{}; @@ -42,14 +41,16 @@ public: template friend std::string - operator+(T const& lhs, CassandraError const& rhs) requires std::is_convertible_v + operator+(T const& lhs, CassandraError const& rhs) + requires std::is_convertible_v { return lhs + rhs.message(); } template friend bool - operator==(T const& lhs, CassandraError const& rhs) requires std::is_convertible_v + operator==(T const& lhs, CassandraError const& rhs) + requires std::is_convertible_v { return lhs == rhs.message(); } diff --git a/src/data/cassandra/Handle.cpp b/src/data/cassandra/Handle.cpp index 8798e30f..b7ee74a3 100644 --- a/src/data/cassandra/Handle.cpp +++ b/src/data/cassandra/Handle.cpp @@ -97,8 +97,7 @@ Handle::asyncExecuteEach(std::vector const& statements) const Handle::MaybeErrorType Handle::executeEach(std::vector const& statements) const { - for (auto futures = asyncExecuteEach(statements); auto const& future : futures) - { + for (auto futures = asyncExecuteEach(statements); auto const& future : futures) { if (auto rc = future.await(); not rc) return rc; } diff --git a/src/data/cassandra/Handle.h b/src/data/cassandra/Handle.h index 37b4056a..65c764fc 100644 --- a/src/data/cassandra/Handle.h +++ b/src/data/cassandra/Handle.h @@ -42,8 +42,7 @@ namespace data::cassandra { /** * @brief Represents a handle to the cassandra database cluster */ -class Handle -{ +class Handle { detail::Cluster cluster_; detail::Session session_; diff --git a/src/data/cassandra/Schema.h b/src/data/cassandra/Schema.h index 7cd8ff95..5b5ff682 100644 --- a/src/data/cassandra/Schema.h +++ b/src/data/cassandra/Schema.h @@ -41,8 +41,7 @@ template * @brief Manages the DB schema and provides access to prepared statements. */ template -class Schema -{ +class Schema { util::Logger log_{"Backend"}; std::reference_wrapper settingsProvider_; @@ -62,7 +61,8 @@ public: AND durable_writes = true )", settingsProvider_.get().getKeyspace(), - settingsProvider_.get().getReplicationFactor()); + settingsProvider_.get().getReplicationFactor() + ); }(); // ======================= @@ -85,7 +85,8 @@ public: AND default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "objects"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -100,7 +101,8 @@ public: WITH default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "transactions"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -113,7 +115,8 @@ public: WITH default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "ledger_transactions"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -127,7 +130,8 @@ public: WITH default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "successor"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -140,7 +144,8 @@ public: WITH default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "diff"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -155,7 +160,8 @@ public: AND default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "account_tx"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -167,7 +173,8 @@ public: WITH default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "ledgers"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -179,7 +186,8 @@ public: WITH default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "ledger_hashes"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -189,7 +197,8 @@ public: sequence bigint ) )", - qualifiedTableName(settingsProvider_.get(), "ledger_range"))); + qualifiedTableName(settingsProvider_.get(), "ledger_range") + )); statements.emplace_back(fmt::format( R"( @@ -205,7 +214,8 @@ public: AND default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "nf_tokens"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -220,7 +230,8 @@ public: AND default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "issuer_nf_tokens_v2"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -235,7 +246,8 @@ public: AND default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "nf_token_uris"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); statements.emplace_back(fmt::format( R"( @@ -250,7 +262,8 @@ public: AND default_time_to_live = {} )", qualifiedTableName(settingsProvider_.get(), "nf_token_transactions"), - settingsProvider_.get().getTtl())); + settingsProvider_.get().getTtl() + )); return statements; }(); @@ -258,8 +271,7 @@ public: /** * @brief Prepared statements holder. */ - class Statements - { + class Statements { std::reference_wrapper settingsProvider_; std::reference_wrapper handle_; @@ -280,7 +292,8 @@ public: (key, sequence, object) VALUES (?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "objects"))); + qualifiedTableName(settingsProvider_.get(), "objects") + )); }(); PreparedStatement insertTransaction = [this]() { @@ -290,7 +303,8 @@ public: (hash, ledger_sequence, date, transaction, metadata) VALUES (?, ?, ?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "transactions"))); + qualifiedTableName(settingsProvider_.get(), "transactions") + )); }(); PreparedStatement insertLedgerTransaction = [this]() { @@ -300,7 +314,8 @@ public: (ledger_sequence, hash) VALUES (?, ?) )", - qualifiedTableName(settingsProvider_.get(), "ledger_transactions"))); + qualifiedTableName(settingsProvider_.get(), "ledger_transactions") + )); }(); PreparedStatement insertSuccessor = [this]() { @@ -310,7 +325,8 @@ public: (key, seq, next) VALUES (?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "successor"))); + qualifiedTableName(settingsProvider_.get(), "successor") + )); }(); PreparedStatement insertDiff = [this]() { @@ -320,7 +336,8 @@ public: (seq, key) VALUES (?, ?) )", - qualifiedTableName(settingsProvider_.get(), "diff"))); + qualifiedTableName(settingsProvider_.get(), "diff") + )); }(); PreparedStatement insertAccountTx = [this]() { @@ -330,7 +347,8 @@ public: (account, seq_idx, hash) VALUES (?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "account_tx"))); + qualifiedTableName(settingsProvider_.get(), "account_tx") + )); }(); PreparedStatement insertNFT = [this]() { @@ -340,7 +358,8 @@ public: (token_id, sequence, owner, is_burned) VALUES (?, ?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "nf_tokens"))); + qualifiedTableName(settingsProvider_.get(), "nf_tokens") + )); }(); PreparedStatement insertIssuerNFT = [this]() { @@ -350,7 +369,8 @@ public: (issuer, taxon, token_id) VALUES (?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "issuer_nf_tokens_v2"))); + qualifiedTableName(settingsProvider_.get(), "issuer_nf_tokens_v2") + )); }(); PreparedStatement insertNFTURI = [this]() { @@ -360,7 +380,8 @@ public: (token_id, sequence, uri) VALUES (?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "nf_token_uris"))); + qualifiedTableName(settingsProvider_.get(), "nf_token_uris") + )); }(); PreparedStatement insertNFTTx = [this]() { @@ -370,7 +391,8 @@ public: (token_id, seq_idx, hash) VALUES (?, ?, ?) )", - qualifiedTableName(settingsProvider_.get(), "nf_token_transactions"))); + qualifiedTableName(settingsProvider_.get(), "nf_token_transactions") + )); }(); PreparedStatement insertLedgerHeader = [this]() { @@ -380,7 +402,8 @@ public: (sequence, header) VALUES (?, ?) )", - qualifiedTableName(settingsProvider_.get(), "ledgers"))); + qualifiedTableName(settingsProvider_.get(), "ledgers") + )); }(); PreparedStatement insertLedgerHash = [this]() { @@ -390,7 +413,8 @@ public: (hash, sequence) VALUES (?, ?) )", - qualifiedTableName(settingsProvider_.get(), "ledger_hashes"))); + qualifiedTableName(settingsProvider_.get(), "ledger_hashes") + )); }(); // @@ -405,7 +429,8 @@ public: WHERE is_latest = ? IF sequence IN (?, null) )", - qualifiedTableName(settingsProvider_.get(), "ledger_range"))); + qualifiedTableName(settingsProvider_.get(), "ledger_range") + )); }(); PreparedStatement deleteLedgerRange = [this]() { @@ -415,7 +440,8 @@ public: SET sequence = ? WHERE is_latest = false )", - qualifiedTableName(settingsProvider_.get(), "ledger_range"))); + qualifiedTableName(settingsProvider_.get(), "ledger_range") + )); }(); // @@ -432,7 +458,8 @@ public: ORDER BY seq DESC LIMIT 1 )", - qualifiedTableName(settingsProvider_.get(), "successor"))); + qualifiedTableName(settingsProvider_.get(), "successor") + )); }(); PreparedStatement selectDiff = [this]() { @@ -442,7 +469,8 @@ public: FROM {} WHERE seq = ? )", - qualifiedTableName(settingsProvider_.get(), "diff"))); + qualifiedTableName(settingsProvider_.get(), "diff") + )); }(); PreparedStatement selectObject = [this]() { @@ -455,7 +483,8 @@ public: ORDER BY sequence DESC LIMIT 1 )", - qualifiedTableName(settingsProvider_.get(), "objects"))); + qualifiedTableName(settingsProvider_.get(), "objects") + )); }(); PreparedStatement selectTransaction = [this]() { @@ -465,7 +494,8 @@ public: FROM {} WHERE hash = ? )", - qualifiedTableName(settingsProvider_.get(), "transactions"))); + qualifiedTableName(settingsProvider_.get(), "transactions") + )); }(); PreparedStatement selectAllTransactionHashesInLedger = [this]() { @@ -475,7 +505,8 @@ public: FROM {} WHERE ledger_sequence = ? )", - qualifiedTableName(settingsProvider_.get(), "ledger_transactions"))); + qualifiedTableName(settingsProvider_.get(), "ledger_transactions") + )); }(); PreparedStatement selectLedgerPageKeys = [this]() { @@ -489,7 +520,8 @@ public: LIMIT ? ALLOW FILTERING )", - qualifiedTableName(settingsProvider_.get(), "objects"))); + qualifiedTableName(settingsProvider_.get(), "objects") + )); }(); PreparedStatement selectLedgerPage = [this]() { @@ -503,7 +535,8 @@ public: LIMIT ? ALLOW FILTERING )", - qualifiedTableName(settingsProvider_.get(), "objects"))); + qualifiedTableName(settingsProvider_.get(), "objects") + )); }(); PreparedStatement getToken = [this]() { @@ -514,7 +547,8 @@ public: WHERE key = ? LIMIT 1 )", - qualifiedTableName(settingsProvider_.get(), "objects"))); + qualifiedTableName(settingsProvider_.get(), "objects") + )); }(); PreparedStatement selectAccountTx = [this]() { @@ -526,7 +560,8 @@ public: AND seq_idx < ? LIMIT ? )", - qualifiedTableName(settingsProvider_.get(), "account_tx"))); + qualifiedTableName(settingsProvider_.get(), "account_tx") + )); }(); PreparedStatement selectAccountTxForward = [this]() { @@ -539,7 +574,8 @@ public: ORDER BY seq_idx ASC LIMIT ? )", - qualifiedTableName(settingsProvider_.get(), "account_tx"))); + qualifiedTableName(settingsProvider_.get(), "account_tx") + )); }(); PreparedStatement selectNFT = [this]() { @@ -552,7 +588,8 @@ public: ORDER BY sequence DESC LIMIT 1 )", - qualifiedTableName(settingsProvider_.get(), "nf_tokens"))); + qualifiedTableName(settingsProvider_.get(), "nf_tokens") + )); }(); PreparedStatement selectNFTURI = [this]() { @@ -565,7 +602,8 @@ public: ORDER BY sequence DESC LIMIT 1 )", - qualifiedTableName(settingsProvider_.get(), "nf_token_uris"))); + qualifiedTableName(settingsProvider_.get(), "nf_token_uris") + )); }(); PreparedStatement selectNFTTx = [this]() { @@ -578,7 +616,8 @@ public: ORDER BY seq_idx DESC LIMIT ? )", - qualifiedTableName(settingsProvider_.get(), "nf_token_transactions"))); + qualifiedTableName(settingsProvider_.get(), "nf_token_transactions") + )); }(); PreparedStatement selectNFTTxForward = [this]() { @@ -591,7 +630,8 @@ public: ORDER BY seq_idx ASC LIMIT ? )", - qualifiedTableName(settingsProvider_.get(), "nf_token_transactions"))); + qualifiedTableName(settingsProvider_.get(), "nf_token_transactions") + )); }(); PreparedStatement selectLedgerByHash = [this]() { @@ -602,7 +642,8 @@ public: WHERE hash = ? LIMIT 1 )", - qualifiedTableName(settingsProvider_.get(), "ledger_hashes"))); + qualifiedTableName(settingsProvider_.get(), "ledger_hashes") + )); }(); PreparedStatement selectLedgerBySeq = [this]() { @@ -612,7 +653,8 @@ public: FROM {} WHERE sequence = ? )", - qualifiedTableName(settingsProvider_.get(), "ledgers"))); + qualifiedTableName(settingsProvider_.get(), "ledgers") + )); }(); PreparedStatement selectLatestLedger = [this]() { @@ -622,7 +664,8 @@ public: FROM {} WHERE is_latest = true )", - qualifiedTableName(settingsProvider_.get(), "ledger_range"))); + qualifiedTableName(settingsProvider_.get(), "ledger_range") + )); }(); PreparedStatement selectLedgerRange = [this]() { @@ -631,7 +674,8 @@ public: SELECT sequence FROM {} )", - qualifiedTableName(settingsProvider_.get(), "ledger_range"))); + qualifiedTableName(settingsProvider_.get(), "ledger_range") + )); }(); }; diff --git a/src/data/cassandra/SettingsProvider.cpp b/src/data/cassandra/SettingsProvider.cpp index ada4ce8d..d13d4ec4 100644 --- a/src/data/cassandra/SettingsProvider.cpp +++ b/src/data/cassandra/SettingsProvider.cpp @@ -35,11 +35,8 @@ namespace detail { inline Settings::ContactPoints tag_invoke(boost::json::value_to_tag, boost::json::value const& value) { - if (not value.is_object()) - { - throw std::runtime_error( - "Feed entire Cassandra section to parse " - "Settings::ContactPoints instead"); + if (not value.is_object()) { + throw std::runtime_error("Feed entire Cassandra section to parse Settings::ContactPoints instead"); } util::Config const obj{value}; @@ -79,18 +76,15 @@ SettingsProvider::getSettings() const std::optional SettingsProvider::parseOptionalCertificate() const { - if (auto const certPath = config_.maybeValue("certfile"); certPath) - { + if (auto const certPath = config_.maybeValue("certfile"); certPath) { auto const path = std::filesystem::path(*certPath); std::ifstream fileStream(path.string(), std::ios::in); - if (!fileStream) - { + if (!fileStream) { throw std::system_error(errno, std::generic_category(), "Opening certificate " + path.string()); } std::string contents(std::istreambuf_iterator{fileStream}, std::istreambuf_iterator{}); - if (fileStream.bad()) - { + if (fileStream.bad()) { throw std::system_error(errno, std::generic_category(), "Reading certificate " + path.string()); } @@ -104,12 +98,9 @@ Settings SettingsProvider::parseSettings() const { auto settings = Settings::defaultSettings(); - if (auto const bundle = config_.maybeValue("secure_connect_bundle"); bundle) - { + if (auto const bundle = config_.maybeValue("secure_connect_bundle"); bundle) { settings.connectionInfo = *bundle; - } - else - { + } else { settings.connectionInfo = config_.valueOrThrow("Missing contact_points in Cassandra config"); } diff --git a/src/data/cassandra/SettingsProvider.h b/src/data/cassandra/SettingsProvider.h index 4dfc276a..0d3c8969 100644 --- a/src/data/cassandra/SettingsProvider.h +++ b/src/data/cassandra/SettingsProvider.h @@ -30,8 +30,7 @@ namespace data::cassandra { /** * @brief Provides settings for @ref BasicCassandraBackend. */ -class SettingsProvider -{ +class SettingsProvider { util::Config config_; std::string keyspace_; diff --git a/src/data/cassandra/Types.h b/src/data/cassandra/Types.h index b3deaa37..1df1c96d 100644 --- a/src/data/cassandra/Types.h +++ b/src/data/cassandra/Types.h @@ -52,8 +52,7 @@ using Batch = detail::Batch; * because clio uses bigint (int64) everywhere except for when one need * to specify LIMIT, which needs an int32 :-/ */ -struct Limit -{ +struct Limit { int32_t limit; }; diff --git a/src/data/cassandra/impl/AsyncExecutor.h b/src/data/cassandra/impl/AsyncExecutor.h index a2d066ac..6c4ad86b 100644 --- a/src/data/cassandra/impl/AsyncExecutor.h +++ b/src/data/cassandra/impl/AsyncExecutor.h @@ -48,8 +48,7 @@ template < typename StatementType, typename HandleType = Handle, SomeRetryPolicy RetryPolicyType = ExponentialBackoffRetryPolicy> -class AsyncExecutor : public std::enable_shared_from_this> -{ +class AsyncExecutor : public std::enable_shared_from_this> { using FutureWithCallbackType = typename HandleType::FutureWithCallbackType; using CallbackType = std::function; using RetryCallbackType = std::function; @@ -77,13 +76,13 @@ public: RetryCallbackType&& onRetry) { // this is a helper that allows us to use std::make_shared below - struct EnableMakeShared : public AsyncExecutor - { + struct EnableMakeShared : public AsyncExecutor { EnableMakeShared( boost::asio::io_context& ioc, StatementType&& data, CallbackType&& onComplete, - RetryCallbackType&& onRetry) + RetryCallbackType&& onRetry + ) : AsyncExecutor(ioc, std::move(data), std::move(onComplete), std::move(onRetry)) { } @@ -98,7 +97,8 @@ private: boost::asio::io_context& ioc, StatementType&& data, CallbackType&& onComplete, - RetryCallbackType&& onRetry) + RetryCallbackType&& onRetry + ) : data_{std::move(data)}, retryPolicy_{ioc}, onComplete_{std::move(onComplete)}, onRetry_{std::move(onRetry)} { } @@ -110,19 +110,13 @@ private: // lifetime is extended by capturing self ptr auto handler = [this, &handle, self](auto&& res) mutable { - if (res) - { + if (res) { onComplete_(std::forward(res)); - } - else - { - if (retryPolicy_.shouldRetry(res.error())) - { + } else { + if (retryPolicy_.shouldRetry(res.error())) { onRetry_(); retryPolicy_.retry([self, &handle]() { self->execute(handle); }); - } - else - { + } else { onComplete_(std::forward(res)); // report error } } diff --git a/src/data/cassandra/impl/Batch.cpp b/src/data/cassandra/impl/Batch.cpp index 1d31d29e..6277eefa 100644 --- a/src/data/cassandra/impl/Batch.cpp +++ b/src/data/cassandra/impl/Batch.cpp @@ -37,8 +37,7 @@ Batch::Batch(std::vector const& statements) { cass_batch_set_is_idempotent(*this, cass_true); - for (auto const& statement : statements) - { + for (auto const& statement : statements) { if (auto const res = add(statement); not res) throw std::runtime_error("Failed to add statement to batch: " + res.error()); } @@ -47,8 +46,7 @@ Batch::Batch(std::vector const& statements) MaybeError Batch::add(Statement const& statement) { - if (auto const rc = cass_batch_add_statement(*this, statement); rc != CASS_OK) - { + if (auto const rc = cass_batch_add_statement(*this, statement); rc != CASS_OK) { return Error{CassandraError{cass_error_desc(rc), rc}}; } return {}; diff --git a/src/data/cassandra/impl/Batch.h b/src/data/cassandra/impl/Batch.h index 1f563b59..b6b1c9fb 100644 --- a/src/data/cassandra/impl/Batch.h +++ b/src/data/cassandra/impl/Batch.h @@ -26,8 +26,7 @@ namespace data::cassandra::detail { -struct Batch : public ManagedObject -{ +struct Batch : public ManagedObject { Batch(std::vector const& statements); MaybeError diff --git a/src/data/cassandra/impl/Cluster.cpp b/src/data/cassandra/impl/Cluster.cpp index 2a6f6ac4..08ac03ed 100644 --- a/src/data/cassandra/impl/Cluster.cpp +++ b/src/data/cassandra/impl/Cluster.cpp @@ -31,8 +31,7 @@ namespace { constexpr auto clusterDeleter = [](CassCluster* ptr) { cass_cluster_free(ptr); }; template -struct overloadSet : Ts... -{ +struct overloadSet : Ts... { using Ts::operator()...; }; @@ -48,16 +47,15 @@ Cluster::Cluster(Settings const& settings) : ManagedObject{cass_cluster_new(), c using std::to_string; cass_cluster_set_token_aware_routing(*this, cass_true); - if (auto const rc = cass_cluster_set_protocol_version(*this, CASS_PROTOCOL_VERSION_V4); rc != CASS_OK) - { - throw std::runtime_error( - fmt::format("Error setting cassandra protocol version to v4: {}", cass_error_desc(rc))); + if (auto const rc = cass_cluster_set_protocol_version(*this, CASS_PROTOCOL_VERSION_V4); rc != CASS_OK) { + throw std::runtime_error(fmt::format("Error setting cassandra protocol version to v4: {}", cass_error_desc(rc)) + ); } - if (auto const rc = cass_cluster_set_num_threads_io(*this, settings.threads); rc != CASS_OK) - { + if (auto const rc = cass_cluster_set_num_threads_io(*this, settings.threads); rc != CASS_OK) { throw std::runtime_error( - fmt::format("Error setting cassandra io threads to {}: {}", settings.threads, cass_error_desc(rc))); + fmt::format("Error setting cassandra io threads to {}: {}", settings.threads, cass_error_desc(rc)) + ); } cass_log_set_level(settings.enableLog ? CASS_LOG_TRACE : CASS_LOG_DISABLED); @@ -65,15 +63,13 @@ Cluster::Cluster(Settings const& settings) : ManagedObject{cass_cluster_new(), c cass_cluster_set_request_timeout(*this, settings.requestTimeout.count()); if (auto const rc = cass_cluster_set_core_connections_per_host(*this, settings.coreConnectionsPerHost); - rc != CASS_OK) - { + rc != CASS_OK) { throw std::runtime_error(fmt::format("Could not set core connections per host: {}", cass_error_desc(rc))); } auto const queueSize = settings.queueSizeIO.value_or(settings.maxWriteRequestsOutstanding + settings.maxReadRequestsOutstanding); - if (auto const rc = cass_cluster_set_queue_size_io(*this, queueSize); rc != CASS_OK) - { + if (auto const rc = cass_cluster_set_queue_size_io(*this, queueSize); rc != CASS_OK) { throw std::runtime_error(fmt::format("Could not set queue size for IO per host: {}", cass_error_desc(rc))); } @@ -93,7 +89,8 @@ Cluster::setupConnection(Settings const& settings) overloadSet{ [this](Settings::ContactPoints const& points) { setupContactPoints(points); }, [this](Settings::SecureConnectionBundle const& bundle) { setupSecureBundle(bundle); }}, - settings.connectionInfo); + settings.connectionInfo + ); } void @@ -101,10 +98,10 @@ Cluster::setupContactPoints(Settings::ContactPoints const& points) { using std::to_string; auto throwErrorIfNeeded = [](CassError rc, std::string const& label, std::string const& value) { - if (rc != CASS_OK) - { + if (rc != CASS_OK) { throw std::runtime_error( - fmt::format("Cassandra: Error setting {} [{}]: {}", label, value, cass_error_desc(rc))); + fmt::format("Cassandra: Error setting {} [{}]: {}", label, value, cass_error_desc(rc)) + ); } }; @@ -114,8 +111,7 @@ Cluster::setupContactPoints(Settings::ContactPoints const& points) throwErrorIfNeeded(rc, "contact_points", points.contactPoints); } - if (points.port) - { + if (points.port) { auto const rc = cass_cluster_set_port(*this, points.port.value()); throwErrorIfNeeded(rc, "port", to_string(points.port.value())); } @@ -125,8 +121,7 @@ void Cluster::setupSecureBundle(Settings::SecureConnectionBundle const& bundle) { LOG(log_.debug()) << "Attempt connection using secure bundle"; - if (auto const rc = cass_cluster_set_cloud_secure_connection_bundle(*this, bundle.bundle.data()); rc != CASS_OK) - { + if (auto const rc = cass_cluster_set_cloud_secure_connection_bundle(*this, bundle.bundle.data()); rc != CASS_OK) { throw std::runtime_error("Failed to connect using secure connection bundle " + bundle.bundle); } } diff --git a/src/data/cassandra/impl/Cluster.h b/src/data/cassandra/impl/Cluster.h index 99583081..fcaa00bd 100644 --- a/src/data/cassandra/impl/Cluster.h +++ b/src/data/cassandra/impl/Cluster.h @@ -38,16 +38,14 @@ namespace data::cassandra::detail { /** * @brief Bundles all cassandra settings in one place. */ -struct Settings -{ +struct Settings { static constexpr std::size_t DEFAULT_CONNECTION_TIMEOUT = 10000; static constexpr uint32_t DEFAULT_MAX_WRITE_REQUESTS_OUTSTANDING = 10'000; static constexpr uint32_t DEFAULT_MAX_READ_REQUESTS_OUTSTANDING = 100'000; /** * @brief Represents the configuration of contact points for cassandra. */ - struct ContactPoints - { + struct ContactPoints { std::string contactPoints = "127.0.0.1"; // defaults to localhost std::optional port = {}; }; @@ -55,8 +53,7 @@ struct Settings /** * @brief Represents the configuration of a secure connection bundle. */ - struct SecureConnectionBundle - { + struct SecureConnectionBundle { std::string bundle; // no meaningful default }; @@ -117,8 +114,7 @@ struct Settings } }; -class Cluster : public ManagedObject -{ +class Cluster : public ManagedObject { util::Logger log_{"Backend"}; public: diff --git a/src/data/cassandra/impl/ExecutionStrategy.h b/src/data/cassandra/impl/ExecutionStrategy.h index 478053ba..dc1b25dc 100644 --- a/src/data/cassandra/impl/ExecutionStrategy.h +++ b/src/data/cassandra/impl/ExecutionStrategy.h @@ -49,8 +49,7 @@ namespace data::cassandra::detail { * This is ok for now because we are hopefully going to be getting rid of it entirely later on. */ template -class DefaultExecutionStrategy -{ +class DefaultExecutionStrategy { util::Logger log_{"Backend"}; std::uint32_t maxWriteRequestsOutstanding_; @@ -89,7 +88,8 @@ public: DefaultExecutionStrategy( Settings const& settings, HandleType const& handle, - typename BackendCountersType::PtrType counters = BackendCountersType::make()) + typename BackendCountersType::PtrType counters = BackendCountersType::make() + ) : maxWriteRequestsOutstanding_{settings.maxWriteRequestsOutstanding} , maxReadRequestsOutstanding_{settings.maxReadRequestsOutstanding} , work_{ioc_} @@ -141,11 +141,9 @@ public: writeSync(StatementType const& statement) { counters_->registerWriteSync(); - while (true) - { + while (true) { auto res = handle_.get().execute(statement); - if (res) - { + if (res) { return res; } @@ -194,7 +192,8 @@ public: counters_->registerWriteFinished(); }, - [this]() { counters_->registerWriteRetry(); }); + [this]() { counters_->registerWriteRetry(); } + ); } /** @@ -223,7 +222,8 @@ public: decrementOutstandingRequestCount(); counters_->registerWriteFinished(); }, - [this]() { counters_->registerWriteRetry(); }); + [this]() { counters_->registerWriteRetry(); } + ); } /** @@ -262,8 +262,7 @@ public: counters_->registerReadStarted(numStatements); // todo: perhaps use policy instead - while (true) - { + while (true) { numReadRequestsOutstanding_ += numStatements; auto init = [this, &statements, &future](Self& self) { @@ -272,27 +271,25 @@ public: future.emplace(handle_.get().asyncExecute(statements, [sself](auto&& res) mutable { boost::asio::post( boost::asio::get_associated_executor(*sself), - [sself, res = std::forward(res)]() mutable { sself->complete(std::move(res)); }); + [sself, res = std::forward(res)]() mutable { sself->complete(std::move(res)); } + ); })); }; auto res = boost::asio::async_compose( - init, token, boost::asio::get_associated_executor(token)); + init, token, boost::asio::get_associated_executor(token) + ); numReadRequestsOutstanding_ -= numStatements; - if (res) - { + if (res) { counters_->registerReadFinished(numStatements); return res; } LOG(log_.error()) << "Failed batch read in coroutine: " << res.error(); - try - { + try { throwErrorIfNeeded(res.error()); - } - catch (...) - { + } catch (...) { counters_->registerReadError(numStatements); throw; } @@ -317,8 +314,7 @@ public: counters_->registerReadStarted(); // todo: perhaps use policy instead - while (true) - { + while (true) { ++numReadRequestsOutstanding_; auto init = [this, &statement, &future](Self& self) { auto sself = std::make_shared(std::move(self)); @@ -326,27 +322,25 @@ public: future.emplace(handle_.get().asyncExecute(statement, [sself](auto&& res) mutable { boost::asio::post( boost::asio::get_associated_executor(*sself), - [sself, res = std::forward(res)]() mutable { sself->complete(std::move(res)); }); + [sself, res = std::forward(res)]() mutable { sself->complete(std::move(res)); } + ); })); }; auto res = boost::asio::async_compose( - init, token, boost::asio::get_associated_executor(token)); + init, token, boost::asio::get_associated_executor(token) + ); --numReadRequestsOutstanding_; - if (res) - { + if (res) { counters_->registerReadFinished(); return res; } LOG(log_.error()) << "Failed read in coroutine: " << res.error(); - try - { + try { throwErrorIfNeeded(res.error()); - } - catch (...) - { + } catch (...) { counters_->registerReadError(); throw; } @@ -383,10 +377,10 @@ public: ++errorsCount; // when all async operations complete unblock the result - if (--numOutstanding == 0) - { - boost::asio::post( - boost::asio::get_associated_executor(*sself), [sself]() mutable { sself->complete(); }); + if (--numOutstanding == 0) { + boost::asio::post(boost::asio::get_associated_executor(*sself), [sself]() mutable { + sself->complete(); + }); } }; @@ -396,15 +390,16 @@ public: std::back_inserter(futures), [this, &executionHandler](auto const& statement) { return handle_.get().asyncExecute(statement, executionHandler); - }); + } + ); }; boost::asio::async_compose( - init, token, boost::asio::get_associated_executor(token)); + init, token, boost::asio::get_associated_executor(token) + ); numReadRequestsOutstanding_ -= statements.size(); - if (errorsCount > 0) - { + if (errorsCount > 0) { assert(errorsCount <= statements.size()); counters_->registerReadError(errorsCount); counters_->registerReadFinished(statements.size() - errorsCount); @@ -424,7 +419,8 @@ public: auto entry = future.get(); auto&& res = entry.value(); return std::move(res); - }); + } + ); assert(futures.size() == statements.size()); assert(results.size() == statements.size()); @@ -446,8 +442,7 @@ private: { { std::unique_lock lck(throttleMutex_); - if (!canAddWriteRequest()) - { + if (!canAddWriteRequest()) { LOG(log_.trace()) << "Max outstanding requests reached. " << "Waiting for other requests to finish"; throttleCv_.wait(lck, [this]() { return canAddWriteRequest(); }); @@ -460,8 +455,7 @@ private: decrementOutstandingRequestCount() { // sanity check - if (numWriteRequestsOutstanding_ == 0) - { + if (numWriteRequestsOutstanding_ == 0) { assert(false); throw std::runtime_error("decrementing num outstanding below 0"); } @@ -472,8 +466,7 @@ private: std::lock_guard const lck(throttleMutex_); throttleCv_.notify_one(); } - if (cur == 0) - { + if (cur == 0) { // mutex lock required to prevent race condition around spurious // wakeup std::lock_guard const lck(syncMutex_); diff --git a/src/data/cassandra/impl/Future.cpp b/src/data/cassandra/impl/Future.cpp index 89694c4b..4075644b 100644 --- a/src/data/cassandra/impl/Future.cpp +++ b/src/data/cassandra/impl/Future.cpp @@ -37,8 +37,7 @@ namespace data::cassandra::detail { MaybeError Future::await() const { - if (auto const rc = cass_future_error_code(*this); rc) - { + if (auto const rc = cass_future_error_code(*this); rc) { auto errMsg = [this](std::string const& label) { char const* message = nullptr; std::size_t len = 0; @@ -53,8 +52,7 @@ Future::await() const ResultOrError Future::get() const { - if (auto const rc = cass_future_error_code(*this); rc) - { + if (auto const rc = cass_future_error_code(*this); rc) { auto const errMsg = [this](std::string const& label) { char const* message = nullptr; std::size_t len = 0; @@ -75,8 +73,7 @@ invokeHelper(CassFuture* ptr, void* cbPtr) // stackoverflow.com/questions/77004137/boost-asio-async-compose-gets-stuck-under-load auto* cb = static_cast(cbPtr); auto local = std::make_unique(std::move(*cb)); - if (auto const rc = cass_future_error_code(ptr); rc) - { + if (auto const rc = cass_future_error_code(ptr); rc) { auto const errMsg = [&ptr](std::string const& label) { char const* message = nullptr; std::size_t len = 0; @@ -84,9 +81,7 @@ invokeHelper(CassFuture* ptr, void* cbPtr) return label + ": " + std::string{message, len}; }("invokeHelper"); (*local)(Error{CassandraError{errMsg, rc}}); - } - else - { + } else { (*local)(Result{cass_future_get_result(ptr)}); } } diff --git a/src/data/cassandra/impl/Future.h b/src/data/cassandra/impl/Future.h index 102f6aa9..42356fc1 100644 --- a/src/data/cassandra/impl/Future.h +++ b/src/data/cassandra/impl/Future.h @@ -26,8 +26,7 @@ namespace data::cassandra::detail { -struct Future : public ManagedObject -{ +struct Future : public ManagedObject { /* implicit */ Future(CassFuture* ptr); MaybeError @@ -40,8 +39,7 @@ struct Future : public ManagedObject void invokeHelper(CassFuture* ptr, void* cbPtr); -class FutureWithCallback : public Future -{ +class FutureWithCallback : public Future { public: using FnType = std::function; using FnPtrType = std::unique_ptr; diff --git a/src/data/cassandra/impl/ManagedObject.h b/src/data/cassandra/impl/ManagedObject.h index 11eb1fd7..ff7ec2e7 100644 --- a/src/data/cassandra/impl/ManagedObject.h +++ b/src/data/cassandra/impl/ManagedObject.h @@ -24,8 +24,7 @@ namespace data::cassandra::detail { template -class ManagedObject -{ +class ManagedObject { protected: std::unique_ptr ptr_; diff --git a/src/data/cassandra/impl/Result.h b/src/data/cassandra/impl/Result.h index bcee9ca7..79935136 100644 --- a/src/data/cassandra/impl/Result.h +++ b/src/data/cassandra/impl/Result.h @@ -44,8 +44,7 @@ extractColumn(CassRow const* row, std::size_t idx) Type output; auto throwErrorIfNeeded = [](CassError rc, std::string_view label) { - if (rc != CASS_OK) - { + if (rc != CASS_OK) { auto const tag = '[' + std::string{label} + ']'; throw std::logic_error(tag + ": " + cass_error_desc(rc)); } @@ -55,60 +54,46 @@ extractColumn(CassRow const* row, std::size_t idx) using UintTupleType = std::tuple; using UCharVectorType = std::vector; - if constexpr (std::is_same_v) - { + if constexpr (std::is_same_v) { cass_byte_t const* buf = nullptr; std::size_t bufSize = 0; auto const rc = cass_value_get_bytes(cass_row_get_column(row, idx), &buf, &bufSize); throwErrorIfNeeded(rc, "Extract ripple::uint256"); output = ripple::uint256::fromVoid(buf); - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { cass_byte_t const* buf = nullptr; std::size_t bufSize = 0; auto const rc = cass_value_get_bytes(cass_row_get_column(row, idx), &buf, &bufSize); throwErrorIfNeeded(rc, "Extract ripple::AccountID"); output = ripple::AccountID::fromVoid(buf); - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { cass_byte_t const* buf = nullptr; std::size_t bufSize = 0; auto const rc = cass_value_get_bytes(cass_row_get_column(row, idx), &buf, &bufSize); throwErrorIfNeeded(rc, "Extract vector"); output = UCharVectorType{buf, buf + bufSize}; - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { auto const* tuple = cass_row_get_column(row, idx); output = TupleIterator::fromTuple(tuple).extract(); - } - else if constexpr (std::is_convertible_v) - { + } else if constexpr (std::is_convertible_v) { char const* value = nullptr; std::size_t len = 0; auto const rc = cass_value_get_string(cass_row_get_column(row, idx), &value, &len); throwErrorIfNeeded(rc, "Extract string"); output = std::string{value, len}; - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { cass_bool_t flag = cass_bool_t::cass_false; auto const rc = cass_value_get_bool(cass_row_get_column(row, idx), &flag); throwErrorIfNeeded(rc, "Extract bool"); output = flag != cass_bool_t::cass_false; } // clio only uses bigint (int64_t) so we convert any incoming type - else if constexpr (std::is_convertible_v) - { + else if constexpr (std::is_convertible_v) { int64_t out = 0; auto const rc = cass_value_get_int64(cass_row_get_column(row, idx), &out); throwErrorIfNeeded(rc, "Extract int64"); output = static_cast(out); - } - else - { + } else { // type not supported for extraction static_assert(unsupported_v); } @@ -116,8 +101,7 @@ extractColumn(CassRow const* row, std::size_t idx) return output; } -struct Result : public ManagedObject -{ +struct Result : public ManagedObject { /* implicit */ Result(CassResult const* ptr); [[nodiscard]] std::size_t @@ -128,7 +112,8 @@ struct Result : public ManagedObject template std::optional> - get() const requires(std::tuple_size>{} > 1) + get() const + requires(std::tuple_size>{} > 1) { // row managed internally by cassandra driver, hence no ManagedObject. auto const* row = cass_result_first_row(*this); @@ -153,8 +138,7 @@ struct Result : public ManagedObject } }; -class ResultIterator : public ManagedObject -{ +class ResultIterator : public ManagedObject { bool hasMore_ = false; public: @@ -185,17 +169,13 @@ public: }; template -class ResultExtractor -{ +class ResultExtractor { std::reference_wrapper ref_; public: - struct Sentinel - { - }; + struct Sentinel {}; - struct Iterator - { + struct Iterator { using iterator_category = std::input_iterator_tag; using difference_type = std::size_t; // rows count using value_type = std::tuple; diff --git a/src/data/cassandra/impl/RetryPolicy.h b/src/data/cassandra/impl/RetryPolicy.h index fd37adde..25b67167 100644 --- a/src/data/cassandra/impl/RetryPolicy.h +++ b/src/data/cassandra/impl/RetryPolicy.h @@ -35,8 +35,7 @@ namespace data::cassandra::detail { /** * @brief A retry policy that employs exponential backoff */ -class ExponentialBackoffRetryPolicy -{ +class ExponentialBackoffRetryPolicy { util::Logger log_{"Backend"}; boost::asio::steady_timer timer_; @@ -75,7 +74,7 @@ public: retry(Fn&& fn) { timer_.expires_after(calculateDelay(attempt_++)); - timer_.async_wait([fn = std::forward(fn)]([[maybe_unused]] const auto& err) { + timer_.async_wait([fn = std::forward(fn)]([[maybe_unused]] auto const& err) { // todo: deal with cancellation (thru err) fn(); }); diff --git a/src/data/cassandra/impl/Session.h b/src/data/cassandra/impl/Session.h index dcb79d8e..767fe9c2 100644 --- a/src/data/cassandra/impl/Session.h +++ b/src/data/cassandra/impl/Session.h @@ -25,8 +25,7 @@ namespace data::cassandra::detail { -class Session : public ManagedObject -{ +class Session : public ManagedObject { static constexpr auto deleter = [](CassSession* ptr) { cass_session_free(ptr); }; public: diff --git a/src/data/cassandra/impl/SslContext.cpp b/src/data/cassandra/impl/SslContext.cpp index 91772e55..53fc1464 100644 --- a/src/data/cassandra/impl/SslContext.cpp +++ b/src/data/cassandra/impl/SslContext.cpp @@ -28,8 +28,7 @@ namespace data::cassandra::detail { SslContext::SslContext(std::string const& certificate) : ManagedObject{cass_ssl_new(), contextDeleter} { cass_ssl_set_verify_flags(*this, CASS_SSL_VERIFY_NONE); - if (auto const rc = cass_ssl_add_trusted_cert(*this, certificate.c_str()); rc != CASS_OK) - { + if (auto const rc = cass_ssl_add_trusted_cert(*this, certificate.c_str()); rc != CASS_OK) { throw std::runtime_error(std::string{"Error setting Cassandra SSL Context: "} + cass_error_desc(rc)); } } diff --git a/src/data/cassandra/impl/SslContext.h b/src/data/cassandra/impl/SslContext.h index e82b2252..4bb47d5c 100644 --- a/src/data/cassandra/impl/SslContext.h +++ b/src/data/cassandra/impl/SslContext.h @@ -27,8 +27,7 @@ namespace data::cassandra::detail { -struct SslContext : public ManagedObject -{ +struct SslContext : public ManagedObject { explicit SslContext(std::string const& certificate); }; diff --git a/src/data/cassandra/impl/Statement.h b/src/data/cassandra/impl/Statement.h index 6bb53fde..d4fd698e 100644 --- a/src/data/cassandra/impl/Statement.h +++ b/src/data/cassandra/impl/Statement.h @@ -35,8 +35,7 @@ namespace data::cassandra::detail { -class Statement : public ManagedObject -{ +class Statement : public ManagedObject { static constexpr auto deleter = [](CassStatement* ptr) { cass_statement_free(ptr); }; template @@ -101,50 +100,34 @@ public: using UCharVectorType = std::vector; using UintTupleType = std::tuple; - if constexpr (std::is_same_v) - { + if constexpr (std::is_same_v) { auto const rc = bindBytes(value.data(), value.size()); throwErrorIfNeeded(rc, "Bind ripple::uint256"); - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { auto const rc = bindBytes(value.data(), value.size()); throwErrorIfNeeded(rc, "Bind ripple::AccountID"); - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { auto const rc = bindBytes(value.data(), value.size()); throwErrorIfNeeded(rc, "Bind vector"); - } - else if constexpr (std::is_convertible_v) - { + } else if constexpr (std::is_convertible_v) { // reinterpret_cast is needed here :'( auto const rc = bindBytes(reinterpret_cast(value.data()), value.size()); throwErrorIfNeeded(rc, "Bind string (as bytes)"); - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { auto const rc = cass_statement_bind_tuple(*this, idx, Tuple{std::forward(value)}); throwErrorIfNeeded(rc, "Bind tuple"); - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { auto const rc = cass_statement_bind_bool(*this, idx, value ? cass_true : cass_false); throwErrorIfNeeded(rc, "Bind bool"); - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { auto const rc = cass_statement_bind_int32(*this, idx, value.limit); throwErrorIfNeeded(rc, "Bind limit (int32)"); } // clio only uses bigint (int64_t) so we convert any incoming type - else if constexpr (std::is_convertible_v) - { + else if constexpr (std::is_convertible_v) { auto const rc = cass_statement_bind_int64(*this, idx, value); throwErrorIfNeeded(rc, "Bind int64"); - } - else - { + } else { // type not supported for binding static_assert(unsupported_v); } @@ -156,8 +139,7 @@ public: * * This is used to produce Statement objects that can be executed. */ -class PreparedStatement : public ManagedObject -{ +class PreparedStatement : public ManagedObject { static constexpr auto deleter = [](CassPrepared const* ptr) { cass_prepared_free(ptr); }; public: diff --git a/src/data/cassandra/impl/Tuple.h b/src/data/cassandra/impl/Tuple.h index 3db5f6c6..94c26463 100644 --- a/src/data/cassandra/impl/Tuple.h +++ b/src/data/cassandra/impl/Tuple.h @@ -30,8 +30,7 @@ namespace data::cassandra::detail { -class Tuple : public ManagedObject -{ +class Tuple : public ManagedObject { static constexpr auto deleter = [](CassTuple* ptr) { cass_tuple_free(ptr); }; template @@ -61,8 +60,7 @@ public: { using std::to_string; auto throwErrorIfNeeded = [idx](CassError rc, std::string_view label) { - if (rc != CASS_OK) - { + if (rc != CASS_OK) { auto const tag = '[' + std::string{label} + ']'; throw std::logic_error(tag + " at idx " + to_string(idx) + ": " + cass_error_desc(rc)); } @@ -70,27 +68,22 @@ public: using DecayedType = std::decay_t; - if constexpr (std::is_same_v) - { + if constexpr (std::is_same_v) { auto const rc = cass_tuple_set_bool(*this, idx, value ? cass_true : cass_false); throwErrorIfNeeded(rc, "Bind bool"); } // clio only uses bigint (int64_t) so we convert any incoming type - else if constexpr (std::is_convertible_v) - { + else if constexpr (std::is_convertible_v) { auto const rc = cass_tuple_set_int64(*this, idx, value); throwErrorIfNeeded(rc, "Bind int64"); - } - else - { + } else { // type not supported for binding static_assert(unsupported_v); } } }; -class TupleIterator : public ManagedObject -{ +class TupleIterator : public ManagedObject { template static constexpr bool unsupported_v = false; @@ -119,8 +112,7 @@ private: throw std::logic_error("Could not extract next value from tuple iterator"); auto throwErrorIfNeeded = [](CassError rc, std::string_view label) { - if (rc != CASS_OK) - { + if (rc != CASS_OK) { auto const tag = '[' + std::string{label} + ']'; throw std::logic_error(tag + ": " + cass_error_desc(rc)); } @@ -129,15 +121,12 @@ private: using DecayedType = std::decay_t; // clio only uses bigint (int64_t) so we convert any incoming type - if constexpr (std::is_convertible_v) - { + if constexpr (std::is_convertible_v) { int64_t out = 0; auto const rc = cass_value_get_int64(cass_iterator_get_value(*this), &out); throwErrorIfNeeded(rc, "Extract int64 from tuple"); output = static_cast(out); - } - else - { + } else { // type not supported for extraction static_assert(unsupported_v); } diff --git a/src/etl/ETLHelpers.h b/src/etl/ETLHelpers.h index df4b4e3b..d716c552 100644 --- a/src/etl/ETLHelpers.h +++ b/src/etl/ETLHelpers.h @@ -36,8 +36,7 @@ namespace etl { * Any later calls to methods of this datastructure will not wait. Once the datastructure is stopped, the datastructure * remains stopped for the rest of its lifetime. */ -class NetworkValidatedLedgers -{ +class NetworkValidatedLedgers { // max sequence validated by network std::optional max_; @@ -95,12 +94,9 @@ public: { std::unique_lock lck(m_); auto pred = [sequence, this]() -> bool { return (max_ && sequence <= *max_); }; - if (maxWaitMs) - { + if (maxWaitMs) { cv_.wait_for(lck, std::chrono::milliseconds(*maxWaitMs)); - } - else - { + } else { cv_.wait(lck, pred); } return pred(); @@ -115,8 +111,7 @@ public: * added or removed from the queue. These waits are blocking calls. */ template -class ThreadSafeQueue -{ +class ThreadSafeQueue { std::queue queue_; mutable std::mutex m_; @@ -221,8 +216,7 @@ getMarkers(size_t numMarkers) std::vector markers; markers.reserve(numMarkers); ripple::uint256 base{0}; - for (size_t i = 0; i < numMarkers; ++i) - { + for (size_t i = 0; i < numMarkers; ++i) { markers.push_back(base); base.data()[0] += incr; } diff --git a/src/etl/ETLService.cpp b/src/etl/ETLService.cpp index 68bbac41..33c71505 100644 --- a/src/etl/ETLService.cpp +++ b/src/etl/ETLService.cpp @@ -36,8 +36,7 @@ ETLService::runETLPipeline(uint32_t startSequence, uint32_t numExtractors) state_.isWriting = true; auto rng = backend_->hardFetchLedgerRangeNoThrow(); - if (!rng || rng->maxSequence < startSequence - 1) - { + if (!rng || rng->maxSequence < startSequence - 1) { assert(false); throw std::runtime_error("runETLPipeline: parent ledger is null"); } @@ -46,10 +45,10 @@ ETLService::runETLPipeline(uint32_t startSequence, uint32_t numExtractors) auto extractors = std::vector>{}; auto pipe = DataPipeType{numExtractors, startSequence}; - for (auto i = 0u; i < numExtractors; ++i) - { + for (auto i = 0u; i < numExtractors; ++i) { extractors.push_back(std::make_unique( - pipe, networkValidatedLedgers_, ledgerFetcher_, startSequence + i, finishSequence_, state_)); + pipe, networkValidatedLedgers_, ledgerFetcher_, startSequence + i, finishSequence_, state_ + )); } auto transformer = @@ -85,54 +84,40 @@ void ETLService::monitor() { auto rng = backend_->hardFetchLedgerRangeNoThrow(); - if (!rng) - { + if (!rng) { LOG(log_.info()) << "Database is empty. Will download a ledger from the network."; std::optional ledger; - try - { - if (startSequence_) - { + try { + if (startSequence_) { LOG(log_.info()) << "ledger sequence specified in config. " << "Will begin ETL process starting with ledger " << *startSequence_; ledger = ledgerLoader_.loadInitialLedger(*startSequence_); - } - else - { + } else { LOG(log_.info()) << "Waiting for next ledger to be validated by network..."; std::optional mostRecentValidated = networkValidatedLedgers_->getMostRecent(); - if (mostRecentValidated) - { + if (mostRecentValidated) { LOG(log_.info()) << "Ledger " << *mostRecentValidated << " has been validated. Downloading..."; ledger = ledgerLoader_.loadInitialLedger(*mostRecentValidated); - } - else - { - LOG(log_.info()) << "The wait for the next validated ledger has been aborted. Exiting monitor loop"; + } else { + LOG(log_.info()) << "The wait for the next validated ledger has been aborted. " + "Exiting monitor loop"; return; } } - } - catch (std::runtime_error const& e) - { + } catch (std::runtime_error const& e) { LOG(log_.fatal()) << "Failed to load initial ledger: " << e.what(); return amendmentBlockHandler_.onAmendmentBlock(); } - if (ledger) - { + if (ledger) { rng = backend_->hardFetchLedgerRangeNoThrow(); - } - else - { + } else { LOG(log_.error()) << "Failed to load initial ledger. Exiting monitor loop"; return; } - } - else - { + } else { if (startSequence_) LOG(log_.warn()) << "start sequence specified but db is already populated"; @@ -146,8 +131,7 @@ ETLService::monitor() LOG(log_.debug()) << "Database is populated. " << "Starting monitor loop. sequence = " << nextSequence; - while (true) - { + while (true) { nextSequence = publishNextSequence(nextSequence); } } @@ -155,13 +139,10 @@ ETLService::monitor() uint32_t ETLService::publishNextSequence(uint32_t nextSequence) { - if (auto rng = backend_->hardFetchLedgerRangeNoThrow(); rng && rng->maxSequence >= nextSequence) - { + if (auto rng = backend_->hardFetchLedgerRangeNoThrow(); rng && rng->maxSequence >= nextSequence) { ledgerPublisher_.publish(nextSequence, {}); ++nextSequence; - } - else if (networkValidatedLedgers_->waitUntilValidatedByNetwork(nextSequence, util::MILLISECONDS_PER_SECOND)) - { + } else if (networkValidatedLedgers_->waitUntilValidatedByNetwork(nextSequence, util::MILLISECONDS_PER_SECOND)) { LOG(log_.info()) << "Ledger with sequence = " << nextSequence << " has been validated by the network. " << "Attempting to find in database and publish"; @@ -174,8 +155,7 @@ ETLService::publishNextSequence(uint32_t nextSequence) constexpr size_t timeoutSeconds = 10; bool const success = ledgerPublisher_.publish(nextSequence, timeoutSeconds); - if (!success) - { + if (!success) { LOG(log_.warn()) << "Failed to publish ledger with sequence = " << nextSequence << " . Beginning ETL"; // returns the most recent sequence published empty optional if no sequence was published @@ -185,9 +165,7 @@ ETLService::publishNextSequence(uint32_t nextSequence) // if no ledger was published, don't increment nextSequence if (lastPublished) nextSequence = *lastPublished + 1; - } - else - { + } else { ++nextSequence; } } @@ -199,13 +177,11 @@ ETLService::monitorReadOnly() { LOG(log_.debug()) << "Starting reporting in strict read only mode"; - const auto latestSequenceOpt = [this]() -> std::optional { + auto const latestSequenceOpt = [this]() -> std::optional { auto rng = backend_->hardFetchLedgerRangeNoThrow(); - if (!rng) - { - if (auto net = networkValidatedLedgers_->getMostRecent()) - { + if (!rng) { + if (auto net = networkValidatedLedgers_->getMostRecent()) { return *net; } return std::nullopt; @@ -214,8 +190,7 @@ ETLService::monitorReadOnly() return rng->maxSequence; }(); - if (!latestSequenceOpt.has_value()) - { + if (!latestSequenceOpt.has_value()) { return; } @@ -224,17 +199,14 @@ ETLService::monitorReadOnly() cacheLoader_.load(latestSequence); latestSequence++; - while (true) - { - if (auto rng = backend_->hardFetchLedgerRangeNoThrow(); rng && rng->maxSequence >= latestSequence) - { + while (true) { + if (auto rng = backend_->hardFetchLedgerRangeNoThrow(); rng && rng->maxSequence >= latestSequence) { ledgerPublisher_.publish(latestSequence, {}); latestSequence = latestSequence + 1; - } - else - { - // if we can't, wait until it's validated by the network, or 1 second passes, whichever occurs first. - // Even if we don't hear from rippled, if ledgers are being written to the db, we publish them. + } else { + // if we can't, wait until it's validated by the network, or 1 second passes, whichever occurs + // first. Even if we don't hear from rippled, if ledgers are being written to the db, we publish + // them. networkValidatedLedgers_->waitUntilValidatedByNetwork(latestSequence, util::MILLISECONDS_PER_SECOND); } } @@ -255,12 +227,9 @@ ETLService::doWork() worker_ = std::thread([this]() { beast::setCurrentThreadName("ETLService worker"); - if (state_.isReadOnly) - { + if (state_.isReadOnly) { monitorReadOnly(); - } - else - { + } else { monitor(); } }); @@ -272,7 +241,8 @@ ETLService::ETLService( std::shared_ptr backend, std::shared_ptr subscriptions, std::shared_ptr balancer, - std::shared_ptr ledgers) + std::shared_ptr ledgers +) : backend_(backend) , loadBalancer_(balancer) , networkValidatedLedgers_(std::move(ledgers)) diff --git a/src/etl/ETLService.h b/src/etl/ETLService.h index bc774935..c0d5036f 100644 --- a/src/etl/ETLService.h +++ b/src/etl/ETLService.h @@ -66,8 +66,7 @@ namespace etl { * the others will fall back to monitoring/publishing. In this sense, this class dynamically transitions from monitoring * to writing and from writing to monitoring, based on the activity of other processes running on different machines. */ -class ETLService -{ +class ETLService { // TODO: make these template parameters in ETLService using SubscriptionManagerType = feed::SubscriptionManager; using LoadBalancerType = LoadBalancer; @@ -122,7 +121,8 @@ public: std::shared_ptr backend, std::shared_ptr subscriptions, std::shared_ptr balancer, - std::shared_ptr ledgers); + std::shared_ptr ledgers + ); /** * @brief A factory function to spawn new ETLService instances. @@ -143,7 +143,8 @@ public: std::shared_ptr backend, std::shared_ptr subscriptions, std::shared_ptr balancer, - std::shared_ptr ledgers) + std::shared_ptr ledgers + ) { auto etl = std::make_shared(config, ioc, backend, subscriptions, balancer, ledgers); etl->run(); diff --git a/src/etl/ETLState.cpp b/src/etl/ETLState.cpp index b3ce211e..3d1dd6a5 100644 --- a/src/etl/ETLState.cpp +++ b/src/etl/ETLState.cpp @@ -43,10 +43,8 @@ tag_invoke(boost::json::value_to_tag, boost::json::value const& jv) ETLState state; auto const& jsonObject = jv.as_object(); - if (!jsonObject.contains(JS(error))) - { - if (jsonObject.contains(JS(result)) && jsonObject.at(JS(result)).as_object().contains(JS(info))) - { + if (!jsonObject.contains(JS(error))) { + if (jsonObject.contains(JS(result)) && jsonObject.at(JS(result)).as_object().contains(JS(info))) { auto const rippledInfo = jsonObject.at(JS(result)).as_object().at(JS(info)).as_object(); if (rippledInfo.contains(JS(network_id))) state.networkID.emplace(boost::json::value_to(rippledInfo.at(JS(network_id)))); diff --git a/src/etl/ETLState.h b/src/etl/ETLState.h index e2685787..857136e7 100644 --- a/src/etl/ETLState.h +++ b/src/etl/ETLState.h @@ -31,8 +31,7 @@ class Source; /** * @brief This class is responsible for fetching and storing the state of the ETL information, such as the network id */ -struct ETLState -{ +struct ETLState { std::optional networkID; /** diff --git a/src/etl/LoadBalancer.cpp b/src/etl/LoadBalancer.cpp index 737a481f..8649bed3 100644 --- a/src/etl/LoadBalancer.cpp +++ b/src/etl/LoadBalancer.cpp @@ -47,7 +47,8 @@ LoadBalancer::make_Source( std::shared_ptr backend, std::shared_ptr subscriptions, std::shared_ptr validatedLedgers, - LoadBalancer& balancer) + LoadBalancer& balancer +) { auto src = std::make_unique(config, ioc, backend, subscriptions, validatedLedgers, balancer); src->run(); @@ -61,7 +62,8 @@ LoadBalancer::make_LoadBalancer( boost::asio::io_context& ioc, std::shared_ptr backend, std::shared_ptr subscriptions, - std::shared_ptr validatedLedgers) + std::shared_ptr validatedLedgers +) { return std::make_shared(config, ioc, backend, subscriptions, validatedLedgers); } @@ -71,34 +73,29 @@ LoadBalancer::LoadBalancer( boost::asio::io_context& ioc, std::shared_ptr backend, std::shared_ptr subscriptions, - std::shared_ptr validatedLedgers) + std::shared_ptr validatedLedgers +) { static constexpr std::uint32_t MAX_DOWNLOAD = 256; - if (auto value = config.maybeValue("num_markers"); value) - { + if (auto value = config.maybeValue("num_markers"); value) { downloadRanges_ = std::clamp(*value, 1u, MAX_DOWNLOAD); - } - else if (backend->fetchLedgerRange()) - { + } else if (backend->fetchLedgerRange()) { downloadRanges_ = 4; } - for (auto const& entry : config.array("etl_sources")) - { + for (auto const& entry : config.array("etl_sources")) { std::unique_ptr source = make_Source(entry, ioc, backend, subscriptions, validatedLedgers, *this); // checking etl node validity auto const state = ETLState::fetchETLStateFromSource(*source); - if (!state.networkID) - { + if (!state.networkID) { LOG(log_.error()) << "Failed to fetch ETL state from source = " << source->toString() << " Please check the configuration and network"; throw std::logic_error("ETL node not available"); } - if (etlState_ && etlState_->networkID != state.networkID) - { + if (etlState_ && etlState_->networkID != state.networkID) { LOG(log_.error()) << "ETL sources must be on the same network. " << "Source network id = " << *(state.networkID) << " does not match others network id = " << *(etlState_->networkID); @@ -109,8 +106,7 @@ LoadBalancer::LoadBalancer( LOG(log_.info()) << "Added etl source - " << sources_.back()->toString(); } - if (sources_.empty()) - { + if (sources_.empty()) { LOG(log_.error()) << "No ETL sources configured. Please check the configuration"; throw std::logic_error("No ETL sources configured"); } @@ -129,19 +125,17 @@ LoadBalancer::loadInitialLedger(uint32_t sequence, bool cacheOnly) [this, &response, &sequence, cacheOnly](auto& source) { auto [data, res] = source->loadInitialLedger(sequence, downloadRanges_, cacheOnly); - if (!res) - { + if (!res) { LOG(log_.error()) << "Failed to download initial ledger." << " Sequence = " << sequence << " source = " << source->toString(); - } - else - { + } else { response = std::move(data); } return res; }, - sequence); + sequence + ); return {std::move(response), success}; } @@ -153,8 +147,7 @@ LoadBalancer::fetchLedger(uint32_t ledgerSequence, bool getObjects, bool getObje [&response, ledgerSequence, getObjects, getObjectNeighbors, log = log_](auto& source) { auto [status, data] = source->fetchLedger(ledgerSequence, getObjects, getObjectNeighbors); response = std::move(data); - if (status.ok() && response.validated()) - { + if (status.ok() && response.validated()) { LOG(log.info()) << "Successfully fetched ledger = " << ledgerSequence << " from source = " << source->toString(); return true; @@ -165,9 +158,9 @@ LoadBalancer::fetchLedger(uint32_t ledgerSequence, bool getObjects, bool getObje << ", source = " << source->toString(); return false; }, - ledgerSequence); - if (success) - { + ledgerSequence + ); + if (success) { return response; } return {}; @@ -177,14 +170,14 @@ std::optional LoadBalancer::forwardToRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { srand(static_cast(time(0))); auto sourceIdx = rand() % sources_.size(); auto numAttempts = 0u; - while (numAttempts < sources_.size()) - { + while (numAttempts < sources_.size()) { if (auto res = sources_[sourceIdx]->forwardToRippled(request, clientIp, yield)) return res; @@ -198,8 +191,7 @@ LoadBalancer::forwardToRippled( bool LoadBalancer::shouldPropagateTxnStream(Source* in) const { - for (auto& src : sources_) - { + for (auto& src : sources_) { assert(src); // We pick the first Source encountered that is connected @@ -229,8 +221,7 @@ LoadBalancer::execute(Func f, uint32_t ledgerSequence) auto sourceIdx = rand() % sources_.size(); auto numAttempts = 0; - while (true) - { + while (true) { auto& source = sources_[sourceIdx]; LOG(log_.debug()) << "Attempting to execute func. ledger sequence = " << ledgerSequence @@ -239,11 +230,9 @@ LoadBalancer::execute(Func f, uint32_t ledgerSequence) /* Sometimes rippled has ledger but doesn't actually know. However, but this does NOT happen in the normal case and is safe to remove This || true is only needed when loading full history standalone */ - if (source->hasLedger(ledgerSequence)) - { + if (source->hasLedger(ledgerSequence)) { bool const res = f(source); - if (res) - { + if (res) { LOG(log_.debug()) << "Successfully executed func at source = " << source->toString() << " - ledger sequence = " << ledgerSequence; break; @@ -251,16 +240,13 @@ LoadBalancer::execute(Func f, uint32_t ledgerSequence) LOG(log_.warn()) << "Failed to execute func at source = " << source->toString() << " - ledger sequence = " << ledgerSequence; - } - else - { + } else { LOG(log_.warn()) << "Ledger not present at source = " << source->toString() << " - ledger sequence = " << ledgerSequence; } sourceIdx = (sourceIdx + 1) % sources_.size(); numAttempts++; - if (numAttempts % sources_.size() == 0) - { + if (numAttempts % sources_.size() == 0) { LOG(log_.info()) << "Ledger sequence " << ledgerSequence << " is not yet available from any configured sources. " << "Sleeping and trying again"; diff --git a/src/etl/LoadBalancer.h b/src/etl/LoadBalancer.h index 9a8ab853..d1264a40 100644 --- a/src/etl/LoadBalancer.h +++ b/src/etl/LoadBalancer.h @@ -48,8 +48,7 @@ namespace etl { * which ledgers have been validated by the network, and the range of ledgers each etl source has). This class also * allows requests for ledger data to be load balanced across all possible ETL sources. */ -class LoadBalancer -{ +class LoadBalancer { public: using RawLedgerObjectType = org::xrpl::rpc::v1::RawLedgerObject; using GetLedgerResponseType = org::xrpl::rpc::v1::GetLedgerResponse; @@ -79,7 +78,8 @@ public: boost::asio::io_context& ioc, std::shared_ptr backend, std::shared_ptr subscriptions, - std::shared_ptr validatedLedgers); + std::shared_ptr validatedLedgers + ); /** * @brief A factory function for the load balancer. @@ -96,7 +96,8 @@ public: boost::asio::io_context& ioc, std::shared_ptr backend, std::shared_ptr subscriptions, - std::shared_ptr validatedLedgers); + std::shared_ptr validatedLedgers + ); /** * @brief A factory function for the ETL source. @@ -115,7 +116,8 @@ public: std::shared_ptr backend, std::shared_ptr subscriptions, std::shared_ptr validatedLedgers, - LoadBalancer& balancer); + LoadBalancer& balancer + ); ~LoadBalancer(); @@ -174,7 +176,8 @@ public: forwardToRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const; + boost::asio::yield_context yield + ) const; /** * @brief Return state of ETL nodes. diff --git a/src/etl/NFTHelpers.cpp b/src/etl/NFTHelpers.cpp index 04ac884c..40c7b4ca 100644 --- a/src/etl/NFTHelpers.cpp +++ b/src/etl/NFTHelpers.cpp @@ -45,27 +45,26 @@ getNFTokenMintData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) // that were changed. std::optional owner; - for (ripple::STObject const& node : txMeta.getNodes()) - { + for (ripple::STObject const& node : txMeta.getNodes()) { if (node.getFieldU16(ripple::sfLedgerEntryType) != ripple::ltNFTOKEN_PAGE) continue; if (!owner) owner = ripple::AccountID::fromVoid(node.getFieldH256(ripple::sfLedgerIndex).data()); - if (node.getFName() == ripple::sfCreatedNode) - { + if (node.getFName() == ripple::sfCreatedNode) { ripple::STArray const& toAddNFTs = node.peekAtField(ripple::sfNewFields).downcast().getFieldArray(ripple::sfNFTokens); std::transform( - toAddNFTs.begin(), toAddNFTs.end(), std::back_inserter(finalIDs), [](ripple::STObject const& nft) { - return nft.getFieldH256(ripple::sfNFTokenID); - }); + toAddNFTs.begin(), + toAddNFTs.end(), + std::back_inserter(finalIDs), + [](ripple::STObject const& nft) { return nft.getFieldH256(ripple::sfNFTokenID); } + ); } // Else it's modified, as there should never be a deleted NFToken page // as a result of a mint. - else - { + else { // When a mint results in splitting an existing page, // it results in a created page and a modified node. Sometimes, // the created node needs to be linked to a third page, resulting @@ -82,9 +81,11 @@ getNFTokenMintData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) ripple::STArray const& toAddNFTs = previousFields.getFieldArray(ripple::sfNFTokens); std::transform( - toAddNFTs.begin(), toAddNFTs.end(), std::back_inserter(prevIDs), [](ripple::STObject const& nft) { - return nft.getFieldH256(ripple::sfNFTokenID); - }); + toAddNFTs.begin(), + toAddNFTs.end(), + std::back_inserter(prevIDs), + [](ripple::STObject const& nft) { return nft.getFieldH256(ripple::sfNFTokenID); } + ); ripple::STArray const& toAddFinalNFTs = node.peekAtField(ripple::sfFinalFields).downcast().getFieldArray(ripple::sfNFTokens); @@ -92,7 +93,8 @@ getNFTokenMintData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) toAddFinalNFTs.begin(), toAddFinalNFTs.end(), std::back_inserter(finalIDs), - [](ripple::STObject const& nft) { return nft.getFieldH256(ripple::sfNFTokenID); }); + [](ripple::STObject const& nft) { return nft.getFieldH256(ripple::sfNFTokenID); } + ); } } @@ -105,10 +107,9 @@ getNFTokenMintData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) // There should always be a difference so the returned finalIDs // iterator should never be end(). But better safe than sorry. - if (finalIDs.size() != prevIDs.size() + 1 || diff.first == finalIDs.end() || !owner) - { - throw std::runtime_error( - fmt::format(" - unexpected NFTokenMint data in tx {}", strHex(sttx.getTransactionID()))); + if (finalIDs.size() != prevIDs.size() + 1 || diff.first == finalIDs.end() || !owner) { + throw std::runtime_error(fmt::format(" - unexpected NFTokenMint data in tx {}", strHex(sttx.getTransactionID())) + ); } return { @@ -125,8 +126,7 @@ getNFTokenBurnData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) // Determine who owned the token when it was burned by finding an // NFTokenPage that was deleted or modified that contains this // tokenID. - for (ripple::STObject const& node : txMeta.getNodes()) - { + for (ripple::STObject const& node : txMeta.getNodes()) { if (node.getFieldU16(ripple::sfLedgerEntryType) != ripple::ltNFTOKEN_PAGE || node.getFName() == ripple::sfCreatedNode) continue; @@ -141,15 +141,12 @@ getNFTokenBurnData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) // need to look in the FinalFields. std::optional prevNFTs; - if (node.isFieldPresent(ripple::sfPreviousFields)) - { + if (node.isFieldPresent(ripple::sfPreviousFields)) { ripple::STObject const& previousFields = node.peekAtField(ripple::sfPreviousFields).downcast(); if (previousFields.isFieldPresent(ripple::sfNFTokens)) prevNFTs = previousFields.getFieldArray(ripple::sfNFTokens); - } - else if (!prevNFTs && node.getFName() == ripple::sfDeletedNode) - { + } else if (!prevNFTs && node.getFName() == ripple::sfDeletedNode) { prevNFTs = node.peekAtField(ripple::sfFinalFields).downcast().getFieldArray(ripple::sfNFTokens); } @@ -161,15 +158,13 @@ getNFTokenBurnData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) std::find_if(prevNFTs->begin(), prevNFTs->end(), [&tokenID](ripple::STObject const& candidate) { return candidate.getFieldH256(ripple::sfNFTokenID) == tokenID; }); - if (nft != prevNFTs->end()) - { + if (nft != prevNFTs->end()) { return std::make_pair( txs, NFTsData( - tokenID, - ripple::AccountID::fromVoid(node.getFieldH256(ripple::sfLedgerIndex).data()), - txMeta, - true)); + tokenID, ripple::AccountID::fromVoid(node.getFieldH256(ripple::sfLedgerIndex).data()), txMeta, true + ) + ); } } @@ -184,14 +179,12 @@ getNFTokenAcceptOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx // If we have the buy offer from this tx, we can determine the owner // more easily by just looking at the owner of the accepted NFTokenOffer // object. - if (sttx.isFieldPresent(ripple::sfNFTokenBuyOffer)) - { + if (sttx.isFieldPresent(ripple::sfNFTokenBuyOffer)) { auto const affectedBuyOffer = std::find_if(txMeta.getNodes().begin(), txMeta.getNodes().end(), [&sttx](ripple::STObject const& node) { return node.getFieldH256(ripple::sfLedgerIndex) == sttx.getFieldH256(ripple::sfNFTokenBuyOffer); }); - if (affectedBuyOffer == txMeta.getNodes().end()) - { + if (affectedBuyOffer == txMeta.getNodes().end()) { std::stringstream msg; msg << " - unexpected NFTokenAcceptOffer data in tx " << sttx.getTransactionID(); throw std::runtime_error(msg.str()); @@ -213,8 +206,7 @@ getNFTokenAcceptOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx std::find_if(txMeta.getNodes().begin(), txMeta.getNodes().end(), [&sttx](ripple::STObject const& node) { return node.getFieldH256(ripple::sfLedgerIndex) == sttx.getFieldH256(ripple::sfNFTokenSellOffer); }); - if (affectedSellOffer == txMeta.getNodes().end()) - { + if (affectedSellOffer == txMeta.getNodes().end()) { std::stringstream msg; msg << " - unexpected NFTokenAcceptOffer data in tx " << sttx.getTransactionID(); throw std::runtime_error(msg.str()); @@ -228,8 +220,7 @@ getNFTokenAcceptOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx .downcast() .getAccountID(ripple::sfOwner); - for (ripple::STObject const& node : txMeta.getNodes()) - { + for (ripple::STObject const& node : txMeta.getNodes()) { if (node.getFieldU16(ripple::sfLedgerEntryType) != ripple::ltNFTOKEN_PAGE || node.getFName() == ripple::sfDeletedNode) continue; @@ -240,8 +231,7 @@ getNFTokenAcceptOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx continue; ripple::STArray const& nfts = [&node] { - if (node.getFName() == ripple::sfCreatedNode) - { + if (node.getFName() == ripple::sfCreatedNode) { return node.peekAtField(ripple::sfNewFields) .downcast() .getFieldArray(ripple::sfNFTokens); @@ -254,8 +244,7 @@ getNFTokenAcceptOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx auto const nft = std::find_if(nfts.begin(), nfts.end(), [&tokenID](ripple::STObject const& candidate) { return candidate.getFieldH256(ripple::sfNFTokenID) == tokenID; }); - if (nft != nfts.end()) - { + if (nft != nfts.end()) { return { {NFTTransactionsData(tokenID, txMeta, sttx.getTransactionID())}, NFTsData(tokenID, nodeOwner, txMeta, false)}; @@ -275,8 +264,7 @@ std::pair, std::optional> getNFTokenCancelOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) { std::vector txs; - for (ripple::STObject const& node : txMeta.getNodes()) - { + for (ripple::STObject const& node : txMeta.getNodes()) { if (node.getFieldU16(ripple::sfLedgerEntryType) != ripple::ltNFTOKEN_OFFER) continue; @@ -312,8 +300,7 @@ getNFTDataFromTx(ripple::TxMeta const& txMeta, ripple::STTx const& sttx) if (txMeta.getResultTER() != ripple::tesSUCCESS) return {{}, {}}; - switch (sttx.getTxnType()) - { + switch (sttx.getTxnType()) { case ripple::TxType::ttNFTOKEN_MINT: return getNFTokenMintData(txMeta, sttx); diff --git a/src/etl/ProbingSource.cpp b/src/etl/ProbingSource.cpp index 3935d4a5..a526aefe 100644 --- a/src/etl/ProbingSource.cpp +++ b/src/etl/ProbingSource.cpp @@ -28,7 +28,8 @@ ProbingSource::ProbingSource( std::shared_ptr subscriptions, std::shared_ptr nwvl, LoadBalancer& balancer, - boost::asio::ssl::context sslCtx) + boost::asio::ssl::context sslCtx +) : sslCtx_{std::move(sslCtx)} , sslSrc_{make_shared< SslSource>(config, ioc, std::ref(sslCtx_), backend, subscriptions, nwvl, balancer, make_SSLHooks())} @@ -74,8 +75,7 @@ ProbingSource::hasLedger(uint32_t sequence) const boost::json::object ProbingSource::toJson() const { - if (!currentSrc_) - { + if (!currentSrc_) { boost::json::object sourcesJson = { {"ws", plainSrc_->toJson()}, {"wss", sslSrc_->toJson()}, @@ -124,7 +124,8 @@ std::optional ProbingSource::forwardToRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { if (!currentSrc_) // Source may connect to rippled before the connection built to check the validity { @@ -140,7 +141,8 @@ std::optional ProbingSource::requestFromRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { if (!currentSrc_) return {}; @@ -156,8 +158,7 @@ ProbingSource::make_SSLHooks() noexcept if (currentSrc_) return SourceHooks::Action::STOP; - if (!ec) - { + if (!ec) { plainSrc_->pause(); currentSrc_ = sslSrc_; LOG(log_.info()) << "Selected WSS as the main source: " << currentSrc_->toString(); @@ -167,8 +168,7 @@ ProbingSource::make_SSLHooks() noexcept // onDisconnected [this](auto /* ec */) { std::lock_guard const lck(mtx_); - if (currentSrc_) - { + if (currentSrc_) { currentSrc_ = nullptr; plainSrc_->resume(); } @@ -185,8 +185,7 @@ ProbingSource::make_PlainHooks() noexcept if (currentSrc_) return SourceHooks::Action::STOP; - if (!ec) - { + if (!ec) { sslSrc_->pause(); currentSrc_ = plainSrc_; LOG(log_.info()) << "Selected Plain WS as the main source: " << currentSrc_->toString(); @@ -196,8 +195,7 @@ ProbingSource::make_PlainHooks() noexcept // onDisconnected [this](auto /* ec */) { std::lock_guard const lck(mtx_); - if (currentSrc_) - { + if (currentSrc_) { currentSrc_ = nullptr; sslSrc_->resume(); } diff --git a/src/etl/ProbingSource.h b/src/etl/ProbingSource.h index 6284f96f..fe5bc9ff 100644 --- a/src/etl/ProbingSource.h +++ b/src/etl/ProbingSource.h @@ -39,8 +39,7 @@ namespace etl { * First to connect pauses the other and the probing is considered done at this point. * If however the connected source loses connection the probing is kickstarted again. */ -class ProbingSource : public Source -{ +class ProbingSource : public Source { public: // TODO: inject when unit tests will be written for ProbingSource using GetLedgerResponseType = org::xrpl::rpc::v1::GetLedgerResponse; @@ -73,7 +72,8 @@ public: std::shared_ptr subscriptions, std::shared_ptr nwvl, LoadBalancer& balancer, - boost::asio::ssl::context sslCtx = boost::asio::ssl::context{boost::asio::ssl::context::tlsv12}); + boost::asio::ssl::context sslCtx = boost::asio::ssl::context{boost::asio::ssl::context::tlsv12} + ); ~ProbingSource() override = default; @@ -108,7 +108,8 @@ public: forwardToRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const override; + boost::asio::yield_context yield + ) const override; boost::uuids::uuid token() const override; @@ -118,7 +119,8 @@ private: requestFromRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const override; + boost::asio::yield_context yield + ) const override; SourceHooks make_SSLHooks() noexcept; diff --git a/src/etl/Source.cpp b/src/etl/Source.cpp index c4acfa5c..e69ca2f7 100644 --- a/src/etl/Source.cpp +++ b/src/etl/Source.cpp @@ -50,27 +50,22 @@ PlainSource::close(bool startAgain) if (closing_) return; - if (derived().ws().is_open()) - { + if (derived().ws().is_open()) { // onStop() also calls close(). If the async_close is called twice, // an assertion fails. Using closing_ makes sure async_close is only // called once closing_ = true; derived().ws().async_close(boost::beast::websocket::close_code::normal, [this, startAgain](auto ec) { - if (ec) - { + if (ec) { LOG(log_.error()) << "async_close: error code = " << ec << " - " << toString(); } closing_ = false; - if (startAgain) - { + if (startAgain) { ws_ = std::make_unique(strand_); run(); } }); - } - else if (startAgain) - { + } else if (startAgain) { ws_ = std::make_unique(strand_); run(); } @@ -85,26 +80,21 @@ SslSource::close(bool startAgain) if (closing_) return; - if (derived().ws().is_open()) - { - // onStop() also calls close(). If the async_close is called twice, an assertion fails. Using closing_ makes - // sure async_close is only called once + if (derived().ws().is_open()) { + // onStop() also calls close(). If the async_close is called twice, an assertion fails. Using closing_ + // makes sure async_close is only called once closing_ = true; derived().ws().async_close(boost::beast::websocket::close_code::normal, [this, startAgain](auto ec) { - if (ec) - { + if (ec) { LOG(log_.error()) << "async_close: error code = " << ec << " - " << toString(); } closing_ = false; - if (startAgain) - { + if (startAgain) { ws_ = std::make_unique(strand_, *sslCtx_); run(); } }); - } - else if (startAgain) - { + } else if (startAgain) { ws_ = std::make_unique(strand_, *sslCtx_); run(); } @@ -114,15 +104,13 @@ SslSource::close(bool startAgain) void PlainSource::onConnect( boost::beast::error_code ec, - boost::asio::ip::tcp::resolver::results_type::endpoint_type endpoint) + boost::asio::ip::tcp::resolver::results_type::endpoint_type endpoint +) { - if (ec) - { + if (ec) { // start over reconnect(ec); - } - else - { + } else { connected_ = true; numFailures_ = 0; @@ -134,7 +122,8 @@ PlainSource::onConnect( boost::beast::websocket::stream_base::decorator([](boost::beast::websocket::request_type& req) { req.set(boost::beast::http::field::user_agent, "clio-client"); req.set("X-User", "clio-client"); - })); + }) + ); // Update the host_ string. This will provide the value of the // Host HTTP header during the WebSocket handshake. @@ -147,13 +136,10 @@ PlainSource::onConnect( void SslSource::onConnect(boost::beast::error_code ec, boost::asio::ip::tcp::resolver::results_type::endpoint_type endpoint) { - if (ec) - { + if (ec) { // start over reconnect(ec); - } - else - { + } else { connected_ = true; numFailures_ = 0; @@ -165,28 +151,28 @@ SslSource::onConnect(boost::beast::error_code ec, boost::asio::ip::tcp::resolver boost::beast::websocket::stream_base::decorator([](boost::beast::websocket::request_type& req) { req.set(boost::beast::http::field::user_agent, "clio-client"); req.set("X-User", "clio-client"); - })); + }) + ); // Update the host_ string. This will provide the value of the // Host HTTP header during the WebSocket handshake. // See https://tools.ietf.org/html/rfc7230#section-5.4 auto host = ip_ + ':' + std::to_string(endpoint.port()); - ws().next_layer().async_handshake( - boost::asio::ssl::stream_base::client, [this, endpoint](auto ec) { onSslHandshake(ec, endpoint); }); + ws().next_layer().async_handshake(boost::asio::ssl::stream_base::client, [this, endpoint](auto ec) { + onSslHandshake(ec, endpoint); + }); } } void SslSource::onSslHandshake( boost::beast::error_code ec, - boost::asio::ip::tcp::resolver::results_type::endpoint_type endpoint) + boost::asio::ip::tcp::resolver::results_type::endpoint_type endpoint +) { - if (ec) - { + if (ec) { reconnect(ec); - } - else - { + } else { auto host = ip_ + ':' + std::to_string(endpoint.port()); ws().async_handshake(host, "/", [this](auto ec) { onHandshake(ec); }); } diff --git a/src/etl/Source.h b/src/etl/Source.h index b155582f..d869fb6b 100644 --- a/src/etl/Source.h +++ b/src/etl/Source.h @@ -60,8 +60,7 @@ class ProbingSource; * Note: Since sources below are implemented via CRTP, it sort of makes no sense to have a virtual base class. * We should consider using a vector of ProbingSources instead of vector of unique ptrs to this virtual base. */ -class Source -{ +class Source { public: /** @return true if source is connected; false otherwise */ virtual bool @@ -133,7 +132,8 @@ public: forwardToRippled( boost::json::object const& request, std::optional const& forwardToRippledclientIp, - boost::asio::yield_context yield) const = 0; + boost::asio::yield_context yield + ) const = 0; /** * @return A token that uniquely identifies this source instance. @@ -166,14 +166,14 @@ private: requestFromRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const = 0; + boost::asio::yield_context yield + ) const = 0; }; /** * @brief Hooks for source events such as connects and disconnects. */ -struct SourceHooks -{ +struct SourceHooks { enum class Action { STOP, PROCEED }; std::function onConnected; @@ -186,8 +186,7 @@ struct SourceHooks * @tparam Derived The derived class for CRTP */ template -class SourceImpl : public Source -{ +class SourceImpl : public Source { std::string wsPort_; std::string grpcPort_; @@ -248,7 +247,8 @@ public: std::shared_ptr subscriptions, std::shared_ptr validatedLedgers, LoadBalancer& balancer, - SourceHooks hooks) + SourceHooks hooks + ) : networkValidatedLedgers_(std::move(validatedLedgers)) , backend_(std::move(backend)) , subscriptions_(std::move(subscriptions)) @@ -265,22 +265,19 @@ public: ip_ = config.valueOr("ip", {}); wsPort_ = config.valueOr("ws_port", {}); - if (auto value = config.maybeValue("grpc_port"); value) - { + if (auto value = config.maybeValue("grpc_port"); value) { grpcPort_ = *value; - try - { + try { boost::asio::ip::tcp::endpoint const endpoint{boost::asio::ip::make_address(ip_), std::stoi(grpcPort_)}; std::stringstream ss; ss << endpoint; grpc::ChannelArguments chArgs; chArgs.SetMaxReceiveMessageSize(-1); stub_ = org::xrpl::rpc::v1::XRPLedgerAPIService::NewStub( - grpc::CreateCustomChannel(ss.str(), grpc::InsecureChannelCredentials(), chArgs)); + grpc::CreateCustomChannel(ss.str(), grpc::InsecureChannelCredentials(), chArgs) + ); LOG(log_.debug()) << "Made stub for remote = " << toString(); - } - catch (std::exception const& e) - { + } catch (std::exception const& e) { LOG(log_.debug()) << "Exception while creating stub = " << e.what() << " . Remote = " << toString(); } } @@ -307,7 +304,8 @@ public: requestFromRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const override + boost::asio::yield_context yield + ) const override { LOG(log_.trace()) << "Attempting to forward request to tx. Request = " << boost::json::serialize(request); @@ -319,8 +317,7 @@ public: namespace net = boost::asio; using tcp = boost::asio::ip::tcp; - try - { + try { auto executor = boost::asio::get_associated_executor(yield); beast::error_code ec; tcp::resolver resolver{executor}; @@ -336,8 +333,8 @@ public: if (ec) return {}; - // if client ip is know, change the User-Agent of the handshake and to tell rippled to charge the client IP - // for RPC resources. See "secure_gateway" in + // if client ip is know, change the User-Agent of the handshake and to tell rippled to charge the client + // IP for RPC resources. See "secure_gateway" in // https://github.com/ripple/rippled/blob/develop/cfg/rippled-example.cfg // TODO: user-agent can be clio-[version] @@ -364,8 +361,7 @@ public: auto end = begin + buffer.data().size(); auto parsed = boost::json::parse(std::string(begin, end)); - if (!parsed.is_object()) - { + if (!parsed.is_object()) { LOG(log_.error()) << "Error parsing response: " << std::string{begin, end}; return {}; } @@ -374,9 +370,7 @@ public: response["forwarded"] = true; return response; - } - catch (std::exception const& e) - { + } catch (std::exception const& e) { LOG(log_.error()) << "Encountered exception : " << e.what(); return {}; } @@ -386,14 +380,11 @@ public: hasLedger(uint32_t sequence) const override { std::lock_guard const lck(mtx_); - for (auto& pair : validatedLedgers_) - { - if (sequence >= pair.first && sequence <= pair.second) - { + for (auto& pair : validatedLedgers_) { + if (sequence >= pair.first && sequence <= pair.second) { return true; } - if (sequence < pair.first) - { + if (sequence < pair.first) { // validatedLedgers_ is a sorted list of disjoint ranges // if the sequence comes before this range, the sequence will // come before all subsequent ranges @@ -423,11 +414,10 @@ public: grpc::Status const status = stub_->GetLedger(&context, request, &response); - if (status.ok() && !response.is_unlimited()) - { - log_.warn() - << "is_unlimited is false. Make sure secure_gateway is set correctly on the ETL source. source = " - << toString() << "; status = " << status.error_message(); + if (status.ok() && !response.is_unlimited()) { + log_.warn( + ) << "is_unlimited is false. Make sure secure_gateway is set correctly on the ETL source. source = " + << toString() << "; status = " << status.error_message(); } return {status, std::move(response)}; @@ -452,11 +442,11 @@ public: res["grpc_port"] = grpcPort_; auto last = getLastMsgTime(); - if (last.time_since_epoch().count() != 0) - { + if (last.time_since_epoch().count() != 0) { res["last_msg_age_seconds"] = std::to_string( std::chrono::duration_cast(std::chrono::system_clock::now() - getLastMsgTime()) - .count()); + .count() + ); } return res; @@ -474,8 +464,7 @@ public: std::vector calls; auto markers = getMarkers(numMarkers); - for (size_t i = 0; i < markers.size(); ++i) - { + for (size_t i = 0; i < markers.size(); ++i) { std::optional nextMarker; if (i + 1 < markers.size()) @@ -495,13 +484,11 @@ public: size_t progress = incr; std::vector edgeKeys; - while (numFinished < calls.size() && cq.Next(&tag, &ok)) - { + while (numFinished < calls.size() && cq.Next(&tag, &ok)) { assert(tag); auto ptr = static_cast(tag); - if (!ok) - { + if (!ok) { LOG(log_.error()) << "loadInitialLedger - ok is false"; return {{}, false}; // handle cancelled } @@ -509,8 +496,7 @@ public: LOG(log_.trace()) << "Marker prefix = " << ptr->getMarkerPrefix(); auto result = ptr->process(stub_, cq, *backend_, abort, cacheOnly); - if (result != etl::detail::AsyncCallData::CallStatus::MORE) - { + if (result != etl::detail::AsyncCallData::CallStatus::MORE) { ++numFinished; LOG(log_.debug()) << "Finished a marker. " << "Current number of finished = " << numFinished; @@ -524,8 +510,7 @@ public: if (result == etl::detail::AsyncCallData::CallStatus::ERRORED) abort = true; - if (backend_->cache().size() > progress) - { + if (backend_->cache().size() > progress) { LOG(log_.info()) << "Downloaded " << backend_->cache().size() << " records from rippled"; progress += incr; } @@ -539,10 +524,10 @@ public: forwardToRippled( boost::json::object const& request, std::optional const& clientIp, - boost::asio::yield_context yield) const override + boost::asio::yield_context yield + ) const override { - if (auto resp = forwardCache_.get(request); resp) - { + if (auto resp = forwardCache_.get(request); resp) { LOG(log_.debug()) << "request hit forwardCache"; return resp; } @@ -573,13 +558,10 @@ public: void onResolve(boost::beast::error_code ec, boost::asio::ip::tcp::resolver::results_type results) { - if (ec) - { + if (ec) { // try again reconnect(ec); - } - else - { + } else { static constexpr std::size_t LOWEST_LAYER_TIMEOUT_SECONDS = 30; boost::beast::get_lowest_layer(derived().ws()) .expires_after(std::chrono::seconds(LOWEST_LAYER_TIMEOUT_SECONDS)); @@ -600,13 +582,10 @@ public: if (auto action = hooks_.onConnected(ec); action == SourceHooks::Action::STOP) return; - if (ec) - { + if (ec) { // start over reconnect(ec); - } - else - { + } else { boost::json::object const jv{ {"command", "subscribe"}, {"streams", {"ledger", "manifests", "validations", "transactions_proposed"}}, @@ -617,10 +596,11 @@ public: derived().ws().set_option( boost::beast::websocket::stream_base::decorator([](boost::beast::websocket::request_type& req) { req.set( - boost::beast::http::field::user_agent, - std::string(BOOST_BEAST_VERSION_STRING) + " clio-client"); + boost::beast::http::field::user_agent, std::string(BOOST_BEAST_VERSION_STRING) + " clio-client" + ); req.set("X-User", "coro-client"); - })); + }) + ); // Send subscription message derived().ws().async_write(boost::asio::buffer(s), [this](auto ec, size_t size) { onWrite(ec, size); }); @@ -636,12 +616,9 @@ public: void onWrite(boost::beast::error_code ec, [[maybe_unused]] size_t size) { - if (ec) - { + if (ec) { reconnect(ec); - } - else - { + } else { derived().ws().async_read(readBuffer_, [this](auto ec, size_t size) { onRead(ec, size); }); } } @@ -655,12 +632,9 @@ public: void onRead(boost::beast::error_code ec, size_t size) { - if (ec) - { + if (ec) { reconnect(ec); - } - else - { + } else { handleMessage(size); derived().ws().async_read(readBuffer_, [this](auto ec, size_t size) { onRead(ec, size); }); } @@ -677,8 +651,7 @@ public: { setLastMsgTime(); - try - { + try { auto const msg = boost::beast::buffers_to_string(readBuffer_.data()); readBuffer_.consume(size); @@ -686,65 +659,48 @@ public: auto const response = raw.as_object(); uint32_t ledgerIndex = 0; - if (response.contains("result")) - { + if (response.contains("result")) { auto const& result = response.at("result").as_object(); if (result.contains("ledger_index")) ledgerIndex = result.at("ledger_index").as_int64(); - if (result.contains("validated_ledgers")) - { + if (result.contains("validated_ledgers")) { auto const& validatedLedgers = result.at("validated_ledgers").as_string(); setValidatedRange({validatedLedgers.data(), validatedLedgers.size()}); } LOG(log_.info()) << "Received a message on ledger " << " subscription stream. Message : " << response << " - " << toString(); - } - else if (response.contains("type") && response.at("type") == "ledgerClosed") - { + } else if (response.contains("type") && response.at("type") == "ledgerClosed") { LOG(log_.info()) << "Received a message on ledger " << " subscription stream. Message : " << response << " - " << toString(); - if (response.contains("ledger_index")) - { + if (response.contains("ledger_index")) { ledgerIndex = response.at("ledger_index").as_int64(); } - if (response.contains("validated_ledgers")) - { + if (response.contains("validated_ledgers")) { auto const& validatedLedgers = response.at("validated_ledgers").as_string(); setValidatedRange({validatedLedgers.data(), validatedLedgers.size()}); } - } - else - { - if (balancer_.shouldPropagateTxnStream(this)) - { - if (response.contains("transaction")) - { + } else { + if (balancer_.shouldPropagateTxnStream(this)) { + if (response.contains("transaction")) { forwardCache_.freshen(); subscriptions_->forwardProposedTransaction(response); - } - else if (response.contains("type") && response.at("type") == "validationReceived") - { + } else if (response.contains("type") && response.at("type") == "validationReceived") { subscriptions_->forwardValidation(response); - } - else if (response.contains("type") && response.at("type") == "manifestReceived") - { + } else if (response.contains("type") && response.at("type") == "manifestReceived") { subscriptions_->forwardManifest(response); } } } - if (ledgerIndex != 0) - { + if (ledgerIndex != 0) { LOG(log_.trace()) << "Pushing ledger sequence = " << ledgerIndex << " - " << toString(); networkValidatedLedgers_->push(ledgerIndex); } return true; - } - catch (std::exception const& e) - { + } catch (std::exception const& e) { LOG(log_.error()) << "Exception in handleMessage : " << e.what(); return false; } @@ -780,8 +736,7 @@ protected: // when the timer is cancelled. connection_refused will occur repeatedly std::string err = ec.message(); // if we cannot connect to the transaction processing process - if (ec.category() == boost::asio::error::get_ssl_category()) - { + if (ec.category() == boost::asio::error::get_ssl_category()) { err = std::string(" (") + boost::lexical_cast(ERR_GET_LIB(ec.value())) + "," + boost::lexical_cast(ERR_GET_REASON(ec.value())) + ") "; @@ -793,12 +748,9 @@ protected: LOG(log_.error()) << err; } - if (ec != boost::asio::error::operation_aborted && ec != boost::asio::error::connection_refused) - { + if (ec != boost::asio::error::operation_aborted && ec != boost::asio::error::connection_refused) { LOG(log_.error()) << "error code = " << ec << " - " << toString(); - } - else - { + } else { LOG(log_.warn()) << "error code = " << ec << " - " << toString(); } @@ -833,19 +785,15 @@ private: std::vector> pairs; std::vector ranges; boost::split(ranges, range, boost::is_any_of(",")); - for (auto& pair : ranges) - { + for (auto& pair : ranges) { std::vector minAndMax; boost::split(minAndMax, pair, boost::is_any_of("-")); - if (minAndMax.size() == 1) - { + if (minAndMax.size() == 1) { uint32_t const sequence = std::stoll(minAndMax[0]); pairs.emplace_back(sequence, sequence); - } - else - { + } else { assert(minAndMax.size() == 2); uint32_t const min = std::stoll(minAndMax[0]); uint32_t const max = std::stoll(minAndMax[1]); @@ -871,8 +819,7 @@ private: /** * @brief Implementation of a source that uses a regular, non-secure websocket connection. */ -class PlainSource : public SourceImpl -{ +class PlainSource : public SourceImpl { using StreamType = boost::beast::websocket::stream; std::unique_ptr ws_; @@ -895,7 +842,8 @@ public: std::shared_ptr subscriptions, std::shared_ptr validatedLedgers, LoadBalancer& balancer, - SourceHooks hooks) + SourceHooks hooks + ) : SourceImpl(config, ioc, backend, subscriptions, validatedLedgers, balancer, std::move(hooks)) , ws_(std::make_unique(strand_)) { @@ -929,8 +877,7 @@ public: /** * @brief Implementation of a source that uses a secure websocket connection. */ -class SslSource : public SourceImpl -{ +class SslSource : public SourceImpl { using StreamType = boost::beast::websocket::stream>; std::optional> sslCtx_; std::unique_ptr ws_; @@ -956,7 +903,8 @@ public: std::shared_ptr subscriptions, std::shared_ptr validatedLedgers, LoadBalancer& balancer, - SourceHooks hooks) + SourceHooks hooks + ) : SourceImpl(config, ioc, backend, subscriptions, validatedLedgers, balancer, std::move(hooks)) , sslCtx_(sslCtx) , ws_(std::make_unique(strand_, *sslCtx_)) diff --git a/src/etl/SystemState.h b/src/etl/SystemState.h index bbfa9009..f3694e02 100644 --- a/src/etl/SystemState.h +++ b/src/etl/SystemState.h @@ -26,8 +26,7 @@ namespace etl { /** * @brief Represents the state of the ETL subsystem. */ -struct SystemState -{ +struct SystemState { /** * @brief Whether the process is in strict read-only mode. * diff --git a/src/etl/impl/AmendmentBlock.h b/src/etl/impl/AmendmentBlock.h index 2d7f656f..1e3f0999 100644 --- a/src/etl/impl/AmendmentBlock.h +++ b/src/etl/impl/AmendmentBlock.h @@ -30,21 +30,18 @@ namespace etl::detail { -struct AmendmentBlockAction -{ +struct AmendmentBlockAction { void operator()() { static util::Logger const log{"ETL"}; - LOG(log.fatal()) - << "Can't process new ledgers: The current ETL source is not compatible with the version of the " - "libxrpl Clio is currently using. Please upgrade Clio to a newer version."; + LOG(log.fatal()) << "Can't process new ledgers: The current ETL source is not compatible with the version of " + << "the libxrpl Clio is currently using. Please upgrade Clio to a newer version."; } }; template -class AmendmentBlockHandler -{ +class AmendmentBlockHandler { std::reference_wrapper ctx_; std::reference_wrapper state_; boost::asio::steady_timer timer_; @@ -58,7 +55,8 @@ public: boost::asio::io_context& ioc, SystemState& state, DurationType interval = DurationType{1}, - ActionCallableType&& action = ActionCallableType()) + ActionCallableType&& action = ActionCallableType() + ) : ctx_{std::ref(ioc)} , state_{std::ref(state)} , timer_{ioc} diff --git a/src/etl/impl/AsyncData.h b/src/etl/impl/AsyncData.h index fc4d9e0b..477f143e 100644 --- a/src/etl/impl/AsyncData.h +++ b/src/etl/impl/AsyncData.h @@ -28,8 +28,7 @@ namespace etl::detail { -class AsyncCallData -{ +class AsyncCallData { util::Logger log_{"ETL"}; std::unique_ptr cur_; @@ -47,8 +46,7 @@ public: AsyncCallData(uint32_t seq, ripple::uint256 const& marker, std::optional const& nextMarker) { request_.mutable_ledger()->set_sequence(seq); - if (marker.isNonZero()) - { + if (marker.isNonZero()) { request_.set_marker(marker.data(), ripple::uint256::size()); } request_.set_user("ETL"); @@ -77,25 +75,23 @@ public: grpc::CompletionQueue& cq, BackendInterface& backend, bool abort, - bool cacheOnly = false) + bool cacheOnly = false + ) { LOG(log_.trace()) << "Processing response. " << "Marker prefix = " << getMarkerPrefix(); - if (abort) - { + if (abort) { LOG(log_.error()) << "AsyncCallData aborted"; return CallStatus::ERRORED; } - if (!status_.ok()) - { + if (!status_.ok()) { LOG(log_.error()) << "AsyncCallData status_ not ok: " << " code = " << status_.error_code() << " message = " << status_.error_message(); return CallStatus::ERRORED; } - if (!next_->is_unlimited()) - { - LOG(log_.warn()) << "AsyncCallData is_unlimited is false. Make sure " - "secure_gateway is set correctly at the ETL source"; + if (!next_->is_unlimited()) { + LOG(log_.warn()) << "AsyncCallData is_unlimited is false. " + << "Make sure secure_gateway is set correctly at the ETL source"; } std::swap(cur_, next_); @@ -112,8 +108,7 @@ public: more = false; // if we are not done, make the next async call - if (more) - { + if (more) { request_.set_marker(cur_->marker()); call(stub, cq); } @@ -124,25 +119,23 @@ public: std::vector cacheUpdates; cacheUpdates.reserve(numObjects); - for (int i = 0; i < numObjects; ++i) - { + for (int i = 0; i < numObjects; ++i) { auto& obj = *(cur_->mutable_ledger_objects()->mutable_objects(i)); - if (!more && nextPrefix_ != 0x00) - { + if (!more && nextPrefix_ != 0x00) { if (static_cast(obj.key()[0]) >= nextPrefix_) continue; } cacheUpdates.push_back( - {*ripple::uint256::fromVoidChecked(obj.key()), - {obj.mutable_data()->begin(), obj.mutable_data()->end()}}); - if (!cacheOnly) - { + {*ripple::uint256::fromVoidChecked(obj.key()), {obj.mutable_data()->begin(), obj.mutable_data()->end()}} + ); + if (!cacheOnly) { if (!lastKey_.empty()) backend.writeSuccessor(std::move(lastKey_), request_.ledger().sequence(), std::string{obj.key()}); lastKey_ = obj.key(); backend.writeNFTs(getNFTDataFromObj(request_.ledger().sequence(), obj.key(), obj.data())); backend.writeLedgerObject( - std::move(*obj.mutable_key()), request_.ledger().sequence(), std::move(*obj.mutable_data())); + std::move(*obj.mutable_key()), request_.ledger().sequence(), std::move(*obj.mutable_data()) + ); } } backend.cache().update(cacheUpdates, request_.ledger().sequence(), cacheOnly); @@ -157,7 +150,8 @@ public: context_ = std::make_unique(); std::unique_ptr> rpc( - stub->PrepareAsyncGetLedgerData(context_.get(), request_, &cq)); + stub->PrepareAsyncGetLedgerData(context_.get(), request_, &cq) + ); rpc->StartCall(); @@ -167,8 +161,7 @@ public: std::string getMarkerPrefix() { - if (next_->marker().empty()) - { + if (next_->marker().empty()) { return ""; } return ripple::strHex(std::string{next_->marker().data()[0]}); diff --git a/src/etl/impl/CacheLoader.h b/src/etl/impl/CacheLoader.h index 682718f3..44a6c5a3 100644 --- a/src/etl/impl/CacheLoader.h +++ b/src/etl/impl/CacheLoader.h @@ -40,8 +40,7 @@ namespace etl::detail { * @brief Cache loading interface */ template -class CacheLoader -{ +class CacheLoader { static constexpr size_t DEFAULT_NUM_CACHE_DIFFS = 32; static constexpr size_t DEFAULT_NUM_CACHE_MARKERS = 48; static constexpr size_t DEFAULT_CACHE_PAGE_FETCH_SIZE = 512; @@ -64,8 +63,7 @@ class CacheLoader // number of ledger objects to fetch concurrently per marker during cache download size_t cachePageFetchSize_ = DEFAULT_CACHE_PAGE_FETCH_SIZE; - struct ClioPeer - { + struct ClioPeer { std::string ip; int port{}; }; @@ -80,14 +78,13 @@ public: util::Config const& config, boost::asio::io_context& ioc, std::shared_ptr const& backend, - CacheType& ledgerCache) + CacheType& ledgerCache + ) : ioContext_{std::ref(ioc)}, backend_{backend}, cache_{ledgerCache} { - if (config.contains("cache")) - { + if (config.contains("cache")) { auto const cache = config.section("cache"); - if (auto entry = cache.maybeValue("load"); entry) - { + if (auto entry = cache.maybeValue("load"); entry) { if (boost::iequals(*entry, "sync")) cacheLoadStyle_ = LoadStyle::SYNC; if (boost::iequals(*entry, "async")) @@ -100,10 +97,8 @@ public: numCacheMarkers_ = cache.valueOr("num_markers", numCacheMarkers_); cachePageFetchSize_ = cache.valueOr("page_fetch_size", cachePageFetchSize_); - if (auto peers = cache.maybeArray("peers"); peers) - { - for (auto const& peer : *peers) - { + if (auto peers = cache.maybeArray("peers"); peers) { + for (auto const& peer : *peers) { auto ip = peer.value("ip"); auto port = peer.value("port"); @@ -133,24 +128,20 @@ public: void load(uint32_t seq) { - if (cacheLoadStyle_ == LoadStyle::NOT_AT_ALL) - { + if (cacheLoadStyle_ == LoadStyle::NOT_AT_ALL) { cache_.get().setDisabled(); LOG(log_.warn()) << "Cache is disabled. Not loading"; return; } - if (cache_.get().isFull()) - { + if (cache_.get().isFull()) { assert(false); return; } - if (!clioPeers_.empty()) - { + if (!clioPeers_.empty()) { boost::asio::spawn(ioContext_.get(), [this, seq](boost::asio::yield_context yield) { - for (auto const& peer : clioPeers_) - { + for (auto const& peer : clioPeers_) { // returns true on success if (loadCacheFromClioPeer(seq, peer.ip, std::to_string(peer.port), yield)) return; @@ -166,8 +157,7 @@ public: // If loading synchronously, poll cache until full static constexpr size_t SLEEP_TIME_SECONDS = 10; - while (cacheLoadStyle_ == LoadStyle::SYNC && not cache_.get().isFull()) - { + while (cacheLoadStyle_ == LoadStyle::SYNC && not cache_.get().isFull()) { LOG(log_.debug()) << "Cache not full. Cache size = " << cache_.get().size() << ". Sleeping ..."; std::this_thread::sleep_for(std::chrono::seconds(SLEEP_TIME_SECONDS)); if (cache_.get().isFull()) @@ -187,15 +177,15 @@ private: uint32_t ledgerIndex, std::string const& ip, std::string const& port, - boost::asio::yield_context yield) + boost::asio::yield_context yield + ) { LOG(log_.info()) << "Loading cache from peer. ip = " << ip << " . port = " << port; namespace beast = boost::beast; // from namespace websocket = beast::websocket; // from namespace net = boost::asio; // from using tcp = boost::asio::ip::tcp; // from - try - { + try { beast::error_code ec; // These objects perform our I/O tcp::resolver resolver{ioContext_.get()}; @@ -239,20 +229,17 @@ private: bool started = false; size_t numAttempts = 0; - do - { + do { // Send the message ws->async_write(net::buffer(boost::json::serialize(getRequest(marker))), yield[ec]); - if (ec) - { + if (ec) { LOG(log_.error()) << "error writing = " << ec.message(); return false; } beast::flat_buffer buffer; ws->async_read(buffer, yield[ec]); - if (ec) - { + if (ec) { LOG(log_.error()) << "error reading = " << ec.message(); return false; } @@ -260,27 +247,22 @@ private: auto raw = beast::buffers_to_string(buffer.data()); auto parsed = boost::json::parse(raw); - if (!parsed.is_object()) - { + if (!parsed.is_object()) { LOG(log_.error()) << "Error parsing response: " << raw; return false; } LOG(log_.trace()) << "Successfully parsed response " << parsed; - if (auto const& response = parsed.as_object(); response.contains("error")) - { + if (auto const& response = parsed.as_object(); response.contains("error")) { LOG(log_.error()) << "Response contains error: " << response; auto const& err = response.at("error"); - if (err.is_string() && err.as_string() == "lgrNotFound") - { + if (err.is_string() && err.as_string() == "lgrNotFound") { static constexpr size_t MAX_ATTEMPTS = 5; ++numAttempts; - if (numAttempts >= MAX_ATTEMPTS) - { - LOG(log_.error()) << " ledger not found at peer after 5 attempts. " - "peer = " - << ip << " ledger = " << ledgerIndex - << ". Check your config and the health of the peer"; + if (numAttempts >= MAX_ATTEMPTS) { + LOG(log_.error()) + << " ledger not found at peer after 5 attempts. peer = " << ip + << " ledger = " << ledgerIndex << ". Check your config and the health of the peer"; return false; } LOG(log_.warn()) << "Ledger not found. ledger = " << ledgerIndex @@ -293,17 +275,13 @@ private: started = true; auto const& response = parsed.as_object()["result"].as_object(); - if (!response.contains("cache_full") || !response.at("cache_full").as_bool()) - { + if (!response.contains("cache_full") || !response.at("cache_full").as_bool()) { LOG(log_.error()) << "cache not full for clio node. ip = " << ip; return false; } - if (response.contains("marker")) - { + if (response.contains("marker")) { marker = response.at("marker"); - } - else - { + } else { marker = {}; } @@ -311,14 +289,12 @@ private: std::vector objects; objects.reserve(state.size()); - for (auto const& ledgerObject : state) - { + for (auto const& ledgerObject : state) { auto const& obj = ledgerObject.as_object(); data::LedgerObject stateObject = {}; - if (!stateObject.key.parseHex(obj.at("index").as_string().c_str())) - { + if (!stateObject.key.parseHex(obj.at("index").as_string().c_str())) { LOG(log_.error()) << "failed to parse object id"; return false; } @@ -335,9 +311,7 @@ private: cache_.get().setFull(); return true; - } - catch (std::exception const& e) - { + } catch (std::exception const& e) { LOG(log_.error()) << "Encountered exception : " << e.what() << " - ip = " << ip; return false; } @@ -351,8 +325,7 @@ private: auto append = [](auto&& a, auto&& b) { a.insert(std::end(a), std::begin(b), std::end(b)); }; - for (size_t i = 0; i < numCacheDiffs_; ++i) - { + for (size_t i = 0; i < numCacheDiffs_; ++i) { append(diff, data::synchronousAndRetryOnTimeout([&](auto yield) { return backend_->fetchLedgerDiff(seq - i, yield); })); @@ -365,16 +338,14 @@ private: diff.erase(std::unique(diff.begin(), diff.end(), [](auto a, auto b) { return a.key == b.key; }), diff.end()); cursors.emplace_back(); - for (auto const& obj : diff) - { + for (auto const& obj : diff) { if (!obj.blob.empty()) cursors.emplace_back(obj.key); } cursors.emplace_back(); std::stringstream cursorStr; - for (auto const& c : cursors) - { + for (auto const& c : cursors) { if (c) cursorStr << ripple::strHex(*c) << ", "; } @@ -387,8 +358,7 @@ private: auto markers = std::make_shared(0); auto numRemaining = std::make_shared(cursors.size() - 1); - for (size_t i = 0; i < cursors.size() - 1; ++i) - { + for (size_t i = 0; i < cursors.size() - 1; ++i) { auto const start = cursors.at(i); auto const end = cursors.at(i + 1); @@ -403,8 +373,7 @@ private: cursor.has_value() ? ripple::strHex(cursor.value()) : ripple::strHex(data::firstKey); LOG(log_.debug()) << "Starting a cursor: " << cursorStr << " markers = " << *markers; - while (not stopping_) - { + while (not stopping_) { auto res = data::retryOnTimeout([this, seq, &cursor, yield]() { return backend_->fetchLedgerPage(cursor, seq, cachePageFetchSize_, false, yield); }); @@ -424,21 +393,19 @@ private: --(*markers); markers->notify_one(); - if (--(*numRemaining) == 0) - { + if (--(*numRemaining) == 0) { auto endTime = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(endTime - startTime); LOG(log_.info()) << "Finished loading cache. cache size = " << cache_.get().size() << ". Took " << duration.count() << " seconds"; cache_.get().setFull(); - } - else - { + } else { LOG(log_.info()) << "Finished a cursor. num remaining = " << *numRemaining << " start = " << cursorStr << " markers = " << *markers; } - }); + } + ); } }}; } diff --git a/src/etl/impl/ExtractionDataPipe.h b/src/etl/impl/ExtractionDataPipe.h index da1cd13b..72c48898 100644 --- a/src/etl/impl/ExtractionDataPipe.h +++ b/src/etl/impl/ExtractionDataPipe.h @@ -31,8 +31,7 @@ namespace etl::detail { * @brief A collection of thread safe async queues used by Extractor and Transformer to communicate */ template -class ExtractionDataPipe -{ +class ExtractionDataPipe { public: using DataType = std::optional; using QueueType = ThreadSafeQueue; // TODO: probably should use boost::lockfree::queue instead? diff --git a/src/etl/impl/Extractor.h b/src/etl/impl/Extractor.h index bfe3c9e2..c4b6391a 100644 --- a/src/etl/impl/Extractor.h +++ b/src/etl/impl/Extractor.h @@ -36,8 +36,7 @@ namespace etl::detail { * @brief Extractor thread that is fetching GRPC data and enqueue it on the DataPipeType */ template -class Extractor -{ +class Extractor { util::Logger log_{"ETL"}; std::reference_wrapper pipe_; @@ -56,7 +55,8 @@ public: LedgerFetcherType& ledgerFetcher, uint32_t startSequence, std::optional finishSequence, - SystemState const& state) + SystemState const& state + ) : pipe_(std::ref(pipe)) , networkValidatedLedgers_{std::move(networkValidatedLedgers)} , ledgerFetcher_{std::ref(ledgerFetcher)} @@ -89,16 +89,17 @@ private: double totalTime = 0.0; auto currentSequence = startSequence_; - while (!shouldFinish(currentSequence) && networkValidatedLedgers_->waitUntilValidatedByNetwork(currentSequence)) - { - auto [fetchResponse, time] = ::util::timed>( - [this, currentSequence]() { return ledgerFetcher_.get().fetchDataAndDiff(currentSequence); }); + while (!shouldFinish(currentSequence) && networkValidatedLedgers_->waitUntilValidatedByNetwork(currentSequence) + ) { + auto [fetchResponse, time] = ::util::timed>([this, currentSequence]() { + return ledgerFetcher_.get().fetchDataAndDiff(currentSequence); + }); totalTime += time; - // if the fetch is unsuccessful, stop. fetchLedger only returns false if the server is shutting down, or if - // the ledger was found in the database (which means another process already wrote the ledger that this - // process was trying to extract; this is a form of a write conflict). - // Otherwise, fetchDataAndDiff will keep trying to fetch the specified ledger until successful. + // if the fetch is unsuccessful, stop. fetchLedger only returns false if the server is shutting down, or + // if the ledger was found in the database (which means another process already wrote the ledger that + // this process was trying to extract; this is a form of a write conflict). Otherwise, fetchDataAndDiff + // will keep trying to fetch the specified ledger until successful. if (!fetchResponse) break; diff --git a/src/etl/impl/ForwardCache.cpp b/src/etl/impl/ForwardCache.cpp index ad6ea6dc..7b4e6d35 100644 --- a/src/etl/impl/ForwardCache.cpp +++ b/src/etl/impl/ForwardCache.cpp @@ -33,10 +33,10 @@ ForwardCache::freshen() auto numOutstanding = std::make_shared(latestForwarded_.size()); - for (auto const& cacheEntry : latestForwarded_) - { + for (auto const& cacheEntry : latestForwarded_) { boost::asio::spawn( - strand_, [this, numOutstanding, command = cacheEntry.first](boost::asio::yield_context yield) { + strand_, + [this, numOutstanding, command = cacheEntry.first](boost::asio::yield_context yield) { boost::json::object const request = {{"command", command}}; auto resp = source_.requestFromRippled(request, std::nullopt, yield); @@ -47,7 +47,8 @@ ForwardCache::freshen() std::scoped_lock const lk(mtx_); latestForwarded_[command] = resp; } - }); + } + ); } } @@ -63,12 +64,9 @@ std::optional ForwardCache::get(boost::json::object const& request) const { std::optional command = {}; - if (request.contains("command") && !request.contains("method") && request.at("command").is_string()) - { + if (request.contains("command") && !request.contains("method") && request.at("command").is_string()) { command = request.at("command").as_string().c_str(); - } - else if (request.contains("method") && !request.contains("command") && request.at("method").is_string()) - { + } else if (request.contains("method") && !request.contains("command") && request.at("method").is_string()) { command = request.at("method").as_string().c_str(); } diff --git a/src/etl/impl/ForwardCache.h b/src/etl/impl/ForwardCache.h index 091b4b19..8a1f8cdb 100644 --- a/src/etl/impl/ForwardCache.h +++ b/src/etl/impl/ForwardCache.h @@ -40,8 +40,7 @@ namespace etl::detail { /** * @brief Cache for rippled responses */ -class ForwardCache -{ +class ForwardCache { using ResponseType = std::optional; static constexpr std::uint32_t DEFAULT_DURATION = 10; @@ -60,15 +59,13 @@ public: ForwardCache(util::Config const& config, boost::asio::io_context& ioc, Source const& source) : strand_(boost::asio::make_strand(ioc)), source_(source) { - if (config.contains("cache")) - { + if (config.contains("cache")) { auto commands = config.arrayOrThrow("cache", "Source cache must be array"); if (config.contains("cache_duration")) duration_ = config.valueOrThrow("cache_duration", "Source cache_duration must be a number"); - for (auto const& command : commands) - { + for (auto const& command : commands) { auto key = command.valueOrThrow("Source forward command must be array of strings"); latestForwarded_[key] = {}; } diff --git a/src/etl/impl/LedgerFetcher.h b/src/etl/impl/LedgerFetcher.h index 8678c21a..3ca348a5 100644 --- a/src/etl/impl/LedgerFetcher.h +++ b/src/etl/impl/LedgerFetcher.h @@ -35,8 +35,7 @@ namespace etl::detail { * @brief GRPC Ledger data fetcher */ template -class LedgerFetcher -{ +class LedgerFetcher { public: using OptionalGetLedgerResponseType = typename LoadBalancerType::OptionalGetLedgerResponseType; @@ -91,7 +90,8 @@ public: LOG(log_.debug()) << "Attempting to fetch ledger with sequence = " << sequence; auto response = loadBalancer_->fetchLedger( - sequence, true, !backend_->cache().isFull() || backend_->cache().latestLedgerSequence() >= sequence); + sequence, true, !backend_->cache().isFull() || backend_->cache().latestLedgerSequence() >= sequence + ); if (response) LOG(log_.trace()) << "GetLedger reply = " << response->DebugString(); diff --git a/src/etl/impl/LedgerLoader.h b/src/etl/impl/LedgerLoader.h index eed92e15..e8d89d58 100644 --- a/src/etl/impl/LedgerLoader.h +++ b/src/etl/impl/LedgerLoader.h @@ -35,8 +35,7 @@ /** * @brief Account transactions, NFT transactions and NFT data bundled togeher. */ -struct FormattedTransactionsData -{ +struct FormattedTransactionsData { std::vector accountTxData; std::vector nfTokenTxData; std::vector nfTokensData; @@ -48,8 +47,7 @@ namespace etl::detail { * @brief Loads ledger data into the DB */ template -class LedgerLoader -{ +class LedgerLoader { public: using GetLedgerResponseType = typename LoadBalancerType::GetLedgerResponseType; using OptionalGetLedgerResponseType = typename LoadBalancerType::OptionalGetLedgerResponseType; @@ -71,7 +69,8 @@ public: std::shared_ptr backend, std::shared_ptr balancer, LedgerFetcherType& fetcher, - SystemState const& state) + SystemState const& state + ) : backend_{std::move(backend)} , loadBalancer_{std::move(balancer)} , fetcher_{std::ref(fetcher)} @@ -95,8 +94,7 @@ public: { FormattedTransactionsData result; - for (auto& txn : *(data.mutable_transactions_list()->mutable_transactions())) - { + for (auto& txn : *(data.mutable_transactions_list()->mutable_transactions())) { std::string* raw = txn.mutable_transaction_blob(); ripple::SerialIter it{raw->data(), raw->size()}; @@ -113,13 +111,14 @@ public: result.accountTxData.emplace_back(txMeta, sttx.getTransactionID()); static constexpr std::size_t KEY_SIZE = 32; - std::string keyStr{reinterpret_cast(sttx.getTransactionID().data()), KEY_SIZE}; + std::string keyStr{reinterpret_cast(sttx.getTransactionID().data()), KEY_SIZE}; backend_->writeTransaction( std::move(keyStr), ledger.seq, ledger.closeTime.time_since_epoch().count(), std::move(*raw), - std::move(*txn.mutable_metadata_blob())); + std::move(*txn.mutable_metadata_blob()) + ); } // Remove all but the last NFTsData for each id. unique removes all but the first of a group, so we want to @@ -130,9 +129,10 @@ public: // Now we can unique the NFTs by tokenID. auto last = std::unique( - result.nfTokensData.begin(), result.nfTokensData.end(), [](NFTsData const& a, NFTsData const& b) { - return a.tokenID == b.tokenID; - }); + result.nfTokensData.begin(), + result.nfTokensData.end(), + [](NFTsData const& a, NFTsData const& b) { return a.tokenID == b.tokenID; } + ); result.nfTokensData.erase(last, result.nfTokensData.end()); return result; @@ -151,8 +151,7 @@ public: { // check that database is actually empty auto rng = backend_->hardFetchLedgerRangeNoThrow(); - if (rng) - { + if (rng) { LOG(log_.fatal()) << "Database is not empty"; assert(false); return {}; @@ -186,15 +185,13 @@ public: // into the queue auto [edgeKeys, success] = loadBalancer_->loadInitialLedger(sequence); - if (success) - { + if (success) { size_t numWrites = 0; backend_->cache().setFull(); auto seconds = ::util::timed([this, edgeKeys = &edgeKeys, sequence, &numWrites]() { - for (auto& key : *edgeKeys) - { + for (auto& key : *edgeKeys) { LOG(log_.debug()) << "Writing edge key = " << ripple::strHex(key); auto succ = backend_->cache().getSuccessor(*ripple::uint256::fromVoidChecked(key), sequence); @@ -203,27 +200,24 @@ public: } ripple::uint256 prev = data::firstKey; - while (auto cur = backend_->cache().getSuccessor(prev, sequence)) - { + while (auto cur = backend_->cache().getSuccessor(prev, sequence)) { assert(cur); if (prev == data::firstKey) backend_->writeSuccessor(uint256ToString(prev), sequence, uint256ToString(cur->key)); - if (isBookDir(cur->key, cur->blob)) - { + if (isBookDir(cur->key, cur->blob)) { auto base = getBookBase(cur->key); // make sure the base is not an actual object - if (!backend_->cache().get(cur->key, sequence)) - { + if (!backend_->cache().get(cur->key, sequence)) { auto succ = backend_->cache().getSuccessor(base, sequence); assert(succ); - if (succ->key == cur->key) - { + if (succ->key == cur->key) { LOG(log_.debug()) << "Writing book successor = " << ripple::strHex(base) << " - " << ripple::strHex(cur->key); backend_->writeSuccessor( - uint256ToString(base), sequence, uint256ToString(cur->key)); + uint256ToString(base), sequence, uint256ToString(cur->key) + ); } } @@ -246,8 +240,7 @@ public: LOG(log_.debug()) << "Loaded initial ledger"; - if (not state_.get().isStopping) - { + if (not state_.get().isStopping) { backend_->writeAccountTransactions(std::move(insertTxResult.accountTxData)); backend_->writeNFTs(std::move(insertTxResult.nfTokensData)); backend_->writeNFTTransactions(std::move(insertTxResult.nfTokenTxData)); diff --git a/src/etl/impl/LedgerPublisher.h b/src/etl/impl/LedgerPublisher.h index 280f0e3c..f5a0c1d7 100644 --- a/src/etl/impl/LedgerPublisher.h +++ b/src/etl/impl/LedgerPublisher.h @@ -44,8 +44,7 @@ namespace etl::detail { * strand is used to ensure ledgers are published in order. */ template -class LedgerPublisher -{ +class LedgerPublisher { util::Logger log_{"ETL"}; boost::asio::strand publishStrand_; @@ -73,7 +72,8 @@ public: std::shared_ptr backend, CacheType& cache, std::shared_ptr subscriptions, - SystemState const& state) + SystemState const& state + ) : publishStrand_{boost::asio::make_strand(ioc)} , backend_{std::move(backend)} , cache_{cache} @@ -95,20 +95,15 @@ public: { LOG(log_.info()) << "Attempting to publish ledger = " << ledgerSequence; size_t numAttempts = 0; - while (not state_.get().isStopping) - { + while (not state_.get().isStopping) { auto range = backend_->hardFetchLedgerRangeNoThrow(); - if (!range || range->maxSequence < ledgerSequence) - { + if (!range || range->maxSequence < ledgerSequence) { ++numAttempts; - LOG(log_.debug()) << "Trying to publish. Could not find " - "ledger with sequence = " - << ledgerSequence; + LOG(log_.debug()) << "Trying to publish. Could not find ledger with sequence = " << ledgerSequence; // We try maxAttempts times to publish the ledger, waiting one second in between each attempt. - if (maxAttempts && numAttempts >= maxAttempts) - { + if (maxAttempts && numAttempts >= maxAttempts) { LOG(log_.debug()) << "Failed to publish ledger after " << numAttempts << " attempts."; return false; } @@ -116,8 +111,9 @@ public: continue; } - auto lgr = data::synchronousAndRetryOnTimeout( - [&](auto yield) { return backend_->fetchLedgerBySequence(ledgerSequence, yield); }); + auto lgr = data::synchronousAndRetryOnTimeout([&](auto yield) { + return backend_->fetchLedgerBySequence(ledgerSequence, yield); + }); assert(lgr); publish(*lgr); @@ -140,12 +136,12 @@ public: boost::asio::post(publishStrand_, [this, lgrInfo = lgrInfo]() { LOG(log_.info()) << "Publishing ledger " << std::to_string(lgrInfo.seq); - if (!state_.get().isWriting) - { + if (!state_.get().isWriting) { LOG(log_.info()) << "Updating cache"; - std::vector const diff = data::synchronousAndRetryOnTimeout( - [&](auto yield) { return backend_->fetchLedgerDiff(lgrInfo.seq, yield); }); + std::vector const diff = data::synchronousAndRetryOnTimeout([&](auto yield) { + return backend_->fetchLedgerDiff(lgrInfo.seq, yield); + }); cache_.get().update(diff, lgrInfo.seq); backend_->updateRange(lgrInfo.seq); @@ -157,14 +153,16 @@ public: // if the ledger closed over MAX_LEDGER_AGE_SECONDS ago, assume we are still catching up and don't publish // TODO: this probably should be a strategy static constexpr std::uint32_t MAX_LEDGER_AGE_SECONDS = 600; - if (age < MAX_LEDGER_AGE_SECONDS) - { - std::optional fees = data::synchronousAndRetryOnTimeout( - [&](auto yield) { return backend_->fetchFees(lgrInfo.seq, yield); }); + if (age < MAX_LEDGER_AGE_SECONDS) { + std::optional fees = data::synchronousAndRetryOnTimeout([&](auto yield) { + return backend_->fetchFees(lgrInfo.seq, yield); + }); assert(fees); - std::vector transactions = data::synchronousAndRetryOnTimeout( - [&](auto yield) { return backend_->fetchAllTransactionsInLedger(lgrInfo.seq, yield); }); + std::vector transactions = + data::synchronousAndRetryOnTimeout([&](auto yield) { + return backend_->fetchAllTransactionsInLedger(lgrInfo.seq, yield); + }); auto const ledgerRange = backend_->fetchLedgerRange(); assert(ledgerRange); @@ -191,8 +189,7 @@ public: setLastPublishTime(); LOG(log_.info()) << "Published ledger " << std::to_string(lgrInfo.seq); - } - else + } else LOG(log_.info()) << "Skipping publishing ledger " << std::to_string(lgrInfo.seq); }); diff --git a/src/etl/impl/Transformer.h b/src/etl/impl/Transformer.h index 87b41cac..83988304 100644 --- a/src/etl/impl/Transformer.h +++ b/src/etl/impl/Transformer.h @@ -54,8 +54,7 @@ template < typename LedgerLoaderType, typename LedgerPublisherType, typename AmendmentBlockHandlerType> -class Transformer -{ +class Transformer { using GetLedgerResponseType = typename LedgerLoaderType::GetLedgerResponseType; using RawLedgerObjectType = typename LedgerLoaderType::RawLedgerObjectType; @@ -86,7 +85,8 @@ public: LedgerPublisherType& publisher, AmendmentBlockHandlerType& amendmentBlockHandler, uint32_t startSequence, - SystemState& state) + SystemState& state + ) : pipe_{std::ref(pipe)} , backend_{std::move(backend)} , loader_{std::ref(loader)} @@ -124,8 +124,7 @@ private: beast::setCurrentThreadName("ETLService transform"); uint32_t currentSequence = startSequence_; - while (not hasWriteConflict()) - { + while (not hasWriteConflict()) { auto fetchResponse = pipe_.get().popNext(currentSequence); ++currentSequence; @@ -140,8 +139,7 @@ private: auto const start = std::chrono::system_clock::now(); auto [lgrInfo, success] = buildNextLedger(*fetchResponse); - if (success) - { + if (success) { auto const numTxns = fetchResponse->transactions_list().transactions_size(); auto const numObjects = fetchResponse->ledger_objects().objects_size(); auto const end = std::chrono::system_clock::now(); @@ -155,9 +153,7 @@ private: // success is false if the ledger was already written publisher_.get().publish(lgrInfo); - } - else - { + } else { LOG(log_.error()) << "Error writing ledger. " << util::toString(lgrInfo); } @@ -184,17 +180,14 @@ private: writeSuccessors(lgrInfo, rawData); std::optional insertTxResultOp; - try - { + try { updateCache(lgrInfo, rawData); LOG(log_.debug()) << "Inserted/modified/deleted all objects. Number of objects = " << rawData.ledger_objects().objects_size(); insertTxResultOp.emplace(loader_.get().insertTransactions(lgrInfo, rawData)); - } - catch (std::runtime_error const& e) - { + } catch (std::runtime_error const& e) { LOG(log_.fatal()) << "Failed to build next ledger: " << e.what(); amendmentBlockHandler_.get().onAmendmentBlock(); @@ -233,16 +226,14 @@ private: std::set bookSuccessorsToCalculate; std::set modified; - for (auto& obj : *(rawData.mutable_ledger_objects()->mutable_objects())) - { + for (auto& obj : *(rawData.mutable_ledger_objects()->mutable_objects())) { auto key = ripple::uint256::fromVoidChecked(obj.key()); assert(key); cacheUpdates.push_back({*key, {obj.mutable_data()->begin(), obj.mutable_data()->end()}}); LOG(log_.debug()) << "key = " << ripple::strHex(*key) << " - mod type = " << obj.mod_type(); - if (obj.mod_type() != RawLedgerObjectType::MODIFIED && !rawData.object_neighbors_included()) - { + if (obj.mod_type() != RawLedgerObjectType::MODIFIED && !rawData.object_neighbors_included()) { LOG(log_.debug()) << "object neighbors not included. using cache"; if (!backend_->cache().isFull() || backend_->cache().latestLedgerSequence() != lgrInfo.seq - 1) @@ -252,28 +243,24 @@ private: auto checkBookBase = false; auto const isDeleted = (blob->size() == 0); - if (isDeleted) - { + if (isDeleted) { auto const old = backend_->cache().get(*key, lgrInfo.seq - 1); assert(old); checkBookBase = isBookDir(*key, *old); - } - else - { + } else { checkBookBase = isBookDir(*key, *blob); } - if (checkBookBase) - { + if (checkBookBase) { LOG(log_.debug()) << "Is book dir. Key = " << ripple::strHex(*key); auto const bookBase = getBookBase(*key); auto const oldFirstDir = backend_->cache().getSuccessor(bookBase, lgrInfo.seq - 1); assert(oldFirstDir); - // We deleted the first directory, or we added a directory prior to the old first directory - if ((isDeleted && key == oldFirstDir->key) || (!isDeleted && key < oldFirstDir->key)) - { + // We deleted the first directory, or we added a directory prior to the old first + // directory + if ((isDeleted && key == oldFirstDir->key) || (!isDeleted && key < oldFirstDir->key)) { LOG(log_.debug()) << "Need to recalculate book base successor. base = " << ripple::strHex(bookBase) << " - key = " << ripple::strHex(*key) << " - isDeleted = " << isDeleted @@ -292,14 +279,12 @@ private: backend_->cache().update(cacheUpdates, lgrInfo.seq); // rippled didn't send successor information, so use our cache - if (!rawData.object_neighbors_included()) - { + if (!rawData.object_neighbors_included()) { LOG(log_.debug()) << "object neighbors not included. using cache"; if (!backend_->cache().isFull() || backend_->cache().latestLedgerSequence() != lgrInfo.seq) throw std::logic_error("Cache is not full, but object neighbors were not included"); - for (auto const& obj : cacheUpdates) - { + for (auto const& obj : cacheUpdates) { if (modified.contains(obj.key)) continue; @@ -311,15 +296,12 @@ private: if (!ub) ub = {data::lastKey, {}}; - if (obj.blob.empty()) - { + if (obj.blob.empty()) { LOG(log_.debug()) << "writing successor for deleted object " << ripple::strHex(obj.key) << " - " << ripple::strHex(lb->key) << " - " << ripple::strHex(ub->key); backend_->writeSuccessor(uint256ToString(lb->key), lgrInfo.seq, uint256ToString(ub->key)); - } - else - { + } else { backend_->writeSuccessor(uint256ToString(lb->key), lgrInfo.seq, uint256ToString(obj.key)); backend_->writeSuccessor(uint256ToString(obj.key), lgrInfo.seq, uint256ToString(ub->key)); @@ -328,18 +310,14 @@ private: } } - for (auto const& base : bookSuccessorsToCalculate) - { + for (auto const& base : bookSuccessorsToCalculate) { auto succ = backend_->cache().getSuccessor(base, lgrInfo.seq); - if (succ) - { + if (succ) { backend_->writeSuccessor(uint256ToString(base), lgrInfo.seq, uint256ToString(succ->key)); LOG(log_.debug()) << "Updating book successor " << ripple::strHex(base) << " - " << ripple::strHex(succ->key); - } - else - { + } else { backend_->writeSuccessor(uint256ToString(base), lgrInfo.seq, uint256ToString(data::lastKey)); LOG(log_.debug()) << "Updating book successor " << ripple::strHex(base) << " - " @@ -359,12 +337,10 @@ private: writeSuccessors(ripple::LedgerHeader const& lgrInfo, GetLedgerResponseType& rawData) { // Write successor info, if included from rippled - if (rawData.object_neighbors_included()) - { + if (rawData.object_neighbors_included()) { LOG(log_.debug()) << "object neighbors included"; - for (auto& obj : *(rawData.mutable_book_successors())) - { + for (auto& obj : *(rawData.mutable_book_successors())) { auto firstBook = std::move(*obj.mutable_first_book()); if (!firstBook.size()) firstBook = uint256ToString(data::lastKey); @@ -374,10 +350,8 @@ private: backend_->writeSuccessor(std::move(*obj.mutable_book_base()), lgrInfo.seq, std::move(firstBook)); } - for (auto& obj : *(rawData.mutable_ledger_objects()->mutable_objects())) - { - if (obj.mod_type() != RawLedgerObjectType::MODIFIED) - { + for (auto& obj : *(rawData.mutable_ledger_objects()->mutable_objects())) { + if (obj.mod_type() != RawLedgerObjectType::MODIFIED) { std::string* predPtr = obj.mutable_predecessor(); if (predPtr->empty()) *predPtr = uint256ToString(data::firstKey); @@ -385,23 +359,19 @@ private: if (succPtr->empty()) *succPtr = uint256ToString(data::lastKey); - if (obj.mod_type() == RawLedgerObjectType::DELETED) - { + if (obj.mod_type() == RawLedgerObjectType::DELETED) { LOG(log_.debug()) << "Modifying successors for deleted object " << ripple::strHex(obj.key()) << " - " << ripple::strHex(*predPtr) << " - " << ripple::strHex(*succPtr); backend_->writeSuccessor(std::move(*predPtr), lgrInfo.seq, std::move(*succPtr)); - } - else - { + } else { LOG(log_.debug()) << "adding successor for new object " << ripple::strHex(obj.key()) << " - " << ripple::strHex(*predPtr) << " - " << ripple::strHex(*succPtr); backend_->writeSuccessor(std::move(*predPtr), lgrInfo.seq, std::string{obj.key()}); backend_->writeSuccessor(std::string{obj.key()}, lgrInfo.seq, std::move(*succPtr)); } - } - else + } else LOG(log_.debug()) << "object modified " << ripple::strHex(obj.key()); } } diff --git a/src/feed/SubscriptionManager.cpp b/src/feed/SubscriptionManager.cpp index 78e9059d..0487c485 100644 --- a/src/feed/SubscriptionManager.cpp +++ b/src/feed/SubscriptionManager.cpp @@ -52,7 +52,8 @@ getLedgerPubMessage( ripple::LedgerHeader const& lgrInfo, ripple::Fees const& fees, std::string const& ledgerRange, - std::uint32_t txnCount) + std::uint32_t txnCount +) { boost::json::object pubMsg; @@ -127,8 +128,9 @@ SubscriptionManager::unsubAccount(ripple::AccountID const& account, SessionPtrTy void SubscriptionManager::subBook(ripple::Book const& book, SessionPtrType session) { - subscribeHelper( - session, book, bookSubscribers_, [this, book](SessionPtrType session) { unsubBook(book, session); }); + subscribeHelper(session, book, bookSubscribers_, [this, book](SessionPtrType session) { + unsubBook(book, session); + }); } void @@ -154,10 +156,12 @@ SubscriptionManager::pubLedger( ripple::LedgerHeader const& lgrInfo, ripple::Fees const& fees, std::string const& ledgerRange, - std::uint32_t txnCount) + std::uint32_t txnCount +) { - auto message = std::make_shared( - boost::json::serialize(getLedgerPubMessage(lgrInfo, fees, ledgerRange, txnCount))); + auto message = + std::make_shared(boost::json::serialize(getLedgerPubMessage(lgrInfo, fees, ledgerRange, txnCount)) + ); ledgerSubscribers_.publish(message); } @@ -184,12 +188,10 @@ SubscriptionManager::pubTransaction(data::TransactionAndMetadata const& blobs, r ripple::transResultInfo(meta->getResultTER(), token, human); pubObj["engine_result"] = token; pubObj["engine_result_message"] = human; - if (tx->getTxnType() == ripple::ttOFFER_CREATE) - { + if (tx->getTxnType() == ripple::ttOFFER_CREATE) { auto account = tx->getAccountID(ripple::sfAccount); auto amount = tx->getFieldAmount(ripple::sfTakerGets); - if (account != amount.issue().account) - { + if (account != amount.issue().account) { ripple::STAmount ownerFunds; auto fetchFundsSynchronous = [&]() { data::synchronous([&](boost::asio::yield_context yield) { @@ -213,40 +215,30 @@ SubscriptionManager::pubTransaction(data::TransactionAndMetadata const& blobs, r std::unordered_set alreadySent; - for (auto const& node : meta->getNodes()) - { - if (node.getFieldU16(ripple::sfLedgerEntryType) == ripple::ltOFFER) - { + for (auto const& node : meta->getNodes()) { + if (node.getFieldU16(ripple::sfLedgerEntryType) == ripple::ltOFFER) { ripple::SField const* field = nullptr; // We need a field that contains the TakerGets and TakerPays // parameters. - if (node.getFName() == ripple::sfModifiedNode) - { + if (node.getFName() == ripple::sfModifiedNode) { field = &ripple::sfPreviousFields; - } - else if (node.getFName() == ripple::sfCreatedNode) - { + } else if (node.getFName() == ripple::sfCreatedNode) { field = &ripple::sfNewFields; - } - else if (node.getFName() == ripple::sfDeletedNode) - { + } else if (node.getFName() == ripple::sfDeletedNode) { field = &ripple::sfFinalFields; } - if (field != nullptr) - { - auto data = dynamic_cast(node.peekAtPField(*field)); + if (field != nullptr) { + auto data = dynamic_cast(node.peekAtPField(*field)); if ((data != nullptr) && data->isFieldPresent(ripple::sfTakerPays) && - data->isFieldPresent(ripple::sfTakerGets)) - { + data->isFieldPresent(ripple::sfTakerGets)) { // determine the OrderBook ripple::Book const book{ data->getFieldAmount(ripple::sfTakerGets).issue(), data->getFieldAmount(ripple::sfTakerPays).issue()}; - if (alreadySent.find(book) == alreadySent.end()) - { + if (alreadySent.find(book) == alreadySent.end()) { bookSubscribers_.publish(pubMsg, book); alreadySent.insert(book); } @@ -259,7 +251,8 @@ SubscriptionManager::pubTransaction(data::TransactionAndMetadata const& blobs, r void SubscriptionManager::pubBookChanges( ripple::LedgerHeader const& lgrInfo, - std::vector const& transactions) + std::vector const& transactions +) { auto const json = rpc::computeBookChanges(lgrInfo, transactions); auto const bookChangesMsg = std::make_shared(boost::json::serialize(json)); @@ -334,8 +327,9 @@ SubscriptionManager::unsubProposedAccount(ripple::AccountID const& account, Sess void SubscriptionManager::subProposedTransactions(SessionPtrType session) { - subscribeHelper( - session, txProposedSubscribers_, [this](SessionPtrType session) { unsubProposedTransactions(session); }); + subscribeHelper(session, txProposedSubscribers_, [this](SessionPtrType session) { + unsubProposedTransactions(session); + }); } void @@ -360,7 +354,8 @@ SubscriptionManager::subscribeHelper( SessionPtrType const& session, Key const& k, SubscriptionMap& subs, - CleanupFunction&& func) + CleanupFunction&& func +) { if (subs.hasSession(session, k)) return; @@ -376,8 +371,7 @@ SubscriptionManager::cleanup(SessionPtrType session) if (!cleanupFuncs_.contains(session)) return; - for (auto const& f : cleanupFuncs_[session]) - { + for (auto const& f : cleanupFuncs_[session]) { f(session); } diff --git a/src/feed/SubscriptionManager.h b/src/feed/SubscriptionManager.h index fe7e4670..9ca8ca60 100644 --- a/src/feed/SubscriptionManager.h +++ b/src/feed/SubscriptionManager.h @@ -46,16 +46,12 @@ template inline void sendToSubscribers(std::shared_ptr const& message, T& subscribers, std::atomic_uint64_t& counter) { - for (auto it = subscribers.begin(); it != subscribers.end();) - { + for (auto it = subscribers.begin(); it != subscribers.end();) { auto& session = *it; - if (session->dead()) - { + if (session->dead()) { it = subscribers.erase(it); --counter; - } - else - { + } else { session->send(message); ++it; } @@ -73,8 +69,7 @@ template inline void addSession(SessionPtrType session, T& subscribers, std::atomic_uint64_t& counter) { - if (!subscribers.contains(session)) - { + if (!subscribers.contains(session)) { subscribers.insert(session); ++counter; } @@ -91,8 +86,7 @@ template inline void removeSession(SessionPtrType session, T& subscribers, std::atomic_uint64_t& counter) { - if (subscribers.contains(session)) - { + if (subscribers.contains(session)) { subscribers.erase(session); --counter; } @@ -101,8 +95,7 @@ removeSession(SessionPtrType session, T& subscribers, std::atomic_uint64_t& coun /** * @brief Represents a subscription stream. */ -class Subscription -{ +class Subscription { boost::asio::strand strand_; std::unordered_set subscribers_ = {}; std::atomic_uint64_t subCount_ = 0; @@ -179,8 +172,7 @@ public: * @brief Represents a collection of subscriptions where each stream is mapped to a key. */ template -class SubscriptionMap -{ +class SubscriptionMap { using SubscribersType = std::set; boost::asio::strand strand_; @@ -234,8 +226,7 @@ public: --subCount_; subscribers_[key].erase(session); - if (subscribers_[key].size() == 0) - { + if (subscribers_[key].size() == 0) { subscribers_.erase(key); } }); @@ -287,8 +278,7 @@ public: /** * @brief Manages subscriptions. */ -class SubscriptionManager -{ +class SubscriptionManager { util::Logger log_{"Subscriptions"}; std::vector workers_; @@ -385,7 +375,8 @@ public: ripple::LedgerHeader const& lgrInfo, ripple::Fees const& fees, std::string const& ledgerRange, - std::uint32_t txnCount); + std::uint32_t txnCount + ); /** * @brief Publish to the book changes stream. diff --git a/src/main/Main.cpp b/src/main/Main.cpp index 20dde9f8..cad1e58f 100644 --- a/src/main/Main.cpp +++ b/src/main/Main.cpp @@ -18,12 +18,6 @@ //============================================================================== #include -#ifdef GRPC_TSAN_ENABLED -#undef GRPC_TSAN_ENABLED -#endif -#ifdef GRPC_ASAN_ENABLED -#undef GRPC_ASAN_ENABLED -#endif #include #include @@ -79,14 +73,12 @@ parseCli(int argc, char* argv[]) po::store(po::command_line_parser(argc, argv).options(description).positional(positional).run(), parsed); po::notify(parsed); - if (parsed.count("version") != 0u) - { + if (parsed.count("version") != 0u) { std::cout << Build::getClioFullVersionString() << '\n'; std::exit(EXIT_SUCCESS); } - if (parsed.count("help") != 0u) - { + if (parsed.count("help") != 0u) { std::cout << "Clio server " << Build::getClioFullVersionString() << "\n\n" << description; std::exit(EXIT_SUCCESS); } @@ -153,12 +145,10 @@ start(io_context& ioc, std::uint32_t numThreads) int main(int argc, char* argv[]) -try -{ +try { auto const configPath = parseCli(argc, argv); auto const config = ConfigReader::open(configPath); - if (!config) - { + if (!config) { std::cerr << "Couldnt parse config '" << configPath << "'." << std::endl; return EXIT_FAILURE; } @@ -167,8 +157,7 @@ try LOG(LogService::info()) << "Clio version: " << Build::getClioFullVersionString(); auto const threads = config.valueOr("io_threads", 2); - if (threads <= 0) - { + if (threads <= 0) { LOG(LogService::fatal()) << "io_threads is less than 1"; return EXIT_FAILURE; } @@ -204,13 +193,16 @@ try auto workQueue = rpc::WorkQueue::make_WorkQueue(config); auto counters = rpc::Counters::make_Counters(workQueue); auto const handlerProvider = std::make_shared( - config, backend, subscriptions, balancer, etl, counters); + config, backend, subscriptions, balancer, etl, counters + ); auto const rpcEngine = rpc::RPCEngine::make_RPCEngine( - backend, subscriptions, balancer, dosGuard, workQueue, counters, handlerProvider); + backend, subscriptions, balancer, dosGuard, workQueue, counters, handlerProvider + ); // Init the web server auto handler = std::make_shared>( - config, backend, rpcEngine, etl, subscriptions); + config, backend, rpcEngine, etl, subscriptions + ); auto ctx = parseCerts(config); auto const ctxRef = ctx ? std::optional>{ctx.value()} : std::nullopt; auto const httpServer = web::make_HttpServer(config, ioc, ctxRef, dosGuard, handler); @@ -221,8 +213,6 @@ try start(ioc, threads); return EXIT_SUCCESS; -} -catch (std::exception const& e) -{ +} catch (std::exception const& e) { LOG(LogService::fatal()) << "Exit on exception: " << e.what(); } diff --git a/src/rpc/Amendments.h b/src/rpc/Amendments.h index a7578af6..66b5e0f5 100644 --- a/src/rpc/Amendments.h +++ b/src/rpc/Amendments.h @@ -30,8 +30,7 @@ namespace rpc { /** * @brief Represents a list of amendments in the XRPL. */ -struct Amendments -{ +struct Amendments { /** * @param name The name of the amendment * @return The corresponding amendment Id diff --git a/src/rpc/BookChangesHelper.h b/src/rpc/BookChangesHelper.h index f45da5a7..cce83349 100644 --- a/src/rpc/BookChangesHelper.h +++ b/src/rpc/BookChangesHelper.h @@ -29,8 +29,7 @@ namespace rpc { /** * @brief Represents an entry in the book_changes' changes array. */ -struct BookChange -{ +struct BookChange { ripple::STAmount sideAVolume; ripple::STAmount sideBVolume; ripple::STAmount highRate; @@ -42,8 +41,7 @@ struct BookChange /** * @brief Encapsulates the book_changes computations and transformations. */ -class BookChanges final -{ +class BookChanges final { public: BookChanges() = delete; // only accessed via static handle function @@ -60,8 +58,7 @@ public: } private: - class HandlerImpl final - { + class HandlerImpl final { std::map tally_ = {}; std::optional offerCancel_ = {}; @@ -78,7 +75,8 @@ private: std::make_move_iterator(std::begin(tally_)), std::make_move_iterator(std::end(tally_)), std::back_inserter(changes), - [](auto obj) { return obj.second; }); + [](auto obj) { return obj.second; } + ); return changes; } @@ -148,8 +146,7 @@ private: second = -second; auto const key = noswap ? (g + '|' + p) : (p + '|' + g); - if (tally_.contains(key)) - { + if (tally_.contains(key)) { auto& entry = tally_.at(key); entry.sideAVolume += first; @@ -162,9 +159,7 @@ private: entry.lowRate = rate; entry.closeRate = rate; - } - else - { + } else { tally_[key] = { .sideAVolume = first, .sideBVolume = second, @@ -191,8 +186,7 @@ private: static std::optional shouldCancelOffer(std::shared_ptr const& tx) { - switch (tx->getFieldU16(ripple::sfTransactionType)) - { + switch (tx->getFieldU16(ripple::sfTransactionType)) { // in future if any other ways emerge to cancel an offer // this switch makes them easy to add case ripple::ttOFFER_CANCEL: diff --git a/src/rpc/Counters.cpp b/src/rpc/Counters.cpp index b1ca0e20..ffbc8213 100644 --- a/src/rpc/Counters.cpp +++ b/src/rpc/Counters.cpp @@ -112,8 +112,7 @@ Counters::report() const obj[JS(rpc)] = boost::json::object{}; auto& rpc = obj[JS(rpc)].as_object(); - for (auto const& [method, info] : methodInfo_) - { + for (auto const& [method, info] : methodInfo_) { auto counters = boost::json::object{}; counters[JS(started)] = std::to_string(info.started); counters[JS(finished)] = std::to_string(info.finished); diff --git a/src/rpc/Counters.h b/src/rpc/Counters.h index db4dc8f4..9f59c14d 100644 --- a/src/rpc/Counters.h +++ b/src/rpc/Counters.h @@ -33,13 +33,11 @@ namespace rpc { /** * @brief Holds information about successful, failed, forwarded, etc. RPC handler calls. */ -class Counters -{ +class Counters { /** * @brief All counters the system keeps track of for each RPC method. */ - struct MethodInfo - { + struct MethodInfo { std::uint64_t started = 0u; std::uint64_t finished = 0u; std::uint64_t failed = 0u; @@ -59,7 +57,7 @@ class Counters std::atomic_uint64_t unknownCommandCounter_; std::atomic_uint64_t internalErrorCounter_; - std::reference_wrapper workQueue_; + std::reference_wrapper workQueue_; std::chrono::time_point startupTime_; public: diff --git a/src/rpc/Errors.cpp b/src/rpc/Errors.cpp index bbd3d994..135b865a 100644 --- a/src/rpc/Errors.cpp +++ b/src/rpc/Errors.cpp @@ -26,8 +26,7 @@ using namespace std; namespace { template -struct overloadSet : Ts... -{ +struct overloadSet : Ts... { using Ts::operator()...; }; @@ -44,9 +43,8 @@ getWarningInfo(WarningCode code) constexpr static WarningInfo infos[]{ {warnUNKNOWN, "Unknown warning"}, {warnRPC_CLIO, - "This is a clio server. clio only serves validated data. If you " - "want to talk to rippled, include 'ledger_index':'current' in your " - "request"}, + "This is a clio server. clio only serves validated data. If you want to talk to rippled, include " + "'ledger_index':'current' in your request"}, {warnRPC_OUTDATED, "This server may be out of date"}, {warnRPC_RATE_LIMIT, "You are about to be rate limited"}, }; @@ -143,10 +141,10 @@ makeError(Status const& status) return makeError(err, wrapOptional(status.error), wrapOptional(status.message)); }, }, - status.code); + status.code + ); - if (status.extraInfo) - { + if (status.extraInfo) { for (auto& [key, value] : status.extraInfo.value()) res[key] = value; } diff --git a/src/rpc/Errors.h b/src/rpc/Errors.h index ef391717..2e333010 100644 --- a/src/rpc/Errors.h +++ b/src/rpc/Errors.h @@ -52,8 +52,7 @@ enum class ClioError { }; /** @brief Holds info about a particular @ref ClioError. */ -struct ClioErrorInfo -{ +struct ClioErrorInfo { ClioError const code; std::string_view const error; std::string_view const message; @@ -71,8 +70,7 @@ using RippledError = ripple::error_code_i; using CombinedError = std::variant; /** @brief A status returned from any RPC handler. */ -struct Status -{ +struct Status { CombinedError code = RippledError::rpcSUCCESS; std::string error; std::string message; @@ -141,8 +139,7 @@ struct Status enum WarningCode { warnUNKNOWN = -1, warnRPC_CLIO = 2001, warnRPC_OUTDATED = 2002, warnRPC_RATE_LIMIT = 2003 }; /** @brief Holds information about a clio warning. */ -struct WarningInfo -{ +struct WarningInfo { constexpr WarningInfo() = default; constexpr WarningInfo(WarningCode code, char const* message) : code(code), message(message) { @@ -153,8 +150,7 @@ struct WarningInfo }; /** @brief Invalid parameters error. */ -class InvalidParamsError : public std::exception -{ +class InvalidParamsError : public std::exception { std::string msg; public: @@ -162,7 +158,7 @@ public: { } - const char* + char const* what() const throw() override { return msg.c_str(); @@ -170,8 +166,7 @@ public: }; /** @brief Account not found error. */ -class AccountNotFoundError : public std::exception -{ +class AccountNotFoundError : public std::exception { std::string account; public: @@ -179,7 +174,7 @@ public: { } - const char* + char const* what() const throw() override { return account.c_str(); @@ -235,7 +230,8 @@ boost::json::object makeError( RippledError err, std::optional customError = std::nullopt, - std::optional customMessage = std::nullopt); + std::optional customMessage = std::nullopt +); /** * @brief Generate JSON from a @ref rpc::ClioError. @@ -247,6 +243,7 @@ boost::json::object makeError( ClioError err, std::optional customError = std::nullopt, - std::optional customMessage = std::nullopt); + std::optional customMessage = std::nullopt +); } // namespace rpc diff --git a/src/rpc/Factories.cpp b/src/rpc/Factories.cpp index 06c58a9c..0e482049 100644 --- a/src/rpc/Factories.cpp +++ b/src/rpc/Factories.cpp @@ -33,15 +33,13 @@ make_WsContext( TagDecoratorFactory const& tagFactory, data::LedgerRange const& range, string const& clientIp, - std::reference_wrapper apiVersionParser) + std::reference_wrapper apiVersionParser +) { boost::json::value commandValue = nullptr; - if (!request.contains("command") && request.contains("method")) - { + if (!request.contains("command") && request.contains("method")) { commandValue = request.at("method"); - } - else if (request.contains("command") && !request.contains("method")) - { + } else if (request.contains("command") && !request.contains("method")) { commandValue = request.at("command"); } @@ -64,7 +62,8 @@ make_HttpContext( data::LedgerRange const& range, string const& clientIp, std::reference_wrapper apiVersionParser, - bool const isAdmin) + bool const isAdmin +) { if (!request.contains("method")) return Error{{ClioError::rpcCOMMAND_IS_MISSING}}; @@ -93,7 +92,8 @@ make_HttpContext( return Error{{ClioError::rpcINVALID_API_VERSION, apiVersion.error()}}; return web::Context( - yc, command, *apiVersion, array.at(0).as_object(), nullptr, tagFactory, range, clientIp, isAdmin); + yc, command, *apiVersion, array.at(0).as_object(), nullptr, tagFactory, range, clientIp, isAdmin + ); } } // namespace rpc diff --git a/src/rpc/Factories.h b/src/rpc/Factories.h index 20e21846..d7c10d18 100644 --- a/src/rpc/Factories.h +++ b/src/rpc/Factories.h @@ -60,7 +60,8 @@ make_WsContext( util::TagDecoratorFactory const& tagFactory, data::LedgerRange const& range, std::string const& clientIp, - std::reference_wrapper apiVersionParser); + std::reference_wrapper apiVersionParser +); /** * @brief A factory function that creates a HTTP context. @@ -81,6 +82,7 @@ make_HttpContext( data::LedgerRange const& range, std::string const& clientIp, std::reference_wrapper apiVersionParser, - bool isAdmin); + bool isAdmin +); } // namespace rpc diff --git a/src/rpc/RPCEngine.h b/src/rpc/RPCEngine.h index 0bff88a2..4d266d8d 100644 --- a/src/rpc/RPCEngine.h +++ b/src/rpc/RPCEngine.h @@ -59,8 +59,7 @@ namespace rpc { /** * @brief The RPC engine that ties all RPC-related functionality together. */ -class RPCEngine -{ +class RPCEngine { util::Logger perfLog_{"Performance"}; util::Logger log_{"RPC"}; @@ -83,7 +82,8 @@ public: web::DOSGuard const& dosGuard, WorkQueue& workQueue, Counters& counters, - std::shared_ptr const& handlerProvider) + std::shared_ptr const& handlerProvider + ) : backend_{backend} , subscriptions_{subscriptions} , balancer_{balancer} @@ -103,10 +103,12 @@ public: web::DOSGuard const& dosGuard, WorkQueue& workQueue, Counters& counters, - std::shared_ptr const& handlerProvider) + std::shared_ptr const& handlerProvider + ) { return std::make_shared( - backend, subscriptions, balancer, dosGuard, workQueue, counters, handlerProvider); + backend, subscriptions, balancer, dosGuard, workQueue, counters, handlerProvider + ); } /** @@ -121,22 +123,19 @@ public: if (forwardingProxy_.shouldForward(ctx)) return forwardingProxy_.forward(ctx); - if (backend_->isTooBusy()) - { + if (backend_->isTooBusy()) { LOG(log_.error()) << "Database is too busy. Rejecting request"; notifyTooBusy(); // TODO: should we add ctx.method if we have it? return Status{RippledError::rpcTOO_BUSY}; } auto const method = handlerProvider_->getHandler(ctx.method); - if (!method) - { + if (!method) { notifyUnknownCommand(); return Status{RippledError::rpcUNKNOWN_COMMAND}; } - try - { + try { LOG(perfLog_.debug()) << ctx.tag() << " start executing rpc `" << ctx.method << '`'; auto const context = Context{ctx.yield, ctx.session, ctx.isAdmin, ctx.clientIp, ctx.apiVersion}; @@ -149,16 +148,12 @@ public: notifyErrored(ctx.method); return Status{v.error()}; - } - catch (data::DatabaseTimeout const& t) - { + } catch (data::DatabaseTimeout const& t) { LOG(log_.error()) << "Database timeout"; notifyTooBusy(); return Status{RippledError::rpcTOO_BUSY}; - } - catch (std::exception const& ex) - { + } catch (std::exception const& ex) { LOG(log_.error()) << ctx.tag() << "Caught exception: " << ex.what(); notifyInternalError(); diff --git a/src/rpc/RPCHelpers.cpp b/src/rpc/RPCHelpers.cpp index 8222e740..42d5c829 100644 --- a/src/rpc/RPCHelpers.cpp +++ b/src/rpc/RPCHelpers.cpp @@ -60,12 +60,9 @@ parseAccountCursor(std::optional jsonCursor) if (!std::getline(cursor, value, ',')) return {}; - try - { + try { startHint = boost::lexical_cast(value); - } - catch (boost::bad_lexical_cast&) - { + } catch (boost::bad_lexical_cast&) { return {}; } @@ -77,12 +74,12 @@ getDeliveredAmount( std::shared_ptr const& txn, std::shared_ptr const& meta, std::uint32_t const ledgerSequence, - uint32_t date) + uint32_t date +) { if (meta->hasDeliveredAmount()) return meta->getDeliveredAmount(); - if (txn->isFieldPresent(ripple::sfAmount)) - { + if (txn->isFieldPresent(ripple::sfAmount)) { using namespace std::chrono_literals; // Ledger 4594095 is the first ledger in which the DeliveredAmount field @@ -95,8 +92,7 @@ getDeliveredAmount( // 446000000 is in Feb 2014, well after DeliveredAmount went live static std::uint32_t constexpr FIRST_LEDGER_WITH_DELIVERED_AMOUNT = 4594095; static std::uint32_t constexpr DELIVERED_AMOUNT_LIVE_DATE = 446000000; - if (ledgerSequence >= FIRST_LEDGER_WITH_DELIVERED_AMOUNT || date > DELIVERED_AMOUNT_LIVE_DATE) - { + if (ledgerSequence >= FIRST_LEDGER_WITH_DELIVERED_AMOUNT || date > DELIVERED_AMOUNT_LIVE_DATE) { return txn->getFieldAmount(ripple::sfAmount); } } @@ -106,7 +102,8 @@ getDeliveredAmount( bool canHaveDeliveredAmount( std::shared_ptr const& txn, - std::shared_ptr const& meta) + std::shared_ptr const& meta +) { ripple::TxType const tt{txn->getTxnType()}; if (tt != ripple::ttPAYMENT && tt != ripple::ttCHECK_CASH && tt != ripple::ttACCOUNT_DELETE) @@ -124,27 +121,20 @@ accountFromStringStrict(std::string const& account) auto blob = ripple::strUnHex(account); std::optional publicKey = {}; - if (blob && ripple::publicKeyType(ripple::makeSlice(*blob))) - { + if (blob && ripple::publicKeyType(ripple::makeSlice(*blob))) { publicKey = ripple::PublicKey(ripple::Slice{blob->data(), blob->size()}); - } - else - { + } else { publicKey = ripple::parseBase58(ripple::TokenType::AccountPublic, account); } std::optional result; - if (publicKey) - { + if (publicKey) { result = ripple::calcAccountID(*publicKey); - } - else - { + } else { result = ripple::parseBase58(account); } - if (result) - { + if (result) { return result.value(); } return {}; @@ -153,8 +143,7 @@ accountFromStringStrict(std::string const& account) std::pair, std::shared_ptr> deserializeTxPlusMeta(data::TransactionAndMetadata const& blobs) { - try - { + try { std::pair, std::shared_ptr> result; { ripple::SerialIter s{blobs.transaction.data(), blobs.transaction.size()}; @@ -165,9 +154,7 @@ deserializeTxPlusMeta(data::TransactionAndMetadata const& blobs) result.second = std::make_shared(s, ripple::sfMetadata); } return result; - } - catch (std::exception const& e) - { + } catch (std::exception const& e) { std::stringstream txn; std::stringstream meta; std::copy(blobs.transaction.begin(), blobs.transaction.end(), std::ostream_iterator(txn)); @@ -205,24 +192,20 @@ toExpandedJson(data::TransactionAndMetadata const& blobs, NFTokenjson nftEnabled auto metaJson = toJson(*meta); insertDeliveredAmount(metaJson, txn, meta, blobs.date); - if (nftEnabled == NFTokenjson::ENABLE) - { + if (nftEnabled == NFTokenjson::ENABLE) { Json::Value nftJson; ripple::insertNFTSyntheticInJson(nftJson, txn, *meta); // if there is no nft fields, the nftJson will be {"meta":null} auto const nftBoostJson = toBoostJson(nftJson).as_object(); - if (nftBoostJson.contains(JS(meta)) and nftBoostJson.at(JS(meta)).is_object()) - { + if (nftBoostJson.contains(JS(meta)) and nftBoostJson.at(JS(meta)).is_object()) { for (auto const& [k, v] : nftBoostJson.at(JS(meta)).as_object()) metaJson.insert_or_assign(k, v); } } - if (networkId) - { + if (networkId) { // networkId is available, insert ctid field to tx - if (auto const ctid = rpc::encodeCTID(meta->getLgrSeq(), meta->getIndex(), *networkId)) - { + if (auto const ctid = rpc::encodeCTID(meta->getLgrSeq(), meta->getIndex(), *networkId)) { txnJson[JS(ctid)] = *ctid; } } @@ -249,16 +232,13 @@ insertDeliveredAmount( boost::json::object& metaJson, std::shared_ptr const& txn, std::shared_ptr const& meta, - uint32_t date) + uint32_t date +) { - if (canHaveDeliveredAmount(txn, meta)) - { - if (auto amt = getDeliveredAmount(txn, meta, meta->getLgrSeq(), date)) - { + if (canHaveDeliveredAmount(txn, meta)) { + if (auto amt = getDeliveredAmount(txn, meta, meta->getLgrSeq(), date)) { metaJson["delivered_amount"] = toBoostJson(amt->getJson(ripple::JsonOptions::include_date)); - } - else - { + } else { metaJson["delivered_amount"] = "unavailable"; } return true; @@ -286,10 +266,8 @@ boost::json::object toJson(ripple::SLE const& sle) { boost::json::value value = boost::json::parse(sle.getJson(ripple::JsonOptions::none).toStyledString()); - if (sle.getType() == ripple::ltACCOUNT_ROOT) - { - if (sle.isFieldPresent(ripple::sfEmailHash)) - { + if (sle.getType() == ripple::ltACCOUNT_ROOT) { + if (sle.isFieldPresent(ripple::sfEmailHash)) { auto const& hash = sle.getFieldH128(ripple::sfEmailHash); std::string md5 = strHex(hash); boost::algorithm::to_lower(md5); @@ -322,12 +300,9 @@ std::optional parseStringAsUInt(std::string const& value) { std::optional index = {}; - try - { + try { index = boost::lexical_cast(value); - } - catch (boost::bad_lexical_cast const&) - { + } catch (boost::bad_lexical_cast const&) { } return index; @@ -338,8 +313,7 @@ ledgerInfoFromRequest(std::shared_ptr const& backe { auto hashValue = ctx.params.contains("ledger_hash") ? ctx.params.at("ledger_hash") : nullptr; - if (!hashValue.is_null()) - { + if (!hashValue.is_null()) { if (!hashValue.is_string()) return Status{RippledError::rpcINVALID_PARAMS, "ledgerHashNotString"}; @@ -358,25 +332,17 @@ ledgerInfoFromRequest(std::shared_ptr const& backe auto indexValue = ctx.params.contains("ledger_index") ? ctx.params.at("ledger_index") : nullptr; std::optional ledgerSequence = {}; - if (!indexValue.is_null()) - { - if (indexValue.is_string()) - { + if (!indexValue.is_null()) { + if (indexValue.is_string()) { boost::json::string const& stringIndex = indexValue.as_string(); - if (stringIndex == "validated") - { + if (stringIndex == "validated") { ledgerSequence = ctx.range.maxSequence; - } - else - { + } else { ledgerSequence = parseStringAsUInt(stringIndex.c_str()); } - } - else if (indexValue.is_int64()) + } else if (indexValue.is_int64()) ledgerSequence = indexValue.as_int64(); - } - else - { + } else { ledgerSequence = ctx.range.maxSequence; } @@ -398,12 +364,12 @@ getLedgerInfoFromHashOrSeq( boost::asio::yield_context yield, std::optional ledgerHash, std::optional ledgerIndex, - uint32_t maxSeq) + uint32_t maxSeq +) { std::optional lgrInfo; auto const err = Status{RippledError::rpcLGR_NOT_FOUND, "ledgerNotFound"}; - if (ledgerHash) - { + if (ledgerHash) { // invoke uint256's constructor to parse the hex string , instead of // copying buffer ripple::uint256 const ledgerHash256{std::string_view(*ledgerHash)}; @@ -446,10 +412,8 @@ ledgerInfoToBlob(ripple::LedgerHeader const& info, bool includeHash) std::uint64_t getStartHint(ripple::SLE const& sle, ripple::AccountID const& accountID) { - if (sle.getType() == ripple::ltRIPPLE_STATE) - { - if (sle.getFieldAmount(ripple::sfLowLimit).getIssuer() == accountID) - { + if (sle.getType() == ripple::ltRIPPLE_STATE) { + if (sle.getFieldAmount(ripple::sfLowLimit).getIssuer() == accountID) { return sle.getFieldU64(ripple::sfLowNode); } if (sle.getFieldAmount(ripple::sfHighLimit).getIssuer() == accountID) @@ -473,7 +437,8 @@ traverseNFTObjects( ripple::uint256 nextPage, std::uint32_t limit, boost::asio::yield_context yield, - std::function atOwnedNode) + std::function atOwnedNode +) { auto const firstNFTPage = ripple::keylet::nftpage_min(accountID); auto const lastNFTPage = ripple::keylet::nftpage_max(accountID); @@ -488,10 +453,8 @@ traverseNFTObjects( // read the current page auto page = backend.fetchLedgerObject(currentPage, sequence, yield); - if (!page) - { - if (nextPage == beast::zero) - { // no nft objects in lastNFTPage + if (!page) { + if (nextPage == beast::zero) { // no nft objects in lastNFTPage return AccountCursor{beast::zero, 0}; } // marker is in the right range, but still invalid return Status{RippledError::rpcINVALID_PARAMS, "Invalid marker."}; @@ -502,8 +465,7 @@ traverseNFTObjects( auto count = 0u; // traverse the nft page linked list until the start of the list or reach the limit - while (true) - { + while (true) { auto const nftPreviousPage = pageSLE.getFieldH256(ripple::sfPreviousPageMin); atOwnedNode(std::move(pageSLE)); count++; @@ -527,7 +489,8 @@ traverseOwnedNodes( std::optional jsonCursor, boost::asio::yield_context yield, std::function atOwnedNode, - bool nftIncluded) + bool nftIncluded +) { auto const maybeCursor = parseAccountCursor(jsonCursor); @@ -543,8 +506,7 @@ traverseOwnedNodes( // if we need to traverse nft objects and the marker is still in nft page -> traverse nft objects // if we need to traverse nft objects and the marker is still in nft page but next page is zero -> owned nodes // if we need to traverse nft objects and the marker is not in nft page -> traverse owned nodes - if (nftIncluded and (!jsonCursor or isNftMarkerNonZero)) - { + if (nftIncluded and (!jsonCursor or isNftMarkerNonZero)) { auto const cursorMaybe = traverseNFTObjects(backend, sequence, accountID, hexCursor, limit, yield, atOwnedNode); if (auto const status = std::get_if(&cursorMaybe)) @@ -560,16 +522,15 @@ traverseOwnedNodes( limit -= nftsCount; hexCursor = beast::zero; startHint = 0; - } - else if (nftIncluded and isNftMarkerZero) - { + } else if (nftIncluded and isNftMarkerZero) { // the last request happen to fetch all the nft, adjust marker to continue traversing owned nodes hexCursor = beast::zero; startHint = 0; } return traverseOwnedNodes( - backend, ripple::keylet::ownerDir(accountID), hexCursor, startHint, sequence, limit, yield, atOwnedNode); + backend, ripple::keylet::ownerDir(accountID), hexCursor, startHint, sequence, limit, yield, atOwnedNode + ); } std::variant @@ -581,7 +542,8 @@ traverseOwnedNodes( std::uint32_t sequence, std::uint32_t limit, boost::asio::yield_context yield, - std::function atOwnedNode) + std::function atOwnedNode +) { auto cursor = AccountCursor({beast::zero, 0}); @@ -600,8 +562,7 @@ traverseOwnedNodes( auto start = std::chrono::system_clock::now(); // If startAfter is not zero try jumping to that page using the hint - if (hexMarker.isNonZero()) - { + if (hexMarker.isNonZero()) { auto const hintIndex = ripple::keylet::page(rootIndex, startHint); auto hintDir = backend.fetchLedgerObject(hintIndex.key, sequence, yield); @@ -612,16 +573,14 @@ traverseOwnedNodes( ripple::SLE const hintDirSle{hintDirIt, hintIndex.key}; if (auto const& indexes = hintDirSle.getFieldV256(ripple::sfIndexes); - std::find(std::begin(indexes), std::end(indexes), hexMarker) == std::end(indexes)) - { + std::find(std::begin(indexes), std::end(indexes), hexMarker) == std::end(indexes)) { // the index specified by marker is not in the page specified by marker return Status(ripple::rpcINVALID_PARAMS, "Invalid marker."); } currentIndex = hintIndex; bool found = false; - for (;;) - { + for (;;) { auto const ownerDir = backend.fetchLedgerObject(currentIndex.key, sequence, yield); if (!ownerDir) @@ -630,26 +589,20 @@ traverseOwnedNodes( ripple::SerialIter ownedDirIt{ownerDir->data(), ownerDir->size()}; ripple::SLE const ownedDirSle{ownedDirIt, currentIndex.key}; - for (auto const& key : ownedDirSle.getFieldV256(ripple::sfIndexes)) - { - if (!found) - { + for (auto const& key : ownedDirSle.getFieldV256(ripple::sfIndexes)) { + if (!found) { if (key == hexMarker) found = true; - } - else - { + } else { keys.push_back(key); - if (--limit == 0) - { + if (--limit == 0) { break; } } } - if (limit == 0) - { + if (limit == 0) { cursor = AccountCursor({keys.back(), currentPage}); break; } @@ -661,11 +614,8 @@ traverseOwnedNodes( currentIndex = ripple::keylet::page(rootIndex, uNodeNext); currentPage = uNodeNext; } - } - else - { - for (;;) - { + } else { + for (;;) { auto const ownerDir = backend.fetchLedgerObject(currentIndex.key, sequence, yield); if (!ownerDir) @@ -674,16 +624,14 @@ traverseOwnedNodes( ripple::SerialIter ownedDirIt{ownerDir->data(), ownerDir->size()}; ripple::SLE const ownedDirSle{ownedDirIt, currentIndex.key}; - for (auto const& key : ownedDirSle.getFieldV256(ripple::sfIndexes)) - { + for (auto const& key : ownedDirSle.getFieldV256(ripple::sfIndexes)) { keys.push_back(key); if (--limit == 0) break; } - if (limit == 0) - { + if (limit == 0) { cursor = AccountCursor({keys.back(), currentPage}); break; } @@ -701,14 +649,14 @@ traverseOwnedNodes( LOG(gLog.debug()) << fmt::format( "Time loading owned directories: {} milliseconds, entries size: {}", std::chrono::duration_cast(end - start).count(), - keys.size()); + keys.size() + ); auto [objects, timeDiff] = util::timed([&]() { return backend.fetchLedgerObjects(keys, sequence, yield); }); LOG(gLog.debug()) << "Time loading owned entries: " << timeDiff << " milliseconds"; - for (auto i = 0u; i < objects.size(); ++i) - { + for (auto i = 0u; i < objects.size(); ++i) { ripple::SerialIter it{objects[i].data(), objects[i].size()}; atOwnedNode(ripple::SLE{it, keys[i]}); } @@ -724,10 +672,10 @@ read( std::shared_ptr const& backend, ripple::Keylet const& keylet, ripple::LedgerHeader const& lgrInfo, - web::Context const& context) + web::Context const& context +) { - if (auto const blob = backend->fetchLedgerObject(keylet.key, lgrInfo.seq, context.yield); blob) - { + if (auto const blob = backend->fetchLedgerObject(keylet.key, lgrInfo.seq, context.yield); blob) { return std::make_shared(ripple::SerialIter{blob->data(), blob->size()}, keylet.key); } @@ -766,10 +714,8 @@ keypairFromRequst(boost::json::object const& request) // Identify which secret type is in use. std::string secretType; int count = 0; - for (const auto& t : secretTypes) - { - if (request.contains(t)) - { + for (auto const& t : secretTypes) { + if (request.contains(t)) { ++count; secretType = t; } @@ -778,19 +724,16 @@ keypairFromRequst(boost::json::object const& request) if (count == 0) return Status{RippledError::rpcINVALID_PARAMS, "missing field secret"}; - if (count > 1) - { + if (count > 1) { return Status{ RippledError::rpcINVALID_PARAMS, - "Exactly one of the following must be specified: " - " passphrase, secret, seed, or seed_hex"}; + "Exactly one of the following must be specified: passphrase, secret, seed, or seed_hex"}; } std::optional keyType; std::optional seed; - if (has_key_type) - { + if (has_key_type) { if (!request.at("key_type").is_string()) return Status{RippledError::rpcINVALID_PARAMS, "keyTypeNotString"}; @@ -807,12 +750,10 @@ keypairFromRequst(boost::json::object const& request) // ripple-lib encodes seed used to generate an Ed25519 wallet in a // non-standard way. While we never encode seeds that way, we try // to detect such keys to avoid user confusion. - if (secretType != "seed_hex") - { + if (secretType != "seed_hex") { seed = parseRippleLibSeed(request.at(secretType)); - if (seed) - { + if (seed) { // If the user passed in an Ed25519 seed but *explicitly* // requested another key type, return an error. if (keyType.value_or(ripple::KeyType::ed25519) != ripple::KeyType::ed25519) @@ -825,32 +766,23 @@ keypairFromRequst(boost::json::object const& request) if (!keyType) keyType = ripple::KeyType::secp256k1; - if (!seed) - { - if (has_key_type) - { + if (!seed) { + if (has_key_type) { if (!request.at(secretType).is_string()) return Status{RippledError::rpcINVALID_PARAMS, "secret value must be string"}; std::string const key = request.at(secretType).as_string().c_str(); - if (secretType == "seed") - { + if (secretType == "seed") { seed = ripple::parseBase58(key); - } - else if (secretType == "passphrase") - { + } else if (secretType == "passphrase") { seed = ripple::parseGenericSeed(key); - } - else if (secretType == "seed_hex") - { + } else if (secretType == "seed_hex") { ripple::uint128 s; if (s.parseHex(key)) seed.emplace(ripple::Slice(s.data(), ripple::uint128::size())); } - } - else - { + } else { if (!request.at("secret").is_string()) return Status{RippledError::rpcINVALID_PARAMS, "field secret should be a string"}; @@ -872,18 +804,13 @@ std::vector getAccountsFromTransaction(boost::json::object const& transaction) { std::vector accounts = {}; - for (auto const& [key, value] : transaction) - { - if (value.is_object()) - { + for (auto const& [key, value] : transaction) { + if (value.is_object()) { auto inObject = getAccountsFromTransaction(value.as_object()); accounts.insert(accounts.end(), inObject.begin(), inObject.end()); - } - else if (value.is_string()) - { + } else if (value.is_string()) { auto account = ripple::parseBase58(value.as_string().c_str()); - if (account) - { + if (account) { accounts.push_back(*account); } } @@ -897,7 +824,8 @@ isGlobalFrozen( BackendInterface const& backend, std::uint32_t sequence, ripple::AccountID const& issuer, - boost::asio::yield_context yield) + boost::asio::yield_context yield +) { if (ripple::isXRP(issuer)) return false; @@ -921,7 +849,8 @@ isFrozen( ripple::AccountID const& account, ripple::Currency const& currency, ripple::AccountID const& issuer, - boost::asio::yield_context yield) + boost::asio::yield_context yield +) { if (ripple::isXRP(currency)) return false; @@ -938,8 +867,7 @@ isFrozen( if (sle.isFlag(ripple::lsfGlobalFreeze)) return true; - if (issuer != account) - { + if (issuer != account) { key = ripple::keylet::line(account, issuer, currency).key; blob = backend.fetchLedgerObject(key, sequence, yield); @@ -963,7 +891,8 @@ xrpLiquid( BackendInterface const& backend, std::uint32_t sequence, ripple::AccountID const& id, - boost::asio::yield_context yield) + boost::asio::yield_context yield +) { auto key = ripple::keylet::account(id).key; auto blob = backend.fetchLedgerObject(key, sequence, yield); @@ -993,10 +922,10 @@ accountFunds( std::uint32_t const sequence, ripple::STAmount const& amount, ripple::AccountID const& id, - boost::asio::yield_context yield) + boost::asio::yield_context yield +) { - if (!amount.native() && amount.getIssuer() == id) - { + if (!amount.native() && amount.getIssuer() == id) { return amount; } @@ -1011,19 +940,18 @@ accountHolds( ripple::Currency const& currency, ripple::AccountID const& issuer, bool const zeroIfFrozen, - boost::asio::yield_context yield) + boost::asio::yield_context yield +) { ripple::STAmount amount; - if (ripple::isXRP(currency)) - { + if (ripple::isXRP(currency)) { return {xrpLiquid(backend, sequence, account, yield)}; } auto key = ripple::keylet::line(account, issuer, currency).key; auto const blob = backend.fetchLedgerObject(key, sequence, yield); - if (!blob) - { + if (!blob) { amount.clear({currency, issuer}); return amount; } @@ -1031,15 +959,11 @@ accountHolds( ripple::SerialIter it{blob->data(), blob->size()}; ripple::SLE const sle{it, key}; - if (zeroIfFrozen && isFrozen(backend, sequence, account, currency, issuer, yield)) - { + if (zeroIfFrozen && isFrozen(backend, sequence, account, currency, issuer, yield)) { amount.clear(ripple::Issue(currency, issuer)); - } - else - { + } else { amount = sle.getFieldAmount(ripple::sfBalance); - if (account > issuer) - { + if (account > issuer) { // Put balance in account terms. amount.negate(); } @@ -1054,13 +978,13 @@ transferRate( BackendInterface const& backend, std::uint32_t sequence, ripple::AccountID const& issuer, - boost::asio::yield_context yield) + boost::asio::yield_context yield +) { auto key = ripple::keylet::account(issuer).key; auto blob = backend.fetchLedgerObject(key, sequence, yield); - if (blob) - { + if (blob) { ripple::SerialIter it{blob->data(), blob->size()}; ripple::SLE const sle{it, key}; @@ -1078,7 +1002,8 @@ postProcessOrderBook( ripple::AccountID const& takerID, data::BackendInterface const& backend, std::uint32_t const ledgerSequence, - boost::asio::yield_context yield) + boost::asio::yield_context yield +) { boost::json::array jsonOffers; @@ -1089,10 +1014,8 @@ postProcessOrderBook( auto rate = transferRate(backend, ledgerSequence, book.out.account, yield); - for (auto const& obj : offers) - { - try - { + for (auto const& obj : offers) { + try { ripple::SerialIter it{obj.blob.data(), obj.blob.size()}; ripple::SLE const offer{it, obj.key}; ripple::uint256 const bookDir = offer.getFieldH256(ripple::sfBookDirectory); @@ -1103,32 +1026,25 @@ postProcessOrderBook( ripple::STAmount saOwnerFunds; bool firstOwnerOffer = true; - if (book.out.account == uOfferOwnerID) - { + if (book.out.account == uOfferOwnerID) { // If an offer is selling issuer's own IOUs, it is fully // funded. saOwnerFunds = saTakerGets; - } - else if (globalFreeze) - { + } else if (globalFreeze) { // If either asset is globally frozen, consider all offers // that aren't ours to be totally unfunded saOwnerFunds.clear(book.out); - } - else - { + } else { auto umBalanceEntry = umBalance.find(uOfferOwnerID); - if (umBalanceEntry != umBalance.end()) - { + if (umBalanceEntry != umBalance.end()) { // Found in running balance table. saOwnerFunds = umBalanceEntry->second; firstOwnerOffer = false; - } - else - { + } else { saOwnerFunds = accountHolds( - backend, ledgerSequence, uOfferOwnerID, book.out.currency, book.out.account, true, yield); + backend, ledgerSequence, uOfferOwnerID, book.out.currency, book.out.account, true, yield + ); if (saOwnerFunds < beast::zero) saOwnerFunds.clear(); @@ -1154,13 +1070,10 @@ postProcessOrderBook( saOwnerFundsLimit = ripple::divide(saOwnerFunds, offerRate); } - if (saOwnerFundsLimit >= saTakerGets) - { + if (saOwnerFundsLimit >= saTakerGets) { // Sufficient funds no shenanigans. saTakerGetsFunded = saTakerGets; - } - else - { + } else { saTakerGetsFunded = saOwnerFundsLimit; offerJson["taker_gets_funded"] = toBoostJson(saTakerGetsFunded.getJson(ripple::JsonOptions::none)); offerJson["taker_pays_funded"] = @@ -1180,9 +1093,7 @@ postProcessOrderBook( offerJson["quality"] = dirRate.getText(); jsonOffers.push_back(offerJson); - } - catch (std::exception const& e) - { + } catch (std::exception const& e) { LOG(gLog.error()) << "caught exception: " << e.what(); } } @@ -1193,26 +1104,22 @@ postProcessOrderBook( std::variant parseBook(ripple::Currency pays, ripple::AccountID payIssuer, ripple::Currency gets, ripple::AccountID getIssuer) { - if (isXRP(pays) && !isXRP(payIssuer)) - { + if (isXRP(pays) && !isXRP(payIssuer)) { return Status{ RippledError::rpcSRC_ISR_MALFORMED, "Unneeded field 'taker_pays.issuer' for XRP currency specification."}; } - if (!isXRP(pays) && isXRP(payIssuer)) - { + if (!isXRP(pays) && isXRP(payIssuer)) { return Status{ RippledError::rpcSRC_ISR_MALFORMED, "Invalid field 'taker_pays.issuer', expected non-XRP issuer."}; } - if (ripple::isXRP(gets) && !ripple::isXRP(getIssuer)) - { + if (ripple::isXRP(gets) && !ripple::isXRP(getIssuer)) { return Status{ RippledError::rpcDST_ISR_MALFORMED, "Unneeded field 'taker_gets.issuer' for XRP currency specification."}; } - if (!ripple::isXRP(gets) && ripple::isXRP(getIssuer)) - { + if (!ripple::isXRP(gets) && ripple::isXRP(getIssuer)) { return Status{ RippledError::rpcDST_ISR_MALFORMED, "Invalid field 'taker_gets.issuer', expected non-XRP issuer."}; } @@ -1249,8 +1156,7 @@ parseBook(boost::json::object const& request) if (!taker_gets.contains("currency")) return Status{RippledError::rpcDST_AMT_MALFORMED}; - if (!taker_gets.at("currency").is_string()) - { + if (!taker_gets.at("currency").is_string()) { return Status{ RippledError::rpcDST_AMT_MALFORMED, }; @@ -1265,8 +1171,7 @@ parseBook(boost::json::object const& request) return Status{RippledError::rpcDST_AMT_MALFORMED}; ripple::AccountID pay_issuer; - if (taker_pays.contains("issuer")) - { + if (taker_pays.contains("issuer")) { if (!taker_pays.at("issuer").is_string()) return Status{RippledError::rpcINVALID_PARAMS, "takerPaysIssuerNotString"}; @@ -1275,20 +1180,16 @@ parseBook(boost::json::object const& request) if (pay_issuer == ripple::noAccount()) return Status{RippledError::rpcSRC_ISR_MALFORMED}; - } - else - { + } else { pay_issuer = ripple::xrpAccount(); } - if (isXRP(pay_currency) && !isXRP(pay_issuer)) - { + if (isXRP(pay_currency) && !isXRP(pay_issuer)) { return Status{ RippledError::rpcSRC_ISR_MALFORMED, "Unneeded field 'taker_pays.issuer' for XRP currency specification."}; } - if (!isXRP(pay_currency) && isXRP(pay_issuer)) - { + if (!isXRP(pay_currency) && isXRP(pay_issuer)) { return Status{ RippledError::rpcSRC_ISR_MALFORMED, "Invalid field 'taker_pays.issuer', expected non-XRP issuer."}; } @@ -1298,33 +1199,27 @@ parseBook(boost::json::object const& request) ripple::AccountID get_issuer; - if (taker_gets.contains("issuer")) - { + if (taker_gets.contains("issuer")) { if (!taker_gets["issuer"].is_string()) return Status{RippledError::rpcINVALID_PARAMS, "taker_gets.issuer should be string"}; if (!ripple::to_issuer(get_issuer, taker_gets.at("issuer").as_string().c_str())) return Status{RippledError::rpcDST_ISR_MALFORMED, "Invalid field 'taker_gets.issuer', bad issuer."}; - if (get_issuer == ripple::noAccount()) - { + if (get_issuer == ripple::noAccount()) { return Status{ RippledError::rpcDST_ISR_MALFORMED, "Invalid field 'taker_gets.issuer', bad issuer account one."}; } - } - else - { + } else { get_issuer = ripple::xrpAccount(); } - if (ripple::isXRP(get_currency) && !ripple::isXRP(get_issuer)) - { + if (ripple::isXRP(get_currency) && !ripple::isXRP(get_issuer)) { return Status{ RippledError::rpcDST_ISR_MALFORMED, "Unneeded field 'taker_gets.issuer' for XRP currency specification."}; } - if (!ripple::isXRP(get_currency) && ripple::isXRP(get_issuer)) - { + if (!ripple::isXRP(get_currency) && ripple::isXRP(get_issuer)) { return Status{ RippledError::rpcDST_ISR_MALFORMED, "Invalid field 'taker_gets.issuer', expected non-XRP issuer."}; } @@ -1351,11 +1246,9 @@ parseTaker(boost::json::value const& taker) bool specifiesCurrentOrClosedLedger(boost::json::object const& request) { - if (request.contains("ledger_index")) - { + if (request.contains("ledger_index")) { auto indexValue = request.at("ledger_index"); - if (indexValue.is_string()) - { + if (indexValue.is_string()) { std::string const index = indexValue.as_string().c_str(); return index == "current" || index == "closed"; } @@ -1384,7 +1277,8 @@ isAmendmentEnabled( std::shared_ptr const& backend, boost::asio::yield_context yield, uint32_t seq, - ripple::uint256 amendmentId) + ripple::uint256 amendmentId +) { // the amendments should always be present in ledger auto const& amendments = backend->fetchLedgerObject(ripple::keylet::amendments().key, seq, yield); diff --git a/src/rpc/RPCHelpers.h b/src/rpc/RPCHelpers.h index f0fea976..ac7a5151 100644 --- a/src/rpc/RPCHelpers.h +++ b/src/rpc/RPCHelpers.h @@ -74,14 +74,16 @@ std::pair toExpandedJson( data::TransactionAndMetadata const& blobs, NFTokenjson nftEnabled = NFTokenjson::DISABLE, - std::optional networkId = std::nullopt); + std::optional networkId = std::nullopt +); bool insertDeliveredAmount( boost::json::object& metaJson, std::shared_ptr const& txn, std::shared_ptr const& meta, - uint32_t date); + uint32_t date +); boost::json::object toJson(ripple::STBase const& obj); @@ -104,7 +106,8 @@ generatePubLedgerMessage( ripple::LedgerHeader const& lgrInfo, ripple::Fees const& fees, std::string const& ledgerRange, - std::uint32_t txnCount); + std::uint32_t txnCount +); std::variant ledgerInfoFromRequest(std::shared_ptr const& backend, web::Context const& ctx); @@ -115,7 +118,8 @@ getLedgerInfoFromHashOrSeq( boost::asio::yield_context yield, std::optional ledgerHash, std::optional ledgerIndex, - uint32_t maxSeq); + uint32_t maxSeq +); std::variant traverseOwnedNodes( @@ -126,7 +130,8 @@ traverseOwnedNodes( std::uint32_t sequence, std::uint32_t limit, boost::asio::yield_context yield, - std::function atOwnedNode); + std::function atOwnedNode +); // Remove the account check from traverseOwnedNodes // Account check has been done by framework,remove it from internal function @@ -139,14 +144,16 @@ traverseOwnedNodes( std::optional jsonCursor, boost::asio::yield_context yield, std::function atOwnedNode, - bool nftIncluded = false); + bool nftIncluded = false +); std::shared_ptr read( std::shared_ptr const& backend, ripple::Keylet const& keylet, ripple::LedgerHeader const& lgrInfo, - web::Context const& context); + web::Context const& context +); std::variant> keypairFromRequst(boost::json::object const& request); @@ -162,7 +169,8 @@ isGlobalFrozen( BackendInterface const& backend, std::uint32_t seq, ripple::AccountID const& issuer, - boost::asio::yield_context yield); + boost::asio::yield_context yield +); bool isFrozen( @@ -171,7 +179,8 @@ isFrozen( ripple::AccountID const& account, ripple::Currency const& currency, ripple::AccountID const& issuer, - boost::asio::yield_context yield); + boost::asio::yield_context yield +); ripple::STAmount accountFunds( @@ -179,7 +188,8 @@ accountFunds( std::uint32_t sequence, ripple::STAmount const& amount, ripple::AccountID const& id, - boost::asio::yield_context yield); + boost::asio::yield_context yield +); ripple::STAmount accountHolds( @@ -189,21 +199,24 @@ accountHolds( ripple::Currency const& currency, ripple::AccountID const& issuer, bool zeroIfFrozen, - boost::asio::yield_context yield); + boost::asio::yield_context yield +); ripple::Rate transferRate( BackendInterface const& backend, std::uint32_t sequence, ripple::AccountID const& issuer, - boost::asio::yield_context yield); + boost::asio::yield_context yield +); ripple::XRPAmount xrpLiquid( BackendInterface const& backend, std::uint32_t sequence, ripple::AccountID const& id, - boost::asio::yield_context yield); + boost::asio::yield_context yield +); boost::json::array postProcessOrderBook( @@ -212,7 +225,8 @@ postProcessOrderBook( ripple::AccountID const& takerID, data::BackendInterface const& backend, std::uint32_t ledgerSequence, - boost::asio::yield_context yield); + boost::asio::yield_context yield +); std::variant parseBook(ripple::Currency pays, ripple::AccountID payIssuer, ripple::Currency gets, ripple::AccountID getIssuer); @@ -234,7 +248,8 @@ isAmendmentEnabled( std::shared_ptr const& backend, boost::asio::yield_context yield, uint32_t seq, - ripple::uint256 amendmentId); + ripple::uint256 amendmentId +); std::optional encodeCTID(uint32_t ledgerSeq, uint16_t txnIndex, uint16_t networkId) noexcept; @@ -244,8 +259,7 @@ inline std::optional> decodeCTID(T const ctid) noexcept { auto const getCTID64 = [](T const ctid) noexcept -> std::optional { - if constexpr (std::is_convertible_v) - { + if constexpr (std::is_convertible_v) { std::string const ctidString(ctid); static std::size_t constexpr CTID_STRING_LENGTH = 16; if (ctidString.length() != CTID_STRING_LENGTH) @@ -289,19 +303,14 @@ logDuration(web::Context const& ctx, T const& dur) auto const millis = std::chrono::duration_cast(dur).count(); auto const seconds = std::chrono::duration_cast(dur).count(); auto const msg = fmt::format( - "Request processing duration = {} milliseconds. request = {}", - millis, - serialize(util::removeSecret(ctx.params))); + "Request processing duration = {} milliseconds. request = {}", millis, serialize(util::removeSecret(ctx.params)) + ); - if (seconds > DURATION_ERROR_THRESHOLD_SECONDS) - { + if (seconds > DURATION_ERROR_THRESHOLD_SECONDS) { LOG(log.error()) << ctx.tag() << msg; - } - else if (seconds > 1) - { + } else if (seconds > 1) { LOG(log.warn()) << ctx.tag() << msg; - } - else + } else LOG(log.info()) << ctx.tag() << msg; } diff --git a/src/rpc/WorkQueue.h b/src/rpc/WorkQueue.h index aa6a8f24..26d034bb 100644 --- a/src/rpc/WorkQueue.h +++ b/src/rpc/WorkQueue.h @@ -37,8 +37,7 @@ namespace rpc { /** * @brief An asynchronous, thread-safe queue for RPC requests. */ -class WorkQueue -{ +class WorkQueue { // these are cumulative for the lifetime of the process std::atomic_uint64_t queued_ = 0; std::atomic_uint64_t durationUs_ = 0; @@ -90,8 +89,7 @@ public: bool postCoro(FnType&& func, bool isWhiteListed) { - if (curSize_ >= maxSize_ && !isWhiteListed) - { + if (curSize_ >= maxSize_ && !isWhiteListed) { LOG(log_.warn()) << "Queue is full. rejecting job. current size = " << curSize_ << "; max size = " << maxSize_; return false; @@ -113,7 +111,8 @@ public: func(yield); --curSize_; - }); + } + ); return true; } diff --git a/src/rpc/common/APIVersion.h b/src/rpc/common/APIVersion.h index ce23e460..ed38e52e 100644 --- a/src/rpc/common/APIVersion.h +++ b/src/rpc/common/APIVersion.h @@ -49,8 +49,7 @@ static constexpr uint32_t API_VERSION_MAX = 2u; /** * @brief A baseclass for API version helper */ -class APIVersionParser -{ +class APIVersionParser { public: virtual ~APIVersionParser() = default; diff --git a/src/rpc/common/AnyHandler.h b/src/rpc/common/AnyHandler.h index d1bfe375..30b4e3b2 100644 --- a/src/rpc/common/AnyHandler.h +++ b/src/rpc/common/AnyHandler.h @@ -32,8 +32,7 @@ namespace rpc { * Support for copying was added in order to allow storing in a * map/unordered_map using the initializer_list constructor. */ -class AnyHandler final -{ +class AnyHandler final { public: /** * @brief Type-erases any handler class. @@ -79,8 +78,7 @@ public: } private: - struct Concept - { + struct Concept { virtual ~Concept() = default; [[nodiscard]] virtual ReturnType @@ -91,8 +89,7 @@ private: }; template - struct Model : Concept - { + struct Model : Concept { HandlerType handler; ProcessorType processor; diff --git a/src/rpc/common/Concepts.h b/src/rpc/common/Concepts.h index 04ce17ed..b5efbabc 100644 --- a/src/rpc/common/Concepts.h +++ b/src/rpc/common/Concepts.h @@ -33,22 +33,22 @@ struct RpcSpec; /** * @brief Specifies what a requirement used with @ref rpc::FieldSpec must provide. */ -// clang-format off template concept SomeRequirement = requires(T a, boost::json::value lval) { - { a.verify(lval, std::string{}) } -> std::same_as; + { + a.verify(lval, std::string{}) + } -> std::same_as; }; -// clang-format on /** * @brief Specifies what a modifier used with @ref rpc::FieldSpec must provide. */ -// clang-format off template concept SomeModifier = requires(T a, boost::json::value lval) { - { a.modify(lval, std::string{}) } -> std::same_as; + { + a.modify(lval, std::string{}) + } -> std::same_as; }; -// clang-format on /** * @brief The requirements of a processor to be used with @ref rpc::FieldSpec. @@ -59,54 +59,44 @@ concept SomeProcessor = (SomeRequirement or SomeModifier); /** * @brief A process function that expects both some Input and a Context. */ -// clang-format off template concept SomeContextProcessWithInput = requires(T a, typename T::Input in, typename T::Output out, Context const& ctx) { - { a.process(in, ctx) } -> std::same_as>; + { + a.process(in, ctx) + } -> std::same_as>; }; -// clang-format on /** * @brief A process function that expects no Input but does take a Context. */ -// clang-format off template concept SomeContextProcessWithoutInput = requires(T a, typename T::Output out, Context const& ctx) { - { a.process(ctx) } -> std::same_as>; + { + a.process(ctx) + } -> std::same_as>; }; -// clang-format on /** * @brief Specifies what a Handler with Input must provide. */ -// clang-format off template concept SomeHandlerWithInput = requires(T a, uint32_t version) { - { a.spec(version) } -> std::same_as; -} -and SomeContextProcessWithInput -and boost::json::has_value_to::value; -// clang-format on + { + a.spec(version) + } -> std::same_as; +} and SomeContextProcessWithInput and boost::json::has_value_to::value; /** * @brief Specifies what a Handler without Input must provide. */ -// clang-format off template concept SomeHandlerWithoutInput = SomeContextProcessWithoutInput; -// clang-format on /** * @brief Specifies what a Handler type must provide. */ -// clang-format off template -concept SomeHandler = -( - SomeHandlerWithInput or - SomeHandlerWithoutInput -) -and boost::json::has_value_from::value; -// clang-format on +concept SomeHandler = + (SomeHandlerWithInput or SomeHandlerWithoutInput)and boost::json::has_value_from::value; } // namespace rpc diff --git a/src/rpc/common/JsonBool.h b/src/rpc/common/JsonBool.h index 42cbb7f0..a1378b2a 100644 --- a/src/rpc/common/JsonBool.h +++ b/src/rpc/common/JsonBool.h @@ -1,13 +1,13 @@ #pragma once #include + namespace rpc { /** * @brief A wrapper around bool that allows to convert from any JSON value */ -struct JsonBool -{ +struct JsonBool { bool value = false; operator bool() const @@ -19,8 +19,7 @@ struct JsonBool inline JsonBool tag_invoke(boost::json::value_to_tag const&, boost::json::value const& jsonValue) { - switch (jsonValue.kind()) - { + switch (jsonValue.kind()) { case boost::json::kind::null: return JsonBool{false}; case boost::json::kind::bool_: @@ -32,8 +31,8 @@ tag_invoke(boost::json::value_to_tag const&, boost::json::value const& case boost::json::kind::double_: return JsonBool{jsonValue.as_double() != 0.0}; case boost::json::kind::string: - // Also should be `jsonValue.as_string() != "false"` but rippled doesn't do that. Anyway for v2 api we have - // bool validation + // Also should be `jsonValue.as_string() != "false"` but rippled doesn't do + // that. Anyway for v2 api we have bool validation return JsonBool{!jsonValue.as_string().empty() && jsonValue.as_string()[0] != 0}; case boost::json::kind::array: return JsonBool{!jsonValue.as_array().empty()}; diff --git a/src/rpc/common/MetaProcessors.cpp b/src/rpc/common/MetaProcessors.cpp index 98a3bcdc..3ebc5c28 100644 --- a/src/rpc/common/MetaProcessors.cpp +++ b/src/rpc/common/MetaProcessors.cpp @@ -38,8 +38,7 @@ Section::verify(boost::json::value& value, std::string_view key) const if (!res.is_object()) return {}; - for (auto const& spec : specs) - { + for (auto const& spec : specs) { if (auto const ret = spec.process(res); not ret) return Error{ret.error()}; } @@ -61,8 +60,7 @@ ValidateArrayAt::verify(boost::json::value& value, std::string_view key) const return Error{Status{RippledError::rpcINVALID_PARAMS}}; auto& res = arr.at(idx_); - for (auto const& spec : specs_) - { + for (auto const& spec : specs_) { if (auto const ret = spec.process(res); not ret) return Error{ret.error()}; } diff --git a/src/rpc/common/MetaProcessors.h b/src/rpc/common/MetaProcessors.h index 8ff01b61..6cbcae00 100644 --- a/src/rpc/common/MetaProcessors.h +++ b/src/rpc/common/MetaProcessors.h @@ -33,8 +33,7 @@ namespace rpc::meta { /** * @brief A meta-processor that acts as a spec for a sub-object/section. */ -class Section final -{ +class Section final { std::vector specs; public: @@ -61,8 +60,7 @@ public: /** * @brief A meta-processor that specifies a list of specs to run against the object at the given index in the array. */ -class ValidateArrayAt final -{ +class ValidateArrayAt final { std::size_t idx_; std::vector specs_; @@ -93,8 +91,7 @@ public: * parameter. */ template -class IfType final -{ +class IfType final { public: /** * @brief Constructs a validator that validates the specs if the type matches. @@ -103,26 +100,28 @@ public: template IfType(Requirements&&... requirements) : processor_( - [... r = std::forward( - requirements)](boost::json::value& j, std::string_view key) -> MaybeError { + [... r = std::forward(requirements + )](boost::json::value& j, std::string_view key) -> MaybeError { std::optional firstFailure = std::nullopt; // the check logic is the same as fieldspec - // clang-format off - ([&j, &key, &firstFailure, req = &r]() { - if (firstFailure) - return; + ( + [&j, &key, &firstFailure, req = &r]() { + if (firstFailure) + return; - if (auto const res = req->verify(j, key); not res) - firstFailure = res.error(); - }(), ...); - // clang-format on + if (auto const res = req->verify(j, key); not res) + firstFailure = res.error(); + }(), + ... + ); if (firstFailure) return Error{firstFailure.value()}; return {}; - }) + } + ) { } @@ -153,8 +152,7 @@ private: * @brief A meta-processor that wraps a validator and produces a custom error in case the wrapped validator fails. */ template -class WithCustomError final -{ +class WithCustomError final { SomeRequirement requirement; Status error; diff --git a/src/rpc/common/Modifiers.h b/src/rpc/common/Modifiers.h index b38bf705..0970a288 100644 --- a/src/rpc/common/Modifiers.h +++ b/src/rpc/common/Modifiers.h @@ -32,8 +32,7 @@ namespace rpc::modifiers { * @brief Clamp value between min and max. */ template -class Clamp final -{ +class Clamp final { Type min_; Type max_; @@ -76,8 +75,7 @@ public: * * Note: the conversion is only performed if the input value is a string. */ -struct ToLower final -{ +struct ToLower final { /** * @brief Update the input string to lower case. * diff --git a/src/rpc/common/Specs.cpp b/src/rpc/common/Specs.cpp index d189e486..e47469d7 100644 --- a/src/rpc/common/Specs.cpp +++ b/src/rpc/common/Specs.cpp @@ -32,8 +32,7 @@ FieldSpec::process(boost::json::value& value) const [[nodiscard]] MaybeError RpcSpec::process(boost::json::value& value) const { - for (auto const& field : fields_) - { + for (auto const& field : fields_) { if (auto ret = field.process(value); not ret) return Error{ret.error()}; } diff --git a/src/rpc/common/Specs.h b/src/rpc/common/Specs.h index cdb2f95f..8d6f7cde 100644 --- a/src/rpc/common/Specs.h +++ b/src/rpc/common/Specs.h @@ -31,8 +31,7 @@ namespace rpc { /** * @brief Represents a Specification for one field of an RPC command. */ -struct FieldSpec final -{ +struct FieldSpec final { /** * @brief Construct a field specification out of a set of processors. * @@ -65,8 +64,7 @@ private: * Note: this should really be all constexpr and handlers would expose * static constexpr RpcSpec spec instead. Maybe some day in the future. */ -struct RpcSpec final -{ +struct RpcSpec final { /** * @brief Construct a full RPC request specification. * @@ -82,7 +80,7 @@ struct RpcSpec final * @param other The other spec to copy fields from * @param additionalFields The additional fields to add to the spec */ - RpcSpec(const RpcSpec& other, std::initializer_list additionalFields) : fields_{other.fields_} + RpcSpec(RpcSpec const& other, std::initializer_list additionalFields) : fields_{other.fields_} { for (auto& f : additionalFields) fields_.push_back(f); diff --git a/src/rpc/common/Types.h b/src/rpc/common/Types.h index f6b6a5d5..334604df 100644 --- a/src/rpc/common/Types.h +++ b/src/rpc/common/Types.h @@ -75,15 +75,12 @@ using RpcSpecConstRef = RpcSpec const&; /** * @brief An empty type used as Output for handlers than don't actually produce output. */ -struct VoidOutput -{ -}; +struct VoidOutput {}; /** * @brief Context of an RPC call. */ -struct Context -{ +struct Context { boost::asio::yield_context yield; std::shared_ptr session = {}; bool isAdmin = false; @@ -99,8 +96,7 @@ using Result = std::variant; /** * @brief A cursor object used to traverse nodes owned by an account. */ -struct AccountCursor -{ +struct AccountCursor { ripple::uint256 index; std::uint32_t hint{}; @@ -120,8 +116,7 @@ struct AccountCursor /** * @brief Interface for the provider of RPC handlers. */ -class HandlerProvider -{ +class HandlerProvider { public: virtual ~HandlerProvider() = default; diff --git a/src/rpc/common/Validators.cpp b/src/rpc/common/Validators.cpp index f6441816..c05082df 100644 --- a/src/rpc/common/Validators.cpp +++ b/src/rpc/common/Validators.cpp @@ -112,8 +112,7 @@ CustomValidator AccountMarkerValidator = // TODO: we are using parseAccountCursor from RPCHelpers, after we // remove all old handler, this function can be moved to here - if (!parseAccountCursor(value.as_string().c_str())) - { + if (!parseAccountCursor(value.as_string().c_str())) { // align with the current error message return Error{Status{RippledError::rpcINVALID_PARAMS, "Malformed cursor."}}; } @@ -144,8 +143,7 @@ CustomValidator IssuerValidator = if (!ripple::to_issuer(issuer, value.as_string().c_str())) return Error{Status{RippledError::rpcINVALID_PARAMS, fmt::format("Invalid field '{}', bad issuer.", key)}}; - if (issuer == ripple::noAccount()) - { + if (issuer == ripple::noAccount()) { return Error{Status{ RippledError::rpcINVALID_PARAMS, fmt::format("Invalid field '{}', bad issuer account one.", key)}}; } @@ -163,8 +161,7 @@ CustomValidator SubscribeStreamValidator = static std::unordered_set const reportingNotSupportStreams = { "peer_status", "consensus", "server"}; - for (auto const& v : value.as_array()) - { + for (auto const& v : value.as_array()) { if (!v.is_string()) return Error{Status{RippledError::rpcINVALID_PARAMS, "streamNotString"}}; @@ -186,8 +183,7 @@ CustomValidator SubscribeAccountsValidator = if (value.as_array().empty()) return Error{Status{RippledError::rpcACT_MALFORMED, std::string(key) + " malformed."}}; - for (auto const& v : value.as_array()) - { + for (auto const& v : value.as_array()) { auto obj = boost::json::object(); auto const keyItem = std::string(key) + "'sItem"; diff --git a/src/rpc/common/Validators.h b/src/rpc/common/Validators.h index 2fda743b..7c313017 100644 --- a/src/rpc/common/Validators.h +++ b/src/rpc/common/Validators.h @@ -40,38 +40,26 @@ template [[nodiscard]] bool static checkType(boost::json::value const& value) { auto hasError = false; - if constexpr (std::is_same_v) - { + if constexpr (std::is_same_v) { if (not value.is_bool()) hasError = true; - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { if (not value.is_string()) hasError = true; - } - else if constexpr (std::is_same_v or std::is_same_v) - { + } else if constexpr (std::is_same_v or std::is_same_v) { if (not value.is_double()) hasError = true; - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { if (not value.is_array()) hasError = true; - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { if (not value.is_object()) hasError = true; - } - else if constexpr (std::is_convertible_v or std::is_convertible_v) - { + } else if constexpr (std::is_convertible_v or std::is_convertible_v) { if (not value.is_int64() && not value.is_uint64()) hasError = true; // specify the type is unsigened, it can not be negative - if constexpr (std::is_unsigned_v) - { + if constexpr (std::is_unsigned_v) { if (value.is_int64() and value.as_int64() < 0) hasError = true; } @@ -83,8 +71,7 @@ template /** * @brief A validator that simply requires a field to be present. */ -struct Required final -{ +struct Required final { [[nodiscard]] static MaybeError verify(boost::json::value const& value, std::string_view key); }; @@ -102,8 +89,7 @@ class NotSupported; * @brief A specialized NotSupported validator that forbids a field to be present when the value equals the given value. */ template -class NotSupported final -{ +class NotSupported final { T value_; public: @@ -126,12 +112,10 @@ public: [[nodiscard]] MaybeError verify(boost::json::value const& value, std::string_view key) const { - if (value.is_object() and value.as_object().contains(key.data())) - { + if (value.is_object() and value.as_object().contains(key.data())) { using boost::json::value_to; auto const res = value_to(value.as_object().at(key.data())); - if (value_ == res) - { + if (value_ == res) { return Error{Status{ RippledError::rpcNOT_SUPPORTED, fmt::format("Not supported field '{}'s value '{}'", std::string{key}, res)}}; @@ -145,8 +129,7 @@ public: * @brief A specialized NotSupported validator that forbids a field to be present. */ template <> -class NotSupported<> final -{ +class NotSupported<> final { public: /** * @brief Verify whether the field is supported or not. @@ -175,8 +158,7 @@ NotSupported(T&&... t) -> NotSupported; * @brief Validates that the type of the value is one of the given types. */ template -struct Type final -{ +struct Type final { /** * @brief Verify that the JSON value is (one) of specified type(s). * @@ -204,8 +186,7 @@ struct Type final * @brief Validate that value is between specified min and max. */ template -class Between final -{ +class Between final { Type min_; Type max_; @@ -250,8 +231,7 @@ public: * @brief Validate that value is equal or greater than the specified min. */ template -class Min final -{ +class Min final { Type min_; public: @@ -292,8 +272,7 @@ public: * @brief Validate that value is not greater than max. */ template -class Max final -{ +class Max final { Type max_; public: @@ -334,8 +313,7 @@ public: * @brief Validates that the value is equal to the one passed in. */ template -class EqualTo final -{ +class EqualTo final { Type original_; public: @@ -374,14 +352,13 @@ public: /** * @brief Deduction guide to help disambiguate what it means to EqualTo a "string" without specifying the type. */ -EqualTo(char const*)->EqualTo; +EqualTo(char const*) -> EqualTo; /** * @brief Validates that the value is one of the values passed in. */ template -class OneOf final -{ +class OneOf final { std::vector options_; public: @@ -430,13 +407,12 @@ public: /** * @brief Deduction guide to help disambiguate what it means to OneOf a few "strings" without specifying the type. */ -OneOf(std::initializer_list)->OneOf; +OneOf(std::initializer_list) -> OneOf; /** * @brief A meta-validator that allows to specify a custom validation function. */ -class CustomValidator final -{ +class CustomValidator final { std::function validator_; public: diff --git a/src/rpc/common/impl/APIVersionParser.cpp b/src/rpc/common/impl/APIVersionParser.cpp index f6bfaf5f..4364f0e5 100644 --- a/src/rpc/common/impl/APIVersionParser.cpp +++ b/src/rpc/common/impl/APIVersionParser.cpp @@ -30,7 +30,8 @@ ProductionAPIVersionParser::ProductionAPIVersionParser(util::Config const& confi : ProductionAPIVersionParser( config.valueOr("default", API_VERSION_DEFAULT), config.valueOr("min", API_VERSION_MIN), - config.valueOr("max", API_VERSION_MAX)) + config.valueOr("max", API_VERSION_MAX) + ) { } @@ -39,8 +40,7 @@ ProductionAPIVersionParser::parse(boost::json::object const& request) const { using Error = util::Unexpected; - if (request.contains("api_version")) - { + if (request.contains("api_version")) { if (!request.at("api_version").is_int64()) return Error{"API version must be an integer"}; diff --git a/src/rpc/common/impl/APIVersionParser.h b/src/rpc/common/impl/APIVersionParser.h index 17364bea..f7d2276f 100644 --- a/src/rpc/common/impl/APIVersionParser.h +++ b/src/rpc/common/impl/APIVersionParser.h @@ -29,8 +29,7 @@ namespace rpc::detail { -class ProductionAPIVersionParser : public APIVersionParser -{ +class ProductionAPIVersionParser : public APIVersionParser { util::Logger log_{"RPC"}; uint32_t defaultVersion_; @@ -42,15 +41,15 @@ public: ProductionAPIVersionParser( uint32_t defaultVersion = API_VERSION_DEFAULT, uint32_t minVersion = API_VERSION_MIN, - uint32_t maxVersion = API_VERSION_MAX) + uint32_t maxVersion = API_VERSION_MAX + ) : defaultVersion_{defaultVersion}, minVersion_{minVersion}, maxVersion_{maxVersion} { #ifndef UNITTEST_BUILD // in production, we don't want the ability to misconfigure clio with bogus versions // that are not actually supported by the code itself. for testing it is desired however. auto checkRange = [this](uint32_t version, std::string label) { - if (std::clamp(version, API_VERSION_MIN, API_VERSION_MAX) != version) - { + if (std::clamp(version, API_VERSION_MIN, API_VERSION_MAX) != version) { LOG(log_.error()) << "API version settings issue detected: " << label << " version with value " << version << " is outside of supported range " << API_VERSION_MIN << "-" << API_VERSION_MAX << "; Falling back to hardcoded values."; diff --git a/src/rpc/common/impl/Factories.h b/src/rpc/common/impl/Factories.h index 378cf159..9bdd5455 100644 --- a/src/rpc/common/impl/Factories.h +++ b/src/rpc/common/impl/Factories.h @@ -40,23 +40,23 @@ makeFieldProcessor(std::string const& key, Processors&&... procs) // This expands in order of Requirements and stops evaluating after first failure which is stored in // `firstFailure` and can be checked later on to see whether the verification failed as a whole or not. - // clang-format off - ([&j, &key, &firstFailure, req = &proc]() { - if (firstFailure) - return; // already failed earlier - skip + ( + [&j, &key, &firstFailure, req = &proc]() { + if (firstFailure) + return; // already failed earlier - skip - if constexpr (SomeRequirement) { - if (auto const res = req->verify(j, key); not res) - firstFailure = res.error(); - } else if constexpr (SomeModifier) { - if (auto const res = req->modify(j, key); not res) - firstFailure = res.error(); - } else { - static_assert(unsupported_v); - } - - }(), ...); - // clang-format on + if constexpr (SomeRequirement) { + if (auto const res = req->verify(j, key); not res) + firstFailure = res.error(); + } else if constexpr (SomeModifier) { + if (auto const res = req->modify(j, key); not res) + firstFailure = res.error(); + } else { + static_assert(unsupported_v); + } + }(), + ... + ); if (firstFailure) return Error{firstFailure.value()}; diff --git a/src/rpc/common/impl/ForwardingProxy.h b/src/rpc/common/impl/ForwardingProxy.h index 58564bc3..4e682ca0 100644 --- a/src/rpc/common/impl/ForwardingProxy.h +++ b/src/rpc/common/impl/ForwardingProxy.h @@ -33,8 +33,7 @@ namespace rpc::detail { template -class ForwardingProxy -{ +class ForwardingProxy { util::Logger log_{"RPC"}; std::shared_ptr balancer_; @@ -45,7 +44,8 @@ public: ForwardingProxy( std::shared_ptr const& balancer, CountersType& counters, - std::shared_ptr const& handlerProvider) + std::shared_ptr const& handlerProvider + ) : balancer_{balancer}, counters_{std::ref(counters)}, handlerProvider_{handlerProvider} { } @@ -76,8 +76,8 @@ public: return ctx.method == "ledger" and ((request.contains("queue") and request.at("queue").is_bool() and request.at("queue").as_bool()) or (request.contains("full") and request.at("full").is_bool() and request.at("full").as_bool()) or - (request.contains("accounts") and request.at("accounts").is_bool() and - request.at("accounts").as_bool())); + (request.contains("accounts") and request.at("accounts").is_bool() and request.at("accounts").as_bool() + )); }; return static_cast(checkAccountInfoForward() or checkLedgerForward()); @@ -90,8 +90,7 @@ public: toForward["command"] = ctx.method; auto const res = balancer_->forwardToRippled(toForward, ctx.clientIp, ctx.yield); - if (not res) - { + if (not res) { notifyFailedToForward(ctx.method); return Status{RippledError::rpcFAILED_TO_FORWARD}; } diff --git a/src/rpc/common/impl/HandlerProvider.cpp b/src/rpc/common/impl/HandlerProvider.cpp index 78632083..5540da76 100644 --- a/src/rpc/common/impl/HandlerProvider.cpp +++ b/src/rpc/common/impl/HandlerProvider.cpp @@ -61,7 +61,8 @@ ProductionHandlerProvider::ProductionHandlerProvider( std::shared_ptr const& subscriptionManager, std::shared_ptr const& balancer, std::shared_ptr const& etl, - Counters const& counters) + Counters const& counters +) : handlerMap_{ {"account_channels", {AccountChannelsHandler{backend}}}, {"account_currencies", {AccountCurrenciesHandler{backend}}}, diff --git a/src/rpc/common/impl/HandlerProvider.h b/src/rpc/common/impl/HandlerProvider.h index d73688da..a42cdd85 100644 --- a/src/rpc/common/impl/HandlerProvider.h +++ b/src/rpc/common/impl/HandlerProvider.h @@ -41,10 +41,8 @@ class SubscriptionManager; namespace rpc::detail { -class ProductionHandlerProvider final : public HandlerProvider -{ - struct Handler - { +class ProductionHandlerProvider final : public HandlerProvider { + struct Handler { AnyHandler handler; bool isClioOnly = false; }; @@ -58,7 +56,8 @@ public: std::shared_ptr const& subscriptionManager, std::shared_ptr const& balancer, std::shared_ptr const& etl, - Counters const& counters); + Counters const& counters + ); bool contains(std::string const& method) const override; diff --git a/src/rpc/common/impl/Processors.h b/src/rpc/common/impl/Processors.h index 9d40ce83..5f758a69 100644 --- a/src/rpc/common/impl/Processors.h +++ b/src/rpc/common/impl/Processors.h @@ -29,15 +29,13 @@ template static constexpr bool unsupported_handler_v = false; template -struct DefaultProcessor final -{ +struct DefaultProcessor final { [[nodiscard]] ReturnType operator()(HandlerType const& handler, boost::json::value const& value, Context const& ctx) const { using boost::json::value_from; using boost::json::value_to; - if constexpr (SomeHandlerWithInput) - { + if constexpr (SomeHandlerWithInput) { // first we run validation against specified API version auto const spec = handler.spec(ctx.apiVersion); auto input = value; // copy here, spec require mutable data @@ -49,24 +47,18 @@ struct DefaultProcessor final auto const ret = handler.process(inData, ctx); // real handler is given expected Input, not json - if (!ret) - { + if (!ret) { return Error{ret.error()}; // forward Status } return value_from(ret.value()); - } - else if constexpr (SomeHandlerWithoutInput) - { + } else if constexpr (SomeHandlerWithoutInput) { // no input to pass, ignore the value auto const ret = handler.process(ctx); - if (not ret) - { + if (not ret) { return Error{ret.error()}; // forward Status } return value_from(ret.value()); - } - else - { + } else { // when concept SomeHandlerWithInput and SomeHandlerWithoutInput not cover all Handler case static_assert(unsupported_handler_v); } diff --git a/src/rpc/handlers/AccountChannels.cpp b/src/rpc/handlers/AccountChannels.cpp index 546af1e2..e60ff345 100644 --- a/src/rpc/handlers/AccountChannels.cpp +++ b/src/rpc/handlers/AccountChannels.cpp @@ -33,8 +33,7 @@ AccountChannelsHandler::addChannel(std::vector& jsonChannels, r channel.balance = channelSle[ripple::sfBalance].getText(); channel.settleDelay = channelSle[ripple::sfSettleDelay]; - if (publicKeyType(channelSle[ripple::sfPublicKey])) - { + if (publicKeyType(channelSle[ripple::sfPublicKey])) { ripple::PublicKey const pk(channelSle[ripple::sfPublicKey]); channel.publicKey = toBase58(ripple::TokenType::AccountPublic, pk); channel.publicKeyHex = strHex(pk); @@ -60,7 +59,8 @@ AccountChannelsHandler::process(AccountChannelsHandler::Input input, Context con { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -79,8 +79,7 @@ AccountChannelsHandler::process(AccountChannelsHandler::Input input, Context con Output response; auto const addToResponse = [&](ripple::SLE&& sle) { if (sle.getType() == ripple::ltPAYCHAN && sle.getAccountID(ripple::sfAccount) == accountID && - (!destAccountID || *destAccountID == sle.getAccountID(ripple::sfDestination))) - { + (!destAccountID || *destAccountID == sle.getAccountID(ripple::sfDestination))) { addChannel(response.channels, sle); } @@ -88,7 +87,8 @@ AccountChannelsHandler::process(AccountChannelsHandler::Input input, Context con }; auto const next = traverseOwnedNodes( - *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse); + *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse + ); if (auto status = std::get_if(&next)) return Error{*status}; @@ -125,14 +125,10 @@ tag_invoke(boost::json::value_to_tag, boost::json if (jsonObject.contains(JS(destination_account))) input.destinationAccount = jv.at(JS(destination_account)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/AccountChannels.h b/src/rpc/handlers/AccountChannels.h index 95e0aab7..fe5cf2e1 100644 --- a/src/rpc/handlers/AccountChannels.h +++ b/src/rpc/handlers/AccountChannels.h @@ -36,8 +36,7 @@ namespace rpc { * * For more details see: https://xrpl.org/account_channels.html */ -class AccountChannelsHandler -{ +class AccountChannelsHandler { // dependencies std::shared_ptr const sharedPtrBackend_; @@ -47,8 +46,7 @@ public: static constexpr auto LIMIT_DEFAULT = 200; // type align with SField.h - struct ChannelResponse - { + struct ChannelResponse { std::string channelID; std::string account; std::string accountDestination; @@ -63,8 +61,7 @@ public: std::optional destinationTag; }; - struct Output - { + struct Output { std::vector channels; std::string account; std::string ledgerHash; @@ -75,8 +72,7 @@ public: std::optional marker; }; - struct Input - { + struct Input { std::string account; std::optional destinationAccount; std::optional ledgerHash; diff --git a/src/rpc/handlers/AccountCurrencies.cpp b/src/rpc/handlers/AccountCurrencies.cpp index 9f4d5c42..5fafaa28 100644 --- a/src/rpc/handlers/AccountCurrencies.cpp +++ b/src/rpc/handlers/AccountCurrencies.cpp @@ -25,7 +25,8 @@ AccountCurrenciesHandler::process(AccountCurrenciesHandler::Input input, Context { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -40,8 +41,7 @@ AccountCurrenciesHandler::process(AccountCurrenciesHandler::Input input, Context Output response; auto const addToResponse = [&](ripple::SLE&& sle) { - if (sle.getType() == ripple::ltRIPPLE_STATE) - { + if (sle.getType() == ripple::ltRIPPLE_STATE) { auto balance = sle.getFieldAmount(ripple::sfBalance); auto const lowLimit = sle.getFieldAmount(ripple::sfLowLimit); auto const highLimit = sle.getFieldAmount(ripple::sfHighLimit); @@ -70,7 +70,8 @@ AccountCurrenciesHandler::process(AccountCurrenciesHandler::Input input, Context std::numeric_limits::max(), {}, ctx.yield, - addToResponse); + addToResponse + ); response.ledgerHash = ripple::strHex(lgrInfo.hash); response.ledgerIndex = lgrInfo.seq; @@ -103,14 +104,10 @@ tag_invoke(boost::json::value_to_tag, boost::js if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/AccountCurrencies.h b/src/rpc/handlers/AccountCurrencies.h index 73786bc5..575a5bce 100644 --- a/src/rpc/handlers/AccountCurrencies.h +++ b/src/rpc/handlers/AccountCurrencies.h @@ -35,14 +35,12 @@ namespace rpc { * * For more details see: https://xrpl.org/account_currencies.html */ -class AccountCurrenciesHandler -{ +class AccountCurrenciesHandler { // dependencies std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { std::string ledgerHash; uint32_t ledgerIndex{}; std::set receiveCurrencies; @@ -51,8 +49,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string account; std::optional ledgerHash; std::optional ledgerIndex; diff --git a/src/rpc/handlers/AccountInfo.cpp b/src/rpc/handlers/AccountInfo.cpp index e5735cc4..9fb9f874 100644 --- a/src/rpc/handlers/AccountInfo.cpp +++ b/src/rpc/handlers/AccountInfo.cpp @@ -30,7 +30,8 @@ AccountInfoHandler::process(AccountInfoHandler::Input input, Context const& ctx) auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -57,8 +58,7 @@ AccountInfoHandler::process(AccountInfoHandler::Input input, Context const& ctx) rpc::isAmendmentEnabled(sharedPtrBackend_, ctx.yield, lgrInfo.seq, rpc::Amendments::Clawback); // Return SignerList(s) if that is requested. - if (input.signerLists) - { + if (input.signerLists) { // We put the SignerList in an array because of an anticipated // future when we support multiple signer lists on one account. auto const signersKey = ripple::keylet::signers(*accountID); @@ -68,8 +68,7 @@ AccountInfoHandler::process(AccountInfoHandler::Input input, Context const& ctx) auto const signers = sharedPtrBackend_->fetchLedgerObject(signersKey.key, lgrInfo.seq, ctx.yield); std::vector signerList; - if (signers) - { + if (signers) { ripple::STLedgerEntry const sleSigners{ ripple::SerialIter{signers->data(), signers->size()}, signersKey.key}; @@ -86,11 +85,13 @@ AccountInfoHandler::process(AccountInfoHandler::Input input, Context const& ctx) isDisallowIncomingEnabled, isClawbackEnabled, ctx.apiVersion, - signerList); + signerList + ); } return Output( - lgrInfo.seq, ripple::strHex(lgrInfo.hash), sle, isDisallowIncomingEnabled, isClawbackEnabled, ctx.apiVersion); + lgrInfo.seq, ripple::strHex(lgrInfo.hash), sle, isDisallowIncomingEnabled, isClawbackEnabled, ctx.apiVersion + ); } void @@ -115,8 +116,7 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, AccountInfoHandl {"requireDestinationTag", ripple::lsfRequireDestTag}, }}; - if (output.isDisallowIncomingEnabled) - { + if (output.isDisallowIncomingEnabled) { std::vector> const disallowIncomingFlags = { {"disallowIncomingNFTokenOffer", ripple::lsfDisallowIncomingNFTokenOffer}, {"disallowIncomingCheck", ripple::lsfDisallowIncomingCheck}, @@ -126,8 +126,7 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, AccountInfoHandl lsFlags.insert(lsFlags.end(), disallowIncomingFlags.begin(), disallowIncomingFlags.end()); } - if (output.isClawbackEnabled) - { + if (output.isClawbackEnabled) { lsFlags.emplace_back("allowTrustLineClawback", ripple::lsfAllowTrustLineClawback); } @@ -137,20 +136,17 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, AccountInfoHandl jv.as_object()[JS(account_flags)] = std::move(acctFlags); - if (output.signerLists) - { + if (output.signerLists) { auto signers = boost::json::array(); std::transform( std::cbegin(output.signerLists.value()), std::cend(output.signerLists.value()), std::back_inserter(signers), - [](auto const& signerList) { return toJson(signerList); }); - if (output.apiVersion == 1) - { + [](auto const& signerList) { return toJson(signerList); } + ); + if (output.apiVersion == 1) { jv.as_object()[JS(account_data)].as_object()[JS(signer_lists)] = std::move(signers); - } - else - { + } else { jv.as_object()[JS(signer_lists)] = signers; } } @@ -171,14 +167,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::va if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/AccountInfo.h b/src/rpc/handlers/AccountInfo.h index 038b1ebf..3db76946 100644 --- a/src/rpc/handlers/AccountInfo.h +++ b/src/rpc/handlers/AccountInfo.h @@ -33,13 +33,11 @@ namespace rpc { * * For more details see: https://xrpl.org/account_info.html */ -class AccountInfoHandler -{ +class AccountInfoHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { uint32_t ledgerIndex; std::string ledgerHash; ripple::STLedgerEntry accountData; @@ -57,7 +55,8 @@ public: bool isDisallowIncomingEnabled, bool isClawbackEnabled, uint32_t version, - std::optional> signerLists = std::nullopt) + std::optional> signerLists = std::nullopt + ) : ledgerIndex(ledgerId) , ledgerHash(std::move(ledgerHash)) , accountData(std::move(sle)) @@ -71,8 +70,7 @@ public: // "queue" is not available in Reporting mode // "ident" is deprecated, keep it for now, in line with rippled - struct Input - { + struct Input { std::optional account; std::optional ident; std::optional ledgerHash; diff --git a/src/rpc/handlers/AccountLines.cpp b/src/rpc/handlers/AccountLines.cpp index dd8ff3a4..70b25055 100644 --- a/src/rpc/handlers/AccountLines.cpp +++ b/src/rpc/handlers/AccountLines.cpp @@ -26,7 +26,8 @@ AccountLinesHandler::addLine( std::vector& lines, ripple::SLE const& lineSle, ripple::AccountID const& account, - std::optional const& peerAccount) + std::optional const& peerAccount +) { auto const flags = lineSle.getFieldU32(ripple::sfFlags); auto const lowLimit = lineSle.getFieldAmount(ripple::sfLowLimit); @@ -94,7 +95,8 @@ AccountLinesHandler::process(AccountLinesHandler::Input input, Context const& ct { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -113,17 +115,12 @@ AccountLinesHandler::process(AccountLinesHandler::Input input, Context const& ct response.lines.reserve(input.limit); auto const addToResponse = [&](ripple::SLE&& sle) { - if (sle.getType() == ripple::ltRIPPLE_STATE) - { + if (sle.getType() == ripple::ltRIPPLE_STATE) { auto ignore = false; - if (input.ignoreDefault) - { - if (sle.getFieldAmount(ripple::sfLowLimit).getIssuer() == accountID) - { + if (input.ignoreDefault) { + if (sle.getFieldAmount(ripple::sfLowLimit).getIssuer() == accountID) { ignore = ((sle.getFieldU32(ripple::sfFlags) & ripple::lsfLowReserve) == 0u); - } - else - { + } else { ignore = ((sle.getFieldU32(ripple::sfFlags) & ripple::lsfHighReserve) == 0u); } } @@ -134,7 +131,8 @@ AccountLinesHandler::process(AccountLinesHandler::Input input, Context const& ct }; auto const next = traverseOwnedNodes( - *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse); + *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse + ); if (auto status = std::get_if(&next)) return Error{*status}; @@ -175,14 +173,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::v if (jsonObject.contains(JS(ignore_default))) input.ignoreDefault = jv.at(JS(ignore_default)).as_bool(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } @@ -214,7 +208,8 @@ void tag_invoke( boost::json::value_from_tag, boost::json::value& jv, - [[maybe_unused]] AccountLinesHandler::LineResponse const& line) + [[maybe_unused]] AccountLinesHandler::LineResponse const& line +) { auto obj = boost::json::object{ {JS(account), line.account}, diff --git a/src/rpc/handlers/AccountLines.h b/src/rpc/handlers/AccountLines.h index 10ff6e97..69557621 100644 --- a/src/rpc/handlers/AccountLines.h +++ b/src/rpc/handlers/AccountLines.h @@ -36,8 +36,7 @@ namespace rpc { * * For more details see: https://xrpl.org/account_lines.html */ -class AccountLinesHandler -{ +class AccountLinesHandler { // dependencies std::shared_ptr const sharedPtrBackend_; @@ -46,8 +45,7 @@ public: static auto constexpr LIMIT_MAX = 400; static auto constexpr LIMIT_DEFAULT = 200; - struct LineResponse - { + struct LineResponse { std::string account; std::string balance; std::string currency; @@ -63,8 +61,7 @@ public: std::optional freezePeer; }; - struct Output - { + struct Output { std::string account; std::vector lines; std::string ledgerHash; @@ -74,8 +71,7 @@ public: uint32_t limit{}; }; - struct Input - { + struct Input { std::string account; std::optional ledgerHash; std::optional ledgerIndex; @@ -122,7 +118,8 @@ private: std::vector& lines, ripple::SLE const& lineSle, ripple::AccountID const& account, - std::optional const& peerAccount); + std::optional const& peerAccount + ); private: friend void diff --git a/src/rpc/handlers/AccountNFTs.cpp b/src/rpc/handlers/AccountNFTs.cpp index 7bef4ffc..9af37b5d 100644 --- a/src/rpc/handlers/AccountNFTs.cpp +++ b/src/rpc/handlers/AccountNFTs.cpp @@ -29,7 +29,8 @@ AccountNFTsHandler::process(AccountNFTsHandler::Input input, Context const& ctx) { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -59,12 +60,10 @@ AccountNFTsHandler::process(AccountNFTsHandler::Input input, Context const& ctx) std::optional page{ripple::SLE{ripple::SerialIter{blob->data(), blob->size()}, pageKey}}; auto numPages = 0u; - while (page) - { + while (page) { auto const arr = page->getFieldArray(ripple::sfNFTokens); - for (auto const& nft : arr) - { + for (auto const& nft : arr) { auto const nftokenID = nft[ripple::sfNFTokenID]; response.nfts.push_back(toBoostJson(nft.getJson(ripple::JsonOptions::none))); @@ -81,20 +80,16 @@ AccountNFTsHandler::process(AccountNFTsHandler::Input input, Context const& ctx) } ++numPages; - if (auto const npm = (*page)[~ripple::sfPreviousPageMin]) - { + if (auto const npm = (*page)[~ripple::sfPreviousPageMin]) { auto const nextKey = ripple::Keylet(ripple::ltNFTOKEN_PAGE, *npm); - if (numPages == input.limit) - { + if (numPages == input.limit) { response.marker = to_string(nextKey.key); return response; } auto const nextBlob = sharedPtrBackend_->fetchLedgerObject(nextKey.key, lgrInfo.seq, ctx.yield); page.emplace(ripple::SLE{ripple::SerialIter{nextBlob->data(), nextBlob->size()}, nextKey.key}); - } - else - { + } else { page.reset(); } } @@ -129,14 +124,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::va if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/AccountNFTs.h b/src/rpc/handlers/AccountNFTs.h index 57f0e00f..ea2f3014 100644 --- a/src/rpc/handlers/AccountNFTs.h +++ b/src/rpc/handlers/AccountNFTs.h @@ -32,8 +32,7 @@ namespace rpc { * * For more details see: https://xrpl.org/account_nfts.html */ -class AccountNFTsHandler -{ +class AccountNFTsHandler { std::shared_ptr sharedPtrBackend_; public: @@ -41,8 +40,7 @@ public: static auto constexpr LIMIT_MAX = 400; static auto constexpr LIMIT_DEFAULT = 100; - struct Output - { + struct Output { std::string account; std::string ledgerHash; uint32_t ledgerIndex; @@ -53,8 +51,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string account; std::optional ledgerHash; std::optional ledgerIndex; diff --git a/src/rpc/handlers/AccountObjects.cpp b/src/rpc/handlers/AccountObjects.cpp index cc076070..ca5fd6b5 100644 --- a/src/rpc/handlers/AccountObjects.cpp +++ b/src/rpc/handlers/AccountObjects.cpp @@ -40,7 +40,8 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -55,8 +56,7 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const auto typeFilter = std::optional>{}; - if (input.deletionBlockersOnly) - { + if (input.deletionBlockersOnly) { static constexpr ripple::LedgerEntryType deletionBlockers[] = { ripple::ltCHECK, ripple::ltESCROW, @@ -68,16 +68,13 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const typeFilter.emplace(); typeFilter->reserve(std::size(deletionBlockers)); - for (auto type : deletionBlockers) - { + for (auto type : deletionBlockers) { if (input.type && input.type != type) continue; typeFilter->push_back(type); } - } - else - { + } else { if (input.type && input.type != ripple::ltANY) typeFilter = {*input.type}; } @@ -86,15 +83,15 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const auto const addToResponse = [&](ripple::SLE&& sle) { if (not typeFilter or std::find(std::begin(typeFilter.value()), std::end(typeFilter.value()), sle.getType()) != - std::end(typeFilter.value())) - { + std::end(typeFilter.value())) { response.accountObjects.push_back(std::move(sle)); } return true; }; auto const next = traverseOwnedNodes( - *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse, true); + *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse, true + ); if (auto status = std::get_if(&next)) return Error{*status}; @@ -120,7 +117,8 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, AccountObjectsHa std::cbegin(output.accountObjects), std::cend(output.accountObjects), std::back_inserter(objects), - [](auto const& sle) { return toJson(sle); }); + [](auto const& sle) { return toJson(sle); } + ); jv = { {JS(ledger_hash), output.ledgerHash}, @@ -146,14 +144,10 @@ tag_invoke(boost::json::value_to_tag, boost::json: if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/AccountObjects.h b/src/rpc/handlers/AccountObjects.h index a723bff1..c92e5875 100644 --- a/src/rpc/handlers/AccountObjects.h +++ b/src/rpc/handlers/AccountObjects.h @@ -37,8 +37,7 @@ namespace rpc { * * For more details see: https://xrpl.org/account_objects.html */ -class AccountObjectsHandler -{ +class AccountObjectsHandler { // dependencies std::shared_ptr sharedPtrBackend_; @@ -50,8 +49,7 @@ public: static auto constexpr LIMIT_MAX = 400; static auto constexpr LIMIT_DEFAULT = 200; - struct Output - { + struct Output { std::string account; std::string ledgerHash; uint32_t ledgerIndex{}; @@ -61,8 +59,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string account; std::optional ledgerHash; std::optional ledgerIndex; diff --git a/src/rpc/handlers/AccountOffers.cpp b/src/rpc/handlers/AccountOffers.cpp index e6c38ae5..a30cfe1d 100644 --- a/src/rpc/handlers/AccountOffers.cpp +++ b/src/rpc/handlers/AccountOffers.cpp @@ -45,7 +45,8 @@ AccountOffersHandler::process(AccountOffersHandler::Input input, Context const& { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -71,7 +72,8 @@ AccountOffersHandler::process(AccountOffersHandler::Input input, Context const& }; auto const next = traverseOwnedNodes( - *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse); + *sharedPtrBackend_, *accountID, lgrInfo.seq, input.limit, input.marker, ctx.yield, addToResponse + ); if (auto const status = std::get_if(&next)) return Error{*status}; @@ -113,13 +115,10 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, AccountOffersHan if (offer.expiration) jsonObject[JS(expiration)] = *offer.expiration; - auto const convertAmount = [&](const char* field, ripple::STAmount const& amount) { - if (amount.native()) - { + auto const convertAmount = [&](char const* field, ripple::STAmount const& amount) { + if (amount.native()) { jsonObject[field] = amount.getText(); - } - else - { + } else { jsonObject[field] = { {JS(currency), ripple::to_string(amount.getCurrency())}, {JS(issuer), ripple::to_string(amount.getIssuer())}, @@ -140,18 +139,13 @@ tag_invoke(boost::json::value_to_tag, boost::json:: input.account = jsonObject.at(JS(account)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_hash))) - { + if (jsonObject.contains(JS(ledger_hash))) { input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); } - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/AccountOffers.h b/src/rpc/handlers/AccountOffers.h index c74c5892..6ecb3f9f 100644 --- a/src/rpc/handlers/AccountOffers.h +++ b/src/rpc/handlers/AccountOffers.h @@ -33,8 +33,7 @@ namespace rpc { * * For more details see: https://xrpl.org/account_offers.html */ -class AccountOffersHandler -{ +class AccountOffersHandler { std::shared_ptr sharedPtrBackend_; public: @@ -42,8 +41,7 @@ public: static auto constexpr LIMIT_MAX = 400; static auto constexpr LIMIT_DEFAULT = 200; - struct Offer - { + struct Offer { uint32_t flags{}; uint32_t seq{}; ripple::STAmount takerGets; @@ -52,8 +50,7 @@ public: std::optional expiration; }; - struct Output - { + struct Output { std::string account; std::string ledgerHash; uint32_t ledgerIndex{}; @@ -63,8 +60,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string account; std::optional ledgerHash; std::optional ledgerIndex; diff --git a/src/rpc/handlers/AccountTx.cpp b/src/rpc/handlers/AccountTx.cpp index 9d8eab2e..87fcd490 100644 --- a/src/rpc/handlers/AccountTx.cpp +++ b/src/rpc/handlers/AccountTx.cpp @@ -70,11 +70,9 @@ AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) con auto const range = sharedPtrBackend_->fetchLedgerRange(); auto [minIndex, maxIndex] = *range; - if (input.ledgerIndexMin) - { + if (input.ledgerIndexMin) { if (ctx.apiVersion > 1u && - (input.ledgerIndexMin > range->maxSequence || input.ledgerIndexMin < range->minSequence)) - { + (input.ledgerIndexMin > range->maxSequence || input.ledgerIndexMin < range->minSequence)) { return Error{Status{RippledError::rpcLGR_IDX_MALFORMED, "ledgerSeqMinOutOfRange"}}; } @@ -82,11 +80,9 @@ AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) con minIndex = *input.ledgerIndexMin; } - if (input.ledgerIndexMax) - { + if (input.ledgerIndexMax) { if (ctx.apiVersion > 1u && - (input.ledgerIndexMax > range->maxSequence || input.ledgerIndexMax < range->minSequence)) - { + (input.ledgerIndexMax > range->maxSequence || input.ledgerIndexMax < range->minSequence)) { return Error{Status{RippledError::rpcLGR_IDX_MALFORMED, "ledgerSeqMaxOutOfRange"}}; } @@ -94,25 +90,23 @@ AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) con maxIndex = *input.ledgerIndexMax; } - if (minIndex > maxIndex) - { + if (minIndex > maxIndex) { if (ctx.apiVersion == 1u) return Error{Status{RippledError::rpcLGR_IDXS_INVALID}}; return Error{Status{RippledError::rpcINVALID_LGR_RANGE}}; } - if (input.ledgerHash || input.ledgerIndex || input.usingValidatedLedger) - { + if (input.ledgerHash || input.ledgerIndex || input.usingValidatedLedger) { if (ctx.apiVersion > 1u && (input.ledgerIndexMax || input.ledgerIndexMin)) return Error{Status{RippledError::rpcINVALID_PARAMS, "containsLedgerSpecifierAndRange"}}; - if (!input.ledgerIndexMax && !input.ledgerIndexMin) - { + if (!input.ledgerIndexMax && !input.ledgerIndexMin) { // mimic rippled, when both range and index specified, respect the range. // take ledger from ledgerHash or ledgerIndex only when range is not specified auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -124,20 +118,14 @@ AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) con std::optional cursor; // if marker exists - if (input.marker) - { + if (input.marker) { cursor = {input.marker->ledger, input.marker->seq}; - } - else - { - // if forward, start at minIndex - 1, because the SQL query is exclusive, we need to include the 0 transaction - // index of minIndex - if (input.forward) - { + } else { + // if forward, start at minIndex - 1, because the SQL query is exclusive, we need to include the 0 + // transaction index of minIndex + if (input.forward) { cursor = {minIndex - 1, std::numeric_limits::max()}; - } - else - { + } else { cursor = {maxIndex, std::numeric_limits::max()}; } } @@ -156,30 +144,25 @@ AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) con if (retCursor) response.marker = {retCursor->ledgerSequence, retCursor->transactionIndex}; - for (auto const& txnPlusMeta : blobs) - { + for (auto const& txnPlusMeta : blobs) { // over the range if ((txnPlusMeta.ledgerSequence < minIndex && !input.forward) || - (txnPlusMeta.ledgerSequence > maxIndex && input.forward)) - { + (txnPlusMeta.ledgerSequence > maxIndex && input.forward)) { response.marker = std::nullopt; break; } - if (txnPlusMeta.ledgerSequence > maxIndex && !input.forward) - { + if (txnPlusMeta.ledgerSequence > maxIndex && !input.forward) { LOG(log_.debug()) << "Skipping over transactions from incomplete ledger"; continue; } boost::json::object obj; - if (!input.binary) - { + if (!input.binary) { auto [txn, meta] = toExpandedJson(txnPlusMeta, NFTokenjson::ENABLE); obj[JS(meta)] = std::move(meta); obj[JS(tx)] = std::move(txn); - if (obj[JS(tx)].as_object().contains(JS(TransactionType))) - { + if (obj[JS(tx)].as_object().contains(JS(TransactionType))) { auto const objTransactionType = obj[JS(tx)].as_object()[JS(TransactionType)]; auto const strType = util::toLower(objTransactionType.as_string().c_str()); @@ -194,9 +177,7 @@ AccountTxHandler::process(AccountTxHandler::Input input, Context const& ctx) con if (ctx.apiVersion < 2u) obj[JS(tx)].as_object()[JS(inLedger)] = txnPlusMeta.ledgerSequence; - } - else - { + } else { obj[JS(meta)] = ripple::strHex(txnPlusMeta.metadata); obj[JS(tx_blob)] = ripple::strHex(txnPlusMeta.transaction); obj[JS(ledger_index)] = txnPlusMeta.ledgerSequence; @@ -259,18 +240,12 @@ tag_invoke(boost::json::value_to_tag, boost::json::valu if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); - } - else - { + } else { // could not get the latest validated ledger seq here, using this flag to indicate that input.usingValidatedLedger = true; } @@ -285,15 +260,13 @@ tag_invoke(boost::json::value_to_tag, boost::json::valu if (jsonObject.contains(JS(limit))) input.limit = jsonObject.at(JS(limit)).as_int64(); - if (jsonObject.contains(JS(marker))) - { + if (jsonObject.contains(JS(marker))) { input.marker = AccountTxHandler::Marker{ jsonObject.at(JS(marker)).as_object().at(JS(ledger)).as_int64(), jsonObject.at(JS(marker)).as_object().at(JS(seq)).as_int64()}; } - if (jsonObject.contains("tx_type")) - { + if (jsonObject.contains("tx_type")) { auto objTransactionType = jsonObject.at("tx_type"); input.transactionType = AccountTxHandler::TYPESMAP.at(objTransactionType.as_string().c_str()); } diff --git a/src/rpc/handlers/AccountTx.h b/src/rpc/handlers/AccountTx.h index 575ba978..5cd2c193 100644 --- a/src/rpc/handlers/AccountTx.h +++ b/src/rpc/handlers/AccountTx.h @@ -35,8 +35,7 @@ namespace rpc { * * For more details see: https://xrpl.org/account_tx.html */ -class AccountTxHandler -{ +class AccountTxHandler { util::Logger log_{"RPC"}; std::shared_ptr sharedPtrBackend_; @@ -48,14 +47,12 @@ public: static auto constexpr LIMIT_MIN = 1; static auto constexpr LIMIT_DEFAULT = 200; - struct Marker - { + struct Marker { uint32_t ledger; uint32_t seq; }; - struct Output - { + struct Output { std::string account; uint32_t ledgerIndexMin{0}; uint32_t ledgerIndexMax{0}; @@ -67,8 +64,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string account; // You must use at least one of the following fields in your request: // ledger_index, ledger_hash, ledger_index_min, or ledger_index_max. diff --git a/src/rpc/handlers/BookChanges.cpp b/src/rpc/handlers/BookChanges.cpp index b45c2f5c..812ad4c7 100644 --- a/src/rpc/handlers/BookChanges.cpp +++ b/src/rpc/handlers/BookChanges.cpp @@ -26,7 +26,8 @@ BookChangesHandler::process(BookChangesHandler::Input input, Context const& ctx) { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -67,14 +68,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::va if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/BookChanges.h b/src/rpc/handlers/BookChanges.h index 8af67086..a8e3d250 100644 --- a/src/rpc/handlers/BookChanges.h +++ b/src/rpc/handlers/BookChanges.h @@ -32,13 +32,11 @@ namespace rpc { * * This API is not documented in the rippled API documentation. */ -class BookChangesHandler -{ +class BookChangesHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { std::string ledgerHash; uint32_t ledgerIndex{}; uint32_t ledgerTime{}; @@ -47,8 +45,7 @@ public: }; // Clio does not implement deletion_blockers_only - struct Input - { + struct Input { std::optional ledgerHash; std::optional ledgerIndex; }; diff --git a/src/rpc/handlers/BookOffers.cpp b/src/rpc/handlers/BookOffers.cpp index bec96e55..7ab5b03a 100644 --- a/src/rpc/handlers/BookOffers.cpp +++ b/src/rpc/handlers/BookOffers.cpp @@ -32,7 +32,8 @@ BookOffersHandler::process(Input input, Context const& ctx) const // check ledger auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -48,7 +49,8 @@ BookOffersHandler::process(Input input, Context const& ctx) const output.ledgerHash = ripple::strHex(lgrInfo.hash); output.ledgerIndex = lgrInfo.seq; output.offers = postProcessOrderBook( - offers, book, input.taker ? *(input.taker) : beast::zero, *sharedPtrBackend_, lgrInfo.seq, ctx.yield); + offers, book, input.taker ? *(input.taker) : beast::zero, *sharedPtrBackend_, lgrInfo.seq, ctx.yield + ); return output; } @@ -81,14 +83,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::val if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/BookOffers.h b/src/rpc/handlers/BookOffers.h index c42d8d23..2862ec5a 100644 --- a/src/rpc/handlers/BookOffers.h +++ b/src/rpc/handlers/BookOffers.h @@ -32,8 +32,7 @@ namespace rpc { * * For more details see: https://xrpl.org/book_offers.html */ -class BookOffersHandler -{ +class BookOffersHandler { std::shared_ptr sharedPtrBackend_; public: @@ -41,8 +40,7 @@ public: static auto constexpr LIMIT_MAX = 100; static auto constexpr LIMIT_DEFAULT = 60; - struct Output - { + struct Output { std::string ledgerHash; uint32_t ledgerIndex; boost::json::array offers; @@ -51,8 +49,7 @@ public: // the taker is not really used in both clio and rippled, both of them return all the offers regardless the funding // status - struct Input - { + struct Input { std::optional ledgerHash; std::optional ledgerIndex; uint32_t limit = LIMIT_DEFAULT; diff --git a/src/rpc/handlers/DepositAuthorized.cpp b/src/rpc/handlers/DepositAuthorized.cpp index d445333d..ccfb77bf 100644 --- a/src/rpc/handlers/DepositAuthorized.cpp +++ b/src/rpc/handlers/DepositAuthorized.cpp @@ -27,7 +27,8 @@ DepositAuthorizedHandler::process(DepositAuthorizedHandler::Input input, Context { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -56,15 +57,13 @@ DepositAuthorizedHandler::process(DepositAuthorizedHandler::Input input, Context response.ledgerIndex = lgrInfo.seq; // If the two accounts are the same, then the deposit should be fine. - if (sourceAccountID != destinationAccountID) - { + if (sourceAccountID != destinationAccountID) { auto it = ripple::SerialIter{dstAccountLedgerObject->data(), dstAccountLedgerObject->size()}; auto sle = ripple::SLE{it, dstKeylet}; // Check destination for the DepositAuth flag. // If that flag is not set then a deposit should be just fine. - if ((sle.getFieldU32(ripple::sfFlags) & ripple::lsfDepositAuth) != 0u) - { + if ((sle.getFieldU32(ripple::sfFlags) & ripple::lsfDepositAuth) != 0u) { // See if a preauthorization entry is in the ledger. auto const depositPreauthKeylet = ripple::keylet::depositPreauth(*destinationAccountID, *sourceAccountID); auto const sleDepositAuth = @@ -88,14 +87,10 @@ tag_invoke(boost::json::value_to_tag, boost::js if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/DepositAuthorized.h b/src/rpc/handlers/DepositAuthorized.h index 5cf19862..a6684cda 100644 --- a/src/rpc/handlers/DepositAuthorized.h +++ b/src/rpc/handlers/DepositAuthorized.h @@ -34,15 +34,13 @@ namespace rpc { * * For more details see: https://xrpl.org/deposit_authorized.html */ -class DepositAuthorizedHandler -{ +class DepositAuthorizedHandler { // dependencies std::shared_ptr const sharedPtrBackend_; public: // Note: `ledger_current_index` is omitted because it only makes sense for rippled - struct Output - { + struct Output { bool depositAuthorized = true; std::string sourceAccount; std::string destinationAccount; @@ -52,8 +50,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string sourceAccount; std::string destinationAccount; std::optional ledgerHash; diff --git a/src/rpc/handlers/GatewayBalances.cpp b/src/rpc/handlers/GatewayBalances.cpp index 71b2c028..7b2cca3e 100644 --- a/src/rpc/handlers/GatewayBalances.cpp +++ b/src/rpc/handlers/GatewayBalances.cpp @@ -27,7 +27,8 @@ GatewayBalancesHandler::process(GatewayBalancesHandler::Input input, Context con // check ledger auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -44,8 +45,7 @@ GatewayBalancesHandler::process(GatewayBalancesHandler::Input input, Context con auto output = GatewayBalancesHandler::Output{}; auto const addToResponse = [&](ripple::SLE&& sle) { - if (sle.getType() == ripple::ltRIPPLE_STATE) - { + if (sle.getType() == ripple::ltRIPPLE_STATE) { ripple::STAmount balance = sle.getFieldAmount(ripple::sfBalance); auto const lowLimit = sle.getFieldAmount(ripple::sfLowLimit); auto const highLimit = sle.getFieldAmount(ripple::sfHighLimit); @@ -67,38 +67,25 @@ GatewayBalancesHandler::process(GatewayBalancesHandler::Input input, Context con // Here, a negative balance means the cold wallet owes (normal) // A positive balance means the cold wallet has an asset (unusual) - if (input.hotWallets.contains(peer)) - { + if (input.hotWallets.contains(peer)) { // This is a specified hot wallet output.hotBalances[peer].push_back(-balance); - } - else if (balSign > 0) - { + } else if (balSign > 0) { // This is a gateway asset output.assets[peer].push_back(balance); - } - else if (freeze != 0u) - { + } else if (freeze != 0u) { // An obligation the gateway has frozen output.frozenBalances[peer].push_back(-balance); - } - else - { + } else { // normal negative balance, obligation to customer auto& bal = output.sums[balance.getCurrency()]; - if (bal == beast::zero) - { + if (bal == beast::zero) { // This is needed to set the currency code correctly bal = -balance; - } - else - { - try - { + } else { + try { bal -= balance; - } - catch (std::runtime_error const& e) - { + } catch (std::runtime_error const& e) { bal = ripple::STAmount(bal.issue(), ripple::STAmount::cMaxValue, ripple::STAmount::cMaxOffset); } } @@ -116,7 +103,8 @@ GatewayBalancesHandler::process(GatewayBalancesHandler::Input input, Context con std::numeric_limits::max(), {}, ctx.yield, - addToResponse); + addToResponse + ); if (auto status = std::get_if(&ret)) return Error{*status}; @@ -136,8 +124,7 @@ void tag_invoke(boost::json::value_from_tag, boost::json::value& jv, GatewayBalancesHandler::Output const& output) { boost::json::object obj; - if (!output.sums.empty()) - { + if (!output.sums.empty()) { boost::json::object obligations; for (auto const& [k, v] : output.sums) obligations[ripple::to_string(k)] = v.getText(); @@ -148,13 +135,10 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, GatewayBalancesH auto const toJson = [](std::map> const& balances) { boost::json::object balancesObj; - if (not balances.empty()) - { - for (auto const& [accId, accBalances] : balances) - { + if (not balances.empty()) { + for (auto const& [accId, accBalances] : balances) { boost::json::array arr; - for (auto const& balance : accBalances) - { + for (auto const& balance : accBalances) { boost::json::object entry; entry[JS(currency)] = ripple::to_string(balance.issue().currency); entry[JS(value)] = balance.getText(); @@ -200,32 +184,25 @@ tag_invoke(boost::json::value_to_tag, boost::json if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } - if (jsonObject.contains(JS(hotwallet))) - { - if (jsonObject.at(JS(hotwallet)).is_string()) - { + if (jsonObject.contains(JS(hotwallet))) { + if (jsonObject.at(JS(hotwallet)).is_string()) { input.hotWallets.insert(*accountFromStringStrict(jv.at(JS(hotwallet)).as_string().c_str())); - } - else - { + } else { auto const& hotWallets = jv.at(JS(hotwallet)).as_array(); std::transform( hotWallets.begin(), hotWallets.end(), std::inserter(input.hotWallets, input.hotWallets.begin()), - [](auto const& hotWallet) { return *accountFromStringStrict(hotWallet.as_string().c_str()); }); + [](auto const& hotWallet) { return *accountFromStringStrict(hotWallet.as_string().c_str()); } + ); } } diff --git a/src/rpc/handlers/GatewayBalances.h b/src/rpc/handlers/GatewayBalances.h index 020dacda..9fd7fd0c 100644 --- a/src/rpc/handlers/GatewayBalances.h +++ b/src/rpc/handlers/GatewayBalances.h @@ -33,13 +33,11 @@ namespace rpc { * * For more details see: https://xrpl.org/gateway_balances.html#gateway_balances */ -class GatewayBalancesHandler -{ +class GatewayBalancesHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { std::string ledgerHash; uint32_t ledgerIndex; std::string accountID; @@ -52,8 +50,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string account; std::set hotWallets; std::optional ledgerHash; @@ -78,10 +75,10 @@ public: // wallet needs to be an valid accountID or public key auto const wallets = value.is_array() ? value.as_array() : boost::json::array{value}; auto const getAccountID = [](auto const& j) -> std::optional { - if (j.is_string()) - { + if (j.is_string()) { auto const pk = ripple::parseBase58( - ripple::TokenType::AccountPublic, j.as_string().c_str()); + ripple::TokenType::AccountPublic, j.as_string().c_str() + ); if (pk) return ripple::calcAccountID(*pk); @@ -92,8 +89,7 @@ public: return {}; }; - for (auto const& wallet : wallets) - { + for (auto const& wallet : wallets) { if (!getAccountID(wallet)) return Error{Status{RippledError::rpcINVALID_PARAMS, std::string(key) + "Malformed"}}; } diff --git a/src/rpc/handlers/Ledger.cpp b/src/rpc/handlers/Ledger.cpp index 21f7a98e..04e535a3 100644 --- a/src/rpc/handlers/Ledger.cpp +++ b/src/rpc/handlers/Ledger.cpp @@ -25,7 +25,8 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -33,12 +34,9 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const auto const lgrInfo = std::get(lgrInfoOrStatus); Output output; - if (input.binary) - { + if (input.binary) { output.header[JS(ledger_data)] = ripple::strHex(ledgerInfoToBlob(lgrInfo)); - } - else - { + } else { output.header[JS(account_hash)] = ripple::strHex(lgrInfo.accountHash); output.header[JS(close_flags)] = lgrInfo.closeFlags; output.header[JS(close_time)] = lgrInfo.closeTime.time_since_epoch().count(); @@ -55,13 +53,11 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const output.header[JS(closed)] = true; - if (input.transactions) - { + if (input.transactions) { output.header[JS(transactions)] = boost::json::value(boost::json::array_kind); boost::json::array& jsonTxs = output.header.at(JS(transactions)).as_array(); - if (input.expand) - { + if (input.expand) { auto txns = sharedPtrBackend_->fetchAllTransactionsInLedger(lgrInfo.seq, ctx.yield); std::transform( @@ -70,32 +66,26 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const std::back_inserter(jsonTxs), [&](auto obj) { boost::json::object entry; - if (!input.binary) - { + if (!input.binary) { auto [txn, meta] = toExpandedJson(obj); entry = std::move(txn); entry[JS(metaData)] = std::move(meta); - } - else - { + } else { entry[JS(tx_blob)] = ripple::strHex(obj.transaction); entry[JS(meta)] = ripple::strHex(obj.metadata); } - if (input.ownerFunds) - { + if (input.ownerFunds) { // check the type of tx auto const [tx, meta] = rpc::deserializeTxPlusMeta(obj); if (tx and tx->isFieldPresent(ripple::sfTransactionType) and - tx->getTxnType() == ripple::ttOFFER_CREATE) - { + tx->getTxnType() == ripple::ttOFFER_CREATE) { auto const account = tx->getAccountID(ripple::sfAccount); auto const amount = tx->getFieldAmount(ripple::sfTakerGets); // If the offer create is not self funded then add the // owner balance - if (account != amount.getIssuer()) - { + if (account != amount.getIssuer()) { auto const ownerFunds = accountHolds( *sharedPtrBackend_, lgrInfo.seq, @@ -103,48 +93,42 @@ LedgerHandler::process(LedgerHandler::Input input, Context const& ctx) const amount.getCurrency(), amount.getIssuer(), false, // fhIGNORE_FREEZE from rippled - ctx.yield); + ctx.yield + ); entry[JS(owner_funds)] = ownerFunds.getText(); } } } return entry; - }); - } - else - { + } + ); + } else { auto hashes = sharedPtrBackend_->fetchAllTransactionHashesInLedger(lgrInfo.seq, ctx.yield); std::transform( std::move_iterator(hashes.begin()), std::move_iterator(hashes.end()), std::back_inserter(jsonTxs), - [](auto hash) { return boost::json::string(ripple::strHex(hash)); }); + [](auto hash) { return boost::json::string(ripple::strHex(hash)); } + ); } } - if (input.diff) - { + if (input.diff) { output.header["diff"] = boost::json::value(boost::json::array_kind); boost::json::array& jsonDiff = output.header.at("diff").as_array(); auto diff = sharedPtrBackend_->fetchLedgerDiff(lgrInfo.seq, ctx.yield); - for (auto const& obj : diff) - { + for (auto const& obj : diff) { boost::json::object entry; entry["object_id"] = ripple::strHex(obj.key); - if (input.binary) - { + if (input.binary) { entry["object"] = ripple::strHex(obj.blob); - } - else if (!obj.blob.empty()) - { + } else if (!obj.blob.empty()) { ripple::STLedgerEntry const sle{ripple::SerialIter{obj.blob.data(), obj.blob.size()}, obj.key}; entry["object"] = toJson(sle); - } - else - { + } else { entry["object"] = ""; } @@ -178,14 +162,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::value c if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/Ledger.h b/src/rpc/handlers/Ledger.h index 7cfae11a..ccd4ad1e 100644 --- a/src/rpc/handlers/Ledger.h +++ b/src/rpc/handlers/Ledger.h @@ -31,13 +31,11 @@ namespace rpc { * * For more details see: https://xrpl.org/ledger.html */ -class LedgerHandler -{ +class LedgerHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { uint32_t ledgerIndex{}; std::string ledgerHash; // TODO: use better type @@ -48,8 +46,7 @@ public: // clio not support : accounts/full/owner_finds/queue/type // clio will throw error when accounts/full/owner_funds/queue is set to true // https://github.com/XRPLF/clio/issues/603 - struct Input - { + struct Input { std::optional ledgerHash; std::optional ledgerIndex; bool binary = false; diff --git a/src/rpc/handlers/LedgerData.cpp b/src/rpc/handlers/LedgerData.cpp index 01901f13..4b07226f 100644 --- a/src/rpc/handlers/LedgerData.cpp +++ b/src/rpc/handlers/LedgerData.cpp @@ -63,7 +63,8 @@ LedgerDataHandler::process(Input input, Context const& ctx) const auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -74,14 +75,10 @@ LedgerDataHandler::process(Input input, Context const& ctx) const auto header = boost::json::object(); Output output; - if ((!input.marker) && (!input.diffMarker)) - { - if (input.binary) - { + if ((!input.marker) && (!input.diffMarker)) { + if (input.binary) { header[JS(ledger_data)] = ripple::strHex(ledgerInfoToBlob(lgrInfo)); - } - else - { + } else { header[JS(account_hash)] = ripple::strHex(lgrInfo.accountHash); header[JS(close_flags)] = lgrInfo.closeFlags; header[JS(close_time)] = lgrInfo.closeTime.time_since_epoch().count(); @@ -97,9 +94,7 @@ LedgerDataHandler::process(Input input, Context const& ctx) const header[JS(closed)] = true; output.header = std::move(header); - } - else - { + } else { if (input.marker && !sharedPtrBackend_->fetchLedgerObject(*(input.marker), lgrInfo.seq, ctx.yield)) return Error{Status{RippledError::rpcINVALID_PARAMS, "markerDoesNotExist"}}; } @@ -110,22 +105,19 @@ LedgerDataHandler::process(Input input, Context const& ctx) const auto const start = std::chrono::system_clock::now(); std::vector results; - if (input.diffMarker) - { + if (input.diffMarker) { // keep the same logic as previous implementation auto diff = sharedPtrBackend_->fetchLedgerDiff(*(input.diffMarker), ctx.yield); std::vector keys; - for (auto& [key, object] : diff) - { + for (auto& [key, object] : diff) { if (object.empty()) keys.push_back(key); } auto objs = sharedPtrBackend_->fetchLedgerObjects(keys, lgrInfo.seq, ctx.yield); - for (size_t i = 0; i < objs.size(); ++i) - { + for (size_t i = 0; i < objs.size(); ++i) { auto& obj = objs[i]; if (!obj.empty()) results.push_back({keys[i], std::move(obj)}); @@ -133,9 +125,7 @@ LedgerDataHandler::process(Input input, Context const& ctx) const if (*(input.diffMarker) > lgrInfo.seq) output.diffMarker = *(input.diffMarker) - 1; - } - else - { + } else { // limit's limitation is different based on binary or json // framework can not handler the check right now, adjust the value here auto const limit = @@ -143,12 +133,9 @@ LedgerDataHandler::process(Input input, Context const& ctx) const auto page = sharedPtrBackend_->fetchLedgerPage(input.marker, lgrInfo.seq, limit, input.outOfOrder, ctx.yield); results = std::move(page.objects); - if (page.cursor) - { + if (page.cursor) { output.marker = ripple::strHex(*(page.cursor)); - } - else if (input.outOfOrder) - { + } else if (input.outOfOrder) { output.diffMarker = sharedPtrBackend_->fetchLedgerRange()->maxSequence; } } @@ -159,22 +146,17 @@ LedgerDataHandler::process(Input input, Context const& ctx) const output.states.reserve(results.size()); - for (auto const& [key, object] : results) - { + for (auto const& [key, object] : results) { ripple::STLedgerEntry const sle{ripple::SerialIter{object.data(), object.size()}, key}; // note the filter is after limit is applied, same as rippled - if (input.type == ripple::LedgerEntryType::ltANY || sle.getType() == input.type) - { - if (input.binary) - { + if (input.type == ripple::LedgerEntryType::ltANY || sle.getType() == input.type) { + if (input.binary) { boost::json::object entry; entry[JS(data)] = ripple::serializeHex(sle); entry[JS(index)] = ripple::to_string(sle.key()); output.states.push_back(std::move(entry)); - } - else - { + } else { output.states.push_back(toJson(sle)); } } @@ -206,12 +188,9 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, LedgerDataHandle if (output.cacheFull) obj["cache_full"] = *(output.cacheFull); - if (output.diffMarker) - { + if (output.diffMarker) { obj[JS(marker)] = *(output.diffMarker); - } - else if (output.marker) - { + } else if (output.marker) { obj[JS(marker)] = *(output.marker); } @@ -224,8 +203,7 @@ tag_invoke(boost::json::value_to_tag, boost::json::val auto input = LedgerDataHandler::Input{}; auto const& jsonObject = jv.as_object(); - if (jsonObject.contains(JS(binary))) - { + if (jsonObject.contains(JS(binary))) { input.binary = jsonObject.at(JS(binary)).as_bool(); input.limit = input.binary ? LedgerDataHandler::LIMITBINARY : LedgerDataHandler::LIMITJSON; } @@ -236,14 +214,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::val if (jsonObject.contains("out_of_order")) input.outOfOrder = jsonObject.at("out_of_order").as_bool(); - if (jsonObject.contains("marker")) - { - if (jsonObject.at("marker").is_string()) - { + if (jsonObject.contains("marker")) { + if (jsonObject.at("marker").is_string()) { input.marker = ripple::uint256{jsonObject.at("marker").as_string().c_str()}; - } - else - { + } else { input.diffMarker = jsonObject.at("marker").as_int64(); } } @@ -251,14 +225,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::val if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/LedgerData.h b/src/rpc/handlers/LedgerData.h index 497df40c..a6ce2ceb 100644 --- a/src/rpc/handlers/LedgerData.h +++ b/src/rpc/handlers/LedgerData.h @@ -36,8 +36,7 @@ namespace rpc { * * For more details see: https://xrpl.org/ledger_data.html */ -class LedgerDataHandler -{ +class LedgerDataHandler { // dependencies std::shared_ptr sharedPtrBackend_; util::Logger log_{"RPC"}; @@ -51,8 +50,7 @@ public: static uint32_t constexpr LIMITBINARY = 2048; static uint32_t constexpr LIMITJSON = 256; - struct Output - { + struct Output { uint32_t ledgerIndex{}; std::string ledgerHash; std::optional header; @@ -66,8 +64,7 @@ public: // TODO: Clio does not implement "type" filter // outOfOrder only for clio, there is no document, traverse via seq diff // outOfOrder implementation is copied from old rpc handler - struct Input - { + struct Input { std::optional ledgerHash; std::optional ledgerIndex; bool binary = false; @@ -87,7 +84,7 @@ public: static RpcSpecConstRef spec([[maybe_unused]] uint32_t apiVersion) { - static const auto rpcSpec = RpcSpec{ + static auto const rpcSpec = RpcSpec{ {JS(binary), validation::Type{}}, {"out_of_order", validation::Type{}}, {JS(ledger_hash), validation::Uint256HexStringValidator}, diff --git a/src/rpc/handlers/LedgerEntry.cpp b/src/rpc/handlers/LedgerEntry.cpp index b39f4b02..18596ac0 100644 --- a/src/rpc/handlers/LedgerEntry.cpp +++ b/src/rpc/handlers/LedgerEntry.cpp @@ -28,59 +28,44 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input input, Context const& ctx) { ripple::uint256 key; - if (input.index) - { + if (input.index) { key = ripple::uint256{std::string_view(*(input.index))}; - } - else if (input.accountRoot) - { + } else if (input.accountRoot) { key = ripple::keylet::account(*ripple::parseBase58(*(input.accountRoot))).key; - } - else if (input.directory) - { + } else if (input.directory) { auto const keyOrStatus = composeKeyFromDirectory(*input.directory); if (auto const status = std::get_if(&keyOrStatus)) return Error{*status}; key = std::get(keyOrStatus); - } - else if (input.offer) - { + } else if (input.offer) { auto const id = ripple::parseBase58(input.offer->at(JS(account)).as_string().c_str()); key = ripple::keylet::offer(*id, boost::json::value_to(input.offer->at(JS(seq)))).key; - } - else if (input.rippleStateAccount) - { + } else if (input.rippleStateAccount) { auto const id1 = ripple::parseBase58( - input.rippleStateAccount->at(JS(accounts)).as_array().at(0).as_string().c_str()); + input.rippleStateAccount->at(JS(accounts)).as_array().at(0).as_string().c_str() + ); auto const id2 = ripple::parseBase58( - input.rippleStateAccount->at(JS(accounts)).as_array().at(1).as_string().c_str()); + input.rippleStateAccount->at(JS(accounts)).as_array().at(1).as_string().c_str() + ); auto const currency = ripple::to_currency(input.rippleStateAccount->at(JS(currency)).as_string().c_str()); key = ripple::keylet::line(*id1, *id2, currency).key; - } - else if (input.escrow) - { + } else if (input.escrow) { auto const id = ripple::parseBase58(input.escrow->at(JS(owner)).as_string().c_str()); key = ripple::keylet::escrow(*id, input.escrow->at(JS(seq)).as_int64()).key; - } - else if (input.depositPreauth) - { + } else if (input.depositPreauth) { auto const owner = ripple::parseBase58(input.depositPreauth->at(JS(owner)).as_string().c_str()); auto const authorized = ripple::parseBase58(input.depositPreauth->at(JS(authorized)).as_string().c_str()); key = ripple::keylet::depositPreauth(*owner, *authorized).key; - } - else if (input.ticket) - { + } else if (input.ticket) { auto const id = ripple::parseBase58(input.ticket->at(JS(account)).as_string().c_str()); key = ripple::getTicketIndex(*id, input.ticket->at(JS(ticket_seq)).as_int64()); - } - else - { + } else { // Must specify 1 of the following fields to indicate what type if (ctx.apiVersion == 1) return Error{Status{ClioError::rpcUNKNOWN_OPTION}}; @@ -90,7 +75,8 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input input, Context const& ctx) // check ledger exists auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -111,12 +97,9 @@ LedgerEntryHandler::process(LedgerEntryHandler::Input input, Context const& ctx) output.ledgerIndex = lgrInfo.seq; output.ledgerHash = ripple::strHex(lgrInfo.hash); - if (input.binary) - { + if (input.binary) { output.nodeBinary = ripple::strHex(*ledgerObject); - } - else - { + } else { output.node = toJson(sle); } @@ -137,8 +120,7 @@ LedgerEntryHandler::composeKeyFromDirectory(boost::json::object const& directory uint64_t const subIndex = directory.contains(JS(sub_index)) ? boost::json::value_to(directory.at(JS(sub_index))) : 0; - if (directory.contains(JS(dir_root))) - { + if (directory.contains(JS(dir_root))) { ripple::uint256 const uDirRoot{directory.at(JS(dir_root)).as_string().c_str()}; return ripple::keylet::page(uDirRoot, subIndex).key; } @@ -157,12 +139,9 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, LedgerEntryHandl {JS(index), output.index}, }; - if (output.nodeBinary) - { + if (output.nodeBinary) { object[JS(node_binary)] = *(output.nodeBinary); - } - else - { + } else { object[JS(node)] = *(output.node); } @@ -178,14 +157,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::va if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } @@ -212,39 +187,26 @@ tag_invoke(boost::json::value_to_tag, boost::json::va return jsonObject.contains(field) && jsonObject.at(field).is_string(); }); - if (indexFieldType != indexFieldTypeMap.end()) - { + if (indexFieldType != indexFieldTypeMap.end()) { input.index = jv.at(indexFieldType->first).as_string().c_str(); input.expectedType = indexFieldType->second; } // check if request for account root - else if (jsonObject.contains(JS(account_root))) - { + else if (jsonObject.contains(JS(account_root))) { input.accountRoot = jv.at(JS(account_root)).as_string().c_str(); } // no need to check if_object again, validator only allows string or object - else if (jsonObject.contains(JS(directory))) - { + else if (jsonObject.contains(JS(directory))) { input.directory = jv.at(JS(directory)).as_object(); - } - else if (jsonObject.contains(JS(offer))) - { + } else if (jsonObject.contains(JS(offer))) { input.offer = jv.at(JS(offer)).as_object(); - } - else if (jsonObject.contains(JS(ripple_state))) - { + } else if (jsonObject.contains(JS(ripple_state))) { input.rippleStateAccount = jv.at(JS(ripple_state)).as_object(); - } - else if (jsonObject.contains(JS(escrow))) - { + } else if (jsonObject.contains(JS(escrow))) { input.escrow = jv.at(JS(escrow)).as_object(); - } - else if (jsonObject.contains(JS(deposit_preauth))) - { + } else if (jsonObject.contains(JS(deposit_preauth))) { input.depositPreauth = jv.at(JS(deposit_preauth)).as_object(); - } - else if (jsonObject.contains(JS(ticket))) - { + } else if (jsonObject.contains(JS(ticket))) { input.ticket = jv.at(JS(ticket)).as_object(); } diff --git a/src/rpc/handlers/LedgerEntry.h b/src/rpc/handlers/LedgerEntry.h index e230f5d7..c7e0a1de 100644 --- a/src/rpc/handlers/LedgerEntry.h +++ b/src/rpc/handlers/LedgerEntry.h @@ -32,13 +32,11 @@ namespace rpc { * * For more details see: https://xrpl.org/ledger_entry.html */ -class LedgerEntryHandler -{ +class LedgerEntryHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { std::string index; uint32_t ledgerIndex; std::string ledgerHash; @@ -47,8 +45,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::optional ledgerHash; std::optional ledgerIndex; bool binary = false; @@ -84,8 +81,7 @@ public: validation::CustomValidator{[](boost::json::value const& value, std::string_view /* key */) -> MaybeError { if (!value.is_array() || value.as_array().size() != 2 || !value.as_array()[0].is_string() || !value.as_array()[1].is_string() || - value.as_array()[0].as_string() == value.as_array()[1].as_string()) - { + value.as_array()[0].as_string() == value.as_array()[1].as_string()) { return Error{Status{RippledError::rpcINVALID_PARAMS, "malformedAccounts"}}; } diff --git a/src/rpc/handlers/LedgerRange.h b/src/rpc/handlers/LedgerRange.h index 163fb502..366757a7 100644 --- a/src/rpc/handlers/LedgerRange.h +++ b/src/rpc/handlers/LedgerRange.h @@ -33,13 +33,11 @@ namespace rpc { * * Not documented in the official rippled API docs. */ -class LedgerRangeHandler -{ +class LedgerRangeHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { data::LedgerRange range; }; diff --git a/src/rpc/handlers/NFTBuyOffers.h b/src/rpc/handlers/NFTBuyOffers.h index 7c9eea76..d3f364ed 100644 --- a/src/rpc/handlers/NFTBuyOffers.h +++ b/src/rpc/handlers/NFTBuyOffers.h @@ -29,8 +29,7 @@ namespace rpc { * * For more details see: https://xrpl.org/nft_buy_offers.html */ -class NFTBuyOffersHandler : public NFTOffersHandlerBase -{ +class NFTBuyOffersHandler : public NFTOffersHandlerBase { public: NFTBuyOffersHandler(std::shared_ptr const& sharedPtrBackend) : NFTOffersHandlerBase(sharedPtrBackend) diff --git a/src/rpc/handlers/NFTHistory.cpp b/src/rpc/handlers/NFTHistory.cpp index f45a8509..ff730ec7 100644 --- a/src/rpc/handlers/NFTHistory.cpp +++ b/src/rpc/handlers/NFTHistory.cpp @@ -32,16 +32,14 @@ NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) c auto const range = sharedPtrBackend_->fetchLedgerRange(); auto [minIndex, maxIndex] = *range; - if (input.ledgerIndexMin) - { + if (input.ledgerIndexMin) { if (range->maxSequence < input.ledgerIndexMin || range->minSequence > input.ledgerIndexMin) return Error{Status{RippledError::rpcLGR_IDX_MALFORMED, "ledgerSeqMinOutOfRange"}}; minIndex = *input.ledgerIndexMin; } - if (input.ledgerIndexMax) - { + if (input.ledgerIndexMax) { if (range->maxSequence < input.ledgerIndexMax || range->minSequence > input.ledgerIndexMax) return Error{Status{RippledError::rpcLGR_IDX_MALFORMED, "ledgerSeqMaxOutOfRange"}}; @@ -51,14 +49,14 @@ NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) c if (minIndex > maxIndex) return Error{Status{RippledError::rpcLGR_IDXS_INVALID}}; - if (input.ledgerHash || input.ledgerIndex) - { + if (input.ledgerHash || input.ledgerIndex) { // rippled does not have this check if (input.ledgerIndexMax || input.ledgerIndexMin) return Error{Status{RippledError::rpcINVALID_PARAMS, "containsLedgerSpecifierAndRange"}}; auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -69,18 +67,12 @@ NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) c std::optional cursor; // if marker exists - if (input.marker) - { + if (input.marker) { cursor = {input.marker->ledger, input.marker->seq}; - } - else - { - if (input.forward) - { + } else { + if (input.forward) { cursor = {minIndex, 0}; - } - else - { + } else { cursor = {maxIndex, std::numeric_limits::max()}; } } @@ -88,8 +80,9 @@ NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) c auto const limit = input.limit.value_or(LIMIT_DEFAULT); auto const tokenID = ripple::uint256{input.nftID.c_str()}; - auto const [txnsAndCursor, timeDiff] = util::timed( - [&]() { return sharedPtrBackend_->fetchNFTTransactions(tokenID, limit, input.forward, cursor, ctx.yield); }); + auto const [txnsAndCursor, timeDiff] = util::timed([&]() { + return sharedPtrBackend_->fetchNFTTransactions(tokenID, limit, input.forward, cursor, ctx.yield); + }); LOG(log_.info()) << "db fetch took " << timeDiff << " milliseconds - num blobs = " << txnsAndCursor.txns.size(); Output response; @@ -98,33 +91,27 @@ NFTHistoryHandler::process(NFTHistoryHandler::Input input, Context const& ctx) c if (retCursor) response.marker = {retCursor->ledgerSequence, retCursor->transactionIndex}; - for (auto const& txnPlusMeta : blobs) - { + for (auto const& txnPlusMeta : blobs) { // over the range if ((txnPlusMeta.ledgerSequence < minIndex && !input.forward) || - (txnPlusMeta.ledgerSequence > maxIndex && input.forward)) - { + (txnPlusMeta.ledgerSequence > maxIndex && input.forward)) { response.marker = std::nullopt; break; } - if (txnPlusMeta.ledgerSequence > maxIndex && !input.forward) - { + if (txnPlusMeta.ledgerSequence > maxIndex && !input.forward) { LOG(log_.debug()) << "Skipping over transactions from incomplete ledger"; continue; } boost::json::object obj; - if (!input.binary) - { + if (!input.binary) { auto [txn, meta] = toExpandedJson(txnPlusMeta); obj[JS(meta)] = std::move(meta); obj[JS(tx)] = std::move(txn); obj[JS(tx)].as_object()[JS(ledger_index)] = txnPlusMeta.ledgerSequence; obj[JS(tx)].as_object()[JS(date)] = txnPlusMeta.date; - } - else - { + } else { obj[JS(meta)] = ripple::strHex(txnPlusMeta.metadata); obj[JS(tx_blob)] = ripple::strHex(txnPlusMeta.transaction); obj[JS(ledger_index)] = txnPlusMeta.ledgerSequence; @@ -188,14 +175,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::val if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } @@ -209,8 +192,7 @@ tag_invoke(boost::json::value_to_tag, boost::json::val if (jsonObject.contains(JS(limit))) input.limit = jsonObject.at(JS(limit)).as_int64(); - if (jsonObject.contains(JS(marker))) - { + if (jsonObject.contains(JS(marker))) { input.marker = NFTHistoryHandler::Marker{ jsonObject.at(JS(marker)).as_object().at(JS(ledger)).as_int64(), jsonObject.at(JS(marker)).as_object().at(JS(seq)).as_int64()}; diff --git a/src/rpc/handlers/NFTHistory.h b/src/rpc/handlers/NFTHistory.h index 48ea3a19..cf1ae933 100644 --- a/src/rpc/handlers/NFTHistory.h +++ b/src/rpc/handlers/NFTHistory.h @@ -34,8 +34,7 @@ namespace rpc { * * For more details see: https://xrpl.org/nft_history.html#nft_history */ -class NFTHistoryHandler -{ +class NFTHistoryHandler { util::Logger log_{"RPC"}; std::shared_ptr sharedPtrBackend_; @@ -45,14 +44,12 @@ public: static auto constexpr LIMIT_DEFAULT = 50; // TODO: this marker is same as account_tx, reuse in future - struct Marker - { + struct Marker { uint32_t ledger; uint32_t seq; }; - struct Output - { + struct Output { std::string nftID; uint32_t ledgerIndexMin{0}; uint32_t ledgerIndexMax{0}; @@ -64,8 +61,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string nftID; // You must use at least one of the following fields in your request: // ledger_index, ledger_hash, ledger_index_min, or ledger_index_max. diff --git a/src/rpc/handlers/NFTInfo.cpp b/src/rpc/handlers/NFTInfo.cpp index 3d4b522c..c10890d6 100644 --- a/src/rpc/handlers/NFTInfo.cpp +++ b/src/rpc/handlers/NFTInfo.cpp @@ -34,7 +34,8 @@ NFTInfoHandler::process(NFTInfoHandler::Input input, Context const& ctx) const auto const tokenID = ripple::uint256{input.nftID.c_str()}; auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto const status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -92,14 +93,10 @@ tag_invoke(boost::json::value_to_tag, boost::json::value if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/NFTInfo.h b/src/rpc/handlers/NFTInfo.h index fc9b04f4..1d7c8665 100644 --- a/src/rpc/handlers/NFTInfo.h +++ b/src/rpc/handlers/NFTInfo.h @@ -31,13 +31,11 @@ namespace rpc { * * For more details see: https://xrpl.org/nft_info.html */ -class NFTInfoHandler -{ +class NFTInfoHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { std::string nftID; uint32_t ledgerIndex; std::string owner; @@ -54,8 +52,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string nftID; std::optional ledgerHash; std::optional ledgerIndex; diff --git a/src/rpc/handlers/NFTOffersCommon.cpp b/src/rpc/handlers/NFTOffersCommon.cpp index eb0fb0a6..f7906584 100644 --- a/src/rpc/handlers/NFTOffersCommon.cpp +++ b/src/rpc/handlers/NFTOffersCommon.cpp @@ -58,7 +58,8 @@ NFTOffersHandlerBase::iterateOfferDirectory( Input input, ripple::uint256 const& tokenID, ripple::Keylet const& directory, - boost::asio::yield_context yield) const + boost::asio::yield_context yield +) const { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = @@ -79,8 +80,7 @@ NFTOffersHandlerBase::iterateOfferDirectory( auto cursor = uint256{}; auto startHint = uint64_t{0ul}; - if (input.marker) - { + if (input.marker) { cursor = uint256(input.marker->c_str()); // We have a start point. Use limit - 1 from the result and use the very last one for the resume. @@ -94,37 +94,40 @@ NFTOffersHandlerBase::iterateOfferDirectory( }(); if (!sle || sle->getFieldU16(ripple::sfLedgerEntryType) != ripple::ltNFTOKEN_OFFER || - tokenID != sle->getFieldH256(ripple::sfNFTokenID)) - { + tokenID != sle->getFieldH256(ripple::sfNFTokenID)) { return Error{Status{RippledError::rpcINVALID_PARAMS}}; } startHint = sle->getFieldU64(ripple::sfNFTokenOfferNode); output.offers.push_back(*sle); offers.reserve(reserve); - } - else - { + } else { // We have no start point, limit should be one higher than requested. offers.reserve(++reserve); } auto result = traverseOwnedNodes( - *sharedPtrBackend_, directory, cursor, startHint, lgrInfo.seq, reserve, yield, [&offers](ripple::SLE&& offer) { - if (offer.getType() == ripple::ltNFTOKEN_OFFER) - { + *sharedPtrBackend_, + directory, + cursor, + startHint, + lgrInfo.seq, + reserve, + yield, + [&offers](ripple::SLE&& offer) { + if (offer.getType() == ripple::ltNFTOKEN_OFFER) { offers.push_back(std::move(offer)); return true; } return false; - }); + } + ); if (auto status = std::get_if(&result)) return Error{*status}; - if (offers.size() == reserve) - { + if (offers.size() == reserve) { output.limit = input.limit; output.marker = to_string(offers.back().key()); offers.pop_back(); @@ -166,14 +169,10 @@ tag_invoke(boost::json::value_to_tag, boost::json:: if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/NFTOffersCommon.h b/src/rpc/handlers/NFTOffersCommon.h index cf5032ce..46a054e5 100644 --- a/src/rpc/handlers/NFTOffersCommon.h +++ b/src/rpc/handlers/NFTOffersCommon.h @@ -27,8 +27,7 @@ namespace rpc { -class NFTOffersHandlerBase -{ +class NFTOffersHandlerBase { std::shared_ptr sharedPtrBackend_; public: @@ -36,8 +35,7 @@ public: static auto constexpr LIMIT_MAX = 500; static auto constexpr LIMIT_DEFAULT = 250; - struct Output - { + struct Output { std::string nftID = {}; std::vector offers = {}; @@ -47,8 +45,7 @@ public: std::optional marker = {}; }; - struct Input - { + struct Input { std::string nftID; std::optional ledgerHash; std::optional ledgerIndex; @@ -86,7 +83,8 @@ protected: Input input, ripple::uint256 const& tokenID, ripple::Keylet const& directory, - boost::asio::yield_context yield) const; + boost::asio::yield_context yield + ) const; private: friend void diff --git a/src/rpc/handlers/NFTSellOffers.h b/src/rpc/handlers/NFTSellOffers.h index 0d880f53..c7bfcfc6 100644 --- a/src/rpc/handlers/NFTSellOffers.h +++ b/src/rpc/handlers/NFTSellOffers.h @@ -29,8 +29,7 @@ namespace rpc { * * For more details see: https://xrpl.org/nft_sell_offers.html */ -class NFTSellOffersHandler : public NFTOffersHandlerBase -{ +class NFTSellOffersHandler : public NFTOffersHandlerBase { public: NFTSellOffersHandler(std::shared_ptr const& sharedPtrBackend) : NFTOffersHandlerBase(sharedPtrBackend) diff --git a/src/rpc/handlers/NoRippleCheck.cpp b/src/rpc/handlers/NoRippleCheck.cpp index 634a4894..ab94a22a 100644 --- a/src/rpc/handlers/NoRippleCheck.cpp +++ b/src/rpc/handlers/NoRippleCheck.cpp @@ -29,7 +29,8 @@ NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -62,20 +63,15 @@ NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& return tx; }; - if (bDefaultRipple && !input.roleGateway) - { + if (bDefaultRipple && !input.roleGateway) { output.problems.emplace_back( - "You appear to have set your default ripple flag even though " - "you " - "are not a gateway. This is not recommended unless you are " - "experimenting"); - } - else if (input.roleGateway && !bDefaultRipple) - { + "You appear to have set your default ripple flag even though you are not a gateway. This is not " + "recommended unless you are experimenting" + ); + } else if (input.roleGateway && !bDefaultRipple) { output.problems.emplace_back("You should immediately set your default ripple flag"); - if (input.transactions) - { + if (input.transactions) { auto tx = getBaseTx(*accountID, accountSeq++); tx[JS(TransactionType)] = "AccountSet"; tx[JS(SetFlag)] = ripple::asfDefaultRipple; @@ -94,8 +90,7 @@ NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& ctx.yield, [&](ripple::SLE&& ownedItem) { // don't push to result if limit is reached - if (limit != 0 && ownedItem.getType() == ripple::ltRIPPLE_STATE) - { + if (limit != 0 && ownedItem.getType() == ripple::ltRIPPLE_STATE) { bool const bLow = accountID == ownedItem.getFieldAmount(ripple::sfLowLimit).getIssuer(); bool const bNoRipple = (ownedItem.getFieldU32(ripple::sfFlags) & @@ -103,20 +98,14 @@ NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& std::string problem; bool needFix = false; - if (bNoRipple && input.roleGateway) - { + if (bNoRipple && input.roleGateway) { problem = "You should clear the no ripple flag on your "; needFix = true; - } - else if (!bNoRipple && !input.roleGateway) - { - problem = - "You should probably set the no ripple flag on " - "your "; + } else if (!bNoRipple && !input.roleGateway) { + problem = "You should probably set the no ripple flag on your "; needFix = true; } - if (needFix) - { + if (needFix) { --limit; ripple::AccountID const peer = @@ -125,13 +114,14 @@ NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& ownedItem.getFieldAmount(bLow ? ripple::sfHighLimit : ripple::sfLowLimit); problem += fmt::format( - "{} line to {}", to_string(peerLimit.getCurrency()), to_string(peerLimit.getIssuer())); + "{} line to {}", to_string(peerLimit.getCurrency()), to_string(peerLimit.getIssuer()) + ); output.problems.emplace_back(problem); - if (input.transactions) - { + if (input.transactions) { ripple::STAmount limitAmount( - ownedItem.getFieldAmount(bLow ? ripple::sfLowLimit : ripple::sfHighLimit)); + ownedItem.getFieldAmount(bLow ? ripple::sfLowLimit : ripple::sfHighLimit) + ); limitAmount.setIssuer(peer); auto tx = getBaseTx(*accountID, accountSeq++); @@ -146,7 +136,8 @@ NoRippleCheckHandler::process(NoRippleCheckHandler::Input input, Context const& } return true; - }); + } + ); output.ledgerIndex = lgrInfo.seq; output.ledgerHash = ripple::strHex(lgrInfo.hash); @@ -172,14 +163,10 @@ tag_invoke(boost::json::value_to_tag, boost::json:: if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jsonObject.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jsonObject.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jsonObject.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/NoRippleCheck.h b/src/rpc/handlers/NoRippleCheck.h index 560c9e90..8c626d31 100644 --- a/src/rpc/handlers/NoRippleCheck.h +++ b/src/rpc/handlers/NoRippleCheck.h @@ -37,8 +37,7 @@ namespace rpc { * * For more details see: https://xrpl.org/noripple_check.html */ -class NoRippleCheckHandler -{ +class NoRippleCheckHandler { std::shared_ptr sharedPtrBackend_; public: @@ -46,8 +45,7 @@ public: static auto constexpr LIMIT_MAX = 500; static auto constexpr LIMIT_DEFAULT = 300; - struct Output - { + struct Output { std::string ledgerHash; uint32_t ledgerIndex{}; std::vector problems; @@ -56,8 +54,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string account; bool roleGateway = false; std::optional ledgerHash; diff --git a/src/rpc/handlers/Ping.h b/src/rpc/handlers/Ping.h index 7932c287..f93e5817 100644 --- a/src/rpc/handlers/Ping.h +++ b/src/rpc/handlers/Ping.h @@ -28,8 +28,7 @@ namespace rpc { * * For more details see https://xrpl.org/ping.html */ -class PingHandler -{ +class PingHandler { public: using Output = VoidOutput; using Result = HandlerReturnType; diff --git a/src/rpc/handlers/Random.h b/src/rpc/handlers/Random.h index b08bd6f0..2ca97a51 100644 --- a/src/rpc/handlers/Random.h +++ b/src/rpc/handlers/Random.h @@ -33,11 +33,9 @@ namespace rpc { * * For more details see: https://xrpl.org/random.html */ -class RandomHandler -{ +class RandomHandler { public: - struct Output - { + struct Output { std::string random; }; diff --git a/src/rpc/handlers/ServerInfo.h b/src/rpc/handlers/ServerInfo.h index c06eb4b9..72adcc7e 100644 --- a/src/rpc/handlers/ServerInfo.h +++ b/src/rpc/handlers/ServerInfo.h @@ -47,8 +47,7 @@ class Counters; namespace rpc { template -class BaseServerInfoHandler -{ +class BaseServerInfoHandler { static constexpr auto BACKEND_COUNTERS_KEY = "backend_counters"; std::shared_ptr backend_; @@ -58,29 +57,25 @@ class BaseServerInfoHandler std::reference_wrapper counters_; public: - struct Input - { + struct Input { bool backendCounters = false; }; - struct AdminSection - { + struct AdminSection { boost::json::object counters = {}; std::optional backendCounters = {}; boost::json::object subscriptions = {}; boost::json::object etl = {}; }; - struct ValidatedLedgerSection - { + struct ValidatedLedgerSection { uint32_t age = 0; std::string hash = {}; ripple::LedgerIndex seq = {}; std::optional fees = std::nullopt; }; - struct CacheSection - { + struct CacheSection { std::size_t size = 0; bool isFull = false; ripple::LedgerIndex latestLedgerSeq = {}; @@ -88,8 +83,7 @@ public: float successorHitRate = 1.0; }; - struct InfoSection - { + struct InfoSection { std::optional adminSection = std::nullopt; std::string completeLedgers = {}; uint32_t loadFactor = 1u; @@ -103,8 +97,7 @@ public: bool isAmendmentBlocked = false; }; - struct Output - { + struct Output { InfoSection info = {}; // validated should be sent via framework @@ -118,7 +111,8 @@ public: std::shared_ptr const& subscriptions, std::shared_ptr const& balancer, std::shared_ptr const& etl, - CountersType const& counters) + CountersType const& counters + ) : backend_(backend) , subscriptions_(subscriptions) , balancer_(balancer) @@ -157,8 +151,7 @@ public: output.info.completeLedgers = fmt::format("{}-{}", range->minSequence, range->maxSequence); - if (ctx.isAdmin) - { + if (ctx.isAdmin) { output.info.adminSection = { .counters = counters_.get().report(), .backendCounters = input.backendCounters ? std::make_optional(backend_->stats()) : std::nullopt, @@ -169,11 +162,9 @@ public: auto const serverInfoRippled = balancer_->forwardToRippled({{"command", "server_info"}}, ctx.clientIp, ctx.yield); - if (serverInfoRippled && !serverInfoRippled->contains(JS(error))) - { + if (serverInfoRippled && !serverInfoRippled->contains(JS(error))) { if (serverInfoRippled->contains(JS(result)) && - serverInfoRippled->at(JS(result)).as_object().contains(JS(info))) - { + serverInfoRippled->at(JS(result)).as_object().contains(JS(info))) { output.info.rippledInfo = serverInfoRippled->at(JS(result)).as_object().at(JS(info)).as_object(); } } @@ -225,8 +216,7 @@ private: if (info.isAmendmentBlocked) jv.as_object()[JS(amendment_blocked)] = true; - if (info.rippledInfo) - { + if (info.rippledInfo) { auto const& rippledInfo = info.rippledInfo.value(); if (rippledInfo.contains(JS(load_factor))) @@ -239,13 +229,11 @@ private: jv.as_object()[JS(network_id)] = rippledInfo.at(JS(network_id)); } - if (info.adminSection) - { + if (info.adminSection) { jv.as_object()["etl"] = info.adminSection->etl; jv.as_object()[JS(counters)] = info.adminSection->counters; jv.as_object()[JS(counters)].as_object()["subscriptions"] = info.adminSection->subscriptions; - if (info.adminSection->backendCounters.has_value()) - { + if (info.adminSection->backendCounters.has_value()) { jv.as_object()[BACKEND_COUNTERS_KEY] = *info.adminSection->backendCounters; } } diff --git a/src/rpc/handlers/Subscribe.h b/src/rpc/handlers/Subscribe.h index 50a7958c..d0aca1eb 100644 --- a/src/rpc/handlers/Subscribe.h +++ b/src/rpc/handlers/Subscribe.h @@ -31,14 +31,12 @@ class SubscriptionManager; namespace rpc { template -class BaseSubscribeHandler -{ +class BaseSubscribeHandler { std::shared_ptr sharedPtrBackend_; std::shared_ptr subscriptions_; public: - struct Output - { + struct Output { // response of stream "ledger" // TODO: use better type than json, this type will be used in the stream as well std::optional ledger; @@ -51,16 +49,14 @@ public: std::optional bids; }; - struct OrderBook - { + struct OrderBook { ripple::Book book; std::optional taker; bool snapshot = false; bool both = false; }; - struct Input - { + struct Input { std::optional> accounts; std::optional> streams; std::optional> accountsProposed; @@ -71,7 +67,8 @@ public: BaseSubscribeHandler( std::shared_ptr const& sharedPtrBackend, - std::shared_ptr const& subscriptions) + std::shared_ptr const& subscriptions + ) : sharedPtrBackend_(sharedPtrBackend), subscriptions_(subscriptions) { } @@ -84,8 +81,7 @@ public: if (!value.is_array()) return Error{Status{RippledError::rpcINVALID_PARAMS, std::string(key) + "NotArray"}}; - for (auto const& book : value.as_array()) - { + for (auto const& book : value.as_array()) { if (!book.is_object()) return Error{Status{RippledError::rpcINVALID_PARAMS, std::string(key) + "ItemNotObject"}}; @@ -95,11 +91,11 @@ public: if (book.as_object().contains("snapshot") && !book.as_object().at("snapshot").is_bool()) return Error{Status{RippledError::rpcINVALID_PARAMS, "snapshotNotBool"}}; - if (book.as_object().contains("taker")) - { + if (book.as_object().contains("taker")) { if (auto err = meta::WithCustomError( validation::AccountValidator, - Status{RippledError::rpcBAD_ISSUER, "Issuer account malformed."}) + Status{RippledError::rpcBAD_ISSUER, "Issuer account malformed."} + ) .verify(book.as_object(), "taker"); !err) return err; @@ -128,8 +124,7 @@ public: { auto output = Output{}; - if (input.streams) - { + if (input.streams) { auto const ledger = subscribeToStreams(ctx.yield, *(input.streams), ctx.session); if (!ledger.empty()) output.ledger = ledger; @@ -141,8 +136,7 @@ public: if (input.accountsProposed) subscribeToAccountsProposed(*(input.accountsProposed), ctx.session); - if (input.books) - { + if (input.books) { subscribeToBooks(*(input.books), ctx.session, ctx.yield, output); }; @@ -154,34 +148,23 @@ private: subscribeToStreams( boost::asio::yield_context yield, std::vector const& streams, - std::shared_ptr const& session) const + std::shared_ptr const& session + ) const { auto response = boost::json::object{}; - for (auto const& stream : streams) - { - if (stream == "ledger") - { + for (auto const& stream : streams) { + if (stream == "ledger") { response = subscriptions_->subLedger(yield, session); - } - else if (stream == "transactions") - { + } else if (stream == "transactions") { subscriptions_->subTransactions(session); - } - else if (stream == "transactions_proposed") - { + } else if (stream == "transactions_proposed") { subscriptions_->subProposedTransactions(session); - } - else if (stream == "validations") - { + } else if (stream == "validations") { subscriptions_->subValidation(session); - } - else if (stream == "manifests") - { + } else if (stream == "manifests") { subscriptions_->subManifest(session); - } - else if (stream == "book_changes") - { + } else if (stream == "book_changes") { subscriptions_->subBookChanges(session); } } @@ -193,8 +176,7 @@ private: subscribeToAccounts(std::vector const& accounts, std::shared_ptr const& session) const { - for (auto const& account : accounts) - { + for (auto const& account : accounts) { auto const accountID = accountFromStringStrict(account); subscriptions_->subAccount(*accountID, session); } @@ -203,10 +185,10 @@ private: void subscribeToAccountsProposed( std::vector const& accounts, - std::shared_ptr const& session) const + std::shared_ptr const& session + ) const { - for (auto const& account : accounts) - { + for (auto const& account : accounts) { auto const accountID = accountFromStringStrict(account); subscriptions_->subProposedAccount(*accountID, session); } @@ -217,16 +199,15 @@ private: std::vector const& books, std::shared_ptr const& session, boost::asio::yield_context yield, - Output& output) const + Output& output + ) const { static auto constexpr fetchLimit = 200; std::optional rng; - for (auto const& internalBook : books) - { - if (internalBook.snapshot) - { + for (auto const& internalBook : books) { + if (internalBook.snapshot) { if (!rng) rng = sharedPtrBackend_->fetchLedgerRange(); @@ -245,17 +226,14 @@ private: std::copy(orderBook.begin(), orderBook.end(), std::back_inserter(snapshots)); }; - if (internalBook.both) - { + if (internalBook.both) { if (!output.bids) output.bids = boost::json::array(); if (!output.asks) output.asks = boost::json::array(); getOrderBook(internalBook.book, *(output.bids)); getOrderBook(ripple::reversed(internalBook.book), *(output.asks)); - } - else - { + } else { if (!output.offers) output.offers = boost::json::array(); getOrderBook(internalBook.book, *(output.offers)); @@ -288,32 +266,28 @@ private: auto input = Input{}; auto const& jsonObject = jv.as_object(); - if (auto const& streams = jsonObject.find(JS(streams)); streams != jsonObject.end()) - { + if (auto const& streams = jsonObject.find(JS(streams)); streams != jsonObject.end()) { input.streams = std::vector(); for (auto const& stream : streams->value().as_array()) input.streams->push_back(stream.as_string().c_str()); } - if (auto const& accounts = jsonObject.find(JS(accounts)); accounts != jsonObject.end()) - { + if (auto const& accounts = jsonObject.find(JS(accounts)); accounts != jsonObject.end()) { input.accounts = std::vector(); for (auto const& account : accounts->value().as_array()) input.accounts->push_back(account.as_string().c_str()); } - if (auto const& accountsProposed = jsonObject.find(JS(accounts_proposed)); accountsProposed != jsonObject.end()) - { + if (auto const& accountsProposed = jsonObject.find(JS(accounts_proposed)); + accountsProposed != jsonObject.end()) { input.accountsProposed = std::vector(); for (auto const& account : accountsProposed->value().as_array()) input.accountsProposed->push_back(account.as_string().c_str()); } - if (auto const& books = jsonObject.find(JS(books)); books != jsonObject.end()) - { + if (auto const& books = jsonObject.find(JS(books)); books != jsonObject.end()) { input.books = std::vector(); - for (auto const& book : books->value().as_array()) - { + for (auto const& book : books->value().as_array()) { auto internalBook = OrderBook{}; auto const& bookObject = book.as_object(); diff --git a/src/rpc/handlers/TransactionEntry.cpp b/src/rpc/handlers/TransactionEntry.cpp index 7c606f0a..8ae0a0af 100644 --- a/src/rpc/handlers/TransactionEntry.cpp +++ b/src/rpc/handlers/TransactionEntry.cpp @@ -26,7 +26,8 @@ TransactionEntryHandler::process(TransactionEntryHandler::Input input, Context c { auto const range = sharedPtrBackend_->fetchLedgerRange(); auto const lgrInfoOrStatus = getLedgerInfoFromHashOrSeq( - *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence); + *sharedPtrBackend_, ctx.yield, input.ledgerHash, input.ledgerIndex, range->maxSequence + ); if (auto status = std::get_if(&lgrInfoOrStatus)) return Error{*status}; @@ -79,14 +80,10 @@ tag_invoke(boost::json::value_to_tag, boost::jso if (jsonObject.contains(JS(ledger_hash))) input.ledgerHash = jv.at(JS(ledger_hash)).as_string().c_str(); - if (jsonObject.contains(JS(ledger_index))) - { - if (!jsonObject.at(JS(ledger_index)).is_string()) - { + if (jsonObject.contains(JS(ledger_index))) { + if (!jsonObject.at(JS(ledger_index)).is_string()) { input.ledgerIndex = jv.at(JS(ledger_index)).as_int64(); - } - else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") - { + } else if (jsonObject.at(JS(ledger_index)).as_string() != "validated") { input.ledgerIndex = std::stoi(jv.at(JS(ledger_index)).as_string().c_str()); } } diff --git a/src/rpc/handlers/TransactionEntry.h b/src/rpc/handlers/TransactionEntry.h index 9aae11a7..0b3a8ede 100644 --- a/src/rpc/handlers/TransactionEntry.h +++ b/src/rpc/handlers/TransactionEntry.h @@ -32,13 +32,11 @@ namespace rpc { * * For more details see: https://xrpl.org/transaction_entry.html */ -class TransactionEntryHandler -{ +class TransactionEntryHandler { std::shared_ptr sharedPtrBackend_; public: - struct Output - { + struct Output { uint32_t ledgerIndex; std::string ledgerHash; // TODO: use a better type for this @@ -48,8 +46,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::string txHash; std::optional ledgerHash; std::optional ledgerIndex; diff --git a/src/rpc/handlers/Tx.h b/src/rpc/handlers/Tx.h index 9cf8c58a..8e3279f5 100644 --- a/src/rpc/handlers/Tx.h +++ b/src/rpc/handlers/Tx.h @@ -28,14 +28,12 @@ namespace rpc { template -class BaseTxHandler -{ +class BaseTxHandler { std::shared_ptr sharedPtrBackend_; std::shared_ptr etl_; public: - struct Output - { + struct Output { uint32_t date = 0u; std::string hash{}; uint32_t ledgerIndex = 0u; @@ -48,8 +46,7 @@ public: bool validated = true; }; - struct Input - { + struct Input { std::optional transaction; std::optional ctid; bool binary = false; @@ -61,7 +58,8 @@ public: BaseTxHandler( std::shared_ptr const& sharedPtrBackend, - std::shared_ptr const& etl) + std::shared_ptr const& etl + ) : sharedPtrBackend_(sharedPtrBackend), etl_(etl) { } @@ -92,8 +90,7 @@ public: static auto constexpr maxLedgerRange = 1000u; auto const rangeSupplied = input.minLedger && input.maxLedger; - if (rangeSupplied) - { + if (rangeSupplied) { if (*input.minLedger > *input.maxLedger) return Error{Status{RippledError::rpcINVALID_LGR_RANGE}}; @@ -105,33 +102,29 @@ public: std::optional dbResponse; - if (input.ctid) - { + if (input.ctid) { auto const ctid = rpc::decodeCTID(*input.ctid); if (!ctid) return Error{Status{RippledError::rpcINVALID_PARAMS}}; auto const [lgrSeq, txnIdx, netId] = *ctid; // when current network id is available, let us check the network id from parameter - if (currentNetId && netId != *currentNetId) - { + if (currentNetId && netId != *currentNetId) { return Error{Status{ RippledError::rpcWRONG_NETWORK, fmt::format( - "Wrong network. You should submit this request to a node running on NetworkID: {}", netId)}}; + "Wrong network. You should submit this request to a node running on NetworkID: {}", netId + )}}; } dbResponse = fetchTxViaCtid(lgrSeq, txnIdx, ctx.yield); - } - else - { + } else { dbResponse = sharedPtrBackend_->fetchTransaction(ripple::uint256{input.transaction->c_str()}, ctx.yield); } auto output = BaseTxHandler::Output{.apiVersion = ctx.apiVersion}; - if (!dbResponse) - { + if (!dbResponse) { if (rangeSupplied && input.transaction) // ranges not for ctid { auto const range = sharedPtrBackend_->fetchLedgerRange(); @@ -148,13 +141,10 @@ public: auto const [txn, meta] = toExpandedJson(*dbResponse, NFTokenjson::ENABLE, currentNetId); - if (!input.binary) - { + if (!input.binary) { output.tx = txn; output.meta = meta; - } - else - { + } else { output.txStr = ripple::strHex(dbResponse->transaction); output.metaStr = ripple::strHex(dbResponse->metadata); @@ -163,13 +153,14 @@ public: output.hash = txn.at(JS(hash)).as_string(); // append ctid here to mimic rippled 1.12 behavior: return ctid even binary=true - // rippled will change it in the future, ctid should be part of tx json which not available in binary mode + // rippled will change it in the future, ctid should be part of tx json which not available in binary + // mode auto const txnIdx = boost::json::value_to(meta.at("TransactionIndex")); if (txnIdx <= 0xFFFFU && dbResponse->ledgerSequence < 0x0FFF'FFFFUL && currentNetId && - *currentNetId <= 0xFFFFU) - { + *currentNetId <= 0xFFFFU) { output.ctid = rpc::encodeCTID( - dbResponse->ledgerSequence, static_cast(txnIdx), static_cast(*currentNetId)); + dbResponse->ledgerSequence, static_cast(txnIdx), static_cast(*currentNetId) + ); } } @@ -185,8 +176,7 @@ private: { auto const txs = sharedPtrBackend_->fetchAllTransactionsInLedger(ledgerSeq, yield); - for (auto const& tx : txs) - { + for (auto const& tx : txs) { auto const [txn, meta] = deserializeTxPlusMeta(tx, ledgerSeq); if (meta->getIndex() == txId) @@ -201,13 +191,10 @@ private: { auto obj = boost::json::object{}; - if (output.tx) - { + if (output.tx) { obj = *output.tx; obj[JS(meta)] = *output.meta; - } - else - { + } else { obj[JS(meta)] = *output.metaStr; obj[JS(tx)] = *output.txStr; obj[JS(hash)] = output.hash; diff --git a/src/rpc/handlers/Unsubscribe.h b/src/rpc/handlers/Unsubscribe.h index 4ac0adca..3d6c27b9 100644 --- a/src/rpc/handlers/Unsubscribe.h +++ b/src/rpc/handlers/Unsubscribe.h @@ -31,20 +31,17 @@ class SubscriptionManager; namespace rpc { template -class BaseUnsubscribeHandler -{ +class BaseUnsubscribeHandler { std::shared_ptr sharedPtrBackend_; std::shared_ptr subscriptions_; public: - struct OrderBook - { + struct OrderBook { ripple::Book book; bool both = false; }; - struct Input - { + struct Input { std::optional> accounts; std::optional> streams; std::optional> accountsProposed; @@ -56,7 +53,8 @@ public: BaseUnsubscribeHandler( std::shared_ptr const& sharedPtrBackend, - std::shared_ptr const& subscriptions) + std::shared_ptr const& subscriptions + ) : sharedPtrBackend_(sharedPtrBackend), subscriptions_(subscriptions) { } @@ -69,8 +67,7 @@ public: if (!value.is_array()) return Error{Status{RippledError::rpcINVALID_PARAMS, std::string(key) + "NotArray"}}; - for (auto const& book : value.as_array()) - { + for (auto const& book : value.as_array()) { if (!book.is_object()) return Error{Status{RippledError::rpcINVALID_PARAMS, std::string(key) + "ItemNotObject"}}; @@ -118,34 +115,20 @@ private: unsubscribeFromStreams(std::vector const& streams, std::shared_ptr const& session) const { - for (auto const& stream : streams) - { - if (stream == "ledger") - { + for (auto const& stream : streams) { + if (stream == "ledger") { subscriptions_->unsubLedger(session); - } - else if (stream == "transactions") - { + } else if (stream == "transactions") { subscriptions_->unsubTransactions(session); - } - else if (stream == "transactions_proposed") - { + } else if (stream == "transactions_proposed") { subscriptions_->unsubProposedTransactions(session); - } - else if (stream == "validations") - { + } else if (stream == "validations") { subscriptions_->unsubValidation(session); - } - else if (stream == "manifests") - { + } else if (stream == "manifests") { subscriptions_->unsubManifest(session); - } - else if (stream == "book_changes") - { + } else if (stream == "book_changes") { subscriptions_->unsubBookChanges(session); - } - else - { + } else { assert(false); } } @@ -155,8 +138,7 @@ private: unsubscribeFromAccounts(std::vector accounts, std::shared_ptr const& session) const { - for (auto const& account : accounts) - { + for (auto const& account : accounts) { auto const accountID = accountFromStringStrict(account); subscriptions_->unsubAccount(*accountID, session); } @@ -165,10 +147,10 @@ private: void unsubscribeFromProposedAccounts( std::vector accountsProposed, - std::shared_ptr const& session) const + std::shared_ptr const& session + ) const { - for (auto const& account : accountsProposed) - { + for (auto const& account : accountsProposed) { auto const accountID = accountFromStringStrict(account); subscriptions_->unsubProposedAccount(*accountID, session); } @@ -177,8 +159,7 @@ private: void unsubscribeFromBooks(std::vector const& books, std::shared_ptr const& session) const { - for (auto const& orderBook : books) - { + for (auto const& orderBook : books) { subscriptions_->unsubBook(orderBook.book, session); if (orderBook.both) @@ -192,29 +173,25 @@ private: auto input = Input{}; auto const& jsonObject = jv.as_object(); - if (auto const& streams = jsonObject.find(JS(streams)); streams != jsonObject.end()) - { + if (auto const& streams = jsonObject.find(JS(streams)); streams != jsonObject.end()) { input.streams = std::vector(); for (auto const& stream : streams->value().as_array()) input.streams->push_back(stream.as_string().c_str()); } - if (auto const& accounts = jsonObject.find(JS(accounts)); accounts != jsonObject.end()) - { + if (auto const& accounts = jsonObject.find(JS(accounts)); accounts != jsonObject.end()) { input.accounts = std::vector(); for (auto const& account : accounts->value().as_array()) input.accounts->push_back(account.as_string().c_str()); } - if (auto const& accountsProposed = jsonObject.find(JS(accounts_proposed)); accountsProposed != jsonObject.end()) - { + if (auto const& accountsProposed = jsonObject.find(JS(accounts_proposed)); + accountsProposed != jsonObject.end()) { input.accountsProposed = std::vector(); for (auto const& account : accountsProposed->value().as_array()) input.accountsProposed->push_back(account.as_string().c_str()); } - if (auto const& books = jsonObject.find(JS(books)); books != jsonObject.end()) - { + if (auto const& books = jsonObject.find(JS(books)); books != jsonObject.end()) { input.books = std::vector(); - for (auto const& book : books->value().as_array()) - { + for (auto const& book : books->value().as_array()) { auto internalBook = OrderBook{}; auto const& bookObject = book.as_object(); diff --git a/src/rpc/handlers/VersionHandler.h b/src/rpc/handlers/VersionHandler.h index 53ff86f0..2283c4b2 100644 --- a/src/rpc/handlers/VersionHandler.h +++ b/src/rpc/handlers/VersionHandler.h @@ -31,13 +31,11 @@ namespace rpc { * @brief The version command returns the min,max and current api Version we are using * */ -class VersionHandler -{ +class VersionHandler { rpc::detail::ProductionAPIVersionParser apiVersionParser_; public: - struct Output - { + struct Output { uint32_t minVersion; uint32_t maxVersion; uint32_t currVersion; @@ -47,7 +45,8 @@ public: : apiVersionParser_( config.valueOr("default", API_VERSION_DEFAULT), config.valueOr("min", API_VERSION_MIN), - config.valueOr("max", API_VERSION_MAX)) + config.valueOr("max", API_VERSION_MAX) + ) { } diff --git a/src/util/Expected.h b/src/util/Expected.h index c9d1e517..e680daa6 100644 --- a/src/util/Expected.h +++ b/src/util/Expected.h @@ -47,8 +47,7 @@ namespace util { */ // Exception thrown by an invalid access to Expected. -struct bad_expected_access : public std::runtime_error -{ +struct bad_expected_access : public std::runtime_error { bad_expected_access() : runtime_error("bad expected access") { } @@ -57,8 +56,7 @@ struct bad_expected_access : public std::runtime_error namespace detail { // Custom policy for Expected. Always throw on an invalid access. -struct throw_policy : public boost::outcome_v2::policy::base -{ +struct throw_policy : public boost::outcome_v2::policy::base { template static constexpr void wide_value_check(Impl&& self) @@ -89,8 +87,7 @@ struct throw_policy : public boost::outcome_v2::policy::base // Definition of Unexpected, which is used to construct the unexpected // return type of an Expected. template -class Unexpected -{ +class Unexpected { public: static_assert(!std::is_same::value, "E must not be void"); @@ -104,7 +101,7 @@ public: { } - constexpr const E& + constexpr E const& value() const& { return val_; @@ -122,7 +119,7 @@ public: return std::move(val_); } - constexpr const E&& + constexpr E const&& value() const&& { return std::move(val_); @@ -138,8 +135,7 @@ Unexpected(E (&)[N]) -> Unexpected; // Definition of Expected. All of the machinery comes from boost::result. template -class Expected : private boost::outcome_v2::result -{ +class Expected : private boost::outcome_v2::result { using Base = boost::outcome_v2::result; public: @@ -219,8 +215,7 @@ public: // Specialization of Expected. Allows returning either success // (without a value) or the reason for the failure. template -class [[nodiscard]] Expected : private boost::outcome_v2::result -{ +class [[nodiscard]] Expected : private boost::outcome_v2::result { using Base = boost::outcome_v2::result; public: diff --git a/src/util/JsonUtils.h b/src/util/JsonUtils.h index 40a1cf1c..3941078a 100644 --- a/src/util/JsonUtils.h +++ b/src/util/JsonUtils.h @@ -50,18 +50,15 @@ removeSecret(boost::json::object const& object) auto const secretFields = {"secret", "seed", "seed_hex", "passphrase"}; if (newObject.contains("params") and newObject.at("params").is_array() and - not newObject.at("params").as_array().empty() and newObject.at("params").as_array()[0].is_object()) - { - for (auto const& secretField : secretFields) - { + not newObject.at("params").as_array().empty() and newObject.at("params").as_array()[0].is_object()) { + for (auto const& secretField : secretFields) { if (newObject.at("params").as_array()[0].as_object().contains(secretField)) newObject.at("params").as_array()[0].as_object()[secretField] = "*"; } } // for websocket requests - for (auto const& secretField : secretFields) - { + for (auto const& secretField : secretFields) { if (newObject.contains(secretField)) newObject[secretField] = "*"; } diff --git a/src/util/LedgerUtils.h b/src/util/LedgerUtils.h index 6e7f7549..742c3559 100644 --- a/src/util/LedgerUtils.h +++ b/src/util/LedgerUtils.h @@ -56,7 +56,8 @@ toString(ripple::LedgerHeader const& info) ripple::strHex(info.hash), strHex(info.txHash), ripple::strHex(info.accountHash), - strHex(info.parentHash)); + strHex(info.parentHash) + ); } } // namespace util diff --git a/src/util/Profiler.h b/src/util/Profiler.h index 6b85f7b2..39b4b060 100644 --- a/src/util/Profiler.h +++ b/src/util/Profiler.h @@ -41,13 +41,10 @@ timed(FnType&& func) { auto start = std::chrono::system_clock::now(); - if constexpr (std::is_same_v) - { + if constexpr (std::is_same_v) { func(); return std::chrono::duration_cast(std::chrono::system_clock::now() - start).count(); - } - else - { + } else { auto ret = func(); auto elapsed = std::chrono::duration_cast(std::chrono::system_clock::now() - start).count(); return std::make_pair(std::move(ret), std::move(elapsed)); diff --git a/src/util/Taggable.cpp b/src/util/Taggable.cpp index b3ee543d..8671dcd6 100644 --- a/src/util/Taggable.cpp +++ b/src/util/Taggable.cpp @@ -53,8 +53,7 @@ namespace util { std::unique_ptr TagDecoratorFactory::make() const { - switch (type_) - { + switch (type_) { case Type::UINT: return std::make_unique>(parent_); case Type::UUID: diff --git a/src/util/Taggable.h b/src/util/Taggable.h index 996ec34b..c0a3585a 100644 --- a/src/util/Taggable.h +++ b/src/util/Taggable.h @@ -37,15 +37,12 @@ namespace detail { /** * @brief A `null` tag generator - does nothing. */ -struct NullTagGenerator final -{ -}; +struct NullTagGenerator final {}; /** * @brief This strategy uses an `atomic_uint64_t` to remain lock free. */ -struct UIntTagGenerator final -{ +struct UIntTagGenerator final { using TagType = std::atomic_uint64_t; static TagType @@ -55,8 +52,7 @@ struct UIntTagGenerator final /** * @brief This strategy uses `boost::uuids::uuid` with a static random generator and a mutex. */ -struct UUIDTagGenerator final -{ +struct UUIDTagGenerator final { using TagType = boost::uuids::uuid; static TagType @@ -68,8 +64,7 @@ struct UUIDTagGenerator final /** * @brief Represents any tag decorator. */ -class BaseTagDecorator -{ +class BaseTagDecorator { public: virtual ~BaseTagDecorator() = default; @@ -102,8 +97,7 @@ public: * @tparam Generator The strategy used to generate the tag. */ template -class TagDecorator final : public BaseTagDecorator -{ +class TagDecorator final : public BaseTagDecorator { using ParentType = std::optional>; using TagType = typename Generator::TagType; @@ -148,8 +142,7 @@ public: * This generates a pass-thru decorate member function which can be optimized away by the compiler. */ template <> -class TagDecorator final : public BaseTagDecorator -{ +class TagDecorator final : public BaseTagDecorator { public: /** * @brief Nop implementation for the decorator. @@ -166,8 +159,7 @@ public: /** * @brief A factory for TagDecorator instantiation. */ -class TagDecoratorFactory final -{ +class TagDecoratorFactory final { using ParentType = std::optional>; /** @@ -234,17 +226,14 @@ private: if (boost::iequals(style, "uuid")) return TagDecoratorFactory::Type::UUID; - throw std::runtime_error( - "Could not parse `log_tag_style`: expected `uint`, `uuid` or " - "`null`"); + throw std::runtime_error("Could not parse `log_tag_style`: expected `uint`, `uuid` or `null`"); } }; /** * @brief A base class that allows attaching a tag decorator to a subclass. */ -class Taggable -{ +class Taggable { using DecoratorType = std::unique_ptr; DecoratorType tagDecorator_; diff --git a/src/util/config/Config.cpp b/src/util/config/Config.cpp index 5f0f6cb3..ebddcf9b 100644 --- a/src/util/config/Config.cpp +++ b/src/util/config/Config.cpp @@ -54,21 +54,16 @@ Config::lookup(KeyType key) const std::string subkey{}; auto maybeSection = tokenized.next(); - while (maybeSection.has_value()) - { + while (maybeSection.has_value()) { auto section = maybeSection.value(); subkey += section; - if (not hasBrokenPath) - { + if (not hasBrokenPath) { if (not cur.get().is_object()) throw detail::StoreException("Not an object at '" + subkey + "'"); - if (not cur.get().as_object().contains(section)) - { + if (not cur.get().as_object().contains(section)) { hasBrokenPath = true; - } - else - { + } else { cur = std::cref(cur.get().as_object().at(section)); } } @@ -85,11 +80,9 @@ Config::lookup(KeyType key) const std::optional Config::maybeArray(KeyType key) const { - try - { + try { auto maybe_arr = lookup(key); - if (maybe_arr && maybe_arr->is_array()) - { + if (maybe_arr && maybe_arr->is_array()) { auto& arr = maybe_arr->as_array(); ArrayType out; out.reserve(arr.size()); @@ -99,9 +92,7 @@ Config::maybeArray(KeyType key) const }); return std::make_optional(std::move(out)); } - } - catch (detail::StoreException const&) - { + } catch (detail::StoreException const&) { // ignore store error, but rethrow key errors } @@ -127,12 +118,9 @@ Config::arrayOr(KeyType key, ArrayType fallback) const Config::ArrayType Config::arrayOrThrow(KeyType key, std::string_view err) const { - try - { + try { return maybeArray(key).value(); - } - catch (std::exception const&) - { + } catch (std::exception const&) { throw std::runtime_error(err.data()); } } @@ -165,28 +153,25 @@ Config::array() const auto const& arr = store_.as_array(); out.reserve(arr.size()); - std::transform( - std::cbegin(arr), std::cend(arr), std::back_inserter(out), [](auto const& element) { return Config{element}; }); + std::transform(std::cbegin(arr), std::cend(arr), std::back_inserter(out), [](auto const& element) { + return Config{element}; + }); return out; } Config ConfigReader::open(std::filesystem::path path) { - try - { + try { std::ifstream const in(path, std::ios::in | std::ios::binary); - if (in) - { + if (in) { std::stringstream contents; contents << in.rdbuf(); auto opts = boost::json::parse_options{}; opts.allow_comments = true; return Config{boost::json::parse(contents.str(), {}, opts)}; } - } - catch (std::exception const& e) - { + } catch (std::exception const& e) { LOG(util::LogService::error()) << "Could not read configuration file from '" << path.string() << "': " << e.what(); } diff --git a/src/util/config/Config.h b/src/util/config/Config.h index e89745fe..c1d57641 100644 --- a/src/util/config/Config.h +++ b/src/util/config/Config.h @@ -35,8 +35,7 @@ namespace util { * Any custom data type can be supported by implementing the right `tag_invoke` * for `boost::json::value_to`. */ -class Config final -{ +class Config final { boost::json::value store_; static constexpr char Separator = '.'; @@ -147,12 +146,9 @@ public: [[nodiscard]] Result valueOr(KeyType key, Result fallback) const { - try - { + try { return maybeValue(key).value_or(fallback); - } - catch (detail::StoreException const&) - { + } catch (detail::StoreException const&) { return fallback; } } @@ -177,12 +173,9 @@ public: [[nodiscard]] Result valueOrThrow(KeyType key, std::string_view err) const { - try - { + try { return maybeValue(key).value(); - } - catch (std::exception const&) - { + } catch (std::exception const&) { throw std::runtime_error(err.data()); } } @@ -336,12 +329,9 @@ public: [[nodiscard]] Result valueOrThrow(std::string_view err) const { - try - { + try { return maybeValue().value(); - } - catch (std::exception const&) - { + } catch (std::exception const&) { throw std::runtime_error(err.data()); } } @@ -363,32 +353,25 @@ private: using boost::json::value_to; auto has_error = false; - if constexpr (std::is_same_v) - { + if constexpr (std::is_same_v) { if (not value.is_bool()) has_error = true; - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { if (not value.is_string()) has_error = true; - } - else if constexpr (std::is_same_v) - { + } else if constexpr (std::is_same_v) { if (not value.is_number()) has_error = true; - } - else if constexpr (std::is_convertible_v || std::is_convertible_v) - { + } else if constexpr (std::is_convertible_v || std::is_convertible_v) { if (not value.is_int64() && not value.is_uint64()) has_error = true; } - if (has_error) - { + if (has_error) { throw std::runtime_error( "Type for key '" + key + "' is '" + std::string{to_string(value.kind())} + "' in JSON but requested '" + - detail::typeName() + "'"); + detail::typeName() + "'" + ); } return value_to(value); @@ -407,8 +390,7 @@ private: * Reads the JSON file under specified path and creates a @ref Config object * from its contents. */ -class ConfigReader final -{ +class ConfigReader final { public: static Config open(std::filesystem::path path); diff --git a/src/util/config/detail/Helpers.h b/src/util/config/detail/Helpers.h index 433d5712..3b36e5b4 100644 --- a/src/util/config/detail/Helpers.h +++ b/src/util/config/detail/Helpers.h @@ -29,8 +29,7 @@ namespace util::detail { /** * @brief Thrown when a KeyPath related error occurs */ -struct KeyException : public ::std::logic_error -{ +struct KeyException : public ::std::logic_error { KeyException(::std::string msg) : ::std::logic_error{msg} { } @@ -39,8 +38,7 @@ struct KeyException : public ::std::logic_error /** * @brief Thrown when a Store (config's storage) related error occurs. */ -struct StoreException : public ::std::logic_error -{ +struct StoreException : public ::std::logic_error { StoreException(::std::string msg) : ::std::logic_error{msg} { } @@ -53,8 +51,7 @@ struct StoreException : public ::std::logic_error * @tparam Separator The separator character */ template -class Tokenizer final -{ +class Tokenizer final { using opt_key_t = std::optional; KeyType key_; KeyType token_{}; @@ -66,14 +63,10 @@ public: if (key.empty()) throw KeyException("Empty key"); - for (auto const& c : key) - { - if (c == Separator) - { + for (auto const& c : key) { + if (c == Separator) { saveToken(); - } - else - { + } else { token_ += c; } } @@ -103,63 +96,63 @@ private: }; template -static constexpr const char* +static constexpr char const* typeName() { return typeid(T).name(); } template <> -constexpr const char* +constexpr char const* typeName() { return "uint64_t"; } template <> -constexpr const char* +constexpr char const* typeName() { return "int64_t"; } template <> -constexpr const char* +constexpr char const* typeName() { return "uint32_t"; } template <> -constexpr const char* +constexpr char const* typeName() { return "int32_t"; } template <> -constexpr const char* +constexpr char const* typeName() { return "bool"; } template <> -constexpr const char* +constexpr char const* typeName() { return "std::string"; } template <> -constexpr const char* -typeName() +constexpr char const* +typeName() { return "const char*"; } template <> -constexpr const char* +constexpr char const* typeName() { return "double"; diff --git a/src/util/log/Logger.cpp b/src/util/log/Logger.cpp index 46390fa9..4740300c 100644 --- a/src/util/log/Logger.cpp +++ b/src/util/log/Logger.cpp @@ -32,7 +32,7 @@ Logger LogService::alert_log_ = Logger{"Alert"}; std::ostream& operator<<(std::ostream& stream, Severity sev) { - static constexpr std::array labels = { + static constexpr std::array labels = { "TRC", "DBG", "NFO", @@ -65,8 +65,8 @@ tag_invoke(boost::json::value_to_tag, boost::json::value const& value) return Severity::FTL; throw std::runtime_error( - "Could not parse `log_level`: expected `trace`, `debug`, `info`, " - "`warning`, `error` or `fatal`"); + "Could not parse `log_level`: expected `trace`, `debug`, `info`, `warning`, `error` or `fatal`" + ); } void @@ -77,18 +77,14 @@ LogService::init(util::Config const& config) boost::log::add_common_attributes(); boost::log::register_simple_formatter_factory("Severity"); - auto const defaultFormat = - "%TimeStamp% (%SourceLocation%) [%ThreadID%] %Channel%:%Severity% " - "%Message%"; + auto const defaultFormat = "%TimeStamp% (%SourceLocation%) [%ThreadID%] %Channel%:%Severity% %Message%"; std::string format = config.valueOr("log_format", defaultFormat); - if (config.valueOr("log_to_console", false)) - { + if (config.valueOr("log_to_console", false)) { boost::log::add_console_log(std::cout, keywords::format = format); } - if (auto logDir = config.maybeValue("log_directory"); logDir) - { + if (auto logDir = config.maybeValue("log_directory"); logDir) { boost::filesystem::path dirPath{logDir.value()}; if (!boost::filesystem::exists(dirPath)) boost::filesystem::create_directories(dirPath); @@ -103,15 +99,17 @@ LogService::init(util::Config const& config) keywords::open_mode = std::ios_base::app, keywords::rotation_size = rotationSize, keywords::time_based_rotation = - sinks::file::rotation_at_time_interval(boost::posix_time::hours(rotationPeriod))); + sinks::file::rotation_at_time_interval(boost::posix_time::hours(rotationPeriod)) + ); fileSink->locked_backend()->set_file_collector( - sinks::file::make_collector(keywords::target = dirPath, keywords::max_size = dirSize)); + sinks::file::make_collector(keywords::target = dirPath, keywords::max_size = dirSize) + ); fileSink->locked_backend()->scan_for_files(); } // get default severity, can be overridden per channel using the `log_channels` array auto defaultSeverity = config.valueOr("log_level", Severity::NFO); - static constexpr std::array channels = { + static constexpr std::array channels = { "General", "WebServer", "Backend", @@ -128,8 +126,7 @@ LogService::init(util::Config const& config) min_severity[channel] = defaultSeverity; min_severity["Alert"] = Severity::WRN; // Channel for alerts, always warning severity - for (auto const overrides = config.arrayOr("log_channels", {}); auto const& cfg : overrides) - { + for (auto const overrides = config.arrayOr("log_channels", {}); auto const& cfg : overrides) { auto name = cfg.valueOrThrow("channel", "Channel name is required"); if (std::count(std::begin(channels), std::end(channels), name) == 0) throw std::runtime_error("Can't override settings for log channel " + name + ": invalid channel"); @@ -177,8 +174,7 @@ Logger::Pump::pretty_path(SourceLocationType const& loc, size_t max_depth) { auto const file_path = std::string{loc.file_name()}; auto idx = file_path.size(); - while (max_depth-- > 0) - { + while (max_depth-- > 0) { idx = file_path.rfind('/', idx - 1); if (idx == std::string::npos || idx == 0) break; diff --git a/src/util/log/Logger.h b/src/util/log/Logger.h index 96de5c7a..16863a7a 100644 --- a/src/util/log/Logger.h +++ b/src/util/log/Logger.h @@ -62,8 +62,7 @@ using SourceLocationType = std::experimental::source_location; #else // A workaround for AppleClang that is lacking source_location atm. // TODO: remove this workaround when all compilers catch up to c++20 -class SourceLocation -{ +class SourceLocation { std::string_view file_; std::size_t line_; @@ -94,11 +93,9 @@ using SourceLocationType = SourceLocation; * Note: Currently this introduces potential shadowing (unlikely). */ #ifndef COVERAGE_ENABLED -#define LOG(x) \ - if (auto clio_pump__ = x; not clio_pump__) \ - { \ - } \ - else \ +#define LOG(x) \ + if (auto clio_pump__ = x; not clio_pump__) { \ + } else \ clio_pump__ #else #define LOG(x) x @@ -137,8 +134,7 @@ operator<<(std::ostream& stream, Severity sev); * otherwise. See @ref LogService::init() for setup of the logging core and * severity levels for each channel. */ -class Logger final -{ +class Logger final { using LoggerType = boost::log::sources::severity_channel_logger_mt; mutable LoggerType logger_; @@ -147,8 +143,7 @@ class Logger final /** * @brief Helper that pumps data into a log record via `operator<<`. */ - class Pump final - { + class Pump final { using PumpOptType = std::optional>; boost::log::record rec_; @@ -159,8 +154,7 @@ class Logger final Pump(LoggerType& logger, Severity sev, SourceLocationType const& loc) : rec_{logger.open_record(boost::log::keywords::severity = sev)} { - if (rec_) - { + if (rec_) { pump_.emplace(boost::log::aux::make_record_pump(logger, rec_)); pump_->stream() << boost::log::add_value("SourceLocation", pretty_path(loc)); } @@ -264,8 +258,7 @@ public: * Used to initialize and setup the logging core as well as a globally available * entrypoint for logging into the `General` channel as well as raising alerts. */ -class LogService -{ +class LogService { static Logger general_log_; /*< Global logger for General channel */ static Logger alert_log_; /*< Global logger for Alerts channel */ diff --git a/src/web/Context.h b/src/web/Context.h index 773d4ce8..7ca7791a 100644 --- a/src/web/Context.h +++ b/src/web/Context.h @@ -36,8 +36,7 @@ namespace web { /** * @brief Context that is used by the Webserver to pass around information about an incoming request. */ -struct Context : util::Taggable -{ +struct Context : util::Taggable { boost::asio::yield_context yield; std::string method; std::uint32_t apiVersion; @@ -69,7 +68,8 @@ struct Context : util::Taggable util::TagDecoratorFactory const& tagFactory, data::LedgerRange const& range, std::string clientIp, - bool isAdmin) + bool isAdmin + ) : Taggable(tagFactory) , yield(std::move(yield)) , method(std::move(command)) diff --git a/src/web/DOSGuard.h b/src/web/DOSGuard.h index 220d882d..70e308f6 100644 --- a/src/web/DOSGuard.h +++ b/src/web/DOSGuard.h @@ -37,8 +37,7 @@ namespace web { /** * @brief The interface of a denial of service guard. */ -class BaseDOSGuard -{ +class BaseDOSGuard { public: virtual ~BaseDOSGuard() = default; @@ -56,11 +55,9 @@ public: * @tparam SweepHandlerType The type of the sweep handler */ template -class BasicDOSGuard : public BaseDOSGuard -{ +class BasicDOSGuard : public BaseDOSGuard { // Accumulated state per IP, state will be reset accordingly - struct ClientState - { + struct ClientState { // accumulated transfered byte std::uint32_t transferedByte = 0; // accumulated served requests count @@ -92,7 +89,8 @@ public: BasicDOSGuard( util::Config const& config, WhitelistHandlerType const& whitelistHandler, - SweepHandlerType& sweepHandler) + SweepHandlerType& sweepHandler + ) : whitelistHandler_{std::cref(whitelistHandler)} , maxFetches_{config.valueOr("dos_guard.max_fetches", DEFAULT_MAX_FETCHES)} , maxConnCount_{config.valueOr("dos_guard.max_connections", DEFAULT_MAX_CONNECTIONS)} @@ -129,21 +127,17 @@ public: { std::scoped_lock const lck(mtx_); - if (ipState_.find(ip) != ipState_.end()) - { + if (ipState_.find(ip) != ipState_.end()) { auto [transferedByte, requests] = ipState_.at(ip); - if (transferedByte > maxFetches_ || requests > maxRequestCount_) - { + if (transferedByte > maxFetches_ || requests > maxRequestCount_) { LOG(log_.warn()) << "Dosguard: Client surpassed the rate limit. ip = " << ip << " Transfered Byte: " << transferedByte << "; Requests: " << requests; return false; } } auto it = ipConnCount_.find(ip); - if (it != ipConnCount_.end()) - { - if (it->second > maxConnCount_) - { + if (it != ipConnCount_.end()) { + if (it->second > maxConnCount_) { LOG(log_.warn()) << "Dosguard: Client surpassed the rate limit. ip = " << ip << " Concurrent connection: " << it->second; return false; diff --git a/src/web/HttpSession.h b/src/web/HttpSession.h index 33210a9d..4f5f9eba 100644 --- a/src/web/HttpSession.h +++ b/src/web/HttpSession.h @@ -36,8 +36,7 @@ using tcp = boost::asio::ip::tcp; */ template class HttpSession : public detail::HttpBase, - public std::enable_shared_from_this> -{ + public std::enable_shared_from_this> { boost::beast::tcp_stream stream_; std::reference_wrapper tagFactory_; @@ -60,14 +59,16 @@ public: std::reference_wrapper tagFactory, std::reference_wrapper dosGuard, std::shared_ptr const& handler, - boost::beast::flat_buffer buffer) + boost::beast::flat_buffer buffer + ) : detail::HttpBase( ip, tagFactory, std::move(adminPassword), dosGuard, handler, - std::move(buffer)) + std::move(buffer) + ) , stream_(std::move(socket)) , tagFactory_(tagFactory) { @@ -89,7 +90,9 @@ public: boost::asio::dispatch( stream_.get_executor(), boost::beast::bind_front_handler( - &detail::HttpBase::doRead, this->shared_from_this())); + &detail::HttpBase::doRead, this->shared_from_this() + ) + ); } /** @brief Closes the underlying socket. */ @@ -112,7 +115,8 @@ public: this->handler_, std::move(this->buffer_), std::move(this->req_), - ConnectionBase::isAdmin()) + ConnectionBase::isAdmin() + ) ->run(); } }; diff --git a/src/web/IntervalSweepHandler.cpp b/src/web/IntervalSweepHandler.cpp index 7c615d96..599a65f6 100644 --- a/src/web/IntervalSweepHandler.cpp +++ b/src/web/IntervalSweepHandler.cpp @@ -31,7 +31,9 @@ IntervalSweepHandler::IntervalSweepHandler(util::Config const& config, boost::as : sweepInterval_{std::max( 1u, static_cast( - config.valueOr("dos_guard.sweep_interval", 1.0) * static_cast(util::MILLISECONDS_PER_SECOND)))} + config.valueOr("dos_guard.sweep_interval", 1.0) * static_cast(util::MILLISECONDS_PER_SECOND) + ) + )} , ctx_{std::ref(ctx)} , timer_{ctx.get_executor()} { diff --git a/src/web/IntervalSweepHandler.h b/src/web/IntervalSweepHandler.h index d9a0f215..4ffbc6d0 100644 --- a/src/web/IntervalSweepHandler.h +++ b/src/web/IntervalSweepHandler.h @@ -32,8 +32,7 @@ class BaseDOSGuard; /** * @brief Sweep handler using a steady_timer and boost::asio::io_context. */ -class IntervalSweepHandler -{ +class IntervalSweepHandler { std::chrono::milliseconds sweepInterval_; std::reference_wrapper ctx_; boost::asio::steady_timer timer_; diff --git a/src/web/PlainWsSession.h b/src/web/PlainWsSession.h index 3dc791cd..ba34cd02 100644 --- a/src/web/PlainWsSession.h +++ b/src/web/PlainWsSession.h @@ -31,8 +31,7 @@ namespace web { * Majority of the operations are handled by the base class. */ template -class PlainWsSession : public detail::WsBase -{ +class PlainWsSession : public detail::WsBase { using StreamType = boost::beast::websocket::stream; StreamType ws_; @@ -55,7 +54,8 @@ public: std::reference_wrapper dosGuard, std::shared_ptr const& handler, boost::beast::flat_buffer&& buffer, - bool isAdmin) + bool isAdmin + ) : detail::WsBase(ip, tagFactory, dosGuard, handler, std::move(buffer)) , ws_(std::move(socket)) { @@ -78,8 +78,7 @@ public: * Pass the socket to the session class after upgrade. */ template -class WsUpgrader : public std::enable_shared_from_this> -{ +class WsUpgrader : public std::enable_shared_from_this> { using std::enable_shared_from_this>::shared_from_this; boost::beast::tcp_stream http_; @@ -113,7 +112,8 @@ public: std::shared_ptr const& handler, boost::beast::flat_buffer&& buffer, http::request request, - bool isAdmin) + bool isAdmin + ) : http_(std::move(stream)) , buffer_(std::move(buffer)) , tagFactory_(tagFactory) @@ -131,7 +131,8 @@ public: { boost::asio::dispatch( http_.get_executor(), - boost::beast::bind_front_handler(&WsUpgrader::doUpgrade, shared_from_this())); + boost::beast::bind_front_handler(&WsUpgrader::doUpgrade, shared_from_this()) + ); } private: @@ -157,7 +158,8 @@ private: boost::beast::get_lowest_layer(http_).expires_never(); std::make_shared>( - http_.release_socket(), ip_, tagFactory_, dosGuard_, handler_, std::move(buffer_), isAdmin_) + http_.release_socket(), ip_, tagFactory_, dosGuard_, handler_, std::move(buffer_), isAdmin_ + ) ->run(std::move(req_)); } }; diff --git a/src/web/RPCServerHandler.h b/src/web/RPCServerHandler.h index 13c86b39..18189103 100644 --- a/src/web/RPCServerHandler.h +++ b/src/web/RPCServerHandler.h @@ -37,8 +37,7 @@ namespace web { * Note: see @ref web::SomeServerHandler concept */ template -class RPCServerHandler -{ +class RPCServerHandler { std::shared_ptr const backend_; std::shared_ptr const rpcEngine_; std::shared_ptr const etl_; @@ -65,7 +64,8 @@ public: std::shared_ptr const& backend, std::shared_ptr const& rpcEngine, std::shared_ptr const& etl, - std::shared_ptr const& subscriptions) + std::shared_ptr const& subscriptions + ) : backend_(backend) , rpcEngine_(rpcEngine) , etl_(etl) @@ -84,8 +84,7 @@ public: void operator()(std::string const& request, std::shared_ptr const& connection) { - try - { + try { auto req = boost::json::parse(request).as_object(); LOG(perfLog_.debug()) << connection->tag() << "Adding to work queue"; @@ -96,26 +95,20 @@ public: [this, request = std::move(req), connection](boost::asio::yield_context yield) mutable { handleRequest(yield, std::move(request), connection); }, - connection->clientIp)) - { + connection->clientIp + )) { rpcEngine_->notifyTooBusy(); web::detail::ErrorHelper(connection).sendTooBusyError(); } - } - catch (boost::system::system_error const& ex) - { + } catch (boost::system::system_error const& ex) { // system_error thrown when json parsing failed rpcEngine_->notifyBadSyntax(); web::detail::ErrorHelper(connection).sendJsonParsingError(ex.what()); - } - catch (std::invalid_argument const& ex) - { + } catch (std::invalid_argument const& ex) { // thrown when json parses something that is not an object at top level rpcEngine_->notifyBadSyntax(); web::detail::ErrorHelper(connection).sendJsonParsingError(ex.what()); - } - catch (std::exception const& ex) - { + } catch (std::exception const& ex) { LOG(perfLog_.error()) << connection->tag() << "Caught exception: " << ex.what(); rpcEngine_->notifyInternalError(); throw; @@ -142,25 +135,23 @@ private: handleRequest( boost::asio::yield_context yield, boost::json::object&& request, - std::shared_ptr const& connection) + std::shared_ptr const& connection + ) { LOG(log_.info()) << connection->tag() << (connection->upgraded ? "ws" : "http") << " received request from work queue: " << util::removeSecret(request) << " ip = " << connection->clientIp; - try - { + try { auto const range = backend_->fetchLedgerRange(); - if (!range) - { + if (!range) { // for error that happened before the handler, we don't attach any warnings rpcEngine_->notifyNotReady(); return web::detail::ErrorHelper(connection, request).sendNotReadyError(); } auto const context = [&] { - if (connection->upgraded) - { + if (connection->upgraded) { return rpc::make_WsContext( yield, request, @@ -168,7 +159,8 @@ private: tagFactory_.with(connection->tag()), *range, connection->clientIp, - std::cref(apiVersionParser_)); + std::cref(apiVersionParser_) + ); } return rpc::make_HttpContext( yield, @@ -177,11 +169,11 @@ private: *range, connection->clientIp, std::cref(apiVersionParser_), - connection->isAdmin()); + connection->isAdmin() + ); }(); - if (!context) - { + if (!context) { auto const err = context.error(); LOG(perfLog_.warn()) << connection->tag() << "Could not create Web context: " << err; LOG(log_.warn()) << connection->tag() << "Could not create Web context: " << err; @@ -198,17 +190,14 @@ private: rpc::logDuration(*context, us); boost::json::object response; - if (auto const status = std::get_if(&result)) - { + if (auto const status = std::get_if(&result)) { // note: error statuses are counted/notified in buildResponse itself response = web::detail::ErrorHelper(connection, request).composeError(*status); auto const responseStr = boost::json::serialize(response); LOG(perfLog_.debug()) << context->tag() << "Encountered error: " << responseStr; LOG(log_.debug()) << context->tag() << "Encountered error: " << responseStr; - } - else - { + } else { // This can still technically be an error. Clio counts forwarded requests as successful. rpcEngine_->notifyComplete(context->method, us); @@ -217,21 +206,18 @@ private: json.contains("forwarded") && json.at("forwarded").is_bool() && json.at("forwarded").as_bool(); // if the result is forwarded - just use it as is - // if forwarded request has error, for http, error should be in "result"; for ws, error should be at top - if (isForwarded && (json.contains("result") || connection->upgraded)) - { + // if forwarded request has error, for http, error should be in "result"; for ws, error should + // be at top + if (isForwarded && (json.contains("result") || connection->upgraded)) { for (auto const& [k, v] : json) response.insert_or_assign(k, v); - } - else - { + } else { response["result"] = json; } // for ws there is an additional field "status" in the response, // otherwise the "status" is in the "result" field - if (connection->upgraded) - { + if (connection->upgraded) { auto const id = request.contains("id") ? request.at("id") : nullptr; if (not id.is_null()) @@ -241,9 +227,7 @@ private: response["status"] = "success"; response["type"] = "response"; - } - else - { + } else { if (response.contains("result") && !response["result"].as_object().contains("error")) response["result"].as_object()["status"] = "success"; } @@ -257,9 +241,7 @@ private: response["warnings"] = warnings; connection->send(boost::json::serialize(response)); - } - catch (std::exception const& ex) - { + } catch (std::exception const& ex) { // note: while we are catching this in buildResponse too, this is here to make sure // that any other code that may throw is outside of buildResponse is also worked around. LOG(perfLog_.error()) << connection->tag() << "Caught exception: " << ex.what(); diff --git a/src/web/Server.h b/src/web/Server.h index 45132d92..a7af5cb6 100644 --- a/src/web/Server.h +++ b/src/web/Server.h @@ -47,8 +47,7 @@ namespace web { * @tparam HandlerType The executor to handle the requests */ template