diff --git a/.clang-tidy b/.clang-tidy index 9cfc08ff5b..07274eb53a 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -78,14 +78,14 @@ Checks: "-*, bugprone-unused-return-value, bugprone-unused-local-non-trivial-variable, bugprone-virtual-near-miss, - # cppcoreguidelines-init-variables, # has issues - # cppcoreguidelines-misleading-capture-default-by-value, # has issues + cppcoreguidelines-init-variables, + cppcoreguidelines-misleading-capture-default-by-value, cppcoreguidelines-no-suspend-with-lock, - # cppcoreguidelines-pro-type-member-init, # has issues + cppcoreguidelines-pro-type-member-init, cppcoreguidelines-pro-type-static-cast-downcast, - # cppcoreguidelines-rvalue-reference-param-not-moved, # has issues - # cppcoreguidelines-use-default-member-init, # has issues - # cppcoreguidelines-virtual-class-destructor, # has issues + cppcoreguidelines-rvalue-reference-param-not-moved, + cppcoreguidelines-use-default-member-init, + cppcoreguidelines-virtual-class-destructor, hicpp-ignored-remove-result, misc-const-correctness, misc-definitions-in-headers, diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 7d40ff3363..637246ec40 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -36,7 +36,7 @@ env: BUILD_DIR: build # ubuntu-latest has only 2 CPUs for private repositories # https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for--private-repositories - NPROC_SUBTRACT: ${{ github.event.repository.private && '1' || '2' }} + NPROC_SUBTRACT: ${{ github.event.repository.visibility == 'public' && '2' || '1' }} jobs: build: @@ -81,13 +81,13 @@ jobs: cmake --build . --target docs --parallel ${BUILD_NPROC} - name: Create documentation artifact - if: ${{ github.event.repository.visibility == 'public' && github.event_name == 'push' }} + if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && github.event_name == 'push' }} uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0 with: path: ${{ env.BUILD_DIR }}/docs/html deploy: - if: ${{ github.event.repository.visibility == 'public' && github.event_name == 'push' }} + if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && github.event_name == 'push' }} needs: build runs-on: ubuntu-latest permissions: diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index 27dfa2fd6a..920b5b5278 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -199,7 +199,7 @@ jobs: fi - name: Upload the binary (Linux) - if: ${{ github.event.repository.visibility == 'public' && runner.os == 'Linux' }} + if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && runner.os == 'Linux' }} uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: xrpld-${{ inputs.config_name }} diff --git a/.github/workflows/reusable-clang-tidy-files.yml b/.github/workflows/reusable-clang-tidy-files.yml index fcbb041ed9..81264cf24e 100644 --- a/.github/workflows/reusable-clang-tidy-files.yml +++ b/.github/workflows/reusable-clang-tidy-files.yml @@ -83,7 +83,7 @@ jobs: run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -allow-no-checks ${TARGETS} 2>&1 | tee clang-tidy-output.txt - name: Upload clang-tidy output - if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }} + if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && steps.run_clang_tidy.outcome != 'success' }} uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: clang-tidy-results diff --git a/BUILD.md b/BUILD.md index 4f709a032b..757f76a716 100644 --- a/BUILD.md +++ b/BUILD.md @@ -141,7 +141,7 @@ Alternatively, you can pull our recipes from the repository and export them loca ```bash # Define which recipes to export. -recipes=('abseil' 'ed25519' 'grpc' 'm4' 'mpt-crypto' 'nudb' 'openssl' 'secp256k1' 'snappy' 'soci' 'wasm-xrplf' 'wasmi') +recipes=('abseil' 'ed25519' 'grpc' 'm4' 'mpt-crypto' 'openssl' 'secp256k1' 'snappy' 'soci' 'wasm-xrplf' 'wasmi') # Selectively check out the recipes from our CCI fork. cd external diff --git a/conan.lock b/conan.lock index 575be2e071..f1d6ed3fa5 100644 --- a/conan.lock +++ b/conan.lock @@ -3,22 +3,22 @@ "requires": [ "zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809", "xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987", - "sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1763899256.358", + "sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1774467355.988", "soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231", "snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878", "secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329", "rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86", "re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1774398111.888", - "protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1773224203.27", + "protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12", "openssl/3.6.1#e6399de266349245a4542fc5f6c71552%1774458290.139", - "nudb/2.0.9#0432758a24204da08fee953ec9ea03cb%1769436073.32", + "nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1774883011.384", "lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914", "libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492", "libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03", "libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736", "jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244", "gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152", - "grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1772623605.068", + "grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1774467387.342", "ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772", "date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772", "c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681", @@ -29,7 +29,7 @@ "build_requires": [ "zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809", "strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1774447376.964", - "protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1773224203.27", + "protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12", "nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707", "msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649", "m4/1.4.19#5d7a4994e5875d76faf7acf3ed056036%1774365463.87", @@ -41,16 +41,15 @@ ], "python_requires": [], "overrides": { - "boost/1.90.0#d5e8defe7355494953be18524a7f135b": [ - null, - "boost/1.90.0" - ], "protobuf/[>=5.27.0 <7]": [ "protobuf/6.33.5" ], "lz4/1.9.4": [ "lz4/1.10.0" ], + "boost/[>=1.83.0 <1.91.0]": [ + "boost/1.90.0" + ], "sqlite3/[>=3.44 <4]": [ "sqlite3/3.51.0" ], diff --git a/include/xrpl/basics/CountedObject.h b/include/xrpl/basics/CountedObject.h index 55a895dbb1..acf75360e1 100644 --- a/include/xrpl/basics/CountedObject.h +++ b/include/xrpl/basics/CountedObject.h @@ -34,7 +34,7 @@ public: { // Insert ourselves at the front of the lock-free linked list CountedObjects& instance = CountedObjects::getInstance(); - Counter* head; + Counter* head = nullptr; do { diff --git a/include/xrpl/basics/DecayingSample.h b/include/xrpl/basics/DecayingSample.h index a8d6a2360e..d3343535e9 100644 --- a/include/xrpl/basics/DecayingSample.h +++ b/include/xrpl/basics/DecayingSample.h @@ -93,7 +93,7 @@ class DecayWindow public: using time_point = typename Clock::time_point; - explicit DecayWindow(time_point now) : value_(0), when_(now) + explicit DecayWindow(time_point now) : when_(now) { } @@ -125,7 +125,7 @@ private: when_ = now; } - double value_; + double value_{0}; time_point when_; }; diff --git a/include/xrpl/basics/IntrusivePointer.h b/include/xrpl/basics/IntrusivePointer.h index e6261be340..f816af1c05 100644 --- a/include/xrpl/basics/IntrusivePointer.h +++ b/include/xrpl/basics/IntrusivePointer.h @@ -84,7 +84,8 @@ public: template requires std::convertible_to - SharedIntrusive(SharedIntrusive&& rhs); + SharedIntrusive( + SharedIntrusive&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) SharedIntrusive& operator=(SharedIntrusive const& rhs); @@ -106,7 +107,8 @@ public: template requires std::convertible_to SharedIntrusive& - operator=(SharedIntrusive&& rhs); + operator=( + SharedIntrusive&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) /** Adopt the raw pointer. The strong reference may or may not be incremented, depending on the TAdoptTag @@ -314,7 +316,8 @@ public: template requires std::convertible_to - SharedWeakUnion(SharedIntrusive&& rhs); + SharedWeakUnion( + SharedIntrusive&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) SharedWeakUnion& operator=(SharedWeakUnion const& rhs); @@ -327,7 +330,8 @@ public: template requires std::convertible_to SharedWeakUnion& - operator=(SharedIntrusive&& rhs); + operator=( + SharedIntrusive&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) ~SharedWeakUnion(); diff --git a/include/xrpl/basics/Number.h b/include/xrpl/basics/Number.h index e3da029c03..c39aae2dd3 100644 --- a/include/xrpl/basics/Number.h +++ b/include/xrpl/basics/Number.h @@ -73,12 +73,12 @@ struct MantissaRange enum mantissa_scale { small, large }; explicit constexpr MantissaRange(mantissa_scale scale_) - : min(getMin(scale_)), max(min * 10 - 1), log(logTen(min).value_or(-1)), scale(scale_) + : min(getMin(scale_)), log(logTen(min).value_or(-1)), scale(scale_) { } rep min; - rep max; + rep max{min * 10 - 1}; int log; mantissa_scale scale; diff --git a/include/xrpl/basics/SlabAllocator.h b/include/xrpl/basics/SlabAllocator.h index 17acbbaa87..4ed88a32f7 100644 --- a/include/xrpl/basics/SlabAllocator.h +++ b/include/xrpl/basics/SlabAllocator.h @@ -91,7 +91,7 @@ class SlabAllocator std::uint8_t* allocate() noexcept { - std::uint8_t* ret; + std::uint8_t* ret = nullptr; // NOLINT(misc-const-correctness) { std::lock_guard const l(m_); diff --git a/include/xrpl/basics/TaggedCache.h b/include/xrpl/basics/TaggedCache.h index 6cbe8680c9..1a19c653bc 100644 --- a/include/xrpl/basics/TaggedCache.h +++ b/include/xrpl/basics/TaggedCache.h @@ -182,8 +182,7 @@ private: : hook(collector->make_hook(handler)) , size(collector->make_gauge(prefix, "size")) , hit_rate(collector->make_gauge(prefix, "hit_rate")) - , hits(0) - , misses(0) + { } @@ -191,8 +190,8 @@ private: beast::insight::Gauge size; beast::insight::Gauge hit_rate; - std::size_t hits; - std::size_t misses; + std::size_t hits{0}; + std::size_t misses{0}; }; class KeyOnlyEntry @@ -294,10 +293,10 @@ private: clock_type::duration const m_target_age; // Number of items cached - int m_cache_count; + int m_cache_count{0}; cache_type m_cache; // Hold strong reference to recent objects - std::uint64_t m_hits; - std::uint64_t m_misses; + std::uint64_t m_hits{0}; + std::uint64_t m_misses{0}; }; } // namespace xrpl diff --git a/include/xrpl/basics/TaggedCache.ipp b/include/xrpl/basics/TaggedCache.ipp index 8c0fde5e7d..6879ad435d 100644 --- a/include/xrpl/basics/TaggedCache.ipp +++ b/include/xrpl/basics/TaggedCache.ipp @@ -36,9 +36,7 @@ inline TaggedCache< , m_name(name) , m_target_size(size) , m_target_age(expiration) - , m_cache_count(0) - , m_hits(0) - , m_misses(0) + { } diff --git a/include/xrpl/basics/base_uint.h b/include/xrpl/basics/base_uint.h index 4ce135c036..5fb13319ea 100644 --- a/include/xrpl/basics/base_uint.h +++ b/include/xrpl/basics/base_uint.h @@ -335,11 +335,13 @@ public: operator=(std::uint64_t uHost) { *this = beast::zero; + // NOLINTBEGIN(cppcoreguidelines-pro-type-member-init) union { unsigned u[2]; std::uint64_t ul; }; + // NOLINTEND(cppcoreguidelines-pro-type-member-init) // Put in least significant bits. ul = boost::endian::native_to_big(uHost); data_[WIDTH - 2] = u[0]; @@ -621,7 +623,7 @@ template <> inline std::size_t extract(uint256 const& key) { - std::size_t result; + std::size_t result = 0; // Use memcpy to avoid unaligned UB // (will optimize to equivalent code) std::memcpy(&result, key.data(), sizeof(std::size_t)); diff --git a/include/xrpl/basics/random.h b/include/xrpl/basics/random.h index ae3a8c6ec6..db66b303d4 100644 --- a/include/xrpl/basics/random.h +++ b/include/xrpl/basics/random.h @@ -58,7 +58,7 @@ default_prng() // The thread-specific PRNGs: thread_local beast::xor_shift_engine engine = [] { - std::uint64_t seed; + std::uint64_t seed = 0; { std::lock_guard const lk(m); std::uniform_int_distribution distribution{1}; diff --git a/include/xrpl/beast/asio/io_latency_probe.h b/include/xrpl/beast/asio/io_latency_probe.h index 0718a32af7..2dc1fcba15 100644 --- a/include/xrpl/beast/asio/io_latency_probe.h +++ b/include/xrpl/beast/asio/io_latency_probe.h @@ -23,15 +23,15 @@ private: std::recursive_mutex m_mutex; std::condition_variable_any m_cond; - std::size_t m_count; + std::size_t m_count{1}; duration const m_period; boost::asio::io_context& m_ios; boost::asio::basic_waitable_timer m_timer; - bool m_cancel; + bool m_cancel{false}; public: io_latency_probe(duration const& period, boost::asio::io_context& ios) - : m_count(1), m_period(period), m_ios(ios), m_timer(m_ios), m_cancel(false) + : m_period(period), m_ios(ios), m_timer(m_ios) { } diff --git a/include/xrpl/beast/container/detail/aged_ordered_container.h b/include/xrpl/beast/container/detail/aged_ordered_container.h index b482cd33c1..dad0d92e0b 100644 --- a/include/xrpl/beast/container/detail/aged_ordered_container.h +++ b/include/xrpl/beast/container/detail/aged_ordered_container.h @@ -262,7 +262,9 @@ private: { } - config_t(config_t&& other, Allocator const& alloc) + config_t( + config_t&& other, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) + Allocator const& alloc) : KeyValueCompare(std::move(other.key_compare())) , beast::detail::empty_base_optimization(alloc) , clock(other.clock) @@ -552,7 +554,10 @@ public: aged_ordered_container(aged_ordered_container&& other); - aged_ordered_container(aged_ordered_container&& other, Allocator const& alloc); + aged_ordered_container( + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + aged_ordered_container&& other, + Allocator const& alloc); aged_ordered_container(std::initializer_list init, clock_type& clock); @@ -1290,7 +1295,7 @@ aged_ordered_container::aged_ template aged_ordered_container::aged_ordered_container( - aged_ordered_container&& other, + aged_ordered_container&& other, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) Allocator const& alloc) : m_config(std::move(other.m_config), alloc) #if BOOST_VERSION >= 108000 diff --git a/include/xrpl/beast/container/detail/aged_unordered_container.h b/include/xrpl/beast/container/detail/aged_unordered_container.h index d912f06ce1..dfc853f019 100644 --- a/include/xrpl/beast/container/detail/aged_unordered_container.h +++ b/include/xrpl/beast/container/detail/aged_unordered_container.h @@ -318,7 +318,9 @@ private: { } - config_t(config_t&& other, Allocator const& alloc) + config_t( + config_t&& other, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) + Allocator const& alloc) : ValueHash(std::move(other.hash_function())) , KeyValueEqual(std::move(other.key_eq())) , beast::detail::empty_base_optimization(alloc) @@ -774,7 +776,10 @@ public: aged_unordered_container(aged_unordered_container&& other); - aged_unordered_container(aged_unordered_container&& other, Allocator const& alloc); + aged_unordered_container( + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + aged_unordered_container&& other, + Allocator const& alloc); aged_unordered_container(std::initializer_list init, clock_type& clock); @@ -1838,7 +1843,10 @@ template < class KeyEqual, class Allocator> aged_unordered_container:: - aged_unordered_container(aged_unordered_container&& other, Allocator const& alloc) + aged_unordered_container( + // NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) + aged_unordered_container&& other, + Allocator const& alloc) : m_config(std::move(other.m_config), alloc) , m_buck(alloc) , m_cont(m_buck, std::cref(m_config.value_hash()), std::cref(m_config.key_value_equal())) diff --git a/include/xrpl/beast/core/LockFreeStack.h b/include/xrpl/beast/core/LockFreeStack.h index fe3baa0564..cf512725fe 100644 --- a/include/xrpl/beast/core/LockFreeStack.h +++ b/include/xrpl/beast/core/LockFreeStack.h @@ -187,7 +187,7 @@ public: bool push_front(Node* node) { - bool first; + bool first = false; Node* old_head = m_head.load(std::memory_order_relaxed); do { @@ -211,7 +211,7 @@ public: pop_front() { Node* node = m_head.load(); - Node* new_head; + Node* new_head = nullptr; do { if (node == &m_end) diff --git a/include/xrpl/beast/hash/xxhasher.h b/include/xrpl/beast/hash/xxhasher.h index 473907ea89..7c6ae894fc 100644 --- a/include/xrpl/beast/hash/xxhasher.h +++ b/include/xrpl/beast/hash/xxhasher.h @@ -23,7 +23,7 @@ private: // A 64-byte buffer should to be big enough for us static constexpr std::size_t INTERNAL_BUFFER_SIZE = 64; - alignas(64) std::array buffer_; + alignas(64) std::array buffer_{}; std::span readBuffer_; std::span writeBuffer_; diff --git a/include/xrpl/beast/unit_test/results.h b/include/xrpl/beast/unit_test/results.h index cbd0a71057..b8a8e2aadf 100644 --- a/include/xrpl/beast/unit_test/results.h +++ b/include/xrpl/beast/unit_test/results.h @@ -35,10 +35,10 @@ private: class tests_t : public detail::const_container> { private: - std::size_t failed_; + std::size_t failed_{0}; public: - tests_t() : failed_(0) + tests_t() { } @@ -167,12 +167,12 @@ public: class results : public detail::const_container> { private: - std::size_t m_cases; - std::size_t total_; - std::size_t failed_; + std::size_t m_cases{0}; + std::size_t total_{0}; + std::size_t failed_{0}; public: - results() : m_cases(0), total_(0), failed_(0) + results() { } diff --git a/include/xrpl/beast/utility/PropertyStream.h b/include/xrpl/beast/utility/PropertyStream.h index 3d29138a12..290730c1a2 100644 --- a/include/xrpl/beast/utility/PropertyStream.h +++ b/include/xrpl/beast/utility/PropertyStream.h @@ -311,7 +311,7 @@ private: std::string const m_name; std::recursive_mutex lock_; Item item_; - Source* parent_; + Source* parent_{nullptr}; List children_; public: diff --git a/include/xrpl/beast/xor_shift_engine.h b/include/xrpl/beast/xor_shift_engine.h index d49cb08fc0..4fbe5ec165 100644 --- a/include/xrpl/beast/xor_shift_engine.h +++ b/include/xrpl/beast/xor_shift_engine.h @@ -37,7 +37,7 @@ public: } private: - result_type s_[2]; + result_type s_[2]{}; static result_type murmurhash3(result_type x); diff --git a/include/xrpl/core/ClosureCounter.h b/include/xrpl/core/ClosureCounter.h index f0f277cc0e..b1939b2e63 100644 --- a/include/xrpl/core/ClosureCounter.h +++ b/include/xrpl/core/ClosureCounter.h @@ -92,7 +92,9 @@ private: ++counter_; } - Substitute(ClosureCounter& counter, Closure&& closure) + Substitute( + ClosureCounter& counter, + Closure&& closure) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) : counter_(counter), closure_(std::forward(closure)) { ++counter_; diff --git a/include/xrpl/core/Coro.ipp b/include/xrpl/core/Coro.ipp index dca9504679..38d921a658 100644 --- a/include/xrpl/core/Coro.ipp +++ b/include/xrpl/core/Coro.ipp @@ -7,7 +7,6 @@ JobQueue::Coro::Coro(Coro_create_t, JobQueue& jq, JobType type, std::string cons : jq_(jq) , type_(type) , name_(name) - , running_(false) , coro_( // Stack size of 1MB wasn't sufficient for deep calls. ASAN tests flagged the issue. Hence // increasing the size to 1.5MB. diff --git a/include/xrpl/core/JobQueue.h b/include/xrpl/core/JobQueue.h index 994e2b424c..558e55cf31 100644 --- a/include/xrpl/core/JobQueue.h +++ b/include/xrpl/core/JobQueue.h @@ -45,7 +45,7 @@ public: JobQueue& jq_; JobType type_; std::string name_; - bool running_; + bool running_{false}; std::mutex mutex_; std::mutex mutex_run_; std::condition_variable cv_; @@ -224,7 +224,7 @@ private: beast::Journal m_journal; mutable std::mutex m_mutex; - std::uint64_t m_lastJob; + std::uint64_t m_lastJob{0}; std::set m_jobSet; JobCounter jobCounter_; std::atomic_bool stopping_{false}; @@ -233,7 +233,7 @@ private: JobTypeData m_invalidJobData; // The number of jobs currently in processTask() - int m_processCount; + int m_processCount{0}; // The number of suspended coroutines int nSuspend_ = 0; diff --git a/include/xrpl/core/JobTypeData.h b/include/xrpl/core/JobTypeData.h index 32df3e88cf..c180629af7 100644 --- a/include/xrpl/core/JobTypeData.h +++ b/include/xrpl/core/JobTypeData.h @@ -19,13 +19,13 @@ public: JobTypeInfo const& info; /* The number of jobs waiting */ - int waiting; + int waiting{0}; /* The number presently running */ - int running; + int running{0}; /* And the number we deferred executing because of job limits */ - int deferred; + int deferred{0}; /* Notification callbacks */ beast::insight::Event dequeue; @@ -35,12 +35,8 @@ public: JobTypeInfo const& info_, beast::insight::Collector::ptr const& collector, Logs& logs) noexcept - : m_load(logs.journal("LoadMonitor")) - , m_collector(collector) - , info(info_) - , waiting(0) - , running(0) - , deferred(0) + : m_load(logs.journal("LoadMonitor")), m_collector(collector), info(info_) + { m_load.setTargetLatency(info.getAverageLatency(), info.getPeakLatency()); diff --git a/include/xrpl/core/LoadMonitor.h b/include/xrpl/core/LoadMonitor.h index 71fbf75d68..b8777a7056 100644 --- a/include/xrpl/core/LoadMonitor.h +++ b/include/xrpl/core/LoadMonitor.h @@ -36,10 +36,10 @@ public: { Stats(); - std::uint64_t count; + std::uint64_t count{0}; std::chrono::milliseconds latencyAvg; std::chrono::milliseconds latencyPeak; - bool isOverloaded; + bool isOverloaded{false}; }; Stats @@ -54,8 +54,8 @@ private: std::mutex mutex_; - std::uint64_t mCounts; - int mLatencyEvents; + std::uint64_t mCounts{0}; + int mLatencyEvents{0}; std::chrono::milliseconds mLatencyMSAvg; std::chrono::milliseconds mLatencyMSPeak; std::chrono::milliseconds mTargetLatencyAvg; diff --git a/include/xrpl/core/PeerReservationTable.h b/include/xrpl/core/PeerReservationTable.h index 6d861e5fbe..fc943f0807 100644 --- a/include/xrpl/core/PeerReservationTable.h +++ b/include/xrpl/core/PeerReservationTable.h @@ -92,7 +92,7 @@ public: private: beast::Journal mutable journal_; std::mutex mutable mutex_; - DatabaseCon* connection_; + DatabaseCon* connection_{}; std::unordered_set, KeyEqual> table_; }; diff --git a/include/xrpl/core/detail/Workers.h b/include/xrpl/core/detail/Workers.h index 7925d11e62..dbc93ecf81 100644 --- a/include/xrpl/core/detail/Workers.h +++ b/include/xrpl/core/detail/Workers.h @@ -183,8 +183,8 @@ private: std::thread thread_; std::mutex mutex_; std::condition_variable wakeup_; - int wakeCount_; // how many times to un-pause - bool shouldExit_; + int wakeCount_{0}; // how many times to un-pause + bool shouldExit_{false}; }; private: @@ -197,9 +197,9 @@ private: std::string m_threadNames; // The name to give each thread std::condition_variable m_cv; // signaled when all threads paused std::mutex m_mut; - bool m_allPaused; + bool m_allPaused{true}; semaphore m_semaphore; // each pending task is 1 resource - int m_numberOfThreads; // how many we want active now + int m_numberOfThreads{0}; // how many we want active now std::atomic m_activeCount; // to know when all are paused std::atomic m_pauseCount; // how many threads need to pause now std::atomic m_runningTaskCount; // how many calls to processTask() active diff --git a/include/xrpl/json/json_reader.h b/include/xrpl/json/json_reader.h index 09dac80a2f..dd1be76923 100644 --- a/include/xrpl/json/json_reader.h +++ b/include/xrpl/json/json_reader.h @@ -103,9 +103,9 @@ private: public: explicit ErrorInfo() = default; - Token token_; + Token token_{}; std::string message_; - Location extra_; + Location extra_{}; }; using Errors = std::deque; @@ -173,11 +173,11 @@ private: Nodes nodes_; Errors errors_; std::string document_; - Location begin_; - Location end_; - Location current_; - Location lastValueEnd_; - Value* lastValue_; + Location begin_{}; + Location end_{}; + Location current_{}; + Location lastValueEnd_{}; + Value* lastValue_{}; }; template diff --git a/include/xrpl/json/json_writer.h b/include/xrpl/json/json_writer.h index cc3790a7dd..e49abcd81a 100644 --- a/include/xrpl/json/json_writer.h +++ b/include/xrpl/json/json_writer.h @@ -106,8 +106,8 @@ private: ChildValues childValues_; std::string document_; std::string indentString_; - int rightMargin_; - int indentSize_; + int rightMargin_{74}; + int indentSize_{3}; bool addChildValues_{}; }; @@ -171,9 +171,9 @@ private: using ChildValues = std::vector; ChildValues childValues_; - std::ostream* document_; + std::ostream* document_{nullptr}; std::string indentString_; - int rightMargin_; + int rightMargin_{74}; std::string indentation_; bool addChildValues_{}; }; diff --git a/include/xrpl/nodestore/Scheduler.h b/include/xrpl/nodestore/Scheduler.h index 6e01533930..dc3e1e3d15 100644 --- a/include/xrpl/nodestore/Scheduler.h +++ b/include/xrpl/nodestore/Scheduler.h @@ -16,7 +16,7 @@ struct FetchReport { } - std::chrono::milliseconds elapsed; + std::chrono::milliseconds elapsed{}; FetchType const fetchType; bool wasFound = false; }; diff --git a/include/xrpl/nodestore/detail/BatchWriter.h b/include/xrpl/nodestore/detail/BatchWriter.h index 1820435133..93993d1c3e 100644 --- a/include/xrpl/nodestore/detail/BatchWriter.h +++ b/include/xrpl/nodestore/detail/BatchWriter.h @@ -71,8 +71,8 @@ private: Scheduler& m_scheduler; LockType mWriteMutex; CondvarType mWriteCondition; - int mWriteLoad; - bool mWritePending; + int mWriteLoad{0}; + bool mWritePending{false}; Batch mWriteSet; }; diff --git a/include/xrpl/nodestore/detail/EncodedBlob.h b/include/xrpl/nodestore/detail/EncodedBlob.h index 78e7153f73..b05583475e 100644 --- a/include/xrpl/nodestore/detail/EncodedBlob.h +++ b/include/xrpl/nodestore/detail/EncodedBlob.h @@ -35,7 +35,7 @@ namespace NodeStore { class EncodedBlob { /** The 32-byte key of the serialized object. */ - std::array key_; + std::array key_{}; /** A pre-allocated buffer for the serialized object. @@ -43,7 +43,8 @@ class EncodedBlob 1024 more bytes. The precise size is calculated automatically at compile time so as to avoid wasting space on padding bytes. */ - std::array payload_; + std::array + payload_{}; /** The size of the serialized data. */ std::uint32_t size_; diff --git a/include/xrpl/nodestore/detail/codec.h b/include/xrpl/nodestore/detail/codec.h index 8a337ca4c3..4e12c6b4db 100644 --- a/include/xrpl/nodestore/detail/codec.h +++ b/include/xrpl/nodestore/detail/codec.h @@ -56,7 +56,7 @@ lz4_compress(void const* in, std::size_t in_size, BufferFactory&& bf) using std::runtime_error; using namespace nudb::detail; std::pair result; - std::array::max> vi; + std::array::max> vi{}; auto const n = write_varint(vi.data(), in_size); auto const out_max = LZ4_compressBound(in_size); std::uint8_t* out = reinterpret_cast(bf(n + out_max)); @@ -88,7 +88,7 @@ nodeobject_decompress(void const* in, std::size_t in_size, BufferFactory&& bf) using namespace nudb::detail; std::uint8_t const* p = reinterpret_cast(in); - std::size_t type; + std::size_t type = 0; auto const vn = read_varint(p, in_size, type); if (vn == 0) Throw("nodeobject decompress"); @@ -117,7 +117,7 @@ nodeobject_decompress(void const* in, std::size_t in_size, BufferFactory&& bf) "nodeobject codec v1: short inner node size: " + std::string("in_size = ") + std::to_string(in_size) + " hs = " + std::to_string(hs)); istream is(p, in_size); - std::uint16_t mask; + std::uint16_t mask = 0; read(is, mask); // Mask in_size -= hs; result.second = 525; @@ -196,10 +196,10 @@ nodeobject_compress(void const* in, std::size_t in_size, BufferFactory&& bf) if (in_size == 525) { istream is(in, in_size); - std::uint32_t index; - std::uint32_t unused; - std::uint8_t kind; - std::uint32_t prefix; + std::uint32_t index = 0; + std::uint32_t unused = 0; + std::uint8_t kind = 0; + std::uint32_t prefix = 0; read(is, index); read(is, unused); read(is, kind); @@ -208,7 +208,7 @@ nodeobject_compress(void const* in, std::size_t in_size, BufferFactory&& bf) { std::size_t n = 0; std::uint16_t mask = 0; - std::array vh; + std::array vh{}; for (unsigned bit = 0x8000; bit; bit >>= 1) { void const* const h = is(32); @@ -247,7 +247,7 @@ nodeobject_compress(void const* in, std::size_t in_size, BufferFactory&& bf) } } - std::array::max> vi; + std::array::max> vi{}; constexpr std::size_t codecType = 1; auto const vn = write_varint(vi.data(), codecType); @@ -257,7 +257,7 @@ nodeobject_compress(void const* in, std::size_t in_size, BufferFactory&& bf) // case 0 was uncompressed data; we always compress now. case 1: // lz4 { - std::uint8_t* p; + std::uint8_t* p = nullptr; auto const lzr = NodeStore::lz4_compress(in, in_size, [&p, &vn, &bf](std::size_t n) { p = reinterpret_cast(bf(vn + n)); return p + vn; @@ -287,10 +287,10 @@ filter_inner(void* in, std::size_t in_size) if (in_size == 525) { istream is(in, in_size); - std::uint32_t index; - std::uint32_t unused; - std::uint8_t kind; - std::uint32_t prefix; + std::uint32_t index = 0; + std::uint32_t unused = 0; + std::uint8_t kind = 0; + std::uint32_t prefix = 0; read(is, index); read(is, unused); read(is, kind); diff --git a/include/xrpl/protocol/IOUAmount.h b/include/xrpl/protocol/IOUAmount.h index 2ee453f575..47aa35e0e8 100644 --- a/include/xrpl/protocol/IOUAmount.h +++ b/include/xrpl/protocol/IOUAmount.h @@ -26,8 +26,8 @@ class IOUAmount : private boost::totally_ordered, private boost::addi private: using mantissa_type = std::int64_t; using exponent_type = int; - mantissa_type mantissa_; - exponent_type exponent_; + mantissa_type mantissa_{}; + exponent_type exponent_{}; /** Adjusts the mantissa and exponent to the proper range. diff --git a/include/xrpl/protocol/Indexes.h b/include/xrpl/protocol/Indexes.h index 7884905d9e..574bbfbde6 100644 --- a/include/xrpl/protocol/Indexes.h +++ b/include/xrpl/protocol/Indexes.h @@ -363,11 +363,12 @@ uint256 getTicketIndex(AccountID const& account, SeqProxy ticketSeq); template +// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init) struct keyletDesc { std::function function; Json::StaticString expectedLEName; - bool includeInTests; + bool includeInTests{}; }; // This list should include all of the keylet functions that take a single diff --git a/include/xrpl/protocol/Quality.h b/include/xrpl/protocol/Quality.h index 0ec797da0c..e9451d44ed 100644 --- a/include/xrpl/protocol/Quality.h +++ b/include/xrpl/protocol/Quality.h @@ -56,8 +56,8 @@ struct TAmounts return *this; } - In in; - Out out; + In in{}; + Out out{}; }; using Amounts = TAmounts; diff --git a/include/xrpl/protocol/STAmount.h b/include/xrpl/protocol/STAmount.h index 9cd7221d1e..df26f99b75 100644 --- a/include/xrpl/protocol/STAmount.h +++ b/include/xrpl/protocol/STAmount.h @@ -35,9 +35,9 @@ public: private: Asset mAsset; - mantissa_type mValue; + mantissa_type mValue{}; exponent_type mOffset; - bool mIsNegative; + bool mIsNegative{}; public: using value_type = STAmount; diff --git a/include/xrpl/protocol/STLedgerEntry.h b/include/xrpl/protocol/STLedgerEntry.h index 994a616210..a28868cd7a 100644 --- a/include/xrpl/protocol/STLedgerEntry.h +++ b/include/xrpl/protocol/STLedgerEntry.h @@ -86,7 +86,9 @@ inline STLedgerEntry::STLedgerEntry(LedgerEntryType type, uint256 const& key) { } -inline STLedgerEntry::STLedgerEntry(SerialIter&& sit, uint256 const& index) +inline STLedgerEntry::STLedgerEntry( + SerialIter&& sit, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) + uint256 const& index) : STLedgerEntry(sit, index) { } diff --git a/include/xrpl/protocol/STObject.h b/include/xrpl/protocol/STObject.h index 3a7d3f4b16..61a1cce05e 100644 --- a/include/xrpl/protocol/STObject.h +++ b/include/xrpl/protocol/STObject.h @@ -671,7 +671,7 @@ public: OptionalProxy& operator=(std::nullopt_t const&); OptionalProxy& - operator=(optional_type&& v); + operator=(optional_type&& v); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) OptionalProxy& operator=(optional_type const& v); @@ -766,7 +766,7 @@ STObject::Proxy::assign(U&& u) st_->makeFieldAbsent(*f_); return; } - T* t; + T* t = nullptr; if (style_ == soeINVALID) t = dynamic_cast(st_->getPField(*f_, true)); else @@ -851,7 +851,9 @@ STObject::OptionalProxy::operator=(std::nullopt_t const&) -> OptionalProxy& template auto -STObject::OptionalProxy::operator=(optional_type&& v) -> OptionalProxy& +STObject::OptionalProxy::operator=( + optional_type&& v) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) + -> OptionalProxy& { if (v) this->assign(std::move(*v)); @@ -930,6 +932,7 @@ STObject::Transform::operator()(detail::STVar const& e) const //------------------------------------------------------------------------------ +// NOLINTNEXTLINE(cppcoreguidelines-rvalue-reference-param-not-moved) inline STObject::STObject(SerialIter&& sit, SField const& name) : STObject(sit, name) { } diff --git a/include/xrpl/protocol/STTx.h b/include/xrpl/protocol/STTx.h index f200c19eac..b27d9e0637 100644 --- a/include/xrpl/protocol/STTx.h +++ b/include/xrpl/protocol/STTx.h @@ -179,7 +179,8 @@ sterilize(STTx const& stx); bool isPseudoTx(STObject const& tx); -inline STTx::STTx(SerialIter&& sit) : STTx(sit) +inline STTx::STTx(SerialIter&& sit) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) + : STTx(sit) { } diff --git a/include/xrpl/protocol/detail/STVar.h b/include/xrpl/protocol/detail/STVar.h index aaf9696571..1131437850 100644 --- a/include/xrpl/protocol/detail/STVar.h +++ b/include/xrpl/protocol/detail/STVar.h @@ -50,7 +50,7 @@ public: STVar& operator=(STVar&& rhs); - STVar(STBase&& t) + STVar(STBase&& t) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) { p_ = t.move(max_size, &d_); } diff --git a/include/xrpl/protocol/detail/b58_utils.h b/include/xrpl/protocol/detail/b58_utils.h index adb889ee53..5ad12d56e3 100644 --- a/include/xrpl/protocol/detail/b58_utils.h +++ b/include/xrpl/protocol/detail/b58_utils.h @@ -59,7 +59,7 @@ inplace_bigint_add(std::span a, std::uint64_t b) return TokenCodecErrc::inputTooSmall; } - std::uint64_t carry; + std::uint64_t carry = 0; std::tie(a[0], carry) = carrying_add(a[0], b); for (auto& v : a.subspan(1)) @@ -162,7 +162,7 @@ b58_10_to_b58_be(std::uint64_t input) int i = 0; while (input > 0) { - std::uint64_t rem; + std::uint64_t rem = 0; std::tie(input, rem) = div_rem(input, 58); result[resultSize - 1 - i] = rem; i += 1; diff --git a/include/xrpl/protocol/json_get_or_throw.h b/include/xrpl/protocol/json_get_or_throw.h index 336d875450..4406d9ff24 100644 --- a/include/xrpl/protocol/json_get_or_throw.h +++ b/include/xrpl/protocol/json_get_or_throw.h @@ -112,7 +112,7 @@ getOrThrow(Json::Value const& v, xrpl::SField const& field) { auto const s = inner.asString(); // parse as hex - std::uint64_t val; + std::uint64_t val = 0; auto [p, ec] = std::from_chars(s.data(), s.data() + s.size(), val, 16); diff --git a/include/xrpl/protocol/nft.h b/include/xrpl/protocol/nft.h index 4be58c381c..821d146ff7 100644 --- a/include/xrpl/protocol/nft.h +++ b/include/xrpl/protocol/nft.h @@ -39,7 +39,7 @@ constexpr std::uint16_t const flagMutable = 0x0010; inline std::uint16_t getFlags(uint256 const& id) { - std::uint16_t flags; + std::uint16_t flags = 0; memcpy(&flags, id.begin(), 2); return boost::endian::big_to_native(flags); } @@ -47,7 +47,7 @@ getFlags(uint256 const& id) inline std::uint16_t getTransferFee(uint256 const& id) { - std::uint16_t fee; + std::uint16_t fee = 0; memcpy(&fee, id.begin() + 2, 2); return boost::endian::big_to_native(fee); } @@ -55,7 +55,7 @@ getTransferFee(uint256 const& id) inline std::uint32_t getSerial(uint256 const& id) { - std::uint32_t seq; + std::uint32_t seq = 0; memcpy(&seq, id.begin() + 28, 4); return boost::endian::big_to_native(seq); } @@ -87,7 +87,7 @@ cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon) inline Taxon getTaxon(uint256 const& id) { - std::uint32_t taxon; + std::uint32_t taxon = 0; memcpy(&taxon, id.begin() + 24, 4); taxon = boost::endian::big_to_native(taxon); diff --git a/include/xrpl/rdb/RelationalDatabase.h b/include/xrpl/rdb/RelationalDatabase.h index 56c20e4263..1c28ddec0a 100644 --- a/include/xrpl/rdb/RelationalDatabase.h +++ b/include/xrpl/rdb/RelationalDatabase.h @@ -51,19 +51,19 @@ public: AccountID const& account; /// Ledger sequence range to search. A value of 0 for min or max /// means unbounded in that direction (no constraint applied). - LedgerRange ledgerRange; - std::uint32_t offset; - std::uint32_t limit; - bool bUnlimited; + LedgerRange ledgerRange{}; + std::uint32_t offset = 0; + std::uint32_t limit = 0; + bool bUnlimited{}; }; struct AccountTxPageOptions { AccountID const& account; - LedgerRange ledgerRange; + LedgerRange ledgerRange{}; std::optional marker; - std::uint32_t limit; - bool bAdmin; + std::uint32_t limit = 0; + bool bAdmin = false; }; using AccountTx = std::pair, std::shared_ptr>; @@ -88,8 +88,8 @@ public: struct AccountTxResult { std::variant transactions; - LedgerRange ledgerRange; - uint32_t limit; + LedgerRange ledgerRange{}; + uint32_t limit = 0; std::optional marker; }; diff --git a/include/xrpl/resource/Gossip.h b/include/xrpl/resource/Gossip.h index e581145149..9a70309cc4 100644 --- a/include/xrpl/resource/Gossip.h +++ b/include/xrpl/resource/Gossip.h @@ -17,7 +17,7 @@ struct Gossip { explicit Item() = default; - int balance; + int balance{}; beast::IP::Endpoint address; }; diff --git a/include/xrpl/resource/detail/Entry.h b/include/xrpl/resource/detail/Entry.h index ecff8828af..2a6414778c 100644 --- a/include/xrpl/resource/detail/Entry.h +++ b/include/xrpl/resource/detail/Entry.h @@ -62,7 +62,7 @@ struct Entry : public beast::List::Node std::optional publicKey; // Back pointer to the map key (bit of a hack here) - Key const* key; + Key const* key{}; // Number of Consumer references int refcount; diff --git a/include/xrpl/resource/detail/Import.h b/include/xrpl/resource/detail/Import.h index 790fc0596a..bee90afbf0 100644 --- a/include/xrpl/resource/detail/Import.h +++ b/include/xrpl/resource/detail/Import.h @@ -13,7 +13,7 @@ struct Import { explicit Item() = default; - int balance; + int balance{}; Consumer consumer; }; diff --git a/include/xrpl/server/LoadFeeTrack.h b/include/xrpl/server/LoadFeeTrack.h index 08be3e0406..226408dbde 100644 --- a/include/xrpl/server/LoadFeeTrack.h +++ b/include/xrpl/server/LoadFeeTrack.h @@ -26,10 +26,6 @@ class LoadFeeTrack final public: explicit LoadFeeTrack(beast::Journal journal = beast::Journal(beast::Journal::getNullSink())) : j_(journal) - , localTxnLoadFee_(lftNormalFee) - , remoteTxnLoadFee_(lftNormalFee) - , clusterTxnLoadFee_(lftNormalFee) - , raiseCount_(0) { } @@ -124,10 +120,10 @@ private: beast::Journal const j_; std::mutex mutable lock_; - std::uint32_t localTxnLoadFee_; // Scale factor, lftNormalFee = normal fee - std::uint32_t remoteTxnLoadFee_; // Scale factor, lftNormalFee = normal fee - std::uint32_t clusterTxnLoadFee_; // Scale factor, lftNormalFee = normal fee - std::uint32_t raiseCount_; + std::uint32_t localTxnLoadFee_{lftNormalFee}; // Scale factor, lftNormalFee = normal fee + std::uint32_t remoteTxnLoadFee_{lftNormalFee}; // Scale factor, lftNormalFee = normal fee + std::uint32_t clusterTxnLoadFee_{lftNormalFee}; // Scale factor, lftNormalFee = normal fee + std::uint32_t raiseCount_{0}; }; //------------------------------------------------------------------------------ diff --git a/include/xrpl/server/Port.h b/include/xrpl/server/Port.h index b00f4f4041..c7acabbc85 100644 --- a/include/xrpl/server/Port.h +++ b/include/xrpl/server/Port.h @@ -54,7 +54,7 @@ struct Port int limit = 0; // Websocket disconnects if send queue exceeds this limit - std::uint16_t ws_queue_limit; + std::uint16_t ws_queue_limit{}; // Returns `true` if any websocket protocols are specified bool @@ -90,7 +90,7 @@ struct ParsedPort std::string ssl_ciphers; boost::beast::websocket::permessage_deflate pmd_options; int limit = 0; - std::uint16_t ws_queue_limit; + std::uint16_t ws_queue_limit{}; std::optional ip; std::optional port; diff --git a/include/xrpl/server/State.h b/include/xrpl/server/State.h index 48e11869f4..c3cc4f609c 100644 --- a/include/xrpl/server/State.h +++ b/include/xrpl/server/State.h @@ -12,7 +12,7 @@ struct SavedState { std::string writableDb; std::string archiveDb; - LedgerIndex lastRotated; + LedgerIndex lastRotated{}; }; /** diff --git a/include/xrpl/server/detail/BaseHTTPPeer.h b/include/xrpl/server/detail/BaseHTTPPeer.h index 8354e63c64..878f6a1ddf 100644 --- a/include/xrpl/server/detail/BaseHTTPPeer.h +++ b/include/xrpl/server/detail/BaseHTTPPeer.h @@ -48,14 +48,14 @@ protected: struct buffer { - buffer(void const* ptr, std::size_t len) : data(new char[len]), bytes(len), used(0) + buffer(void const* ptr, std::size_t len) : data(new char[len]), bytes(len) { memcpy(data.get(), ptr, len); } std::unique_ptr data; std::size_t bytes; - std::size_t used; + std::size_t used{0}; }; Port const& port_; diff --git a/include/xrpl/server/detail/Door.h b/include/xrpl/server/detail/Door.h index f977dc6002..87baad42db 100644 --- a/include/xrpl/server/detail/Door.h +++ b/include/xrpl/server/detail/Door.h @@ -88,8 +88,12 @@ private: boost::asio::io_context& ioc_; acceptor_type acceptor_; boost::asio::strand strand_; - bool ssl_; - bool plain_; + bool ssl_{ + port_.protocol.count("https") > 0 || port_.protocol.count("wss") > 0 || + port_.protocol.count("wss2") > 0 || port_.protocol.count("peer") > 0}; + bool plain_{ + port_.protocol.count("http") > 0 || port_.protocol.count("ws") > 0 || + port_.protocol.count("ws2")}; static constexpr std::chrono::milliseconds INITIAL_ACCEPT_DELAY{50}; static constexpr std::chrono::milliseconds MAX_ACCEPT_DELAY{2000}; std::chrono::milliseconds accept_delay_{INITIAL_ACCEPT_DELAY}; @@ -274,12 +278,6 @@ Door::Door( , ioc_(io_context) , acceptor_(io_context) , strand_(boost::asio::make_strand(io_context)) - , ssl_( - port_.protocol.count("https") > 0 || port_.protocol.count("wss") > 0 || - port_.protocol.count("wss2") > 0 || port_.protocol.count("peer") > 0) - , plain_( - port_.protocol.count("http") > 0 || port_.protocol.count("ws") > 0 || - port_.protocol.count("ws2")) , backoff_timer_(io_context) { reOpen(); @@ -397,7 +395,7 @@ Door::query_fd_stats() const return std::nullopt; #else FDStats s; - struct rlimit rl; + struct rlimit rl{}; if (getrlimit(RLIMIT_NOFILE, &rl) != 0 || rl.rlim_cur == RLIM_INFINITY) return std::nullopt; s.limit = static_cast(rl.rlim_cur); diff --git a/include/xrpl/server/detail/ServerImpl.h b/include/xrpl/server/detail/ServerImpl.h index 1f91413521..0b5d075d87 100644 --- a/include/xrpl/server/detail/ServerImpl.h +++ b/include/xrpl/server/detail/ServerImpl.h @@ -74,7 +74,7 @@ private: std::vector ports_; std::vector>> list_; int high_ = 0; - std::array hist_; + std::array hist_{}; io_list ios_; diff --git a/include/xrpl/tx/Transactor.h b/include/xrpl/tx/Transactor.h index e9d3159919..287f785cd7 100644 --- a/include/xrpl/tx/Transactor.h +++ b/include/xrpl/tx/Transactor.h @@ -116,12 +116,13 @@ protected: AccountID const account_; XRPAmount preFeeBalance_{}; // Balance before fees. - virtual ~Transactor() = default; Transactor(Transactor const&) = delete; Transactor& operator=(Transactor const&) = delete; public: + virtual ~Transactor() = default; + enum ConsequencesFactoryType { Normal, Blocker, Custom }; /** Process the transaction. */ ApplyResult diff --git a/include/xrpl/tx/invariants/AMMInvariant.h b/include/xrpl/tx/invariants/AMMInvariant.h index 63ebb804ae..e872c61f76 100644 --- a/include/xrpl/tx/invariants/AMMInvariant.h +++ b/include/xrpl/tx/invariants/AMMInvariant.h @@ -15,12 +15,12 @@ class ValidAMM std::optional ammAccount_; std::optional lptAMMBalanceAfter_; std::optional lptAMMBalanceBefore_; - bool ammPoolChanged_; + bool ammPoolChanged_{false}; public: enum class ZeroAllowed : bool { No = false, Yes = true }; - ValidAMM() : ammPoolChanged_{false} + ValidAMM() { } void diff --git a/include/xrpl/tx/paths/AMMOffer.h b/include/xrpl/tx/paths/AMMOffer.h index aa6132dfce..4ef1b2048b 100644 --- a/include/xrpl/tx/paths/AMMOffer.h +++ b/include/xrpl/tx/paths/AMMOffer.h @@ -37,7 +37,7 @@ private: // else the amounts quality Quality const quality_; // AMM offer can be consumed once at a given iteration - bool consumed_; + bool consumed_{false}; public: AMMOffer( diff --git a/include/xrpl/tx/paths/BookTip.h b/include/xrpl/tx/paths/BookTip.h index 98036a86eb..6a1805e83a 100644 --- a/include/xrpl/tx/paths/BookTip.h +++ b/include/xrpl/tx/paths/BookTip.h @@ -16,7 +16,7 @@ class BookTip { private: ApplyView& view_; - bool m_valid; + bool m_valid{false}; uint256 m_book; uint256 m_end; uint256 m_dir; diff --git a/include/xrpl/tx/paths/Offer.h b/include/xrpl/tx/paths/Offer.h index 4b161c5f2d..de3eed933a 100644 --- a/include/xrpl/tx/paths/Offer.h +++ b/include/xrpl/tx/paths/Offer.h @@ -32,10 +32,10 @@ class TOffer : private TOfferBase { private: SLE::pointer m_entry; - Quality m_quality; + Quality m_quality{}; AccountID m_account; - TAmounts m_amounts; + TAmounts m_amounts{}; void setFieldAmounts(); diff --git a/include/xrpl/tx/paths/OfferStream.h b/include/xrpl/tx/paths/OfferStream.h index df96a1b6da..ba553360ef 100644 --- a/include/xrpl/tx/paths/OfferStream.h +++ b/include/xrpl/tx/paths/OfferStream.h @@ -19,11 +19,11 @@ public: { private: std::uint32_t const limit_; - std::uint32_t count_; + std::uint32_t count_{0}; beast::Journal j_; public: - StepCounter(std::uint32_t limit, beast::Journal j) : limit_(limit), count_(0), j_(j) + StepCounter(std::uint32_t limit, beast::Journal j) : limit_(limit), j_(j) { } diff --git a/include/xrpl/tx/paths/detail/AmountSpec.h b/include/xrpl/tx/paths/detail/AmountSpec.h index 690e67ae22..1adee6a0a3 100644 --- a/include/xrpl/tx/paths/detail/AmountSpec.h +++ b/include/xrpl/tx/paths/detail/AmountSpec.h @@ -12,7 +12,7 @@ struct AmountSpec { explicit AmountSpec() = default; - bool native; + bool native{}; union { XRPAmount xrp; diff --git a/include/xrpl/tx/paths/detail/StrandFlow.h b/include/xrpl/tx/paths/detail/StrandFlow.h index a67542269e..fba631c695 100644 --- a/include/xrpl/tx/paths/detail/StrandFlow.h +++ b/include/xrpl/tx/paths/detail/StrandFlow.h @@ -27,7 +27,7 @@ namespace xrpl { template struct StrandResult { - bool success; ///< Strand succeeded + bool success = false; ///< Strand succeeded TInAmt in = beast::zero; ///< Currency amount in TOutAmt out = beast::zero; ///< Currency amount out std::optional sandbox; ///< Resulting Sandbox state @@ -61,7 +61,7 @@ struct StrandResult } StrandResult(Strand const& strand, boost::container::flat_set ofrsToRm_) - : success(false), ofrsToRm(std::move(ofrsToRm_)), ofrsUsed(offersUsed(strand)) + : ofrsToRm(std::move(ofrsToRm_)), ofrsUsed(offersUsed(strand)) { } }; diff --git a/include/xrpl/tx/transactors/lending/LendingHelpers.h b/include/xrpl/tx/transactors/lending/LendingHelpers.h index 4057c9c173..897ca3995b 100644 --- a/include/xrpl/tx/transactors/lending/LendingHelpers.h +++ b/include/xrpl/tx/transactors/lending/LendingHelpers.h @@ -143,7 +143,7 @@ struct LoanProperties // - A minimum scale required to represent the periodic payment accurately // All loan state values (principal, interest, fees) are rounded to this // scale. - std::int32_t loanScale; + std::int32_t loanScale{}; // The principal portion of the first payment. Number firstPaymentPrincipal; diff --git a/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h b/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h index 0ebde22a37..5ef12df282 100644 --- a/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h +++ b/include/xrpl/tx/transactors/token/MPTokenIssuanceCreate.h @@ -10,7 +10,7 @@ struct MPTCreateArgs { std::optional priorBalance; AccountID const& account; - std::uint32_t sequence; + std::uint32_t sequence = 0; std::uint32_t flags = 0; std::optional maxAmount{}; std::optional assetScale{}; diff --git a/src/libxrpl/beast/core/CurrentThreadName.cpp b/src/libxrpl/beast/core/CurrentThreadName.cpp index 8e54a74e4d..6f22687dcc 100644 --- a/src/libxrpl/beast/core/CurrentThreadName.cpp +++ b/src/libxrpl/beast/core/CurrentThreadName.cpp @@ -95,11 +95,6 @@ setCurrentThreadNameImpl(std::string_view name) { std::cerr << "WARNING: Thread name \"" << name << "\" (length " << name.size() << ") exceeds maximum of " << maxThreadNameLength << " characters on Linux.\n"; - - XRPL_ASSERT( - false, - "beast::detail::setCurrentThreadNameImpl : Thread name exceeds " - "maximum length for Linux"); } #endif } diff --git a/src/libxrpl/beast/utility/beast_PropertyStream.cpp b/src/libxrpl/beast/utility/beast_PropertyStream.cpp index 9cf4f23065..662d763ce0 100644 --- a/src/libxrpl/beast/utility/beast_PropertyStream.cpp +++ b/src/libxrpl/beast/utility/beast_PropertyStream.cpp @@ -151,8 +151,7 @@ PropertyStream::Set::stream() const // //------------------------------------------------------------------------------ -PropertyStream::Source::Source(std::string const& name) - : m_name(name), item_(this), parent_(nullptr) +PropertyStream::Source::Source(std::string const& name) : m_name(name), item_(this) { } diff --git a/src/libxrpl/core/detail/JobQueue.cpp b/src/libxrpl/core/detail/JobQueue.cpp index 434ab146bd..ddfc42c97e 100644 --- a/src/libxrpl/core/detail/JobQueue.cpp +++ b/src/libxrpl/core/detail/JobQueue.cpp @@ -13,9 +13,7 @@ JobQueue::JobQueue( Logs& logs, perf::PerfLog& perfLog) : m_journal(journal) - , m_lastJob(0) , m_invalidJobData(JobTypes::instance().getInvalid(), collector, logs) - , m_processCount(0) , m_workers(*this, &perfLog, "JobQueue", threadCount) , perfLog_(perfLog) , m_collector(collector) diff --git a/src/libxrpl/core/detail/LoadMonitor.cpp b/src/libxrpl/core/detail/LoadMonitor.cpp index 967947ee17..e613717ed8 100644 --- a/src/libxrpl/core/detail/LoadMonitor.cpp +++ b/src/libxrpl/core/detail/LoadMonitor.cpp @@ -15,16 +15,14 @@ TODO //------------------------------------------------------------------------------ -LoadMonitor::Stats::Stats() : count(0), latencyAvg(0), latencyPeak(0), isOverloaded(false) +LoadMonitor::Stats::Stats() : latencyAvg(0), latencyPeak(0) { } //------------------------------------------------------------------------------ LoadMonitor::LoadMonitor(beast::Journal j) - : mCounts(0) - , mLatencyEvents(0) - , mLatencyMSAvg(0) + : mLatencyMSAvg(0) , mLatencyMSPeak(0) , mTargetLatencyAvg(0) , mTargetLatencyPk(0) diff --git a/src/libxrpl/core/detail/Workers.cpp b/src/libxrpl/core/detail/Workers.cpp index a654d20280..ed9d09d1e8 100644 --- a/src/libxrpl/core/detail/Workers.cpp +++ b/src/libxrpl/core/detail/Workers.cpp @@ -12,9 +12,7 @@ Workers::Workers( : m_callback(callback) , perfLog_(perfLog) , m_threadNames(threadNames) - , m_allPaused(true) , m_semaphore(0) - , m_numberOfThreads(0) , m_activeCount(0) , m_pauseCount(0) , m_runningTaskCount(0) @@ -138,11 +136,8 @@ Workers::deleteWorkers(beast::LockFreeStack& stack) //------------------------------------------------------------------------------ Workers::Worker::Worker(Workers& workers, std::string const& threadName, int const instance) - : m_workers{workers} - , threadName_{threadName} - , instance_{instance} - , wakeCount_{0} - , shouldExit_{false} + : m_workers{workers}, threadName_{threadName}, instance_{instance} + { thread_ = std::thread{&Workers::Worker::run, this}; } diff --git a/src/libxrpl/json/json_writer.cpp b/src/libxrpl/json/json_writer.cpp index 2d0fc1c288..150a7fe2e5 100644 --- a/src/libxrpl/json/json_writer.cpp +++ b/src/libxrpl/json/json_writer.cpp @@ -252,7 +252,7 @@ FastWriter::writeValue(Value const& value) // Class StyledWriter // ////////////////////////////////////////////////////////////////// -StyledWriter::StyledWriter() : rightMargin_(74), indentSize_(3) +StyledWriter::StyledWriter() { } @@ -486,8 +486,7 @@ StyledWriter::unindent() // Class StyledStreamWriter // ////////////////////////////////////////////////////////////////// -StyledStreamWriter::StyledStreamWriter(std::string indentation) - : document_(nullptr), rightMargin_(74), indentation_(indentation) +StyledStreamWriter::StyledStreamWriter(std::string indentation) : indentation_(indentation) { } diff --git a/src/libxrpl/ledger/helpers/TokenHelpers.cpp b/src/libxrpl/ledger/helpers/TokenHelpers.cpp index ce4ba4002a..8d2b0d5fff 100644 --- a/src/libxrpl/ledger/helpers/TokenHelpers.cpp +++ b/src/libxrpl/ledger/helpers/TokenHelpers.cpp @@ -1155,57 +1155,87 @@ rippleSendMultiMPT( beast::Journal j, WaiveTransferFee waiveFee) { - // Safe to get MPT since rippleSendMultiMPT is only called by - // accountSendMultiMPT auto const& issuer = mptIssue.getIssuer(); auto const sle = view.read(keylet::mptIssuance(mptIssue.getMptID())); if (!sle) return tecOBJECT_NOT_FOUND; - // These may diverge + // For the issuer-as-sender case, track the running total to validate + // against MaximumAmount. The read-only SLE (view.read) is not updated + // by rippleCreditMPT, so a per-iteration SLE read would be stale. + // Use uint64_t, not STAmount, to keep MaximumAmount comparisons in exact + // integer arithmetic. STAmount implicitly converts to Number, whose + // small-scale mantissa (~16 digits) can lose precision for values near + // maxMPTokenAmount (19 digits). + std::uint64_t totalSendAmount{0}; + std::uint64_t const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount); + std::uint64_t const outstandingAmount = sle->getFieldU64(sfOutstandingAmount); + + // actual accumulates the total cost to the sender (includes transfer + // fees for third-party transit sends). takeFromSender accumulates only + // the transit portion that is debited to the issuer in bulk after the + // loop. They diverge when there are transfer fees. STAmount takeFromSender{mptIssue}; actual = takeFromSender; - for (auto const& r : receivers) + for (auto const& [receiverID, amt] : receivers) { - auto const& receiverID = r.first; - STAmount const amount{mptIssue, r.second}; + STAmount const amount{mptIssue, amt}; if (amount < beast::zero) - { return tecINTERNAL; // LCOV_EXCL_LINE - } - /* If we aren't sending anything or if the sender is the same as the - * receiver then we don't need to do anything. - */ - if (!amount || (senderID == receiverID)) + if (!amount || senderID == receiverID) continue; if (senderID == issuer || receiverID == issuer) { - // if sender is issuer, check that the new OutstandingAmount will - // not exceed MaximumAmount if (senderID == issuer) { XRPL_ASSERT_PARTS( takeFromSender == beast::zero, "xrpl::rippleSendMultiMPT", "sender == issuer, takeFromSender == zero"); - auto const sendAmount = amount.mpt().value(); - auto const maximumAmount = sle->at(~sfMaximumAmount).value_or(maxMPTokenAmount); - if (sendAmount > maximumAmount || - sle->getFieldU64(sfOutstandingAmount) > maximumAmount - sendAmount) - return tecPATH_DRY; + + std::uint64_t const sendAmount = amount.mpt().value(); + + if (view.rules().enabled(fixSecurity3_1_3)) + { + // Post-fixSecurity3_1_3: aggregate MaximumAmount + // check. WARNING: the order of conditions is + // critical — each guards the subtraction in the + // next against unsigned underflow. Do not reorder. + bool const exceedsMaximumAmount = + // This send alone exceeds the max cap + sendAmount > maximumAmount || + // The aggregate of all sends exceeds the max cap + totalSendAmount > maximumAmount - sendAmount || + // Outstanding + aggregate exceeds the max cap + outstandingAmount > maximumAmount - sendAmount - totalSendAmount; + + if (exceedsMaximumAmount) + return tecPATH_DRY; + totalSendAmount += sendAmount; + } + else + { + // Pre-fixSecurity3_1_3: per-iteration MaximumAmount + // check. Reads sfOutstandingAmount from a stale + // view.read() snapshot — incorrect for multi-destination + // sends but retained for ledger replay compatibility. + if (sendAmount > maximumAmount || + outstandingAmount > maximumAmount - sendAmount) + return tecPATH_DRY; + } } // Direct send: redeeming MPTs and/or sending own MPTs. if (auto const ter = rippleCreditMPT(view, senderID, receiverID, amount, j)) return ter; actual += amount; - // Do not add amount to takeFromSender, because rippleCreditMPT took - // it + // Do not add amount to takeFromSender, because rippleCreditMPT + // took it. continue; } diff --git a/src/libxrpl/nodestore/BatchWriter.cpp b/src/libxrpl/nodestore/BatchWriter.cpp index 50f4486f59..75b9a8dcde 100644 --- a/src/libxrpl/nodestore/BatchWriter.cpp +++ b/src/libxrpl/nodestore/BatchWriter.cpp @@ -4,7 +4,7 @@ namespace xrpl { namespace NodeStore { BatchWriter::BatchWriter(Callback& callback, Scheduler& scheduler) - : m_callback(callback), m_scheduler(scheduler), mWriteLoad(0), mWritePending(false) + : m_callback(callback), m_scheduler(scheduler) { mWriteSet.reserve(batchWritePreallocationSize); } diff --git a/src/libxrpl/protocol/STAmount.cpp b/src/libxrpl/protocol/STAmount.cpp index 0a0da2193e..cc935cff61 100644 --- a/src/libxrpl/protocol/STAmount.cpp +++ b/src/libxrpl/protocol/STAmount.cpp @@ -181,7 +181,7 @@ STAmount::STAmount(SerialIter& sit, SField const& name) : STBase(name) } STAmount::STAmount(SField const& name, std::int64_t mantissa) - : STBase(name), mAsset(xrpIssue()), mValue(0), mOffset(0), mIsNegative(false) + : STBase(name), mAsset(xrpIssue()), mOffset(0) { set(mantissa); } diff --git a/src/libxrpl/tx/paths/AMMOffer.cpp b/src/libxrpl/tx/paths/AMMOffer.cpp index 2168d80094..79071850c2 100644 --- a/src/libxrpl/tx/paths/AMMOffer.cpp +++ b/src/libxrpl/tx/paths/AMMOffer.cpp @@ -10,11 +10,8 @@ AMMOffer::AMMOffer( TAmounts const& amounts, TAmounts const& balances, Quality const& quality) - : ammLiquidity_(ammLiquidity) - , amounts_(amounts) - , balances_(balances) - , quality_(quality) - , consumed_(false) + : ammLiquidity_(ammLiquidity), amounts_(amounts), balances_(balances), quality_(quality) + { } diff --git a/src/libxrpl/tx/paths/BookTip.cpp b/src/libxrpl/tx/paths/BookTip.cpp index 5611a081c3..f9b700b7af 100644 --- a/src/libxrpl/tx/paths/BookTip.cpp +++ b/src/libxrpl/tx/paths/BookTip.cpp @@ -5,7 +5,7 @@ namespace xrpl { BookTip::BookTip(ApplyView& view, Book const& book) - : view_(view), m_valid(false), m_book(getBookBase(book)), m_end(getQualityNext(m_book)) + : view_(view), m_book(getBookBase(book)), m_end(getQualityNext(m_book)) { } diff --git a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp index e4c671b462..f6b8c98788 100644 --- a/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp +++ b/src/libxrpl/tx/transactors/vault/VaultWithdraw.cpp @@ -43,10 +43,10 @@ VaultWithdraw::preclaim(PreclaimContext const& ctx) if (!vault) return tecNO_ENTRY; - auto const assets = ctx.tx[sfAmount]; + auto const amount = ctx.tx[sfAmount]; auto const vaultAsset = vault->at(sfAsset); auto const vaultShare = vault->at(sfShareMPTID); - if (assets.asset() != vaultAsset && assets.asset() != vaultShare) + if (amount.asset() != vaultAsset && amount.asset() != vaultShare) return tecWRONG_ASSET; auto const& vaultAccount = vault->at(sfAccount); @@ -67,8 +67,53 @@ VaultWithdraw::preclaim(PreclaimContext const& ctx) // LCOV_EXCL_STOP } - if (auto const ret = canWithdraw(ctx.view, ctx.tx)) - return ret; + if (ctx.view.rules().enabled(fixSecurity3_1_3) && amount.asset() == vaultShare) + { + // Post-fixSecurity3_1_3: if the user specified shares, convert + // to the equivalent asset amount before checking withdrawal + // limits. Pre-amendment the limit check was skipped for + // share-denominated withdrawals. + auto const sleIssuance = ctx.view.read(keylet::mptIssuance(vaultShare)); + if (!sleIssuance) + { + // LCOV_EXCL_START + JLOG(ctx.j.error()) << "VaultWithdraw: missing issuance of vault shares."; + return tefINTERNAL; + // LCOV_EXCL_STOP + } + + try + { + auto const maybeAssets = sharesToAssetsWithdraw(vault, sleIssuance, amount); + if (!maybeAssets) + return tefINTERNAL; // LCOV_EXCL_LINE + + if (auto const ret = canWithdraw( + ctx.view, + account, + dstAcct, + *maybeAssets, + ctx.tx.isFieldPresent(sfDestinationTag))) + return ret; + } + catch (std::overflow_error const&) + { + // It's easy to hit this exception from Number with large enough Scale + // so we avoid spamming the log and only use debug here. + JLOG(ctx.j.debug()) // + << "VaultWithdraw: overflow error with" + << " scale=" << (int)vault->at(sfScale) // + << ", assetsTotal=" << vault->at(sfAssetsTotal) + << ", sharesTotal=" << sleIssuance->at(sfOutstandingAmount) + << ", amount=" << amount.value(); + return tecPATH_DRY; + } + } + else + { + if (auto const ret = canWithdraw(ctx.view, ctx.tx)) + return ret; + } // If sending to Account (i.e. not a transfer), we will also create (only // if authorized) a trust line or MPToken as needed, in doApply(). diff --git a/src/test/app/MPToken_test.cpp b/src/test/app/MPToken_test.cpp index 6e94ffd9bc..81fcec4b7a 100644 --- a/src/test/app/MPToken_test.cpp +++ b/src/test/app/MPToken_test.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -3272,6 +3273,123 @@ class MPToken_test : public beast::unit_test::suite mptAlice.claw(alice, bob, 1, tecNO_PERMISSION); } + void + testMultiSendMaximumAmount(FeatureBitset features) + { + // Verify that rippleSendMultiMPT correctly enforces MaximumAmount + // when the issuer sends to multiple receivers. Pre-fixSecurity3_1_3, + // a stale view.read() snapshot caused per-iteration checks to miss + // aggregate overflows. Post-fix, a running total is used instead. + testcase("Multi-send MaximumAmount enforcement"); + + using namespace test::jtx; + + Account const issuer("issuer"); + Account const alice("alice"); + Account const bob("bob"); + + std::uint64_t constexpr maxAmt = 150; + Env env{*this, features}; + + MPTTester mptt(env, issuer, {.holders = {alice, bob}}); + mptt.create({.maxAmt = maxAmt, .ownerCount = 1, .flags = tfMPTCanTransfer}); + mptt.authorize({.account = alice}); + mptt.authorize({.account = bob}); + + Asset const asset{MPTIssue{mptt.issuanceID()}}; + + // Each test case creates a fresh ApplyView and calls + // accountSendMulti from the issuer to the given receivers. + auto const runTest = [&](MultiplePaymentDestinations const& receivers, + TER expectedTer, + std::optional expectedOutstanding, + std::string const& label) { + ApplyViewImpl av(&*env.current(), tapNONE); + auto const ter = + accountSendMulti(av, issuer.id(), asset, receivers, env.app().getJournal("View")); + BEAST_EXPECTS(ter == expectedTer, label); + + // Only verify OutstandingAmount on success — on error the + // view may contain partial state and must be discarded. + if (expectedOutstanding) + { + auto const sle = av.peek(keylet::mptIssuance(mptt.issuanceID())); + if (!BEAST_EXPECT(sle)) + return; + BEAST_EXPECTS(sle->getFieldU64(sfOutstandingAmount) == *expectedOutstanding, label); + } + }; + + using R = MultiplePaymentDestinations; + + // Post-amendment: aggregate check with running total + runTest( + R{{alice.id(), 100}, {bob.id(), 100}}, + tecPATH_DRY, + std::nullopt, + "aggregate exceeds max"); + + runTest(R{{alice.id(), 75}, {bob.id(), 75}}, tesSUCCESS, maxAmt, "aggregate at boundary"); + + runTest(R{{alice.id(), 50}, {bob.id(), 50}}, tesSUCCESS, 100, "aggregate within limit"); + + runTest( + R{{alice.id(), 150}, {bob.id(), 0}}, + tesSUCCESS, + maxAmt, + "one receiver at max, other zero"); + + runTest( + R{{alice.id(), 151}, {bob.id(), 0}}, + tecPATH_DRY, + std::nullopt, + "one receiver exceeds max, other zero"); + + // Issue 50 tokens so outstandingAmount is nonzero, then verify + // the third condition: outstandingAmount > maximumAmount - sendAmount - totalSendAmount + mptt.pay(issuer, alice, 50); + env.close(); + + // maxAmt=150, outstanding=50, so 100 more available + runTest( + R{{alice.id(), 50}, {bob.id(), 50}}, + tesSUCCESS, + maxAmt, + "nonzero outstanding, aggregate at boundary"); + + runTest( + R{{alice.id(), 50}, {bob.id(), 51}}, + tecPATH_DRY, + std::nullopt, + "nonzero outstanding, aggregate exceeds max"); + + runTest( + R{{alice.id(), 100}, {bob.id(), 0}}, + tesSUCCESS, + maxAmt, + "nonzero outstanding, single send at remaining capacity"); + + runTest( + R{{alice.id(), 101}, {bob.id(), 0}}, + tecPATH_DRY, + std::nullopt, + "nonzero outstanding, single send exceeds remaining capacity"); + + // Pre-amendment: the stale per-iteration check allows each + // individual send (100 <= 150) even though the aggregate (200) + // exceeds MaximumAmount. Preserved for ledger replay. + { + // KNOWN BUG (pre-fixSecurity3_1_3): preserved for ledger replay only + env.disableFeature(fixSecurity3_1_3); + runTest( + R{{alice.id(), 100}, {bob.id(), 100}}, + tesSUCCESS, + 250, + "pre-amendment allows over-send"); + env.enableFeature(fixSecurity3_1_3); + } + } + public: void run() override @@ -3279,6 +3397,7 @@ public: using namespace test::jtx; FeatureBitset const all{testable_amendments()}; + testMultiSendMaximumAmount(all); // MPTokenIssuanceCreate testCreateValidation(all - featureSingleAssetVault); testCreateValidation(all - featurePermissionedDomains); diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index 50417305b4..823cf7aafd 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -5231,6 +5231,102 @@ class Vault_test : public beast::unit_test::suite } } + // Reproduction: canWithdraw IOU limit check bypassed when + // withdrawal amount is specified in shares (MPT) rather than in assets. + void + testBug6_LimitBypassWithShares() + { + using namespace test::jtx; + testcase("Bug6 - limit bypass with share-denominated withdrawal"); + + auto const allAmendments = testable_amendments() | featureSingleAssetVault; + + for (auto const& features : {allAmendments, allAmendments - fixSecurity3_1_3}) + { + bool const withFix = features[fixSecurity3_1_3]; + + Env env{*this, features}; + Account const owner{"owner"}; + Account const issuer{"issuer"}; + Account const depositor{"depositor"}; + Account const charlie{"charlie"}; + Vault const vault{env}; + + env.fund(XRP(1000), issuer, owner, depositor, charlie); + env(fset(issuer, asfAllowTrustLineClawback)); + env.close(); + + PrettyAsset const asset = issuer["IOU"]; + env.trust(asset(1000), owner); + env.trust(asset(1000), depositor); + env(pay(issuer, owner, asset(200))); + env(pay(issuer, depositor, asset(200))); + env.close(); + + // Charlie gets a LOW trustline limit of 5 + env.trust(asset(5), charlie); + env.close(); + + auto const [tx, keylet] = vault.create({.owner = owner, .asset = asset}); + env(tx); + env.close(); + + auto const depositTx = + vault.deposit({.depositor = depositor, .id = keylet.key, .amount = asset(100)}); + env(depositTx); + env.close(); + + // Get the share MPT info + auto const vaultSle = env.le(keylet); + if (!BEAST_EXPECT(vaultSle)) + return; + auto const mptIssuanceID = vaultSle->at(sfShareMPTID); + MPTIssue const shares(mptIssuanceID); + PrettyAsset const share(shares); + + // CONTROL: Withdraw 10 IOU (asset-denominated) to charlie. + // Charlie's limit is 5, so this should be rejected with tecNO_LINE + // regardless of the amendment. + { + auto withdrawTx = + vault.withdraw({.depositor = depositor, .id = keylet.key, .amount = asset(10)}); + withdrawTx[sfDestination] = charlie.human(); + env(withdrawTx, ter{tecNO_LINE}); + env.close(); + } + auto const charlieBalanceBefore = env.balance(charlie, asset.raw().get()); + + // Withdraw the equivalent amount in shares to charlie. + // Post-fix: rejected (tecNO_LINE) because the share amount is + // converted to assets and the trustline limit is checked. + // Pre-fix: succeeds (tesSUCCESS) because the limit check was + // skipped for share-denominated withdrawals. + { + auto withdrawTx = vault.withdraw( + {.depositor = depositor, + .id = keylet.key, + .amount = STAmount(share, 10'000'000)}); + withdrawTx[sfDestination] = charlie.human(); + env(withdrawTx, ter{withFix ? TER{tecNO_LINE} : TER{tesSUCCESS}}); + env.close(); + + auto const charlieBalanceAfter = env.balance(charlie, asset.raw().get()); + if (withFix) + { + // Post-fix: charlie's balance is unchanged — the withdrawal + // was correctly rejected despite being share-denominated. + BEAST_EXPECT(charlieBalanceAfter == charlieBalanceBefore); + } + else + { + // Pre-fix: charlie received the assets, bypassing the + // trustline limit. + BEAST_EXPECT(charlieBalanceAfter > charlieBalanceBefore); + } + } + } + } + public: void run() override @@ -5251,6 +5347,7 @@ public: testVaultClawbackBurnShares(); testVaultClawbackAssets(); testAssetsMaximum(); + testBug6_LimitBypassWithShares(); } }; diff --git a/src/test/csf/Peer.h b/src/test/csf/Peer.h index 94b2c74a0b..fb1238990e 100644 --- a/src/test/csf/Peer.h +++ b/src/test/csf/Peer.h @@ -231,7 +231,7 @@ struct Peer // Number of proposers in the prior round std::size_t prevProposers = 0; // Duration of prior round - std::chrono::milliseconds prevRoundTime; + std::chrono::milliseconds prevRoundTime{}; // Quorum of validations needed for a ledger to be fully validated // TODO: Use the logic in ValidatorList to set this dynamically @@ -501,16 +501,10 @@ struct Peer NetClock::duration const& closeResolution, ConsensusCloseTimes const& rawCloseTimes, ConsensusMode const& mode, - Json::Value&& consensusJson) + Json::Value const& consensusJson) { onAccept( - result, - prevLedger, - closeResolution, - rawCloseTimes, - mode, - std::move(consensusJson), - validating()); + result, prevLedger, closeResolution, rawCloseTimes, mode, consensusJson, validating()); } void @@ -520,10 +514,10 @@ struct Peer NetClock::duration const& closeResolution, ConsensusCloseTimes const& rawCloseTimes, ConsensusMode const& mode, - Json::Value&& consensusJson, + Json::Value const& consensusJson, bool const validating) { - schedule(delays.ledgerAccept, [=, this]() { + schedule(delays.ledgerAccept, [mode, result, prevLedger, closeResolution, this]() { bool const proposing = mode == ConsensusMode::proposing; bool const consensusFail = result.state == ConsensusState::MovedOn; diff --git a/src/test/csf/Tx.h b/src/test/csf/Tx.h index f919b650db..81393f7bda 100644 --- a/src/test/csf/Tx.h +++ b/src/test/csf/Tx.h @@ -100,7 +100,8 @@ public: { } - TxSet(MutableTxSet&& m) : txs_{std::move(m.txs_)}, id_{calcID(txs_)} + TxSet(MutableTxSet&& m) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) + : txs_{m.txs_}, id_{calcID(txs_)} { } @@ -161,7 +162,7 @@ private: TxSetType txs_; //! The unique ID of this tx set - ID id_; + ID id_{}; }; //------------------------------------------------------------------------------ diff --git a/src/test/jtx/Env_ss.h b/src/test/jtx/Env_ss.h index 9db96d5907..d6f5fd1a29 100644 --- a/src/test/jtx/Env_ss.h +++ b/src/test/jtx/Env_ss.h @@ -24,7 +24,7 @@ private: operator=(SignSubmitRunner&&) = delete; SignSubmitRunner(Env& env, JTx&& jt, std::source_location loc) - : env_(env), jt_(jt), loc_(loc) + : env_(env), jt_(std::move(jt)), loc_(loc) { } diff --git a/src/test/jtx/Oracle.h b/src/test/jtx/Oracle.h index 8efd17802c..7924d278e5 100644 --- a/src/test/jtx/Oracle.h +++ b/src/test/jtx/Oracle.h @@ -99,7 +99,7 @@ private: static inline std::uint32_t fee = 0; Env& env_; AccountID owner_; - std::uint32_t documentID_; + std::uint32_t documentID_{}; private: void diff --git a/src/test/jtx/flags.h b/src/test/jtx/flags.h index 3dde1fa414..a203f1461e 100644 --- a/src/test/jtx/flags.h +++ b/src/test/jtx/flags.h @@ -12,7 +12,7 @@ namespace detail { class flags_helper { protected: - std::uint32_t mask_; + std::uint32_t mask_{0}; private: void @@ -79,7 +79,7 @@ private: protected: template - flags_helper(Args... args) : mask_(0) + flags_helper(Args... args) { set_args(args...); } diff --git a/src/test/jtx/impl/Oracle.cpp b/src/test/jtx/impl/Oracle.cpp index 0c9ddc8f0d..d48432e8e4 100644 --- a/src/test/jtx/impl/Oracle.cpp +++ b/src/test/jtx/impl/Oracle.cpp @@ -12,7 +12,7 @@ namespace test { namespace jtx { namespace oracle { -Oracle::Oracle(Env& env, CreateArg const& arg, bool submit) : env_(env), documentID_{} +Oracle::Oracle(Env& env, CreateArg const& arg, bool submit) : env_(env) { // LastUpdateTime is checked to be in range // {close-maxLastUpdateTimeDelta, close+maxLastUpdateTimeDelta}. diff --git a/src/test/jtx/impl/quality2.cpp b/src/test/jtx/impl/quality2.cpp index c202592b9d..9da366d4c2 100644 --- a/src/test/jtx/impl/quality2.cpp +++ b/src/test/jtx/impl/quality2.cpp @@ -8,12 +8,14 @@ namespace test { namespace jtx { qualityInPercent::qualityInPercent(double percent) + // NOLINTNEXTLINE(cppcoreguidelines-use-default-member-init) : qIn_(static_cast((percent / 100) * QUALITY_ONE)) { assert(percent <= 400 && percent >= 0); } qualityOutPercent::qualityOutPercent(double percent) + // NOLINTNEXTLINE(cppcoreguidelines-use-default-member-init) : qOut_(static_cast((percent / 100) * QUALITY_ONE)) { assert(percent <= 400 && percent >= 0); diff --git a/src/test/jtx/impl/xchain_bridge.cpp b/src/test/jtx/impl/xchain_bridge.cpp index 19c1b7fab5..72d932463f 100644 --- a/src/test/jtx/impl/xchain_bridge.cpp +++ b/src/test/jtx/impl/xchain_bridge.cpp @@ -413,7 +413,6 @@ XChainBridgeObjects::XChainBridgeObjects() } return r; }()) - , quorum(UT_XCHAIN_DEFAULT_QUORUM) , reward(XRP(1)) , split_reward_quorum(divide(reward, STAmount(UT_XCHAIN_DEFAULT_QUORUM), reward.issue())) , split_reward_everyone(divide(reward, STAmount(UT_XCHAIN_DEFAULT_NUM_SIGNERS), reward.issue())) diff --git a/src/test/jtx/quality.h b/src/test/jtx/quality.h index 34c960224f..2da83eeef5 100644 --- a/src/test/jtx/quality.h +++ b/src/test/jtx/quality.h @@ -25,7 +25,7 @@ public: class qualityInPercent { private: - std::uint32_t qIn_; + std::uint32_t qIn_; // NOLINT(cppcoreguidelines-use-default-member-init) public: explicit qualityInPercent(double percent); @@ -53,7 +53,7 @@ public: class qualityOutPercent { private: - std::uint32_t qOut_; + std::uint32_t qOut_; // NOLINT(cppcoreguidelines-use-default-member-init) public: explicit qualityOutPercent(double percent); diff --git a/src/test/jtx/xchain_bridge.h b/src/test/jtx/xchain_bridge.h index 698426c59c..1270d03ed6 100644 --- a/src/test/jtx/xchain_bridge.h +++ b/src/test/jtx/xchain_bridge.h @@ -170,7 +170,7 @@ struct XChainBridgeObjects std::vector const alt_signers; std::vector const payee; std::vector const payees; - std::uint32_t const quorum; + std::uint32_t const quorum{UT_XCHAIN_DEFAULT_QUORUM}; STAmount const reward; // 1 xrp STAmount const split_reward_quorum; // 250,000 drops diff --git a/src/xrpld/app/ledger/InboundLedger.h b/src/xrpld/app/ledger/InboundLedger.h index a2658d1058..30ef009ce9 100644 --- a/src/xrpld/app/ledger/InboundLedger.h +++ b/src/xrpld/app/ledger/InboundLedger.h @@ -153,11 +153,11 @@ private: clock_type::time_point mLastAction; std::shared_ptr mLedger; - bool mHaveHeader; - bool mHaveState; - bool mHaveTransactions; - bool mSignaled; - bool mByHash; + bool mHaveHeader{false}; + bool mHaveState{false}; + bool mHaveTransactions{false}; + bool mSignaled{false}; + bool mByHash{true}; std::uint32_t mSeq; Reason const mReason; @@ -169,7 +169,7 @@ private: std::mutex mReceivedDataLock; std::vector, std::shared_ptr>> mReceivedData; - bool mReceiveDispatched; + bool mReceiveDispatched{false}; std::unique_ptr mPeerSet; }; diff --git a/src/xrpld/app/ledger/OrderBookDBImpl.cpp b/src/xrpld/app/ledger/OrderBookDBImpl.cpp index 229110fa04..ffd8499aba 100644 --- a/src/xrpld/app/ledger/OrderBookDBImpl.cpp +++ b/src/xrpld/app/ledger/OrderBookDBImpl.cpp @@ -56,8 +56,10 @@ OrderBookDBImpl::setup(std::shared_ptr const& ledger) } else { + // Shorten job name to fit Linux 15-char thread name limit with "j:" prefix + // "OB" + seq (max 9 digits) = 11 chars, + "j:" = 13 chars (fits in 15) registry_.get().getJobQueue().addJob( - jtUPDATE_PF, "OBUpd" + std::to_string(ledger->seq()), [this, ledger]() { + jtUPDATE_PF, "OB" + std::to_string(ledger->seq() % 1000000000), [this, ledger]() { update(ledger); }); } diff --git a/src/xrpld/app/ledger/detail/InboundLedger.cpp b/src/xrpld/app/ledger/detail/InboundLedger.cpp index 0b39189102..899abb2323 100644 --- a/src/xrpld/app/ledger/detail/InboundLedger.cpp +++ b/src/xrpld/app/ledger/detail/InboundLedger.cpp @@ -68,14 +68,8 @@ InboundLedger::InboundLedger( {jtLEDGER_DATA, "InboundLedger", 5}, app.getJournal("InboundLedger")) , m_clock(clock) - , mHaveHeader(false) - , mHaveState(false) - , mHaveTransactions(false) - , mSignaled(false) - , mByHash(true) , mSeq(seq) , mReason(reason) - , mReceiveDispatched(false) , mPeerSet(std::move(peerSet)) { JLOG(journal_.trace()) << "Acquiring ledger " << hash_; diff --git a/src/xrpld/app/ledger/detail/TimeoutCounter.cpp b/src/xrpld/app/ledger/detail/TimeoutCounter.cpp index f329665031..216771e60d 100644 --- a/src/xrpld/app/ledger/detail/TimeoutCounter.cpp +++ b/src/xrpld/app/ledger/detail/TimeoutCounter.cpp @@ -15,10 +15,6 @@ TimeoutCounter::TimeoutCounter( : app_(app) , journal_(journal) , hash_(hash) - , timeouts_(0) - , complete_(false) - , failed_(false) - , progress_(false) , timerInterval_(interval) , queueJobParameter_(std::move(jobParameter)) , timer_(app_.getIOContext()) diff --git a/src/xrpld/app/ledger/detail/TimeoutCounter.h b/src/xrpld/app/ledger/detail/TimeoutCounter.h index 5f5ccb2f43..a7e4c043be 100644 --- a/src/xrpld/app/ledger/detail/TimeoutCounter.h +++ b/src/xrpld/app/ledger/detail/TimeoutCounter.h @@ -59,6 +59,8 @@ public: virtual void cancel(); + virtual ~TimeoutCounter() = default; + protected: using ScopedLockType = std::unique_lock; @@ -76,8 +78,6 @@ protected: QueueJobParameter&& jobParameter, beast::Journal journal); - virtual ~TimeoutCounter() = default; - /** Schedule a call to queueJob() after mTimerInterval. */ void setTimer(ScopedLockType&); @@ -109,11 +109,11 @@ protected: /** The hash of the object (in practice, always a ledger) we are trying to * fetch. */ uint256 const hash_; - int timeouts_; - bool complete_; - bool failed_; + int timeouts_{0}; + bool complete_{false}; + bool failed_{false}; /** Whether forward progress has been made. */ - bool progress_; + bool progress_{false}; /** The minimum time to wait between calls to execute(). */ std::chrono::milliseconds timerInterval_; diff --git a/src/xrpld/app/ledger/detail/TransactionAcquire.cpp b/src/xrpld/app/ledger/detail/TransactionAcquire.cpp index f4be5777b0..6bfb09bad6 100644 --- a/src/xrpld/app/ledger/detail/TransactionAcquire.cpp +++ b/src/xrpld/app/ledger/detail/TransactionAcquire.cpp @@ -31,7 +31,6 @@ TransactionAcquire::TransactionAcquire( TX_ACQUIRE_TIMEOUT, {jtTXN_DATA, "TxAcq", {}}, app.getJournal("TransactionAcquire")) - , mHaveRoot(false) , mPeerSet(std::move(peerSet)) { mMap = std::make_shared(SHAMapType::TRANSACTION, hash, app_.getNodeFamily()); diff --git a/src/xrpld/app/ledger/detail/TransactionAcquire.h b/src/xrpld/app/ledger/detail/TransactionAcquire.h index dbd1ad6059..c6b5c19774 100644 --- a/src/xrpld/app/ledger/detail/TransactionAcquire.h +++ b/src/xrpld/app/ledger/detail/TransactionAcquire.h @@ -31,7 +31,7 @@ public: private: std::shared_ptr mMap; - bool mHaveRoot; + bool mHaveRoot{false}; std::unique_ptr mPeerSet; void diff --git a/src/xrpld/app/misc/TxQ.h b/src/xrpld/app/misc/TxQ.h index 7c441867ea..772d51b959 100644 --- a/src/xrpld/app/misc/TxQ.h +++ b/src/xrpld/app/misc/TxQ.h @@ -146,23 +146,23 @@ public: explicit Metrics() = default; /// Number of transactions in the queue - std::size_t txCount; + std::size_t txCount{}; /// Max transactions currently allowed in queue std::optional txQMaxSize; /// Number of transactions currently in the open ledger - std::size_t txInLedger; + std::size_t txInLedger{}; /// Number of transactions expected per ledger - std::size_t txPerLedger; + std::size_t txPerLedger{}; /// Reference transaction fee level - FeeLevel64 referenceFeeLevel; + FeeLevel64 referenceFeeLevel{}; /// Minimum fee level for a transaction to be considered for /// the open ledger or the queue - FeeLevel64 minProcessingFeeLevel; + FeeLevel64 minProcessingFeeLevel{}; /// Median fee level of the last ledger - FeeLevel64 medFeeLevel; + FeeLevel64 medFeeLevel{}; /// Minimum fee level to get into the current open ledger, /// bypassing the queue - FeeLevel64 openLedgerFeeLevel; + FeeLevel64 openLedgerFeeLevel{}; }; /** @@ -511,7 +511,7 @@ private: their `retriesRemaining` forced down as part of the penalty. */ - int retriesRemaining; + int retriesRemaining{retriesAllowed}; /// Flags provided to `apply`. If the transaction is later /// attempted with different flags, it will need to be /// `preflight`ed again. diff --git a/src/xrpld/app/misc/ValidatorList.h b/src/xrpld/app/misc/ValidatorList.h index c10561b6e7..9b7670a482 100644 --- a/src/xrpld/app/misc/ValidatorList.h +++ b/src/xrpld/app/misc/ValidatorList.h @@ -157,7 +157,7 @@ class ValidatorList std::vector list; std::vector manifests; - std::size_t sequence; + std::size_t sequence{}; TimeKeeper::time_point validFrom; TimeKeeper::time_point validUntil; std::string siteUri; @@ -173,7 +173,7 @@ class ValidatorList struct PublisherListCollection { - PublisherStatus status; + PublisherStatus status = PublisherStatus::unavailable; /* The `current` VL is the one which 1. Has the largest sequence number that @@ -223,7 +223,7 @@ class ValidatorList hash_set trustedMasterKeys_; // Minimum number of lists on which a trusted validator must appear on - std::size_t listThreshold_; + std::size_t listThreshold_{1}; // The current list of trusted signing keys. For those validators using // a manifest, the signing key is the ephemeral key. For the ones using diff --git a/src/xrpld/app/misc/ValidatorSite.h b/src/xrpld/app/misc/ValidatorSite.h index 9d9031b9a2..270df6f9f0 100644 --- a/src/xrpld/app/misc/ValidatorSite.h +++ b/src/xrpld/app/misc/ValidatorSite.h @@ -85,12 +85,12 @@ private: /// when we've gotten a temp redirect std::shared_ptr activeResource; - unsigned short redirCount; + unsigned short redirCount{0}; std::chrono::minutes refreshInterval; clock_type::time_point nextRefresh; std::optional lastRefreshStatus; endpoint_type lastRequestEndpoint; - bool lastRequestSuccessful; + bool lastRequestSuccessful{false}; }; Application& app_; diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index 8f8f14d5a7..3494a4b7bd 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -257,7 +257,6 @@ TxQ::MaybeTx::MaybeTx( , account(txn_->getAccountID(sfAccount)) , lastValid(getLastLedgerSequence(*txn_)) , seqProxy(txn_->getSeqProxy()) - , retriesRemaining(retriesAllowed) , flags(flags_) , pfResult(pfResult_) { diff --git a/src/xrpld/app/misc/detail/ValidatorList.cpp b/src/xrpld/app/misc/detail/ValidatorList.cpp index 5543d0029f..bed91afc44 100644 --- a/src/xrpld/app/misc/detail/ValidatorList.cpp +++ b/src/xrpld/app/misc/detail/ValidatorList.cpp @@ -109,7 +109,7 @@ ValidatorList::ValidatorList( , j_(j) , quorum_(minimumQuorum.value_or(1)) // Genesis ledger quorum , minimumQuorum_(minimumQuorum) - , listThreshold_(1) + { } diff --git a/src/xrpld/app/misc/detail/ValidatorSite.cpp b/src/xrpld/app/misc/detail/ValidatorSite.cpp index f9b6553fc2..a4623e7acc 100644 --- a/src/xrpld/app/misc/detail/ValidatorSite.cpp +++ b/src/xrpld/app/misc/detail/ValidatorSite.cpp @@ -60,10 +60,9 @@ ValidatorSite::Site::Resource::Resource(std::string uri_) : uri{std::move(uri_)} ValidatorSite::Site::Site(std::string uri) : loadedResource{std::make_shared(std::move(uri))} , startingResource{loadedResource} - , redirCount{0} , refreshInterval{default_refresh_interval} , nextRefresh{clock_type::now()} - , lastRequestSuccessful{false} + { } diff --git a/src/xrpld/consensus/Consensus.h b/src/xrpld/consensus/Consensus.h index d5441dc1c4..142b1a01f0 100644 --- a/src/xrpld/consensus/Consensus.h +++ b/src/xrpld/consensus/Consensus.h @@ -554,7 +554,7 @@ private: ConsensusParms::AvalancheState closeTimeAvalancheState_ = ConsensusParms::init; // Time it took for the last consensus round to converge - std::chrono::milliseconds prevRoundTime_; + std::chrono::milliseconds prevRoundTime_{}; //------------------------------------------------------------------------- // Network time measurements of consensus progress diff --git a/src/xrpld/consensus/ConsensusTypes.h b/src/xrpld/consensus/ConsensusTypes.h index 2331c9dfbf..8aba48f34e 100644 --- a/src/xrpld/consensus/ConsensusTypes.h +++ b/src/xrpld/consensus/ConsensusTypes.h @@ -117,7 +117,7 @@ class ConsensusTimer { using time_point = std::chrono::steady_clock::time_point; time_point start_; - std::chrono::milliseconds dur_; + std::chrono::milliseconds dur_{}; public: std::chrono::milliseconds diff --git a/src/xrpld/consensus/DisputedTx.h b/src/xrpld/consensus/DisputedTx.h index 0657ad7ac2..e8304f4242 100644 --- a/src/xrpld/consensus/DisputedTx.h +++ b/src/xrpld/consensus/DisputedTx.h @@ -39,7 +39,7 @@ public: @param j Journal for debugging */ DisputedTx(Tx_t const& tx, bool ourVote, std::size_t numPeers, beast::Journal j) - : yays_(0), nays_(0), ourVote_(ourVote), tx_(tx), j_(j) + : ourVote_(ourVote), tx_(tx), j_(j) { votes_.reserve(numPeers); } @@ -173,8 +173,8 @@ public: getJson() const; private: - int yays_; //< Number of yes votes - int nays_; //< Number of no votes + int yays_{0}; //< Number of yes votes + int nays_{0}; //< Number of no votes bool ourVote_; //< Our vote (true is yes) Tx_t tx_; //< Transaction under dispute Map_t votes_; //< Map from NodeID to vote @@ -258,8 +258,8 @@ DisputedTx::updateVote(int percentTime, bool proposing, Consensu if (!ourVote_ && (yays_ == 0)) return false; - bool newPosition; - int weight; + bool newPosition = false; + int weight = 0; // When proposing, to prevent avalanche stalls, we increase the needed // weight slightly over time. We also need to ensure that the consensus has diff --git a/src/xrpld/consensus/LedgerTrie.h b/src/xrpld/consensus/LedgerTrie.h index 335c2cae7f..aecd105c07 100644 --- a/src/xrpld/consensus/LedgerTrie.h +++ b/src/xrpld/consensus/LedgerTrie.h @@ -72,7 +72,7 @@ public: XRPL_ASSERT(ledger_.seq() == start_, "xrpl::Span::Span : ledger is genesis"); } - Span(Ledger ledger) : start_{0}, end_{ledger.seq() + Seq{1}}, ledger_{std::move(ledger)} + Span(Ledger ledger) : end_{ledger.seq() + Seq{1}}, ledger_{std::move(ledger)} { } diff --git a/src/xrpld/overlay/Slot.h b/src/xrpld/overlay/Slot.h index 44a2e7afad..22e908ee99 100644 --- a/src/xrpld/overlay/Slot.h +++ b/src/xrpld/overlay/Slot.h @@ -98,9 +98,7 @@ private: * validator message source */ Slot(SquelchHandler const& handler, beast::Journal journal, uint16_t maxSelectedPeers) - : reachedThreshold_(0) - , lastSelected_(clock_type::now()) - , state_(SlotState::Counting) + : lastSelected_(clock_type::now()) , handler_(handler) , journal_(journal) , maxSelectedPeers_(maxSelectedPeers) @@ -220,14 +218,14 @@ private: std::unordered_set considered_; // number of peers that reached MAX_MESSAGE_THRESHOLD - std::uint16_t reachedThreshold_; + std::uint16_t reachedThreshold_{0}; // last time peers were selected, used to age the slot typename clock_type::time_point lastSelected_; - SlotState state_; // slot's state - SquelchHandler const& handler_; // squelch/unsquelch handler - beast::Journal const journal_; // logging + SlotState state_{SlotState::Counting}; // slot's state + SquelchHandler const& handler_; // squelch/unsquelch handler + beast::Journal const journal_; // logging // the maximum number of peers that should be selected as a validator // message source diff --git a/src/xrpld/overlay/detail/ConnectAttempt.h b/src/xrpld/overlay/detail/ConnectAttempt.h index a3b2fd5cce..520ebe277e 100644 --- a/src/xrpld/overlay/detail/ConnectAttempt.h +++ b/src/xrpld/overlay/detail/ConnectAttempt.h @@ -145,7 +145,7 @@ public: beast::Journal journal, OverlayImpl& overlay); - ~ConnectAttempt(); + virtual ~ConnectAttempt(); /** * @brief Stop the connection attempt diff --git a/src/xrpld/overlay/detail/OverlayImpl.cpp b/src/xrpld/overlay/detail/OverlayImpl.cpp index a1edfe4e33..2720c10140 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.cpp +++ b/src/xrpld/overlay/detail/OverlayImpl.cpp @@ -126,7 +126,6 @@ OverlayImpl::OverlayImpl( collector)) , m_resolver(resolver) , next_id_(1) - , timer_count_(0) , slots_(app, *this, app.config()) , m_stats( std::bind(&OverlayImpl::collect_metrics, this), diff --git a/src/xrpld/overlay/detail/OverlayImpl.h b/src/xrpld/overlay/detail/OverlayImpl.h index 26b5a77371..167d574188 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.h +++ b/src/xrpld/overlay/detail/OverlayImpl.h @@ -49,9 +49,8 @@ public: explicit Child(OverlayImpl& overlay); - virtual ~Child(); - public: + virtual ~Child(); virtual void stop() = 0; }; @@ -98,7 +97,7 @@ private: hash_map> ids_; Resolver& m_resolver; std::atomic next_id_; - int timer_count_; + int timer_count_{0}; std::atomic jqTransOverflow_{0}; std::atomic peerDisconnects_{0}; std::atomic peerDisconnectsCharges_{0}; diff --git a/src/xrpld/overlay/detail/ProtocolMessage.h b/src/xrpld/overlay/detail/ProtocolMessage.h index ac06b10292..41d42674ba 100644 --- a/src/xrpld/overlay/detail/ProtocolMessage.h +++ b/src/xrpld/overlay/detail/ProtocolMessage.h @@ -349,7 +349,7 @@ invokeProtocolMessage(Buffers const& buffers, Handler& handler, std::size_t& hin return result; } - bool success; + bool success = false; switch (header->message_type) { diff --git a/src/xrpld/peerfinder/PeerfinderManager.h b/src/xrpld/peerfinder/PeerfinderManager.h index b850a10975..57fde8a569 100644 --- a/src/xrpld/peerfinder/PeerfinderManager.h +++ b/src/xrpld/peerfinder/PeerfinderManager.h @@ -8,6 +8,8 @@ #include +#include "xrpld/peerfinder/detail/Tuning.h" + #include namespace xrpl { @@ -27,7 +29,7 @@ struct Config This includes both inbound and outbound, but does not include fixed peers. */ - std::size_t maxPeers; + std::size_t maxPeers{Tuning::defaultMaxPeers}; /** The number of automatic outbound connections to maintain. Outbound connections are only maintained if autoConnect @@ -39,25 +41,25 @@ struct Config Inbound connections are only maintained if wantIncoming is `true`. */ - std::size_t inPeers; + std::size_t inPeers{0}; /** `true` if we want our IP address kept private. */ bool peerPrivate = true; /** `true` if we want to accept incoming connections. */ - bool wantIncoming; + bool wantIncoming{true}; /** `true` if we want to establish connections automatically */ - bool autoConnect; + bool autoConnect{true}; /** The listening port number. */ - std::uint16_t listeningPort; + std::uint16_t listeningPort{0}; /** The set of features we advertise. */ std::string features; /** Limit how many incoming connections we allow per IP */ - int ipLimit; + int ipLimit{0}; //-------------------------------------------------------------------------- diff --git a/src/xrpld/peerfinder/detail/Bootcache.cpp b/src/xrpld/peerfinder/detail/Bootcache.cpp index d07ec444a4..580ebe0c53 100644 --- a/src/xrpld/peerfinder/detail/Bootcache.cpp +++ b/src/xrpld/peerfinder/detail/Bootcache.cpp @@ -10,11 +10,8 @@ namespace xrpl { namespace PeerFinder { Bootcache::Bootcache(Store& store, clock_type& clock, beast::Journal journal) - : m_store(store) - , m_clock(clock) - , m_journal(journal) - , m_whenUpdate(m_clock.now()) - , m_needsUpdate(false) + : m_store(store), m_clock(clock), m_journal(journal), m_whenUpdate(m_clock.now()) + { } diff --git a/src/xrpld/peerfinder/detail/Bootcache.h b/src/xrpld/peerfinder/detail/Bootcache.h index a4687d95f4..9ab0a878e8 100644 --- a/src/xrpld/peerfinder/detail/Bootcache.h +++ b/src/xrpld/peerfinder/detail/Bootcache.h @@ -97,7 +97,7 @@ private: clock_type::time_point m_whenUpdate; // Set to true when a database update is needed - bool m_needsUpdate; + bool m_needsUpdate{false}; public: static constexpr int staticValence = 32; diff --git a/src/xrpld/peerfinder/detail/Checker.h b/src/xrpld/peerfinder/detail/Checker.h index ccc395f053..21cc0f160e 100644 --- a/src/xrpld/peerfinder/detail/Checker.h +++ b/src/xrpld/peerfinder/detail/Checker.h @@ -44,7 +44,7 @@ private: async_op(Checker& owner, boost::asio::io_context& io_context, Handler&& handler); - ~async_op(); + virtual ~async_op(); void stop() override; @@ -108,7 +108,7 @@ template Checker::async_op::async_op( Checker& owner, boost::asio::io_context& io_context, - Handler&& handler) + Handler&& handler) // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) : checker_(owner), socket_(io_context), handler_(std::forward(handler)) { } diff --git a/src/xrpld/peerfinder/detail/Counts.h b/src/xrpld/peerfinder/detail/Counts.h index 26e02a4cb1..8d40b44300 100644 --- a/src/xrpld/peerfinder/detail/Counts.h +++ b/src/xrpld/peerfinder/detail/Counts.h @@ -13,24 +13,6 @@ namespace PeerFinder { class Counts { public: - Counts() - : m_attempts(0) - , m_active(0) - , m_in_max(0) - , m_in_active(0) - , m_out_max(0) - , m_out_active(0) - , m_fixed(0) - , m_fixed_active(0) - , m_reserved(0) - - , m_acceptCount(0) - , m_closingCount(0) - { - } - - //-------------------------------------------------------------------------- - /** Adds the slot state and properties to the slot counts. */ void add(Slot const& s) @@ -282,38 +264,38 @@ private: private: /** Outbound connection attempts. */ - int m_attempts; + int m_attempts{0}; /** Active connections, including fixed and reserved. */ - std::size_t m_active; + std::size_t m_active{0}; /** Total number of inbound slots. */ - std::size_t m_in_max; + std::size_t m_in_max{0}; /** Number of inbound slots assigned to active peers. */ - std::size_t m_in_active; + std::size_t m_in_active{0}; /** Maximum desired outbound slots. */ - std::size_t m_out_max; + std::size_t m_out_max{0}; /** Active outbound slots. */ - std::size_t m_out_active; + std::size_t m_out_active{0}; /** Fixed connections. */ - std::size_t m_fixed; + std::size_t m_fixed{0}; /** Active fixed connections. */ - std::size_t m_fixed_active; + std::size_t m_fixed_active{0}; /** Reserved connections. */ - std::size_t m_reserved; + std::size_t m_reserved{0}; // Number of inbound connections that are // not active or gracefully closing. - int m_acceptCount; + int m_acceptCount{0}; // Number of connections that are gracefully closing. - int m_closingCount; + int m_closingCount{0}; }; } // namespace PeerFinder diff --git a/src/xrpld/peerfinder/detail/Fixed.h b/src/xrpld/peerfinder/detail/Fixed.h index 75b5ed9062..8b67347e6a 100644 --- a/src/xrpld/peerfinder/detail/Fixed.h +++ b/src/xrpld/peerfinder/detail/Fixed.h @@ -9,7 +9,7 @@ namespace PeerFinder { class Fixed { public: - explicit Fixed(clock_type& clock) : m_when(clock.now()), m_failures(0) + explicit Fixed(clock_type& clock) : m_when(clock.now()) { } @@ -40,7 +40,7 @@ public: private: clock_type::time_point m_when; - std::size_t m_failures; + std::size_t m_failures{0}; }; } // namespace PeerFinder diff --git a/src/xrpld/peerfinder/detail/Livecache.h b/src/xrpld/peerfinder/detail/Livecache.h index bedfd6c9d6..ac435e1e24 100644 --- a/src/xrpld/peerfinder/detail/Livecache.h +++ b/src/xrpld/peerfinder/detail/Livecache.h @@ -327,7 +327,7 @@ public: friend class Livecache; lists_type m_lists; - Histogram m_hist; + Histogram m_hist{}; } hops; /** Returns `true` if the cache is empty. */ diff --git a/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp b/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp index a94dbdfbd9..6a158fbbab 100644 --- a/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp +++ b/src/xrpld/peerfinder/detail/PeerfinderConfig.cpp @@ -6,14 +6,8 @@ namespace xrpl { namespace PeerFinder { -Config::Config() - : maxPeers(Tuning::defaultMaxPeers) - , outPeers(calcOutPeers()) - , inPeers(0) - , wantIncoming(true) - , autoConnect(true) - , listeningPort(0) - , ipLimit(0) +Config::Config() : outPeers(calcOutPeers()) + { } diff --git a/src/xrpld/peerfinder/detail/Store.h b/src/xrpld/peerfinder/detail/Store.h index dab50b3ce0..390f80800a 100644 --- a/src/xrpld/peerfinder/detail/Store.h +++ b/src/xrpld/peerfinder/detail/Store.h @@ -22,7 +22,7 @@ public: explicit Entry() = default; beast::IP::Endpoint endpoint; - int valence; + int valence{}; }; virtual void save(std::vector const& v) = 0; diff --git a/src/xrpld/rpc/ServerHandler.h b/src/xrpld/rpc/ServerHandler.h index 74f59756b0..2ffdc9556b 100644 --- a/src/xrpld/rpc/ServerHandler.h +++ b/src/xrpld/rpc/ServerHandler.h @@ -147,7 +147,7 @@ public: Handoff onHandoff( Session& session, - http_request_type&& request, + http_request_type&& request, // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved) boost::asio::ip::tcp::endpoint const& remote_address) { return onHandoff(session, {}, std::forward(request), remote_address); diff --git a/src/xrpld/rpc/Status.h b/src/xrpld/rpc/Status.h index c8ec9d0472..418ad9ccae 100644 --- a/src/xrpld/rpc/Status.h +++ b/src/xrpld/rpc/Status.h @@ -29,7 +29,7 @@ public: // The enable_if allows only integers (not enums). Prevents enum narrowing. template ::value>> - Status(T code, Strings d = {}) : type_(Type::none), code_(code), messages_(std::move(d)) + Status(T code, Strings d = {}) : code_(code), messages_(std::move(d)) { } diff --git a/src/xrpld/rpc/detail/LegacyPathFind.cpp b/src/xrpld/rpc/detail/LegacyPathFind.cpp index b0fa07d676..5b5bcc540b 100644 --- a/src/xrpld/rpc/detail/LegacyPathFind.cpp +++ b/src/xrpld/rpc/detail/LegacyPathFind.cpp @@ -9,7 +9,7 @@ namespace xrpl { namespace RPC { -LegacyPathFind::LegacyPathFind(bool isAdmin, Application& app) : m_isOk(false) +LegacyPathFind::LegacyPathFind(bool isAdmin, Application& app) { if (isAdmin) { diff --git a/src/xrpld/rpc/detail/LegacyPathFind.h b/src/xrpld/rpc/detail/LegacyPathFind.h index 139075b53d..3d45bc9cfd 100644 --- a/src/xrpld/rpc/detail/LegacyPathFind.h +++ b/src/xrpld/rpc/detail/LegacyPathFind.h @@ -23,7 +23,7 @@ public: private: static std::atomic inProgress; - bool m_isOk; + bool m_isOk{false}; }; } // namespace RPC diff --git a/src/xrpld/rpc/detail/Pathfinder.h b/src/xrpld/rpc/detail/Pathfinder.h index 5eaafd3370..662d59ac9a 100644 --- a/src/xrpld/rpc/detail/Pathfinder.h +++ b/src/xrpld/rpc/detail/Pathfinder.h @@ -82,10 +82,10 @@ public: struct PathRank { - std::uint64_t quality; - std::uint64_t length; + std::uint64_t quality{}; + std::uint64_t length{}; STAmount liquidity; - int index; + int index{}; }; private: diff --git a/src/xrpld/rpc/handlers/LedgerEntryHelpers.h b/src/xrpld/rpc/handlers/LedgerEntryHelpers.h index 17207d81e8..9c5f0b2fcb 100644 --- a/src/xrpld/rpc/handlers/LedgerEntryHelpers.h +++ b/src/xrpld/rpc/handlers/LedgerEntryHelpers.h @@ -150,7 +150,7 @@ parse(Json::Value const& param) if (param.isString()) { - std::uint32_t v; + std::uint32_t v = 0; if (beast::lexicalCastChecked(v, param.asString())) return v; }