From 349ad4bd101d9f6ad04e1ae596d10e2961dfa09b Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Tue, 10 Nov 2026 18:26:00 +0000 Subject: [PATCH] Resolve native compiler warnings and bitset overflow Permit unused parameters and partial aggregate initializers in the GCC CI image. Fix bitset storage rounding at extreme sizes, make the existing noexcept cleanup allocation policy explicit, and retain targeted fixes for fallthrough, qualifiers, moves, signed comparisons, formatting, deprecated accessors, assignments, and account-query construction. Advance appbase to its merged unused-parameter cleanup. Add bitset and exception-policy regressions. Keep snapshot benchmark instructions on one line to avoid comment splicing. Change-Id: Ia4266943e5016ab11125860089cac3ddc917653f --- .cicd/platforms/gcc.Dockerfile | 5 +- contracts/tests/external_chain_simulator.hpp | 2 +- contracts/tests/kicker_tester.hpp | 4 +- contracts/tests/sysio.bond_tests.cpp | 4 -- contracts/tests/sysio.kicker_math_tests.cpp | 2 +- contracts/tests/sysio.kicker_tests.cpp | 2 +- contracts/tests/sysio.opreg_tests.cpp | 5 -- contracts/tests/sysio.swap_tests.cpp | 2 +- libraries/appbase | 2 +- .../include/sysio/chain/vote_processor.hpp | 2 +- .../webassembly/sys-vm-oc/code_cache.hpp | 4 +- .../chain/webassembly/sys-vm-oc/memory.hpp | 8 ++-- libraries/chain/wasm_sysio_validation.cpp | 1 + .../runtimes/sys-vm-oc/code_cache.cpp | 4 +- .../runtimes/sys-vm-oc/compile_trampoline.cpp | 2 +- .../runtimes/sys-vm-oc/gs_seg_helpers.c | 6 +-- .../webassembly/runtimes/sys-vm-oc/memory.cpp | 2 +- libraries/chaindb/test/undo_index.cpp | 3 +- libraries/libfc/include/fc/bitset.hpp | 6 ++- .../libfc/include/fc/exception/exception.hpp | 19 ++++++-- .../libfc/include/fc/io/json_relaxed.hpp | 1 + .../include/fc/io/random_access_file.hpp | 3 +- libraries/libfc/include/fc/safe.hpp | 2 + libraries/libfc/src/crypto/elliptic_em.cpp | 3 ++ .../src/crypto/ethereum/ethereum_utils.cpp | 1 + libraries/libfc/src/io/json.cpp | 6 +++ libraries/libfc/test/io/test_secure_file.cpp | 2 +- .../libfc/test/network/test_http_client.cpp | 6 +-- libraries/libfc/test/test_bitset.cpp | 26 ++++++++++ libraries/libfc/test/test_exception.cpp | 48 +++++++++++++++++++ .../src/client_config_loader.cpp | 1 - libraries/wasm-jit/Source/ThirdParty/dtoa.c | 11 +++-- plugins/chain_plugin/src/account_query_db.cpp | 5 +- plugins/chain_plugin/src/chain_plugin.cpp | 2 +- .../include/sysio/http_plugin/common.hpp | 2 +- .../sysio/net_plugin/buffer_factory.hpp | 14 +++--- .../test_outpost_ethereum_client_plugin.cpp | 4 -- .../trace_api_plugin/src/store_provider.cpp | 2 +- programs/clio/do_http_post_libcurl.cpp | 1 + programs/clio/main.cpp | 2 +- tests/trx_generator/trx_provider.cpp | 4 +- unittests/fork_db_tests.cpp | 4 +- unittests/snapshot_tests.cpp | 3 +- 43 files changed, 166 insertions(+), 72 deletions(-) diff --git a/.cicd/platforms/gcc.Dockerfile b/.cicd/platforms/gcc.Dockerfile index 6a1e9b3b7e..3ccd18edf5 100644 --- a/.cicd/platforms/gcc.Dockerfile +++ b/.cicd/platforms/gcc.Dockerfile @@ -59,8 +59,9 @@ COPY <<-EOF /extras.cmake set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "" FORCE) set(CMAKE_C_COMPILER "gcc-14" CACHE STRING "") set(CMAKE_CXX_COMPILER "g++-14" CACHE STRING "") - set(CMAKE_C_FLAGS "-Wall -Wextra -fdiagnostics-color=always" CACHE STRING "") - set(CMAKE_CXX_FLAGS "-Wall -Wextra -fdiagnostics-color=always" CACHE STRING "") + # Permit unused callback parameters and partial aggregates that use member defaults. + set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -fdiagnostics-color=always" CACHE STRING "") + set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -fdiagnostics-color=always" CACHE STRING "") EOF ENV SYSIO_PLATFORM_HAS_EXTRAS_CMAKE=1 diff --git a/contracts/tests/external_chain_simulator.hpp b/contracts/tests/external_chain_simulator.hpp index c262fa0115..bef790a96a 100644 --- a/contracts/tests/external_chain_simulator.hpp +++ b/contracts/tests/external_chain_simulator.hpp @@ -121,7 +121,7 @@ class chain { const auto [seen, fresh] = received_.emplace(id, message.SerializeAsString()); FC_ASSERT(fresh || seen->second == message.SerializeAsString(), "conflicting return replay"); if (paid_requests_.contains(id)) return false; - const auto amount = message.amount().amount(); + const auto amount = static_cast(message.amount().amount()); const auto [it, inserted] = pending_.emplace(id, amount); FC_ASSERT(inserted || it->second == amount, "conflicting return replay"); return settle(id); diff --git a/contracts/tests/kicker_tester.hpp b/contracts/tests/kicker_tester.hpp index 1489226e10..2d78e4fd78 100644 --- a/contracts/tests/kicker_tester.hpp +++ b/contracts/tests/kicker_tester.hpp @@ -5,6 +5,7 @@ #include "sysio_liq_tester.hpp" #include #include "kicker_test_reference.hpp" +#include namespace kicker_test_support { namespace math = sysio::kicker_math; using kicker_test_reference::wide; @@ -168,7 +169,8 @@ class kicker_tester : public sysio_liq_tester { const auto row = stat_row(sym); const auto observation = pool(sym); const auto span = (control->pending_block_time() - observation["price_time"].as()).count(); - if (span < configuration()[kicker::field::twap_window_sec].as_uint64() * math::micros_per_sec) return 0; + const auto window_us = configuration()[kicker::field::twap_window_sec].as_uint64() * math::micros_per_sec; + if (std::cmp_less(span, window_us)) return 0; const auto sized_supply = std::min(observation["supply_snapshot"].as_int64(), row["supply"].as().get_amount()); const wide accrued = wide(sized_supply) * observation["rate_bps"].as_uint64() * diff --git a/contracts/tests/sysio.bond_tests.cpp b/contracts/tests/sysio.bond_tests.cpp index 87d7ec8b7b..6fd6ed0adb 100644 --- a/contracts/tests/sysio.bond_tests.cpp +++ b/contracts/tests/sysio.bond_tests.cpp @@ -51,10 +51,6 @@ constexpr std::string_view nothing_msg = "nothing to claim"; constexpr std::string_view wire_no_yield_msg = "WIRE collateral earns no shadow yield"; constexpr std::string_view prune_limit_msg = "limit exceeds the most requests one prune examines"; -/// The memo of the one transfer that pays the issuer an INVALID request's bonds. -constexpr std::string_view forfeit_memo = "sysio.bond::forfeit"; -/// The memo of the transfer that pays a claim in the request's token. -constexpr std::string_view claim_memo = "sysio.bond::claim"; /// `request_state` names as the ABI renders them. constexpr std::string_view STATE_OPEN = "OPEN"; diff --git a/contracts/tests/sysio.kicker_math_tests.cpp b/contracts/tests/sysio.kicker_math_tests.cpp index 56aa6d78b4..d2f8f0fbdb 100644 --- a/contracts/tests/sysio.kicker_math_tests.cpp +++ b/contracts/tests/sysio.kicker_math_tests.cpp @@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE(spot_deviation_threshold) { BOOST_CHECK(!math::spot_deviates(0, 0, 1)); // Prices near 2^128 times 10,000 overflow 128 bits; the comparison stays exact against a wide oracle. const math::u128 top = ~math::u128{0}; - for (const auto [spot, twap, bps] : {std::tuple{top, top / 2, 10'000}, + for (const auto& [spot, twap, bps] : {std::tuple{top, top / 2, 10'000}, {top / 2, top, 5'000}, {top / 2, top, 4'999}, {top, top - 1, 1}}) { const wide gap = spot > twap ? wide(spot) - wide(twap) : wide(twap) - wide(spot); BOOST_CHECK_EQUAL(gap * 10'000 > wide(twap) * bps, math::spot_deviates(spot, twap, bps)); diff --git a/contracts/tests/sysio.kicker_tests.cpp b/contracts/tests/sysio.kicker_tests.cpp index d35802fed4..88a0ab8697 100644 --- a/contracts/tests/sysio.kicker_tests.cpp +++ b/contracts/tests/sysio.kicker_tests.cpp @@ -826,7 +826,7 @@ BOOST_AUTO_TEST_CASE(spot_deviation_threshold_is_inclusive) { BOOST_CHECK_EQUAL(0, t.paid()); BOOST_CHECK(after.deviation); BOOST_CHECK_EQUAL(gift, after.shortfall); - BOOST_CHECK(after.observed == t.control->head_block_time()); + BOOST_CHECK(after.observed == t.control->head().block_time()); // The clock and the observation are held. BOOST_CHECK(after.clock == observation.clock); BOOST_CHECK(after.price_time == observation.price_time); diff --git a/contracts/tests/sysio.opreg_tests.cpp b/contracts/tests/sysio.opreg_tests.cpp index 440ccfbd78..2700217919 100644 --- a/contracts/tests/sysio.opreg_tests.cpp +++ b/contracts/tests/sysio.opreg_tests.cpp @@ -125,8 +125,6 @@ constexpr auto kEligibilityBatchOperator = "batchop.a"_n; /// Producer account used by focused eligibility tests. constexpr auto kEligibilityProducer = "producer.a"_n; -/// Ethereum chain and token codename used by focused collateral tests. -constexpr std::string_view kEthCodename = "ETH"; /// Native WIRE chain and token codename used by focused collateral tests. constexpr std::string_view kWireCodename = "WIRE"; @@ -314,9 +312,6 @@ constexpr std::string_view kYieldNotCoveredError = "assertion failure with message: owed yield is rounding dust the WIRE received from sysio.liq does not " "cover; only later slack can cover it"; -/// Recent-actions reason `depositinle` records when it drops a credit naming the depot chain. -constexpr std::string_view kDepotChainCreditReason = - "depot-chain collateral is bonded through deposit, never credited from an outpost"; /// Account with no stake in the yield cases that cranks `claimyield` for someone else. constexpr auto kYieldKeeper = "uwrit.a"_n; diff --git a/contracts/tests/sysio.swap_tests.cpp b/contracts/tests/sysio.swap_tests.cpp index aee3f3e11e..62d040f975 100644 --- a/contracts/tests/sysio.swap_tests.cpp +++ b/contracts/tests/sysio.swap_tests.cpp @@ -2090,7 +2090,7 @@ BOOST_FIXTURE_TEST_CASE( yield_tick_sells_the_reservoir_over_the_horizon, sysio_ BOOST_REQUIRE_EQUAL( wasm_assert_msg("yield tick parameters not set"), tickyield( SHEO ) ); BOOST_REQUIRE_EQUAL( success(), setyield( SHEO, horizon_sec, cap_bps, clip_floor ) ); const int64_t set_at = last_tick_us( SHEO ); - BOOST_REQUIRE_EQUAL( control->head_block_time().time_since_epoch().count(), set_at ); // setyield starts the clock + BOOST_REQUIRE_EQUAL( control->head().block_time().time_since_epoch().count(), set_at ); // setyield starts the clock // An empty reservoir: the tick is a no-op and the clock is untouched. auto before = system_balance( SHEO.value ); diff --git a/libraries/appbase b/libraries/appbase index 40bcefdabb..fcb746bd5a 160000 --- a/libraries/appbase +++ b/libraries/appbase @@ -1 +1 @@ -Subproject commit 40bcefdabb2db7980a501e0d8b886e08d0fff98c +Subproject commit fcb746bd5ad076f43c99fcc5f6be9a0de4083f9f diff --git a/libraries/chain/include/sysio/chain/vote_processor.hpp b/libraries/chain/include/sysio/chain/vote_processor.hpp index 90023a8d36..fc0c290227 100644 --- a/libraries/chain/include/sysio/chain/vote_processor.hpp +++ b/libraries/chain/include/sysio/chain/vote_processor.hpp @@ -115,7 +115,7 @@ class vote_processor_t { for (auto i = idx.begin(); i != idx.end();) { if (stopped) return; - vote v = std::move(*i); + vote v = *i; idx.erase(i); auto bsp = get_block(v.msg->block_id, g); // g is unlocked diff --git a/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/code_cache.hpp b/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/code_cache.hpp index 26e7cce8ab..092cb341e5 100644 --- a/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/code_cache.hpp +++ b/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/code_cache.hpp @@ -121,7 +121,7 @@ class code_cache_async : public code_cache_base { //If code is in cache: returns pointer & bumps to front of MRU list //If code is not in cache, and not blacklisted, and not currently compiling: return nullptr and kick off compile //otherwise: return nullptr - const code_descriptor* const get_descriptor_for_code(mode m, account_name receiver, const digest_type& code_id, + const code_descriptor* get_descriptor_for_code(mode m, account_name receiver, const digest_type& code_id, const uint8_t& vm_version, get_cd_failure& failure); private: @@ -144,7 +144,7 @@ class code_cache_sync : public code_cache_base { ~code_cache_sync(); //Can still fail and return nullptr if, for example, there is an expected instantiation failure - const code_descriptor* const get_descriptor_for_code_sync(mode m, account_name receiver, + const code_descriptor* get_descriptor_for_code_sync(mode m, account_name receiver, const digest_type& code_id, const uint8_t& vm_version); }; diff --git a/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/memory.hpp b/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/memory.hpp index 4da95f5d78..a22321bf18 100644 --- a/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/memory.hpp +++ b/libraries/chain/include/sysio/chain/webassembly/sys-vm-oc/memory.hpp @@ -28,13 +28,13 @@ class memory { memory(const memory&) = delete; memory& operator=(const memory&) = delete; - uint8_t* const zero_page_memory_base() const { return zeropage_base; } - uint8_t* const full_page_memory_base() const { return fullpage_base; } + uint8_t* zero_page_memory_base() const { return zeropage_base; } + uint8_t* full_page_memory_base() const { return fullpage_base; } - control_block* const get_control_block() const { return reinterpret_cast(zeropage_base - cb_offset);} + control_block* get_control_block() const { return reinterpret_cast(zeropage_base - cb_offset);} //these two are really only inteded for SEGV handling - uint8_t* const start_of_memory_slices() const { return mapbase; } + uint8_t* start_of_memory_slices() const { return mapbase; } size_t size_of_memory_slice_mapping() const { return mapsize; } //to obtain memory protected for n wasm-pages, use the pointer computed from: diff --git a/libraries/chain/wasm_sysio_validation.cpp b/libraries/chain/wasm_sysio_validation.cpp index 46fbef2f4f..25f96e9468 100644 --- a/libraries/chain/wasm_sysio_validation.cpp +++ b/libraries/chain/wasm_sysio_validation.cpp @@ -49,6 +49,7 @@ void globals_validation_visitor::validate( const Module& m ) { case ValueType::i64: case ValueType::f64: mutable_globals_total_size += 4; + [[fallthrough]]; case ValueType::i32: case ValueType::f32: mutable_globals_total_size += 4; diff --git a/libraries/chain/webassembly/runtimes/sys-vm-oc/code_cache.cpp b/libraries/chain/webassembly/runtimes/sys-vm-oc/code_cache.cpp index 058f93fd4a..15d6613e22 100644 --- a/libraries/chain/webassembly/runtimes/sys-vm-oc/code_cache.cpp +++ b/libraries/chain/webassembly/runtimes/sys-vm-oc/code_cache.cpp @@ -160,7 +160,7 @@ std::tuple code_cache_async::consume_compile_thread_queue() { } -const code_descriptor* const +const code_descriptor* code_cache_async::get_descriptor_for_code(mode m, account_name receiver, const digest_type& code_id, const uint8_t& vm_version, get_cd_failure& failure) { //if there are any outstanding compiles, process the result queue now //When app is in write window, all tasks are running sequentially and read-only threads @@ -243,7 +243,7 @@ code_cache_sync::~code_cache_sync() { elog("unexpected response from SYS VM OC compile monitor during shutdown"); } -const code_descriptor* const code_cache_sync::get_descriptor_for_code_sync(mode m, account_name receiver, const digest_type& code_id, const uint8_t& vm_version) { +const code_descriptor* code_cache_sync::get_descriptor_for_code_sync(mode m, account_name receiver, const digest_type& code_id, const uint8_t& vm_version) { //check for entry in cache code_cache_index::index::type::iterator it = _cache_index.get().find(code_id); if(it != _cache_index.get().end()) { diff --git a/libraries/chain/webassembly/runtimes/sys-vm-oc/compile_trampoline.cpp b/libraries/chain/webassembly/runtimes/sys-vm-oc/compile_trampoline.cpp index 0465854513..9b12c9ca83 100644 --- a/libraries/chain/webassembly/runtimes/sys-vm-oc/compile_trampoline.cpp +++ b/libraries/chain/webassembly/runtimes/sys-vm-oc/compile_trampoline.cpp @@ -73,7 +73,7 @@ void run_compile(wrapped_fd&& response_sock, wrapped_fd&& wasm_code, uint64_t st if(!global.type.isMutable) continue; prologue_it -= 8; - global_union* const u = (global_union* const)&*prologue_it; + global_union* const u = (global_union*)&*prologue_it; switch(global.initializer.type) { case InitializerExpression::Type::i32_const: u->i32 = global.initializer.i32; break; diff --git a/libraries/chain/webassembly/runtimes/sys-vm-oc/gs_seg_helpers.c b/libraries/chain/webassembly/runtimes/sys-vm-oc/gs_seg_helpers.c index b2958d7bce..4e88f90b1a 100644 --- a/libraries/chain/webassembly/runtimes/sys-vm-oc/gs_seg_helpers.c +++ b/libraries/chain/webassembly/runtimes/sys-vm-oc/gs_seg_helpers.c @@ -21,7 +21,7 @@ int32_t sys_vm_oc_grow_memory(int32_t grow, int32_t max) { uint64_t previous_page_count = cb_ptr->current_linear_memory_pages; int32_t grow_amount = grow; uint64_t max_pages = max; - if(max_pages > cb_ptr->max_linear_memory_pages) + if(max_pages > (uint64_t)cb_ptr->max_linear_memory_pages) max_pages = cb_ptr->max_linear_memory_pages; if(grow == 0) return (int32_t)cb_ptr->current_linear_memory_pages; @@ -29,8 +29,8 @@ int32_t sys_vm_oc_grow_memory(int32_t grow, int32_t max) { return (int32_t)-1; int64_t max_segments = cb_ptr->execution_thread_memory_length / SYS_VM_OC_MEMORY_STRIDE - 1; - int was_extended = previous_page_count > max_segments; - int will_be_extended = previous_page_count + grow_amount > max_segments; + int was_extended = previous_page_count > (uint64_t)max_segments; + int will_be_extended = previous_page_count + grow_amount > (uint64_t)max_segments; char* extended_memory_start = cb_ptr->full_linear_memory_start + max_segments * 64*1024; int64_t gs_diff; if(will_be_extended && grow_amount > 0) { diff --git a/libraries/chain/webassembly/runtimes/sys-vm-oc/memory.cpp b/libraries/chain/webassembly/runtimes/sys-vm-oc/memory.cpp index a87c94ef52..a39eb27a7c 100644 --- a/libraries/chain/webassembly/runtimes/sys-vm-oc/memory.cpp +++ b/libraries/chain/webassembly/runtimes/sys-vm-oc/memory.cpp @@ -38,7 +38,7 @@ memory::memory(uint64_t sliced_pages) { fullpage_base = last + memory_prologue_size; //layout the intrinsic jump table - uintptr_t* const intrinsic_jump_table = reinterpret_cast(zeropage_base - first_intrinsic_offset); + uintptr_t* const intrinsic_jump_table = reinterpret_cast(zeropage_base - first_intrinsic_offset); const intrinsic_map_t& intrinsics = get_intrinsic_map(); for(const auto& intrinsic : intrinsics) intrinsic_jump_table[-(int)intrinsic.second.ordinal] = (uintptr_t)intrinsic.second.function_ptr; diff --git a/libraries/chaindb/test/undo_index.cpp b/libraries/chaindb/test/undo_index.cpp index cd4cfbd64a..a850f7f330 100644 --- a/libraries/chaindb/test/undo_index.cpp +++ b/libraries/chaindb/test/undo_index.cpp @@ -103,7 +103,8 @@ struct undo_index_in_segment { segment_manager.destroy_ptr(p); } - undo_index_t* const operator->() { + /// Access the stored index without applying an ignored qualifier to the returned pointer. + undo_index_t* operator->() { return p; } diff --git a/libraries/libfc/include/fc/bitset.hpp b/libraries/libfc/include/fc/bitset.hpp index d1e80a8cf8..317aeb1db0 100644 --- a/libraries/libfc/include/fc/bitset.hpp +++ b/libraries/libfc/include/fc/bitset.hpp @@ -27,8 +27,9 @@ struct bitset { static constexpr size_type bits_per_block = 8; static constexpr size_type npos = static_cast(-1); + /// Round up the storage requirement without overflowing at the maximum bit count. static constexpr size_type calc_num_blocks(size_type num_bits) { - return (num_bits + bits_per_block - 1) / bits_per_block; + return num_bits / bits_per_block + (num_bits % bits_per_block != 0); } static size_type block_index(size_type pos) noexcept { return pos / bits_per_block; } @@ -123,13 +124,14 @@ struct bitset { return *this; } + /// Clear padding only when a final storage block exists. void zero_unused_bits() { assert (m_bits.size() == calc_num_blocks(m_num_bits)); // if != 0 this is the number of bits used in the last block const size_type extra_bits = bit_index(size()); - if (extra_bits != 0) + if (!m_bits.empty() && extra_bits != 0) m_bits.back() &= (uint8_t(1) << extra_bits) - 1; } diff --git a/libraries/libfc/include/fc/exception/exception.hpp b/libraries/libfc/include/fc/exception/exception.hpp index 1d0abb47b1..68d3fe64d1 100644 --- a/libraries/libfc/include/fc/exception/exception.hpp +++ b/libraries/libfc/include/fc/exception/exception.hpp @@ -432,10 +432,21 @@ namespace fc throw e; \ } -#define FC_LOG_AND_DROP( FORMAT, ... ) \ - catch( const boost::interprocess::bad_alloc& ) {\ - throw;\ - } catch( fc::exception& er ) { \ +/// Log ordinary failures while allowing shared-memory allocation failures to propagate. +#define FC_LOG_AND_DROP( FORMAT, ... ) \ + catch( const boost::interprocess::bad_alloc& ) { \ + throw; \ + } FC_DETAIL_LOG_AND_DROP( FORMAT, ##__VA_ARGS__ ) + +/// Preserve the fail-fast allocation policy in a noexcept cleanup operation. +#define FC_LOG_AND_DROP_NOEXCEPT( FORMAT, ... ) \ + catch( const boost::interprocess::bad_alloc& ) { \ + std::terminate(); \ + } FC_DETAIL_LOG_AND_DROP( FORMAT, ##__VA_ARGS__ ) + +/// Common logging handlers; callers decide how to handle interprocess allocation failures. +#define FC_DETAIL_LOG_AND_DROP( FORMAT, ... ) \ + catch( fc::exception& er ) { \ wlog( FORMAT " {}", ##__VA_ARGS__, er.to_detail_string() ); \ } catch( const std::exception& e ) { \ fc::std_exception_wrapper sew( \ diff --git a/libraries/libfc/include/fc/io/json_relaxed.hpp b/libraries/libfc/include/fc/io/json_relaxed.hpp index 548789a6fe..c315a22c8e 100644 --- a/libraries/libfc/include/fc/io/json_relaxed.hpp +++ b/libraries/libfc/include/fc/io/json_relaxed.hpp @@ -188,6 +188,7 @@ namespace fc { namespace json_relaxed case 'r': if( strict ) FC_THROW_EXCEPTION( parse_error_exception, "raw strings not supported in strict mode" ); + [[fallthrough]]; case 'R': in.get(); c2 = in.peek(); diff --git a/libraries/libfc/include/fc/io/random_access_file.hpp b/libraries/libfc/include/fc/io/random_access_file.hpp index 2638ec21ff..ce15bbe7f5 100644 --- a/libraries/libfc/include/fc/io/random_access_file.hpp +++ b/libraries/libfc/include/fc/io/random_access_file.hpp @@ -371,11 +371,12 @@ class random_access_file { return write(&c, sizeof(char)); } + /// Flush pending bytes, dropping write errors and retaining fail-fast shared-memory OOM handling. ~write_datastream() { try { if(ctx) do_write(); - } FC_LOG_AND_DROP("write failure ignored"); + } FC_LOG_AND_DROP_NOEXCEPT("write failure ignored"); } private: diff --git a/libraries/libfc/include/fc/safe.hpp b/libraries/libfc/include/fc/safe.hpp index bbe693e1b7..8545114a7a 100644 --- a/libraries/libfc/include/fc/safe.hpp +++ b/libraries/libfc/include/fc/safe.hpp @@ -26,6 +26,8 @@ namespace fc { safe( O o ):value(o){} safe(){} safe( const safe& o ):value(o.value){} + /// Assign the checked value without changing its representation. + safe& operator=(const safe&) = default; static safe min() { diff --git a/libraries/libfc/src/crypto/elliptic_em.cpp b/libraries/libfc/src/crypto/elliptic_em.cpp index 3f6b40d675..ab6a78760c 100644 --- a/libraries/libfc/src/crypto/elliptic_em.cpp +++ b/libraries/libfc/src/crypto/elliptic_em.cpp @@ -49,6 +49,9 @@ class public_key_impl { _init_lib(); } + /// Preserve memberwise key assignment alongside the custom copy constructor. + public_key_impl& operator=(const public_key_impl&) = default; + public_key_data _key{}; }; diff --git a/libraries/libfc/src/crypto/ethereum/ethereum_utils.cpp b/libraries/libfc/src/crypto/ethereum/ethereum_utils.cpp index fa73cd08fe..7d1b61a11c 100644 --- a/libraries/libfc/src/crypto/ethereum/ethereum_utils.cpp +++ b/libraries/libfc/src/crypto/ethereum/ethereum_utils.cpp @@ -93,6 +93,7 @@ fc::em::public_key to_em_public_key(const std::string& pubkey_hex) { switch (pubkey_byte_count) { case 64: copy_to_offset = 1; + [[fallthrough]]; case 65: { em::public_key_data_uncompressed pubkey_data; std::copy_n(pubkey_bytes.data(), pubkey_bytes.size(), pubkey_data.data() + copy_to_offset); diff --git a/libraries/libfc/src/io/json.cpp b/libraries/libfc/src/io/json.cpp index 268703d4b6..e50334904c 100644 --- a/libraries/libfc/src/io/json.cpp +++ b/libraries/libfc/src/io/json.cpp @@ -319,6 +319,7 @@ namespace fc if (dot) FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places"); dot = true; + [[fallthrough]]; case '0': case '1': case '2': @@ -563,26 +564,31 @@ namespace fc out += "\\t"; break; } + [[fallthrough]]; case '\n': // \x0a if( escape_control_chars ) { out += "\\n"; break; } + [[fallthrough]]; case '\r': // \x0d if( escape_control_chars ) { out += "\\r"; break; } + [[fallthrough]]; case '\\': if( escape_control_chars ) { out += "\\\\"; break; } + [[fallthrough]]; case '\"': if( escape_control_chars ) { out += "\\\""; break; } + [[fallthrough]]; default: out += *itr; } diff --git a/libraries/libfc/test/io/test_secure_file.cpp b/libraries/libfc/test/io/test_secure_file.cpp index 3e48bf0738..15717ce54a 100644 --- a/libraries/libfc/test/io/test_secure_file.cpp +++ b/libraries/libfc/test/io/test_secure_file.cpp @@ -32,7 +32,7 @@ constexpr long minimum_long_filename_name_max = 64; /** * Owns an open file stream and closes its underlying descriptor when a test scope exits. */ -using file_stream_ptr = std::unique_ptr; +using file_stream_ptr = std::unique_ptr; /** * Restores the process umask when a test scope exits. diff --git a/libraries/libfc/test/network/test_http_client.cpp b/libraries/libfc/test/network/test_http_client.cpp index 76cd6f3185..2cfbbc5d3a 100644 --- a/libraries/libfc/test/network/test_http_client.cpp +++ b/libraries/libfc/test/network/test_http_client.cpp @@ -680,13 +680,13 @@ class tls_test_material { /** Write one PEM certificate. */ void write_certificate(std::string_view name, X509& certificate) { - std::unique_ptr output(std::fopen(path(name).c_str(), "w"), &std::fclose); + std::unique_ptr output(std::fopen(path(name).c_str(), "w"), &std::fclose); FC_ASSERT(output && PEM_write_X509(output.get(), &certificate) == 1, "Failed to write TLS test certificate"); } /** Write one unencrypted PEM private key. */ void write_key(std::string_view name, EVP_PKEY& key) { - std::unique_ptr output(std::fopen(path(name).c_str(), "w"), &std::fclose); + std::unique_ptr output(std::fopen(path(name).c_str(), "w"), &std::fclose); FC_ASSERT(output && PEM_write_PrivateKey(output.get(), &key, nullptr, nullptr, 0, nullptr, nullptr) == 1, "Failed to write TLS test private key"); } @@ -745,7 +745,7 @@ bool supports_ipv6_loopback() { /** Return the OpenSSL hashed-directory filename for @p certificate. */ std::string certificate_hash_filename(const std::filesystem::path& certificate) { - std::unique_ptr input(std::fopen(certificate.c_str(), "r"), &std::fclose); + std::unique_ptr input(std::fopen(certificate.c_str(), "r"), &std::fclose); BOOST_REQUIRE(input); std::unique_ptr parsed(PEM_read_X509(input.get(), nullptr, nullptr, nullptr), &X509_free); diff --git a/libraries/libfc/test/test_bitset.cpp b/libraries/libfc/test/test_bitset.cpp index 9d86e556c0..ffb3fb792a 100644 --- a/libraries/libfc/test/test_bitset.cpp +++ b/libraries/libfc/test/test_bitset.cpp @@ -2,6 +2,7 @@ #include #include +#include using namespace fc; @@ -167,4 +168,29 @@ BOOST_AUTO_TEST_CASE(bitset_test) test_bitset("01110011010100101111001101100100100111111111111111111001"); } +/// Extreme sizes must not wrap the byte count to zero before allocating storage. +BOOST_AUTO_TEST_CASE(storage_size_overflow) { + using size_type = fc::bitset::size_type; + constexpr auto max_bits = std::numeric_limits::max(); + constexpr auto max_blocks = size_type{1} << (std::numeric_limits::digits - 3); + BOOST_CHECK_EQUAL(fc::bitset::calc_num_blocks(max_bits), max_blocks); + BOOST_CHECK_EQUAL(fc::bitset::calc_num_blocks(max_bits - 6), max_blocks); + BOOST_CHECK_EQUAL(fc::bitset::calc_num_blocks(max_bits - 7), max_blocks - 1); + + // Exercise the same masking path with no block, a partial block, and a full block. + fc::bitset bits("111111111"); + bits.resize(1); + bits.resize(9); + BOOST_CHECK_EQUAL(bits.to_string(), "000000001"); + BOOST_CHECK(bits.unused_bits_zeroed()); + bits.resize(0); + bits.flip(); + BOOST_CHECK_EQUAL(bits.num_blocks(), 0u); + BOOST_CHECK(bits.unused_bits_zeroed()); + bits.resize(8); + bits.flip(); + BOOST_CHECK_EQUAL(bits.to_string(), "11111111"); + BOOST_CHECK(bits.unused_bits_zeroed()); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/libraries/libfc/test/test_exception.cpp b/libraries/libfc/test/test_exception.cpp index fbea7a9407..660b2a04d1 100644 --- a/libraries/libfc/test/test_exception.cpp +++ b/libraries/libfc/test/test_exception.cpp @@ -2,6 +2,10 @@ #include +#include +#include +#include + BOOST_AUTO_TEST_SUITE(exception) /** @@ -35,4 +39,48 @@ BOOST_AUTO_TEST_CASE(rethrow) try { } FC_LOG_AND_RETHROW(); +/// Preserve the existing policy: cleanup drops ordinary failures and the general macro propagates interprocess OOM. +BOOST_AUTO_TEST_CASE(cleanup_exception_policy) { + const auto cleanup = [](auto failure) noexcept { + try { + failure(); + } FC_LOG_AND_DROP_NOEXCEPT("cleanup regression") + }; + BOOST_CHECK_NO_THROW(cleanup([] { FC_THROW_EXCEPTION(fc::invalid_arg_exception, "expected cleanup failure"); })); + BOOST_CHECK_NO_THROW(cleanup([] { throw std::runtime_error("expected cleanup failure"); })); + BOOST_CHECK_NO_THROW(cleanup([] { throw 0; })); + const auto propagate = [] { + try { + throw boost::interprocess::bad_alloc(); + } FC_LOG_AND_DROP("allocation regression") + }; + BOOST_CHECK_THROW(propagate(), boost::interprocess::bad_alloc); +} + +/// Preserve the existing noexcept cleanup policy, which terminates on interprocess OOM. +BOOST_AUTO_TEST_CASE(cleanup_allocation_failure_terminates) { + constexpr int terminated = 73; + constexpr int returned = 74; + const auto child = ::fork(); + BOOST_REQUIRE(child >= 0); + if (child == 0) { + std::set_terminate([] { ::_exit(terminated); }); + const auto cleanup = []() noexcept { + try { + throw boost::interprocess::bad_alloc(); + } FC_LOG_AND_DROP_NOEXCEPT("allocation regression") + }; + cleanup(); + ::_exit(returned); + } + int status = 0; + pid_t waited; + do { + waited = ::waitpid(child, &status, 0); + } while (waited == -1 && errno == EINTR); + BOOST_REQUIRE_EQUAL(waited, child); + BOOST_REQUIRE(WIFEXITED(status)); + BOOST_CHECK_EQUAL(WEXITSTATUS(status), terminated); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/libraries/opp/client_config/src/client_config_loader.cpp b/libraries/opp/client_config/src/client_config_loader.cpp index 90bda2409e..72ff581313 100644 --- a/libraries/opp/client_config/src/client_config_loader.cpp +++ b/libraries/opp/client_config/src/client_config_loader.cpp @@ -34,7 +34,6 @@ constexpr std::string_view max_priority_fee_per_gas_wei = "max_priority_fee_per_ constexpr std::string_view max_fee_per_gas_wei = "max_fee_per_gas_wei"; constexpr std::string_view max_gas_limit = "max_gas_limit"; constexpr std::string_view max_total_native_cost_wei = "max_total_native_cost_wei"; -constexpr std::string_view read_confirmation = "read_confirmation"; constexpr std::string_view block_tag = "block_tag"; constexpr std::string_view confirmations = "confirmations"; constexpr std::string_view max_finality_lag_sec = "max_finality_lag_sec"; diff --git a/libraries/wasm-jit/Source/ThirdParty/dtoa.c b/libraries/wasm-jit/Source/ThirdParty/dtoa.c index 9a6aae4e79..41f0b4a24d 100644 --- a/libraries/wasm-jit/Source/ThirdParty/dtoa.c +++ b/libraries/wasm-jit/Source/ThirdParty/dtoa.c @@ -1865,7 +1865,7 @@ gethex( CONST char **sp, U *rvp, int rounding, int sign) switch(*++s) { case '-': esign = 1; - /* no break */ + /* fall through */ case '+': s++; } @@ -2532,11 +2532,11 @@ strtod for(s = s00;;s++) switch(*s) { case '-': sign = 1; - /* no break */ + /* fall through */ case '+': if (*++s) goto break2; - /* no break */ + /* fall through */ case 0: goto ret0; case '\t': @@ -2644,6 +2644,7 @@ strtod switch(c = *++s) { case '-': esign = 1; + /* fall through */ case '+': c = *++s; } @@ -3898,7 +3899,7 @@ dtoa break; case 2: leftright = 0; - /* no break */ + /* fall through */ case 4: if (ndigits <= 0) ndigits = 1; @@ -3906,7 +3907,7 @@ dtoa break; case 3: leftright = 0; - /* no break */ + /* fall through */ case 5: i = ndigits + k + 1; ilim = i; diff --git a/plugins/chain_plugin/src/account_query_db.cpp b/plugins/chain_plugin/src/account_query_db.cpp index e100204881..8d5651c3b0 100644 --- a/plugins/chain_plugin/src/account_query_db.cpp +++ b/plugins/chain_plugin/src/account_query_db.cpp @@ -412,14 +412,15 @@ namespace sysio::chain_apis { const auto& authorizer = itr->first.value; auto weight = itr->first.weight; - result.accounts.emplace_back(result_t::account_result{ + // Construct the aggregate in place, including disengaged optional authorizers. + result.accounts.emplace_back( pi.owner, pi.name, make_optional_authorizer(authorizer), make_optional_authorizer(authorizer), weight, pi.threshold - }); + ); } }; diff --git a/plugins/chain_plugin/src/chain_plugin.cpp b/plugins/chain_plugin/src/chain_plugin.cpp index 49cc599a00..0eff2d1f31 100644 --- a/plugins/chain_plugin/src/chain_plugin.cpp +++ b/plugins/chain_plugin/src/chain_plugin.cpp @@ -1095,7 +1095,7 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) { } chain_config->sig_cpu_bill_pct = options.at("signature-cpu-billable-pct").as(); - SYS_ASSERT( chain_config->sig_cpu_bill_pct >= 0 && chain_config->sig_cpu_bill_pct <= 100, plugin_config_exception, + SYS_ASSERT( chain_config->sig_cpu_bill_pct <= 100, plugin_config_exception, "signature-cpu-billable-pct must be 0 - 100, {}", chain_config->sig_cpu_bill_pct ); chain_config->sig_cpu_bill_pct *= config::percent_1; diff --git a/plugins/http_plugin/include/sysio/http_plugin/common.hpp b/plugins/http_plugin/include/sysio/http_plugin/common.hpp index 758e1c45b9..665613b4bd 100644 --- a/plugins/http_plugin/include/sysio/http_plugin/common.hpp +++ b/plugins/http_plugin/include/sysio/http_plugin/common.hpp @@ -218,7 +218,7 @@ inline auto make_http_response_handler(http_plugin_state& plugin_state, detail:: if (content_type == http_content_type::plaintext && !plaintext_body) session_ptr->set_content_type_header(http_content_type::json); // HTTP 204 never carries a body, including JSON-RPC notifications. - if (code == magic_enum::enum_integer(boost::beast::http::status::no_content)) { + if (code == static_cast(magic_enum::enum_integer(boost::beast::http::status::no_content))) { session_ptr->send_response({}, code); } else if (response.has_value()) { std::string json = plaintext_body diff --git a/plugins/net_plugin/include/sysio/net_plugin/buffer_factory.hpp b/plugins/net_plugin/include/sysio/net_plugin/buffer_factory.hpp index f63f8f7a2e..baaeefae38 100644 --- a/plugins/net_plugin/include/sysio/net_plugin/buffer_factory.hpp +++ b/plugins/net_plugin/include/sysio/net_plugin/buffer_factory.hpp @@ -29,7 +29,7 @@ namespace sysio { static send_buffer_type create_send_buffer( const net_message& m ) { const uint32_t payload_size = fc::raw::pack_size( m ); - const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t + const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t const size_t buffer_size = message_header_size + payload_size; auto send_buffer = std::make_shared>(buffer_size); @@ -46,7 +46,7 @@ namespace sysio { const uint32_t which_size = fc::raw::pack_size( unsigned_int( which ) ); const uint32_t payload_size = which_size + fc::raw::pack_size( v ); - const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t + const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t const size_t buffer_size = message_header_size + payload_size; auto send_buffer = std::make_shared>( buffer_size ); @@ -65,7 +65,7 @@ namespace sysio { const uint32_t which_size = fc::raw::pack_size( unsigned_int( signed_block_which ) ); const uint32_t payload_size = which_size + v.size(); - const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t + const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t const size_t buffer_size = message_header_size + payload_size; auto send_buffer = std::make_shared>( buffer_size ); @@ -143,7 +143,7 @@ namespace sysio { const uint32_t trx_size = fc::raw::pack_size( *trx ); const uint32_t payload_size = which_size + id_size + trx_size; - const char* const header = reinterpret_cast(&payload_size); + const char* const header = reinterpret_cast(&payload_size); const size_t buffer_size = message_header_size + payload_size; auto send_buffer = std::make_shared>( buffer_size ); @@ -183,7 +183,7 @@ namespace sysio { const uint32_t msg_size = fc::raw::pack_size( msg ); const uint32_t payload_size = which_size + id_size + msg_size; - const char* const header = reinterpret_cast(&payload_size); + const char* const header = reinterpret_cast(&payload_size); const size_t buffer_size = message_header_size + payload_size; auto send_buffer = std::make_shared>( buffer_size ); @@ -223,7 +223,7 @@ namespace sysio { } const uint32_t payload_size = which_size + s; - const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t + const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t const size_t buffer_size = message_header_size + payload_size; auto send_buffer = std::make_shared>( buffer_size ); @@ -263,7 +263,7 @@ namespace sysio { s += fc::raw::pack_size(signed_empty); const uint32_t payload_size = which_size + s; - const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t + const char* const header = reinterpret_cast(&payload_size); // avoid variable size encoding of uint32_t const size_t buffer_size = message_header_size + payload_size; auto send_buffer = std::make_shared>( buffer_size ); diff --git a/plugins/outpost_ethereum_client_plugin/test/test_outpost_ethereum_client_plugin.cpp b/plugins/outpost_ethereum_client_plugin/test/test_outpost_ethereum_client_plugin.cpp index 4ea2f2e475..274234d0fb 100644 --- a/plugins/outpost_ethereum_client_plugin/test/test_outpost_ethereum_client_plugin.cpp +++ b/plugins/outpost_ethereum_client_plugin/test/test_outpost_ethereum_client_plugin.cpp @@ -179,9 +179,6 @@ constexpr std::string_view emit_outbound_envelope_abi_name = "emitOutboundEnvelo constexpr std::string_view emit_outbound_envelope_selector = "a3ad9cc3"; constexpr std::string_view test_opp_address = "5FbDB2315678afecb367f032d93F642f64180aa3"; const std::string latest_slot_test_rpc_url = startup_test::unused_url(); -constexpr std::string_view http_scheme_prefix = "http://"; -/** Prefix identifying the bounded transport category in chain-id startup diagnostics. */ -constexpr std::string_view last_failure_detail_prefix = "last_failure="; constexpr std::string_view latest_slot_test_entry_id = "latest-slot-test"; constexpr std::string_view latest_slot_test_private_key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; @@ -199,7 +196,6 @@ constexpr size_t emit_outbound_envelope_call_hex_chars = evm_function_selector_hex_chars + evm_abi_word_hex_chars; constexpr uint64_t test_outpost_chain_code = 1; constexpr uint32_t test_evm_chain_id = 31337; -constexpr size_t transient_chain_id_failures = 1; constexpr uint32_t test_wire_epoch = 7; constexpr uint32_t test_stale_wire_epoch = test_wire_epoch - 1; constexpr uint32_t test_different_wire_epoch = test_wire_epoch + 1; diff --git a/plugins/trace_api_plugin/src/store_provider.cpp b/plugins/trace_api_plugin/src/store_provider.cpp index bea469cf72..70509e1cb7 100644 --- a/plugins/trace_api_plugin/src/store_provider.cpp +++ b/plugins/trace_api_plugin/src/store_provider.cpp @@ -372,7 +372,7 @@ namespace sysio::trace_api { result.open(); } - return std::move(result); + return result; } else { return {}; } diff --git a/programs/clio/do_http_post_libcurl.cpp b/programs/clio/do_http_post_libcurl.cpp index 803f444828..7713fb8475 100644 --- a/programs/clio/do_http_post_libcurl.cpp +++ b/programs/clio/do_http_post_libcurl.cpp @@ -51,6 +51,7 @@ namespace sysio { namespace client { namespace http { switch (type) { case CURLINFO_TEXT: fprintf(stderr, "== Info: %s", data); + [[fallthrough]]; default: /* in case a new one is introduced to shock us */ return 0; case CURLINFO_HEADER_OUT: text = "=> Send header"; break; diff --git a/programs/clio/main.cpp b/programs/clio/main.cpp index cf297bb04a..e815a51b4a 100644 --- a/programs/clio/main.cpp +++ b/programs/clio/main.cpp @@ -640,7 +640,7 @@ fc::variant json_from_file_or_string(const string& file_or_str, fc::json::parse_ } else if (looks_like_json) { try { return fc::json::from_string(file_or_str, ptype); - } SYS_RETHROW_EXCEPTIONS(json_parse_exception, "Fail to parse JSON from string: {}", ("string", file_or_str)); + } SYS_RETHROW_EXCEPTIONS(json_parse_exception, "Fail to parse JSON from string: {}", file_or_str); } else { return file_or_str; } diff --git a/tests/trx_generator/trx_provider.cpp b/tests/trx_generator/trx_provider.cpp index 63fc7d6c01..d0705095b8 100644 --- a/tests/trx_generator/trx_provider.cpp +++ b/tests/trx_generator/trx_provider.cpp @@ -46,7 +46,7 @@ namespace sysio::testing { const uint32_t payload_size = fc::raw::pack_size(net_msg); const size_t buffer_size = message_header_size + payload_size; // Avoid variable-size encoding for the fixed-width P2P length prefix. - const char* const header = reinterpret_cast(&payload_size); + const char* const header = reinterpret_cast(&payload_size); auto send_buffer = std::make_shared>(buffer_size); fc::datastream ds(send_buffer->data(), buffer_size); @@ -109,7 +109,7 @@ namespace sysio::testing { const size_t buffer_size = message_header_size + payload_size; // Avoid variable-size encoding for the fixed-width P2P length prefix. - const char* const header = reinterpret_cast(&payload_size); + const char* const header = reinterpret_cast(&payload_size); auto send_buffer = std::make_shared>(buffer_size); fc::datastream ds( send_buffer->data(), buffer_size); diff --git a/unittests/fork_db_tests.cpp b/unittests/fork_db_tests.cpp index 9f7e9e6b7b..3c2bdd9dfb 100644 --- a/unittests/fork_db_tests.cpp +++ b/unittests/fork_db_tests.cpp @@ -303,7 +303,7 @@ BOOST_AUTO_TEST_CASE(locks_out_branch_of_test) try { }; // root (block 10) - // / \ + // / \ (branches) // bsp11a bsp11b // | | // bsp12a bsp12b @@ -536,7 +536,7 @@ BOOST_AUTO_TEST_CASE(locks_out_branch_of_lib_advanced_past_shared_ancestor) try // root (block 10) // | // bsp11_shared (block 11) <-- shared ancestor; will be qc_target - // / \ + // / \ (branches) // bsp12a bsp12b (carries strong QC for 11) // | | // bsp13a_shared bsp13b (carries strong QC for 12, lib advances to 11) diff --git a/unittests/snapshot_tests.cpp b/unittests/snapshot_tests.cpp index ba962914f6..52c70affd1 100644 --- a/unittests/snapshot_tests.cpp +++ b/unittests/snapshot_tests.cpp @@ -1815,8 +1815,7 @@ BOOST_AUTO_TEST_CASE( snapshot_perf_benchmark ) // Large-scale benchmark of the two KV sections, which hold nearly all contract state. // // Build with RUN_PERF_BENCHMARKS defined for this file, then run: -// TMPDIR= ./unit_test --run_test=snapshot_part2_tests/snapshot_large_benchmark \ -// --log_level=message -- --sys-vm +// TMPDIR= ./unit_test --run_test=snapshot_part2_tests/snapshot_large_benchmark --log_level=message -- --sys-vm // // TMPDIR holds the mapped state and the snapshot, so a tmpfs would hide the file I/O and rule out KV_SNAP_BENCH_COLD. //