Skip to content

Lazy formatting for logger calls#5046

Merged
pwojcikdev merged 17 commits intonanocurrency:developfrom
pwojcikdev:formatting-improvements-2
Mar 24, 2026
Merged

Lazy formatting for logger calls#5046
pwojcikdev merged 17 commits intonanocurrency:developfrom
pwojcikdev:formatting-improvements-2

Conversation

@pwojcikdev
Copy link
Copy Markdown
Contributor

Replace eager string conversions in logger call sites with lazy formatting using fmt::formatter specializations. This avoids unnecessary string allocations when the log level is disabled. Add lazy wrappers (nano::log::as_account, as_node_id, as_nano, as_raw_nano), and channel formatting support. Make nano::account a distinct type from public_key so it automatically formats in account notation (nano_...).

@gr0vity-dev-bot
Copy link
Copy Markdown

gr0vity-dev-bot commented Mar 20, 2026

Test Results for Commit 55cb4ac

Pull Request 5046: Results
Overall Status:

Test Case Results

  • 5n4pr_conf_10k_bintree: PASS (Duration: 108s)
  • 5n4pr_conf_10k_change: PASS (Duration: 156s)
  • 5n4pr_conf_change_dependant: PASS (Duration: 127s)
  • 5n4pr_conf_change_independant: PASS (Duration: 129s)
  • 5n4pr_conf_send_dependant: PASS (Duration: 127s)
  • 5n4pr_conf_send_independant: PASS (Duration: 123s)
  • 5n4pr_rocks_10k_bintree: PASS (Duration: 122s)
  • 5n4pr_rocks_10k_change: FAIL (Duration: 279s)
  • Log

Last updated: 2026-03-24 04:29:23 UTC

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates logging and formatting across the Nano node codebase to avoid eager string conversions at call sites by relying on fmt formatting support (including new lazy wrappers) so disabled log levels don’t pay conversion/allocation costs. It also introduces a distinct nano::account type (separate from public_key) to enable account-notation formatting and adds channel formatting support for transport logging.

Changes:

  • Replace many logger call-site .to_string() / .to_account() conversions with lazy formatting via fmt::formatter support and nano::log::as_* wrappers.
  • Introduce nano::account as a distinct type from public_key, add DB conversion and hashing support, and adjust affected APIs/usages.
  • Add reusable balance/channel formatting utilities and refactor balance formatting to support stream-based encoding.

Reviewed changes

Copilot reviewed 47 out of 47 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
nano/test_common/system.cpp Uses lazy node-id formatting in startup logs.
nano/test_common/rate_observer.cpp Switches stat enum stringification to ADL-friendly to_string usage.
nano/store/db_val.hpp Adds db_val conversion operator to nano::account.
nano/store/db_val_templ.hpp Implements db_valnano::account conversion via byte read.
nano/secure/ledger.hpp Changes epoch_signer/epoch_link to return by value (supports new account semantics).
nano/secure/ledger.cpp Replaces eager balance formatting with lazy as_nano; minor cleanup in linked-account logic; updates epoch helpers.
nano/rpc/rpc.cpp Avoids eager address .to_string() in warning log.
nano/rpc_test/rpc_context.hpp Updates forward declarations for new nano::account type.
nano/rpc_test/common.hpp Updates forward declarations for new nano::account type.
nano/qt/qt.hpp Adjusts wallet ctor/member types to reflect account vs public_key separation.
nano/qt/qt.cpp Updates wallet constructor implementation to match new signature/type storage.
nano/node/wallet.cpp Replaces eager account/hash/amount string conversions in wallet logs with lazy formatting wrappers and direct formatting.
nano/node/transport/tcp_listener.cpp Formats endpoint type enum lazily (no eager to_string at call site).
nano/node/transport/tcp_channels.cpp Adds formatting support includes; removes eager node-id/channel conversions in logs.
nano/node/transport/formatting.hpp Adds fmt formatters for channels and shared_ptr<channel> for lazy logging.
nano/node/request_aggregator.cpp Removes eager channel .to_string() from debug logs via channel formatter.
nano/node/repcrawler.cpp Uses lazy formatting for representative accounts and channels.
nano/node/portmapping.cpp Removes eager external address .to_string() in logs.
nano/node/online_reps.cpp Uses as_nano for balances and formats accounts lazily.
nano/node/node.cpp Uses lazy node-id formatting and avoids eager genesis/account string conversions.
nano/node/network.cpp Removes eager channel .to_string() in connect observer log.
nano/node/monitor.cpp Uses as_nano for quorum/weights in monitor logs.
nano/node/bounded_backlog.cpp Removes eager hash .to_string() in rollback logs.
nano/node/bootstrap/frontier_strategy.cpp Removes eager channel .to_string() in debug logs.
nano/node/bootstrap/dependency_strategy.cpp Removes eager channel .to_string() in debug logs.
nano/node/bootstrap/bootstrap_context.cpp Removes eager channel .to_string() across multiple bootstrap request logs.
nano/node/block_processor.cpp Removes eager hash/source/channel conversions; relies on enum/channel formatters.
nano/nano_node/benchmarks/benchmarks.cpp Uses fmt::print instead of std::cout << fmt::format to avoid intermediate string creation.
nano/nano_node/benchmarks/benchmark_pipeline.cpp Converts multiple benchmark output lines to fmt::print.
nano/nano_node/benchmarks/benchmark_elections.cpp Converts multiple benchmark output lines to fmt::print.
nano/nano_node/benchmarks/benchmark_cementing.cpp Converts multiple benchmark output lines to fmt::print.
nano/nano_node/benchmarks/benchmark_block_processing.cpp Converts multiple benchmark output lines to fmt::print.
nano/lib/thread_runner.cpp Logs thread role enum lazily (no eager to_string).
nano/lib/stats.cpp Logs stat::sample lazily via enum formatter.
nano/lib/stats_enums.hpp Moves stat to_string declarations into namespace nano::stat.
nano/lib/stats_enums.cpp Implements stat to_string in namespace nano::stat.
nano/lib/object_stream_adapters.hpp Removes the generic fmt formatter adapter for all object-streamable types (prefers explicit wrapping).
nano/lib/numbers.hpp Introduces nano::account class (distinct from public_key); adds encode_node_id to public_key.
nano/lib/numbers.cpp Implements public_key::encode_node_id; refactors balance formatting into stream-based encoder.
nano/lib/numbers_templ.hpp Adds std::hash and boost::hash specializations for nano::account.
nano/lib/fwd.hpp Updates forward declaration from using account = public_key to class account.
nano/lib/formatting.hpp Adds generic enum formatter (ADL to_string), new lazy log wrappers, and additional type formatters.
nano/lib/balance_formatting.hpp New reusable balance encoding helpers (stream-based, precision/grouping).
nano/core_test/vote_cache.cpp Updates helper signature for account const-correctness.
nano/core_test/object_stream.cpp Updates fmt adapter test to use explicit nano::streamed wrapping.
nano/core_test/numbers.cpp Adds tests for new balance encoding path; renames/extends balance formatting tests.
nano/core_test/enums.cpp Updates stat enum to_string tests to use unqualified to_string (ADL) after namespace move.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@pwojcikdev pwojcikdev force-pushed the formatting-improvements-2 branch 2 times, most recently from 7958272 to 8538f0b Compare March 23, 2026 11:45
@pwojcikdev pwojcikdev requested a review from Copilot March 23, 2026 14:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 47 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 47 out of 47 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 247 to +250
logger.info (nano::log::type::ledger, "Active balance: {} | pending: {} | burned: {}",
nano::uint128_union{ static_cast<nano::uint128_t> (active_balance) }.format_balance (nano::nano_ratio, 0, true),
nano::uint128_union{ static_cast<nano::uint128_t> (pending_balance) }.format_balance (nano::nano_ratio, 0, true),
nano::uint128_union{ static_cast<nano::uint128_t> (burned_balance) }.format_balance (nano::nano_ratio, 0, true));
nano::log::as_nano (static_cast<nano::uint128_t> (active_balance)),
nano::log::as_nano (static_cast<nano::uint128_t> (pending_balance)),
nano::log::as_nano (static_cast<nano::uint128_t> (burned_balance)));
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nano::log::as_nano() defaults to precision=1, but these log lines previously used format_balance(..., precision=0, ...). This changes the log output (e.g., showing 1 decimal or “< 0.1”) compared to the prior behavior. Pass an explicit precision of 0 to as_nano here to preserve existing output.

Copilot uses AI. Check for mistakes.
Comment on lines 251 to +253
logger.info (nano::log::type::ledger, "Weight committed: {} | unused: {}",
nano::uint128_union{ rep_weights.get_weight_committed () }.format_balance (nano::nano_ratio, 0, true),
nano::uint128_union{ rep_weights.get_weight_unused () }.format_balance (nano::nano_ratio, 0, true));
nano::log::as_nano (rep_weights.get_weight_committed ()),
nano::log::as_nano (rep_weights.get_weight_unused ()));
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same precision issue as above: these calls replaced format_balance(..., precision=0, ...) but use as_nano() without specifying precision, which defaults to 1. Consider calling as_nano(value, 0) here to keep log output stable.

Copilot uses AI. Check for mistakes.
rep.first.to_account (),
nano::uint128_union (rep.second).format_balance (nano_ratio, 0, true));
rep.first,
nano::log::as_nano (rep.second));
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This log previously formatted the bootstrap rep weight with format_balance(..., precision=0, ...), but nano::log::as_nano() defaults to precision=1. If the intent is only to make formatting lazy (not to change output), pass an explicit precision of 0 here.

Suggested change
nano::log::as_nano (rep.second));
nano::log::as_nano (rep.second, 0));

Copilot uses AI. Check for mistakes.
Add `nano::log::as_account` and `nano::log::as_node_id`
wrappers so log formatting can stream public keys without
creating temporary strings.

Implement ostream-based node ID encoding and update log
call sites to use the new wrappers.
Replace the `account` alias with a dedicated class derived from
`public_key` and add the formatter, hash, forward declarations, and
`db_val` conversion needed to use it across the codebase.

Adjust wallet, Qt, RPC test, and vote cache interfaces to match the
new type semantics and avoid storing mutable account references.
Replace benchmark log statements that streamed `fmt::format(...)`
into `std::cout` with direct `fmt::print(...)` calls.
Extract shared balance formatting helpers into
`balance_formatting.hpp` and add `uint128_union::encode_balance()`
so callers can write formatted balances directly to streams.
Expose a free encode_balance overload for uint128_t values
and update as_nano/as_raw_nano to format by reference
without constructing temporary uint128_union instances.
@pwojcikdev pwojcikdev force-pushed the formatting-improvements-2 branch from 55cb4ac to 2623ba3 Compare March 24, 2026 12:37
@pwojcikdev pwojcikdev merged commit 6ef4b55 into nanocurrency:develop Mar 24, 2026
27 of 28 checks passed
@pwojcikdev pwojcikdev deleted the formatting-improvements-2 branch March 24, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants